R02
The shared freshness calculation explains how both reviews can be rejected without file or requirement changes. In src/gzkit/acceptance_execution.py::input_digest, the hash includes almost all os.environ, plus sys.version and platform.platform(). Only five environment names are excluded. Session variables such as CLAUDE_CODE_SESSION_ID therefore affect acceptance identity. acceptance_store.py::_validate_new_review recomputes that hash in the importing process and reports every mismatch as “stale file contents.” The same check applies to spec, quality, and adversarial reviews.
This is a supported causal mechanism, not a reconstruction of the two incidents: I did not obtain their process environments or receipts. Unchanged working trees alone also do not exclude a legitimate execution-environment change.
The impact account is:
- Meaning: acceptance binds canonical obligations and executed proof to current inputs. The repair must distinguish incidental session identity from behavior-affecting execution inputs; it must not make unchanged files sufficient regardless of runtime differences.
- Producers and representation:
_brief_contractandcanonical_obligationsderive canon;provecaptures before/after input hashes and execution evidence.commands/obpi_acceptance.py::_status_reporthands the digest and proof IDs to reviewers.review_from_receiptextracts their actual captured output. Contract, proof, and original review receipts persist asacceptance_recordedledger payloads;load_historyrebuilds them. The scalar hash retains no component explanation. - Consumers: review import checks current identity;
acceptance.py::_review_proof_scope_errorschecks review-to-proof identity;_proof_blockerschecks current proof freshness. These feed status, Stage-3 advancement, Stage-4 evidence/ceremony, precompletion, and both completion paths. Fixing only the import check would leave these other consumers falsely blocked—or permit mismatched evidence. - Obligations:
acceptance-obligations.mdrequires current executed evidence, immutable history, explicit independent closure, and renewed approval for new proof identities. Trust doctrine requires producer assertions, consumer write-path audits, and bound provenance. State doctrine keeps ledger history authoritative and readiness derived. The pipeline explicitly uses separate reviewer contexts and supplies the current digest to both review types.
I recommend a bounded repair to the shared input-identity producer: make its execution-environment selection explicit and deterministic, excluding only demonstrated session/transport bookkeeping while retaining behavior-affecting variables and conservative treatment of unclassified variables. Do not discard the environment wholesale, broadly exclude every agent-prefixed variable, copy an old digest over current inputs, or weaken equality checks. Establish which changed keys are truly incidental before choosing exclusions. Repository policy identifies session-ID variables, but its general environment-read allowlist is not a semantic dependency inventory.
This narrows an intentional guarantee: test_environment_changes_invalidate currently requires an arbitrary feature-variable change to invalidate proof. Preserve that negative control. Update the freshness explanation in the acceptance manpage and governance document alongside the producer and tests. If reviewer handoff instructions change, update the canonical pipeline skill and delivered mirrors together; existing digest-copy instructions need no rewrite merely because hashing is corrected.
Changing the hash algorithm can stale existing records. Preserve old ledger payloads and findings, disclose that fresh proof/review may be necessary, and never reinterpret historical receipts as newly executed evidence. Add explicit identity-version handling only if compatibility is required; an opaque old hash cannot establish equivalence under the new policy. Improve the error to distinguish input-identity mismatch from proven file changes without printing environment values.
Proposed verification:
- Run proof/status, receipt import, and later status in separate processes with identical files/runtime but changed, added, and removed approved session variables. Both spec and adversarial imports must succeed; readiness must still require quality approval and explicit finding closure.
- Change a semantic feature variable, Python/runtime identity, source/test bytes, source membership, configuration, brief requirement, or parent contract individually. Require stale rejection or blocked readiness, and verify rejected imports append nothing.
- Preserve evidence/history-only stability, before/after mutation-residue rejection, malformed/proof-mismatched receipt rejection, and the rule that replacement proof IDs invalidate prior approvals and closures.
- Exercise Stage-3/4, precompletion, and completion consumers using real stored history. Existing process tests reuse one
self.env; vary it deliberately. Synthetic transport fixtures must remain labeled synthetic, not claims of independent judgment.
No implementation or tests were executed. Remaining uncertainty is the incidents’ exact environment delta, the authorized semantic environment policy, and required compatibility for existing proof records.
Read account: 12 shell/read calls including task read and this answer write. All repository paths below are relative to /tmp/gzkit-three-pillars-discovery/C. Full or targeted reads: src/gzkit/{acceptance.py,acceptance_execution.py,acceptance_store.py,events.py,ledger_events.py,schemas/ledger.json,arb/paths.py,commands/obpi_acceptance.py,commands/obpi_stages.py,commands/obpi_precomplete.py,commands/obpi_complete.py,commands/obpi_cmd.py,governance/stage4_evidence.py}; tests/{test_acceptance_execution.py,test_acceptance_store.py,test_acceptance_integration.py,commands/test_obpi_acceptance_cli.py,policy/test_env_usage.py}; docs/governance/{acceptance-obligations.md,trust-doctrine.md,state-doctrine.md,advisory-rules-audit.md}; docs/user/manpages/obpi-acceptance.md; .gzkit/skills/gz-obpi-pipeline/SKILL.md; .gzkit.json; /tmp/gzkit-three-pillars-inputs/R02.md. Additional repository searches supplied discovery snippets, not whole-file inspection; some large combined outputs were truncated.