docs(config): define the silent-mode contract -- logs quiet, evidence complete - #286
Merged
imran-siddique merged 2 commits intoJun 11, 2026
Merged
Conversation
… complete The docs claimed silent mode "does not log denies", implying no record at all. The actual (and correct) behavior: the hash-chained audit log records every would-have-denied decision as advisory_deny in silent mode; only operational log lines are suppressed. State that contract explicitly and pin it with regression tests so it cannot change silently. Closes #284. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2 tasks
* feat(cli): add cmcp verify command for TRACE claims and audit bundles
The verifier existed only as a library (cmcp_verify), so there was no
obvious reproducible path for a third party to check a claim. New command:
cmcp verify claim.json [--policy-hash sha256:..] [--catalog-hash sha256:..]
[--trusted-key HEX] [--max-age N]
[--audit-bundle bundle.json]
- wraps verify_trace_claim (signature, schema, key binding, freshness,
chain consistency, pinned hashes); unpinned hashes are reported as
"not pinned", never as verified
- new verify_audit_bundle(): recomputes every entry hash, checks the
genesis->tip linkage, cross-checks root/tip/length against the claim,
and verifies bundle_signature with the claim confirmation key
- exit 0 only when everything checks out
End-to-end tests generate a real claim via session close, verify it, then
tamper with one field of the claim and one audit entry and prove both fail.
Closes #283.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix(verify): dev-mode platform honesty + fail-closed hardware verification (#290)
Batch of review findings, all in the trust-decision path:
- Dev-mode claims advertised platform "tpm2" (distinguished only by a
firmware sentinel); any consumer keying trust on runtime.platform treated
non-attested records as TPM-backed. software-only is now a first-class
platform value (requires agentrust-trace with trace-spec#23). The
verifier accepts both the new value and legacy tpm2+sentinel records.
- The SEV-SNP dispatch compared against the provider name ("sev-snp")
instead of the platform name ("amd-sev-snp"), so SNP hardware
verification NEVER ran -- claims fell through to UNSUPPORTED_PROVIDER.
Fixing the dispatch exposed the next bug:
- All four platform verifiers (tpm, sev_snp, tdx, opaque) returned
verified=True when raw_evidence was None -- string-format checks alone
"verified" hardware attestation. All now fail closed with
failure_reason="no_raw_evidence". verify_trace_claim additionally sets
the new HARDWARE_ATTESTATION_FAILED failure when any platform verifier
fails, which previously left overall status VERIFIED.
- Server: malformed _cmcp param (string/list/number) no longer 500s the
call path; session_reset audit entry now records the pre-reset
sensitivity instead of the post-reset value (forensic detail).
Tests asserting the old fail-open behavior updated to the fail-closed
contract.
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
imran-siddique
added a commit
that referenced
this pull request
Jun 11, 2026
* fix(policy): carry workflow_id into the egress evaluation context The egress check re-evaluates the same Cedar bundle with a context that lacked workflow_id, so a default-deny bundle (workflow-scoped permits, no catch-all) denied every response at egress even when ingress allowed the call. Found making the example policies workflow-scoped. authorize_egress() now accepts workflow_id and includes it in the egress context; the proxy passes the call's workflow through. Egress-specific rules can still distinguish direction via context.egress. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(config): define the silent-mode contract -- logs quiet, evidence complete (#286) * docs(config): define the silent-mode contract -- logs quiet, evidence complete The docs claimed silent mode "does not log denies", implying no record at all. The actual (and correct) behavior: the hash-chained audit log records every would-have-denied decision as advisory_deny in silent mode; only operational log lines are suppressed. State that contract explicitly and pin it with regression tests so it cannot change silently. Closes #284. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(cli): cmcp verify command for TRACE claims and audit bundles (#287) * feat(cli): add cmcp verify command for TRACE claims and audit bundles The verifier existed only as a library (cmcp_verify), so there was no obvious reproducible path for a third party to check a claim. New command: cmcp verify claim.json [--policy-hash sha256:..] [--catalog-hash sha256:..] [--trusted-key HEX] [--max-age N] [--audit-bundle bundle.json] - wraps verify_trace_claim (signature, schema, key binding, freshness, chain consistency, pinned hashes); unpinned hashes are reported as "not pinned", never as verified - new verify_audit_bundle(): recomputes every entry hash, checks the genesis->tip linkage, cross-checks root/tip/length against the claim, and verifies bundle_signature with the claim confirmation key - exit 0 only when everything checks out End-to-end tests generate a real claim via session close, verify it, then tamper with one field of the claim and one audit entry and prove both fail. Closes #283. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(verify): dev-mode platform honesty + fail-closed hardware verification (#290) Batch of review findings, all in the trust-decision path: - Dev-mode claims advertised platform "tpm2" (distinguished only by a firmware sentinel); any consumer keying trust on runtime.platform treated non-attested records as TPM-backed. software-only is now a first-class platform value (requires agentrust-trace with trace-spec#23). The verifier accepts both the new value and legacy tpm2+sentinel records. - The SEV-SNP dispatch compared against the provider name ("sev-snp") instead of the platform name ("amd-sev-snp"), so SNP hardware verification NEVER ran -- claims fell through to UNSUPPORTED_PROVIDER. Fixing the dispatch exposed the next bug: - All four platform verifiers (tpm, sev_snp, tdx, opaque) returned verified=True when raw_evidence was None -- string-format checks alone "verified" hardware attestation. All now fail closed with failure_reason="no_raw_evidence". verify_trace_claim additionally sets the new HARDWARE_ATTESTATION_FAILED failure when any platform verifier fails, which previously left overall status VERIFIED. - Server: malformed _cmcp param (string/list/number) no longer 500s the call path; session_reset audit entry now records the pre-reset sensitivity instead of the post-reset value (forensic detail). Tests asserting the old fail-open behavior updated to the fail-closed contract. Co-authored-by: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 task
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #284. The configuration docs said silent mode "does not log denies", which reads as "no evidence at all" -- a compliance problem if true. The actual behavior is the defensible one: the hash-chained audit log records every would-have-denied decision as
advisory_denyeven in silent mode; only operational log lines are suppressed. Logs quiet, evidence complete.docs/configuration.md: enforcement-mode table and inline comment now state the contract explicitly.tests/unit/test_silent_mode_contract.py: 4 regression tests -- silent flagswould_have_denied, emits no deny log lines (advisory does), and the audit chain recordsadvisory_denyend-to-end through the proxy.Also the resolution direction for agentrust-io/trace-spec#19: silent is log-suppression, never evidence-suppression.
Test plan
Stacked on #285.
Generated with Claude Code