feat(agent): complete Agent Accountability remediation (Phases 1-9)#3
Merged
paraphilic-ecchymosis merged 10 commits intomainfrom Feb 3, 2026
Merged
Conversation
Finding 1.1 - OutcomeAttestation signature-attestor binding: - Add verify_against_attestor() which extracts the expected key from the Attestor and verifies against it, preventing an attacker from constructing attestations that falsely attribute outcomes - Returns error for attestor types without public keys (HumanObserver, CryptographicProof) - 6 new tests covering all attestor variants and the key mismatch case Finding 1.2 - CoordinatedAction commitment verification (INV-COORD-2): - Add canonical_bytes() to CoordinatedActionSpec for commitment signing - Add Participant::with_commitment() constructor - Add Participant::verify_commitment() to validate commitment signatures against the action spec using the participant's own agent key - Add CoordinatedAction::validate_commitments() for bulk validation - Add CoordinatedActionBuilder::build_verified() which validates all participant commitments during construction - 6 new tests covering valid/invalid commitments, wrong spec, wrong key, empty commitment, and full build_verified flow Refactor: - Update integration test to use verify_against_attestor() and build_verified() with proper commitment signatures 12 new tests, 373 total (360 unit + 13 integration).
…on (Phase 2 remediation) Implements Finding 2.1 (Capability Revocation) and Finding 2.2 (Delegation Chain Verification) from the Agent Accountability Remediation Roadmap. Revocation (Section 5.4): - Add CapabilityState enum (Active, Expired, Revoked) - Add revoke(), is_revoked(), revoked_at(), revocation_reason() methods - Add lifecycle_state() for state machine transitions - Update is_valid_at() to reject revoked capabilities Delegation (INV-CAP-3, INV-CAP-4, Rule 5.3.3): - Add delegation_depth and parent_capability_id tracking fields - Add delegate() method enforcing scope subset and expiry constraints - Add is_scope_subset() for INV-CAP-3 scope validation - Enforce max_delegation_depth limit per INV-CAP-4 - Re-export CapabilityState from agent module Tests: 11 new tests covering revocation lifecycle, delegation chains, scope subset validation, depth limits, and expiry enforcement.
…test coverage Fix CapabilitySet.permits() to return DenialReason::Revoked instead of DenialReason::Expired when a capability has been revoked. The Revoked variant was dead code before this fix. Add 6 additional tests for Phase 2 coverage: - capability_set_denies_revoked: verifies permits() returns Revoked - delegate_multi_level_chain: exercises depth 0->1->2->3->4 (limit hit) - revoke_idempotent: second revoke updates timestamp and reason - lifecycle_state_revoked_takes_precedence_over_expired: priority check - delegate_inherits_scope_when_none: scope passthrough verification - delegate_inherits_expiry_when_none: expiry passthrough verification Total Phase 2 tests: 17 new (48 in capability module).
… (Phase 3 remediation) Implements Finding 3.1 (ApprovalResponse Field Encapsulation) and Finding 3.2 (Timestamp Consistency) from the Remediation Roadmap. Finding 3.1 - ApprovalResponse encapsulation: - Make all fields private (was: pub) - Add accessor methods: request_id(), responder(), decision(), responded_at(), signature() - Update apply_response() to use accessors instead of direct field access - Update integration test to use decision().is_approval() accessor Finding 3.2 - Timestamp type (Section 3.2.2): - New agent::timestamp module with Timestamp newtype over i64 - Methods: now(), from_millis(), as_millis(), elapsed(), is_expired() - Derives: Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize - Re-exported from agent module Tests: 9 new tests (6 timestamp + 3 ApprovalResponse accessor tests).
…se 4 remediation) Implements Finding 4.1 (Evidence Sufficiency Ambiguity) from the Remediation Roadmap per Section 8.3.3. The Critical severity branch of is_evidence_sufficient() previously treated Receipt as equivalent to ThirdPartyAttestation. A Receipt could be from the agent's own system, making it self-referential rather than independent verification. Updated logic: - ThirdPartyAttestation alone: sufficient (independent crypto proof) - HumanObserver attestor: sufficient (human verification) - Receipt alone: NOT sufficient (could be self-referential) - Receipt + ExternalConfirmation: sufficient (corroborated evidence) Tests: 8 new tests covering all severity levels and edge cases for Critical evidence classification.
…emediation) Implements Finding 5.1 (EmergencyEventBuilder error type) and Finding 5.2 (ID generation deduplication) from the Remediation Roadmap. Finding 5.1 - Builder error consistency: - Change EmergencyEventBuilder::build() return type from Result<EmergencyEvent, &'static str> to Result<EmergencyEvent> - Use Error::invalid_input() for all validation errors, matching every other builder in the agent module Finding 5.2 - ID generation deduplication: - New agent::id module with Id16 base type (16-byte random identifier) - define_id! macro for creating typed ID wrappers with consistent API - Methods: random/generate, from_bytes, as_bytes, to_hex, from_hex, Display - Re-exported Id16 from agent module Tests: 5 new tests (1 builder error type + 4 Id16/macro tests).
… remediation) Implements Finding 6.1 (No Audit Event Bridging) from the Remediation Roadmap per Section 11. This is the largest gap identified in the code review: agent accountability types existed in isolation from the core AuditEvent system. This bridge connects them. New agent::audit_bridge module provides: - AgentEventMetadata: structured metadata embedding session ID, causal context hash, capability ID, attestation hash, reasoning, and human-approval status - AgentAuditEventBuilder: fluent builder that creates properly contextualized AuditEvents with ActorKind::Agent, EventType::AgentAction, and embedded AgentEventMetadata - Serialization roundtrip for metadata through AuditEvent.metadata bytes The bridge uses the existing EventType::AgentAction variant and the flexible metadata field to embed full accountability context without requiring schema changes to the core event system. Tests: 14 new tests covering metadata construction, serialization roundtrip, event creation, causal context preservation, capability references, attestation hashes, chain commitment, and error handling.
Add comprehensive boundary tests exercising exact timing boundaries and edge cases across the accountability system: - Attestation expiry boundary (strict < operator) - Session max_duration boundary (strict > operator) - Capability expiry boundary (strict < operator) - IdempotencyRecord TTL boundaries - Delegation at exact max_depth - Revocation timestamp precision - Scope subset edge cases (equal patterns, same kind, different kind) These 8 tests document the exact comparison operators used at each boundary to prevent future off-by-one regressions.
Implement in-memory idempotency store that makes the existing IdempotencyKey and IdempotencyRecord types actually usable: - insert() stores records keyed by IdempotencyKey hash - lookup() returns None for expired records (transparent expiry) - cleanup() removes all expired records, returns count removed - len()/is_empty() for store introspection 6 new tests: insert+lookup, unknown key, expired invisible, cleanup, overwrite, is_empty.
…> (Phase 9) Remove error-prone hex-encoded string keys from coordination types. PublicKey already implements Hash + Eq, so it can be used directly as a HashMap key, eliminating the hex encode/decode round-trip. Affected types: - CoordinatedActionSpec.tasks - CoordinationMetrics.per_agent_duration - CoordinationResult.agent_outcomes - CoordinationEvent::Disagreement.positions 4 new tests verify type-safe lookups across all affected types.
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
Phase Breakdown
Phase 1: Signature Verification Hardening
AgentAttestation::verify_signature()validates attestation integrityPhase 2: Capability Lifecycle Completion
CapabilityStateenum (Active/Expired/Revoked) per Section 5.4revoke(),is_revoked(),revoked_at(),revocation_reason(),lifecycle_state()delegate()with INV-CAP-3 (scope subset parent) and INV-CAP-4 (depth <= max)CapabilitySet::permits()to returnDenialReason::Revoked(was dead code)Phase 3: Type System Hardening
Timestampnewtype for type-safe millisecond timestamps (Section 3.2.2)ApprovalResponsefields with accessor methodsPhase 4: Evidence Classification Refinement
is_evidence_sufficient()Critical branch per Section 8.3.3Phase 5: Builder and Error Consistency
EmergencyEventBuilder::build()returnscrate::error::Result(was static str)Id16base type +define_id!macro for typed 16-byte identifiersPhase 6: Audit Event Bridge (Section 11)
AgentEventMetadatastruct with causal context hash, capability reference, attestation hashAgentAuditEventBuildercreatesAuditEventwithActorKind::Agentand structured metadataPhase 7: Test Coverage Hardening
agent_adversarial.rsPhase 8: Idempotency Store
IdempotencyStorewith insert, lookup, cleanup, len, is_emptyPhase 9: HashMap Key Type Safety
HashMap<String, _>withHashMap<PublicKey, _>in coordination typesTest plan