Rebrand AOS to ACS across all documentation and files#1
Merged
Conversation
Extend identity in context
Update aos_schema.json, add url to MCPServer object
- Rename Agent Observability Standard → Agent Control Standard - Replace AOS → ACS in all content, filenames, and directories - Update URLs: aos.owasp.org → agentcontrolstandard.org - Update repo references to Agent-Control-Standard/ACS
bar-capsule
added a commit
to bar-capsule/ACS
that referenced
this pull request
Jun 17, 2026
Two passes folded into one commit because they share helper code. ## Pass A — Security review (SECURITY.md threat model + tests + fixes) 12-threat model documented in adapters/SECURITY.md. 5 code fixes for high-priority threats; 7 out-of-scope items documented honestly. - T5 SSRF via ACS_GUARDIAN_URL: validate_guardian_url() allowlist (http/https only); called from every adapter's call_guardian and from do_handshake / ping in _common. - T6 Guardian DoS via oversized request body: MAX_REQUEST_BODY_BYTES (1 MiB) cap, matching the handshake's max_payload_size_bytes advertisement. Refuses Content-Length > cap with HTTP 413. - T7 leaky HMAC secret file: _check_secret_file_perms() refuses mode & 0o077 != 0, wrong owner, or symlink. Raises SecretFilePermissionsError instead of silently using a leaked key. - T8 cache poisoning: save_session_state and do_handshake create cache dirs mode 0700 and files mode 0600 via os.open(O_CREAT, 0o600) so other local users can't read or poison adapter state. - T9 regex DoS via huge command: scan_destructive_bash_safely() refuses inputs > 8 KiB, emits audit event, returns "input_too_large" sentinel — caller MUST treat as suspicious. 16 new tests in _common/tests/test_security.py, each named for the specific attack it falsifies. ## Pass B — Harsh-reviewer audit + 3 production failure modes + fixes Stepped back from the work, audited as a hostile reviewer. Identified the 3 most-likely production failure modes; wrote tests that fail on the current code; fixed the bugs. - BUG Agent-Control-Standard#1 NAT _correlation_request_id collision: the old uuid5-from- (session, function, kwargs-hash) was deterministic. Two calls to the same tool with the same args (list_files(), get_status(), any idempotent tool — very common) produced identical request_ids and the Guardian's replay protection rejected the second with REPLAY_DETECTED. Fix: stash a fresh uuid4 on the context in pre_invoke; post_invoke reads it back. Per-call uniqueness + pre/ post correlation both preserved. - BUG Agent-Control-Standard#2 Guardian state lost on restart: GuardianState was RAM-only. A Guardian restart (deploy / OOM / autoscaling roll) wiped seen_request_ids, opening a replay window for every previously-sent envelope. §10.3 doesn't pause for the duration of a deploy. Fix: per-session state persisted to a JSON file under ACS_GUARDIAN_STATE_DIR (default ~/.cache/acs-guardian-state/), mode 0700/0600. State loads on first session-touch, persists on every mutation in check_replay and append_to_chain. - BUG Agent-Control-Standard#3 lifecycle subscription race: _ensure_lifecycle_subscribed was a check-then-set with no lock. Two parallel pre_invoke calls (normal in NAT) both saw _lifecycle_subscribed=False and both subscribed; every WORKFLOW event then fired its ACS lifecycle hook twice. Fix: threading.Lock around the check-then-set, with re-check inside the lock. 4 new tests in nat/tests/test_failure_modes.py: 3 for the failure modes above, 1 regression guard ensuring the BUG Agent-Control-Standard#1 fix preserves pre/post correlation (post_invoke's request_id_ref must equal pre_invoke's request_id, per tool-call-result.json:19-23). ## Test-strengthening: catching 2 mutations that previously slipped Two mutation tests passed previously because of weaknesses in the tests themselves: - RollingChain::test_chain_hash_links_consecutive_requests only asserted hashes differed. Dropping previous_hash from the chain still produced different per-request hashes, so the mutation slipped. Strengthened test_chain_is_recomputable now EXTERNALLY recomputes the expected chain hash across 3 entries (now possible because the Guardian uses the client's timestamp) and asserts byte-equality. Also asserts the published hash does NOT match the "no previous_hash" computation. - Cursor envelope-schema fixtures all used SESSION_UUID, so a skip-coercion mutation slipped. Added UuidCoercionForNonUuidCursorIds (2 tests) with conv-abc123 / chat_xyz / test-cc-session inputs, asserting the adapter coerces them to valid UUIDs and that the coercion is deterministic. ## Test counts after this commit (all green, zero hidden skips) _common: 16 security claude-code: 32 round-trip + envelope-schema cursor: 50 round-trip + envelope-schema + uuid-coercion (1 intentional manual-Cursor skip) example-guardian: 20 spec-compliance nat: 24 (test_adapter 7 + test_live 5 + test_envelope_schema 6 + test_lifecycle 2 + test_failure_modes 4) Total: 142 tests. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
bar-capsule
added a commit
to bar-capsule/ACS
that referenced
this pull request
Jun 17, 2026
Each item has a falsifying test in adapters/_common/tests/test_edge_cases.py (17 tests total). Items not requiring code changes still have tests that codify the safe behavior so a future regression would be caught. ## Items 1-12 Agent-Control-Standard#1 rfc8785 JCS consistency — test confirms fallback matches the rfc8785 package byte-for-byte on every ACS envelope shape we ship. No code change needed; a mixed-install signature mismatch would surface as test failure. Agent-Control-Standard#2 Guardian regex DoS, server-side: _matches_destructive_bash now returns "too_large" for inputs > DESTRUCTIVE_SCAN_MAX_LEN (8 KiB). The Guardian denies with reason_codes=["input_too_large"] — fail-safe direction. Previously, _common had the cap but the Guardian iterated patterns directly, leaving the server unprotected. Agent-Control-Standard#3 HA Guardian replay window: persist() now takes an exclusive flock on a .lock sidecar, re-reads on-disk state, merges (union of seen_request_ids / seen_nonces with earliest-timestamp wins), and atomically writes. check_replay re-reads the state on every call so Guardian A's writes are visible to Guardian B within one request. Cross-instance replay window closed under shared ACS_GUARDIAN_STATE_DIR. Agent-Control-Standard#4 Unbounded seen_request_ids: switched to dict {rid: timestamp}. New evict_old_request_ids() drops entries older than 2 × skew window (replay impossible past skew anyway). check_replay calls eviction opportunistically every 100 inserts. Memory bound is now O(skew_window / inter-request-time), not unbounded. Backwards- compat for list-format state files preserved. Agent-Control-Standard#5 Handshake cache TTL: do_handshake skips cache files older than ACS_HANDSHAKE_CACHE_TTL_SECONDS (default 3600s). Operator config changes propagate within the TTL. Agent-Control-Standard#6 NAT id(context) collision: WeakKeyDictionary fallback for contexts that reject attribute assignment. Last-resort path (object isn't weak-referenceable either) returns a fresh uuid4 per call and emits an audit event — pre→post correlation is lost in that path, but no silent collision. Agent-Control-Standard#7 Unicode / NULL / surrogate round-trip: emoji, NULL bytes, multi- plane unicode all sign+verify cleanly. JCS handles them via UTF-8 encoding; no code change needed. Agent-Control-Standard#8 ISO 8601 parse resilience: parse_iso8601 already accepts Z suffix, timezone offsets, millisecond + microsecond precision. Test codifies the accepted shapes + asserts garbage is rejected. Agent-Control-Standard#9 ACS_GUARDIAN_HOST_ALLOWLIST: optional env-var allowlist that restricts validate_guardian_url to specific hostnames in addition to the http/https scheme check. Defense in depth against env-var attacks that smuggle a valid http:// URL to internal services. Agent-Control-Standard#10 Cursor session-state file collision: _session_state_path now accepts an optional workspace parameter folded into the hash key. Cursor adapter passes the workspace_path / cwd so two Cursor windows with the same non-UUID conversation_id can't share state. Agent-Control-Standard#11 Guardian envelope schema validation: if jsonschema + ACS_SPEC_DIR are available, every incoming envelope is validated against request-envelope.json before policy evaluation. Malformed envelopes rejected with -32600 Invalid Request. system/ping and handshake/hello exempt because their payload shapes differ. Agent-Control-Standard#12 State-file hash length: bumped _session_state_path and _handshake_cache_path hashes from sha256[:16] (64-bit) to full sha256 (256-bit). Eliminates birthday collisions over deployment lifetime. ## Test counts after this commit (all green, 1 intentional manual skip) _common: 33 (16 security + 17 edge-cases) claude-code: 32 cursor: 50 example-guardian: 20 nat: 24 Total: 159 tests. ## Side-effects of the fixes - Round-trip test fixtures updated to use real UUID session_ids (claude-code/test_adapter.py). Old "test-cc-session" fails the new Guardian-side envelope-schema check, which is correct — non-UUID session_ids never reached the Guardian from real Claude Code. - Cursor adapter wires workspace through to load/save/record session state for Agent-Control-Standard#10 (new _workspace helper). - example_guardian.py imports DESTRUCTIVE_SCAN_MAX_LEN from acs_common to keep the cap in one place. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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
docs/aos.md→acs.md,specification/AOS/→ACS/,AOS_in_action_example.md→ACS_in_action_example.mdTest plan