v0.4.1: add integrity envelopes, typed approvals, runtime preconditions and executable-plan artifacts - #25
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fe06c492a1
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| approval_time = evaluated_at or max( | ||
| (item.approved_at for item in supplied_approvals), default=datetime.min.replace(tzinfo=None) | ||
| ) |
There was a problem hiding this comment.
Check expiration against the actual evaluation time
When callers omit evaluated_at, this substitutes the latest approval's own approved_at timestamp rather than the time admission is being evaluated. Consequently, evidence approved on January 1 and expired on January 2 remains valid when the same proposal is admitted months later, because valid_for evaluates it at January 1. Use a trusted current/evaluation time, or require evaluated_at, so expired approval evidence cannot admit governed changes.
Useful? React with 👍 / 👎.
| approved_ids = { | ||
| item.approval_id | ||
| for item in supplied_approvals | ||
| if approval_time.tzinfo is not None | ||
| and item.valid_for(approval_subject, item.approval_id, approval_time) | ||
| } |
There was a problem hiding this comment.
Match approval evidence by gate ID
For normal evidence where approval_id is a unique evidence identifier and gate_id names the gate being approved, this passes approval_id as the expected gate and later compares approval IDs with the outstanding gate strings. Such valid evidence can never clear its gate unless clients duplicate the gate string into both fields, defeating the newly distinct typed identifiers. Validate each item against its gate_id and collect the matching gate IDs instead.
Useful? React with 👍 / 👎.
| desired_revision=plan.to_revision, | ||
| fingerprint=fingerprint, | ||
| operations=operations, | ||
| admission_decision_digest=plan.source_admission_digest, |
There was a problem hiding this comment.
Include the admission binding in the executable fingerprint
The newly added admission_decision_digest is forwarded to providers as provenance, but it is assigned only after the fingerprint core has been computed. A loaded executable plan can therefore have this field changed without changing fingerprint, and the executor's integrity check still passes before sending the forged decision digest in ProviderContext. Bind this field into the fingerprint payload so executable provenance cannot be altered independently.
Useful? React with 👍 / 👎.
Motivation
Description
0.4.1and add release notes and documentation (CHANGELOG.md,README.md,docs/artefact-chain-v0.4.1.md,SECURITY.md).canonical.pyand useCANONICALIZATION_PROFILE/sha256across artefacts.AdmissionDecisionnow computesdecision_digest/decision_idand exposesintegrity_payload/verify_integrity, andReconciliationPlanexposesplan_digestwithintegrity_payload/verify_integrity; addverify_admission_integrityandverify_plan_integrityinplanning.py.ApprovalEvidence) includingsubject_digest,gate_id,approver,expires_at,verification_status, and verification helper logic to enforce verified, unexpired approvals.desired_revision_from_admissionincontrolplane/models.pythat validates the admission envelope before constructingDesiredRevisionrecords and introducedLegacyAdmissionRecordread-adapter.admit_changenow binds and validates approvals, computes decision envelope;build_planenforces admission integrity and emits integrity-bound plan envelopes;compile_planvalidates plan integrity, resolves capability declarations, enforces idempotency/compensation constraints and emits executable fingerprints.RuntimeFactsandoffline_demo_factsto explicitly inject sovereign facts into the executor; runtime executor now requiresfacts, evaluates preconditions (_failed_precondition) and records precondition failures as evidence; enforce provider dry-run/idempotency/compensation semantics before invoking providers.prior_valuefor compensation, and support a broader capability set used by compilation.approval-v0.4.1.schema.json,desired-revision-v0.4.1.schema.json,executable-plan-v0.4.1.schema.json, and numerous updates to existingadmission,plan,observedschemas.tests/test_chain_integrity.py, updates totests/test_planning.pyandtests/test_runtime.py).Testing
pytest -q; the full test suite includingtests/test_chain_integrity.py,tests/test_planning.py, andtests/test_runtime.pyexecuted and passed.desired_revision_from_admissionactivation guards, compile-time capability checks, and runtime precondition failures and compensation behavior; all assertions succeeded.offline_demo_factswere exercised by tests covering dry-run, retry, observation, resume and compensation semantics and reported as passing.Codex Task