Skip to content

v0.3.2 — change-control every recorded human decision

Choose a tag to compare

@mikim mikim released this 19 Jul 06:01
aac49ef

Extends the register policy diff from "reviewed items cannot silently disappear" (v0.3.1) to change control over every recorded human decision: acceptance, terminal dispositions, accountability, re-review commitments, both residual assessment axes, and the assurance-graph edges. From a fifth external review of v0.3.1. No schema changes; existing adopters see stricter drift findings only on pull requests that change a reviewed decision. See CHANGELOG.md.

Canonical pin for adopters: v0.3.2 @ aac49ef7f0d8a8e8762113df8b7bf1784eaa2e54 (this tag's commit).

Review class: SOLE_OWNER_ATTESTED + AUTOMATION_VERIFIED. The external technical review is cited, not counted as an approving review (GOVERNANCE.md §2).

Fixed — register policy diff: human decisions are change-controlled

  • Residual acceptance is gated. Any status transition into ACCEPTED is now a finding. Accepting a risk is a human decision (PROFILE.md §3, §12) and the acceptance fields are self-declared strings, so an agent could previously fabricate accepted_by/accepted_at/acceptance_rationale, flip a critical residual OPEN → ACCEPTED, and turn a failing CONFORMANT state green with no finding. Rewriting or removing an existing acceptance record is likewise a finding.
  • A recorded judgement value cannot be silently unset. Every weakening check is pair-keyed, so unsetting a value was a free first hop — drop it in one pull request (nothing to compare, silent), record the weaker value in the next (no baseline, silent), while the one-step edit was an error the whole time. Removing, emptying, or de-stringing status (all registers), severity, proof_tier, impact, uncertainty, or an INTENDED intent.classification is now a finding. The residual/defeater disposition gates additionally fire on the head arriving at a gated status whatever the base recorded.
  • Defeater terminal dispositions are gated. MITIGATED → RESOLVED and MITIGATED → WITHDRAWN were invisible inside a single "closed" class, though the schema defines MITIGATED as risk reduced, not eliminated.
  • Assurance-graph edges are protected. Removing items from claims' defeaters/residuals, invariants' assumptions/limitations/defeaters/residuals (at every severity — edges are graph structure, not evidence volume), defeaters' affected_claims/affected_invariants/evidence, and residuals' affected_claims/affected_invariants/mitigation.
  • review_after is a kept commitment. Removal, replacement with an unparsable value, and pushing out a date that has already passed are findings. Rescheduling a future date is deliberately not one.
  • Also: residual uncertainty downgrades (impact's previously unprotected twin axis), entry owner changes, and human_review.reviewer/human_review.record changes in the adoption declaration.

Security

  • Symlinked base registers no longer fail open. The drift job materializes the base side as a detached git worktree instead of per-file git show writes. git show renders a symlink blob as its target-path string, so a symlinked register materialized as a regular file holding a path string, loaded as unusable, and dropped out of the policy diff silently — one innocuous pull request converting a register to a symlink disabled its protection for every later one.
  • A register that parses but is not a mapping with its list, a lite assurance file that is not a mapping or whose section is not a list, and a path that exists but is not a readable regular file (directory, broken symlink) are now reported instead of silently skipped.
  • Duplicate head IDs fail closed. The diff compares by stable ID (last-one-wins), so a shadow entry under a duplicated ID was invisible to it. This no longer depends on the structure job being configured as a required check.

Deliberately not added

Recorded so the reasoning survives: disclosure reclassification (not a strength axis; the risky direction on a public repository is already a CONFORMANT error; retriage is routine), rescheduling a review_after date that has not yet passed (a red check on the act the schedule exists to produce would teach adopters to ignore the check), strengthening promotions, and unrecognized-string overwrites (pair-keyed the same way, but flagging them would also flag an adopter repairing a value that predates the stricter schema — that remains the schema enum check's job).

Upgrade actions when re-pinning

None required. Update upstream.version, upstream.commit, and the reusable workflow's @ reference to this tag's commit in the same change. Pull requests that change a reviewed decision now need the same stage-proportional Assurance policy change: acknowledgment as deletions and closures. Adopters whose registers are in-tree symlinks: the base side of the policy diff previously dropped such registers silently; they are now compared like regular files.