Severity: medium · Area: governance / evidence bundles
Capability: verify_bundle() is documented as a CI-runnable, network-free integrity checker for evidence bundles. docs/cli-reference.md listed "Soul signature verification when soul_signature is present" as a performed check.
Documented claim: CLAUDE.md describes BATON_SOULS_ENABLED as enabling "reviewer verdict signatures flow into evidence bundles," implying signatures can be verified; the baton evidence verify docs listed soul-signature verification as a check.
Actual state: _verify_verdict_signatures() at agent_baton/core/govern/evidence_bundle.py:780-794 only checks (a) that the soul ID exists in the registry and (b) that the soul is non-revoked. It explicitly skips the ed25519 byte-level signature-over-content verification because bead content is not stored in verdicts.json. A tampered verdict — content altered after signing — passes verify_bundle() as long as the signer's soul is still valid. File-level SHA-256 checks (evidence_bundle.py:650-720) cover verdicts.json as a file but not the original signed bead content.
Why it is weak: AgentSoul.verify(content_bytes, signature) exists in soul_registry.py and can do the real check, but it needs the original content bytes, which the bundle does not store. Omitting bead content from verdicts.json made the signature unverifiable at verify time.
Suggested fix (one of): (a) store a content hash alongside the signature in verdicts.json at build time and verify soul.verify(content_hash_bytes, signature); (b) store the (possibly truncated) bead content in verdicts.json; or (c) document that soul-signature entries are a presence/chain record only, not cryptographic tamper detection.
Evidence: agent_baton/core/govern/evidence_bundle.py:780-794 (comment states the skip); agent_baton/core/engine/soul_registry.py AgentSoul.verify() not called.
🤖 Filed from the capability-vs-docs audit (HEAD 12999f2). docs/cli-reference.md already updated to describe the check accurately.
Severity: medium · Area: governance / evidence bundles
Capability:
verify_bundle()is documented as a CI-runnable, network-free integrity checker for evidence bundles.docs/cli-reference.mdlisted "Soul signature verification when soul_signature is present" as a performed check.Documented claim:
CLAUDE.mddescribesBATON_SOULS_ENABLEDas enabling "reviewer verdict signatures flow into evidence bundles," implying signatures can be verified; thebaton evidence verifydocs listed soul-signature verification as a check.Actual state:
_verify_verdict_signatures()atagent_baton/core/govern/evidence_bundle.py:780-794only checks (a) that the soul ID exists in the registry and (b) that the soul is non-revoked. It explicitly skips the ed25519 byte-level signature-over-content verification because bead content is not stored inverdicts.json. A tampered verdict — content altered after signing — passesverify_bundle()as long as the signer's soul is still valid. File-level SHA-256 checks (evidence_bundle.py:650-720) coververdicts.jsonas a file but not the original signed bead content.Why it is weak:
AgentSoul.verify(content_bytes, signature)exists insoul_registry.pyand can do the real check, but it needs the original content bytes, which the bundle does not store. Omitting bead content fromverdicts.jsonmade the signature unverifiable at verify time.Suggested fix (one of): (a) store a content hash alongside the signature in
verdicts.jsonat build time and verifysoul.verify(content_hash_bytes, signature); (b) store the (possibly truncated) bead content inverdicts.json; or (c) document that soul-signature entries are a presence/chain record only, not cryptographic tamper detection.Evidence:
agent_baton/core/govern/evidence_bundle.py:780-794(comment states the skip);agent_baton/core/engine/soul_registry.pyAgentSoul.verify()not called.🤖 Filed from the capability-vs-docs audit (HEAD
12999f2).docs/cli-reference.mdalready updated to describe the check accurately.