You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
operator-proposal schema accepts approval.via on a policy approval, and the loader drops it #46
With #42, config/schemas/v1/operator-proposal.schema.json gives an approval an optional via (terminal or unknown). Only a person's approval should carry it, and the Python model rejects a policy approval that has one. The schema doesn't say that: it accepts via on an autonomous (OperatorPolicy) approval, and when such a receipt is loaded, the field is silently dropped.
So a receipt that passes schema validation can lose data on load, and the schema and the loader disagree about what a valid receipt is.
Expected
The schema refuses via on a policy approval (for example an if/then on the approval's kind), or the loader refuses the receipt instead of dropping the field. Either way, the schema and the loader agree.
config/schemas/v1/operator-proposal.schema.json gives approval.via an enum and nothing ties it to mode, so {"mode": "autonomous", "via": "terminal"} passes validation
The proposal loader (sdk/src/cloudfall/operator.py, around line 598) reads via only when mode == "human", so on an autonomous approval the field is silently dropped. ApprovalRecord itself refuses that combination, so the schema is looser than the model
No code writes via on an autonomous approval. Only a hand-edited receipt can hold one
Design. This tightens a published v1 schema. That is a contract change, but a narrow one: it refuses only a shape that the model already calls invalid and that no code writes. Nothing in a decisions log is departed from (there is none yet).
In the approval object, an ifmode is autonomous, thenvia is not allowed. A receipt with that shape then fails schema validation when it loads, like any other invalid receipt, instead of losing the field
A test that a receipt with an autonomous approval and a via is refused, and that human receipts with and without via (older ones) still load
CHANGELOG under Fixed
Compatibility: a receipt someone edited by hand into that shape stops loading. Code never wrote one
Activity
shipmill-romamo commentedon Oct 9, 2026
Triage: implement.
Confirmed on
main(20b33c7):config/schemas/v1/operator-proposal.schema.jsongivesapproval.viaan enum and nothing ties it tomode, so{"mode": "autonomous", "via": "terminal"}passes validationsdk/src/cloudfall/operator.py, around line 598) readsviaonly whenmode == "human", so on an autonomous approval the field is silently dropped.ApprovalRecorditself refuses that combination, so the schema is looser than the modelviaon an autonomous approval. Only a hand-edited receipt can hold oneDesign. This tightens a published v1 schema. That is a contract change, but a narrow one: it refuses only a shape that the model already calls invalid and that no code writes. Nothing in a decisions log is departed from (there is none yet).
approvalobject, anifmodeisautonomous,thenviais not allowed. A receipt with that shape then fails schema validation when it loads, like any other invalid receipt, instead of losing the fieldviais refused, and that human receipts with and withoutvia(older ones) still loadshipmill-romamo commentedon Oct 9, 2026
Released in v0.6.0rc7.