Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Changelog

All notable changes to this project are documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) once it reaches 1.0.0. Pre-1.0 releases MAY change the ACS-Core baseline in patch versions; the wire format version (`acs_version` in the handshake) evolves separately in the `specification/` directory.

## [0.1.1] — 2026-07-09

### Changed — ACS-Core baseline (relaxations)

- `MODIFY` is now SHOULD-support rather than MUST-support. Deployments whose framework cannot mutate a request (shell-hook integrations, IDE plugins without an argument-mutation surface) or that disable `MODIFY` for auditability reasons are conformant without it. See new [§6.5 MODIFY-incapable clients](docs/spec/instrument/specification.md#65-modify-incapable-clients-normative).
- `subagentStop` is now SHOULD-emit rather than MUST-emit; `subagentStart` remains MUST-emit for subagent-capable frameworks.
- `system/ping` is now SHOULD-implement rather than MUST-implement, provided the deployment declares an alternative liveness mechanism (transport-level keepalive on HTTP; process supervision or heartbeat on stdio; continuous observed hook traffic). Omitting `system/ping` without a declared alternative is non-conformant.
- Wrapped MCP (`protocols/MCP/*`) MUST be implemented by deployments whose sessions involve MCP at any point (tools, resources, prompts, notifications), and MAY be omitted by deployments whose sessions never involve MCP. Deployments that declared no MCP at handshake MUST NOT spawn or register MCP servers mid-session; renegotiation is undefined in v0.1.

### Changed — ACS-Core baseline (additions)

- `subagentStart` is now part of the MUST-emit minimum hook set for subagent-capable frameworks. A client whose framework has no sub-agent abstraction has nothing to emit; the Guardian determines client subagent-emission capability by deployment-defined means (mirroring the [§9.2 ASK precedent](docs/spec/instrument/specification.md#92-approver-incapable-clients-normative)).

### Added

- **§6.5 MODIFY-incapable clients (normative)** in `docs/spec/instrument/specification.md`. Defines Guardian-side substitution (`DENY` with `reason_codes: ["modify_unsupported"]` + audit event) and client-side fallback (a client receiving an unapplicable `MODIFY` MUST treat it as `DENY` + audit event).
- Audit-event mandate in **§9.2** (approver-incapable clients): the Guardian MUST record the ASK-substitution as an audit event, so the substitution rate is machine-detectable rather than only reachable by grepping log prose.

### Changed — normative force harmonization

- **§6.3** (malformed MODIFY): `SHOULD record an audit event` → `MUST record an audit event`. All fallback / substitution rules now use consistent MUST-audit language across §6.3, §6.4, §6.5, and §9.2.

### Changed — schema

- `specification/v0.1.0/hooks/subagent-stop.json`: `final_chain_hash` moved from `required` to optional. Frameworks that maintain no session-chain (shell-hook integrations without an internal audit chain) MAY omit the field rather than fabricate a value; fabrication would corrupt the exact artifact the field exists to produce. A conformant Guardian MUST treat omission as "chain not maintained by this framework" rather than as an integrity failure.

### Related issues

- Guardian-side hook-coverage unfalsifiability tracked at [#31](https://github.com/GenAI-Security-Project/agent-control-standard/issues/31); out of scope for this release, needed for the enforcement side of `subagentStart`'s security rationale to be checkable.

## [0.1.0] — 2026-06-05

- Initial canonical v0.1.0 spec integrated (see [#2](https://github.com/GenAI-Security-Project/agent-control-standard/pull/2)).
2 changes: 1 addition & 1 deletion docs/acs.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ ACS extends existing standards rather than reinventing them: JSON-RPC 2.0 for th

## What v0.1.0 ships

- **ACS-Core** (mandatory baseline) — capability-negotiation handshake, JSON-RPC envelope, 16 native lifecycle hooks (`sessionStart`/`End`, `agentTrigger`, `userMessage`, `agentResponse`, `turnStart`/`End`, `toolCallRequest`/`Result`, `knowledgeRetrieval`, `memoryContextRetrieval`, `memoryStore`, `preCompact`/`postCompact`, `subagentStart`/`Stop`), wrapped MCP, five dispositions (`allow`, `deny`, `modify`, `ask`, `defer`), SessionContext with rolling SHA-256 chain hash, optional Intent with immutability rule, replay protection, and `system/ping` liveness.
- **ACS-Core** (mandatory baseline) — capability-negotiation handshake, JSON-RPC envelope, minimum hook set (`sessionStart`, `userMessage` or `agentTrigger`, `toolCallRequest`/`Result`, `agentResponse`, `sessionEnd`, `subagentStart` for subagent-capable frameworks), four MUST-support dispositions (`allow`, `deny`, `ask`, `defer`) with `modify` SHOULD-support, SessionContext with rolling SHA-256 chain hash, optional Intent with immutability rule, replay protection, baseline HMAC-SHA256 signature, decision honoring, declared liveness mechanism (`system/ping` or a transport-level alternative), and Wrapped MCP when sessions involve MCP. Additional hooks (`turnStart`/`End`, `preCompact`/`postCompact`, `subagentStop`, `knowledgeRetrieval`, `memoryContextRetrieval`, `memoryStore`, `skillRegister`/`Load`/`Unload`) are normatively defined and SHOULD be implemented when the harness can observe the corresponding event.
- **ACS-Trace** profile — OpenTelemetry semconv mapping + OCSF event-class mapping, with decisions emitted as span events on the parent step span.
- **ACS-Inspect** / **ACS-Inspect-Dynamic** profiles — canonical AgBOM with `agbom/snapshot` and `agbom/changed`, deterministic CycloneDX / SPDX / SWID derivations.
- **ACS-Provenance** profile — field-level `Provenance` objects with `origin`, `source_id`, `derived_from`, and an OPTIONAL wire-format `trust` enum that obeys the monotonicity rule.
Expand Down
12 changes: 6 additions & 6 deletions docs/spec/conformance.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,18 @@ A v0.1.0-conformant deployment MUST implement ACS-Core. ACS-Core comprises:

- **Handshake** — `handshake/hello` with ClientHello/ServerHello ([Specification §4](./instrument/specification.md#4-capability-negotiation-handshake)).
- **Request/response envelope** — JSON-RPC 2.0 with ACS extensions ([§3](./instrument/specification.md#3-wire-format)). `request_id`, `timestamp`, `acs_version`, `metadata` required on every request.
- **Hook taxonomy** — At minimum: `sessionStart`, `userMessage` or `agentTrigger`, `toolCallRequest`, `toolCallResult`, `agentResponse`, `sessionEnd`. Additional hooks (`turnStart`/`turnEnd`, `preCompact`/`postCompact`, `subagentStart`/`subagentStop`, `knowledgeRetrieval`, `memoryContextRetrieval`, `memoryStore`, `skillRegister`/`skillLoad`/`skillUnload`) are normatively defined and SHOULD be implemented when the harness can observe the corresponding event; they are capability-negotiated via the handshake. A deployment whose AgBOM includes `skill` components SHOULD emit the skill lifecycle hooks, so a Guardian is not blind to a composition surface the inventory already exposes.
- **Dispositions** — All five (ALLOW, DENY, MODIFY, ASK, DEFER) with required fields per [§6](./instrument/specification.md#6-disposition-vocabulary).
- **Hook taxonomy** — At minimum: `sessionStart`, `userMessage` or `agentTrigger`, `toolCallRequest`, `toolCallResult`, `agentResponse`, `sessionEnd`, `subagentStart`. A subagent-capable client MUST emit `subagentStart` when it spawns a sub-agent; a client whose framework has no sub-agent abstraction has nothing to emit. The Guardian determines client subagent-emission capability by deployment-defined means (agent identity bound at handshake, policy keyed on `agent_id`, organizational configuration), mirroring the ASK precedent in [§9.2](./instrument/specification.md#92-approver-incapable-clients-normative). Without `subagentStart`, a Guardian is blind to cross-agent propagation (the confused-deputy attack class). `subagentStop` is SHOULD-emit (audit-only, not decision-eligible; its `final_chain_hash` field is optional for frameworks maintaining no session-chain — see [`subagent-stop.json`](https://github.com/afogel/ACS_official/blob/dev/specification/v0.1.0/hooks/subagent-stop.json)). Additional hooks (`turnStart`/`turnEnd`, `preCompact`/`postCompact`, `knowledgeRetrieval`, `memoryContextRetrieval`, `memoryStore`, `skillRegister`/`skillLoad`/`skillUnload`) are normatively defined and SHOULD be implemented when the harness can observe the corresponding event; they are capability-negotiated via the handshake. A deployment whose AgBOM includes `skill` components SHOULD emit the skill lifecycle hooks, so a Guardian is not blind to a composition surface the inventory already exposes.
- **Dispositions** — Four MUST-support: ALLOW, DENY, ASK, DEFER, with required fields per [§6](./instrument/specification.md#6-disposition-vocabulary). MODIFY is SHOULD-support: deployments that implement MODIFY MUST follow the MODIFY composition rules ([§6.3](./instrument/specification.md#63-modify-composition-normative)); deployments that do not implement MODIFY are handled per [§6.5](./instrument/specification.md#65-modify-incapable-clients-normative) (the Guardian substitutes `DENY` with `reason_codes: ["modify_unsupported"]` and an audit event recording the substitution, determined by deployment-defined means rather than a wire declaration, mirroring the §9.2 precedent for ASK).
- **SessionContext and Intent**: `session_id`, `chain_hash` (rolling SHA-256), append-only ContextEntry chain, with the Guardian publishing the chain head (`chain_hash`) on responses for content-bearing steps ([§8](./instrument/specification.md#8-sessioncontext-and-intent)). Intent is optional but normative when IBAC is the enforcement paradigm.
- **Replay protection** — `request_id` (UUID) and `timestamp` on every request; Guardians MUST reject replays per [§10.3](./instrument/specification.md#103-replay-protection).
- **Baseline integrity**: every request and response carries a signature over the canonical envelope ([§10](./instrument/specification.md#10-cryptographic-signatures)). `HMAC-SHA256` with an HKDF-derived per-session key from deployment-provided key material is the baseline; asymmetric and post-quantum algorithms are the ACS-Crypto profile.
- **Decision honoring**: the Observed Agent MUST wait for the Guardian's decision up to the negotiated timeout and apply it; on a decision failure (timeout, transport failure, or an error without a decision) it applies the `on_decision_failure` posture (default `proceed`, fail-open) and records every fail-open proceed as an audit event ([§6.4](./instrument/specification.md#64-honoring-decisions-normative)). Handshake failure follows the deployment's startup posture ([§4.1](./instrument/specification.md#41-handshake-failure-normative)).
- **Liveness** — `system/ping` ([§13](./instrument/specification.md#13-liveness-system-methods)).
- **Wrapped MCP** — `protocols/MCP/*` ([Hooks](./instrument/hooks.md#protocolsmcp)).
- **Liveness** — `system/ping` ([§13](./instrument/specification.md#13-liveness-system-methods)) SHOULD be implemented. A deployment MAY omit `system/ping` only if it has declared an alternative liveness mechanism in its configuration (for example: TCP keepalive or HTTP/2 PING on HTTP transports; process supervision or an out-of-band heartbeat on stdio; or continuous observed hook traffic where the session's own cadence acts as the probe). Omitting `system/ping` without a declared alternative is non-conformant: the chain of defaults (`startup_posture: proceed`, `on_decision_failure: proceed`, no liveness) produces silent fail-open on Guardian outage, which the Core baseline cannot allow.
- **Wrapped MCP** — `protocols/MCP/*` ([Hooks](./instrument/hooks.md#protocolsmcp)) MUST be implemented by deployments whose sessions involve MCP at any point (tools, resources, prompts, notifications), so that `protocols/MCP/resources/read` — the canonical prompt-injection ingress for attacker-controlled external content — is not bypassed. Support is declared in the handshake via `wrapped_protocols`. Deployments that declared no MCP at handshake MUST NOT spawn or register MCP servers mid-session; renegotiation is undefined in v0.1, so mid-session MCP addition is non-conformant until v0.2 ships it. Deployments whose sessions never involve MCP MAY omit the namespace.

ACS-Core does NOT require: field-level Provenance objects, Trace event emission, AgBOM, asymmetric or post-quantum signatures, or `request_hash` on ContextEntry (`request_hash` remains SHOULD). It DOES require the baseline signature (§10) and decision honoring (§6.4). ACS-Core deployments validate hook payloads against the base schemas, where `provenance` is OPTIONAL; field-level Provenance is added by the ACS-Provenance profile.

What "ACS-Core conformant" guarantees: the channel is authenticated and the Observed Agent honors the Guardian's decisions. It does NOT assert that a deployment's policies are strict, nor that the audit chain is tamper-evident against a compromised Guardian (that is the ACS-Crypto and ACS-Audit profiles, since the HMAC baseline is symmetric). A permissive Guardian is a conformant but permissive deployment, not a violation.
What "ACS-Core conformant" guarantees: the channel is authenticated and the Observed Agent honors the Guardian's decisions on the four MUST-support dispositions (ALLOW, DENY, ASK, DEFER). Deployments that also implement MODIFY (SHOULD-support, [§6.5](./instrument/specification.md#65-modify-incapable-clients-normative)) honor it too; deployments that do not receive `DENY` substitutions with `reason_code: modify_unsupported`. A minimum-conformant deployment can therefore permit or refuse an action but cannot alter it — redaction and other content rewrites require MODIFY support. This clause does NOT assert that a deployment's policies are strict, nor that the audit chain is tamper-evident against a compromised Guardian (that is the ACS-Crypto and ACS-Audit profiles, since the HMAC baseline is symmetric). A permissive Guardian is a conformant but permissive deployment, not a violation.

## ACS-Trace

Expand Down Expand Up @@ -80,7 +80,7 @@ Profiles compose. A deployment that wants full observability and supply-chain in

| Profile | What it adds | When to claim |
|---|---|---|
| `acs-core` | Handshake, envelope, hook taxonomy, dispositions, SessionContext + published chain head, replay protection, baseline signature (HMAC-SHA256), decision honoring, ping | Always (mandatory) |
| `acs-core` | Handshake, envelope, minimum hook set (incl. `subagentStart` for subagent-capable clients), four MUST-support dispositions (ALLOW/DENY/ASK/DEFER) with MODIFY SHOULD-support (§6.5), SessionContext + published chain head, replay protection, baseline signature (HMAC-SHA256), decision honoring, declared liveness mechanism, Wrapped MCP when sessions involve MCP | Always (mandatory) |
| `acs-trace` | OTel + OCSF event emission per step | Cross-vendor observability or SIEM integration |
| `acs-inspect` | `agbom/snapshot` + canonical AgBOM serialization | Policy depends on component inventory |
| `acs-inspect-dynamic` | `agbom/changed` on mutation | Agent hot-swaps components mid-session |
Expand Down
Loading