From b3019d7d2d8ed61d3c8274970438a539a64d02b2 Mon Sep 17 00:00:00 2001 From: Evgeny Kokuykin Date: Sun, 11 Oct 2026 13:10:03 -0700 Subject: [PATCH 1/5] Add a README to reference-implementations with shared Guardian expectations The directory had no top-level document. The new README says what the directory holds, then states what we expect from each maintained Guardian reference implementation. Four open pull requests add or rework a Guardian, and each read the one-sentence porting issues differently. The expectations let every implementation be reviewed against the same list. The expectations are a working aid for review. They are not part of the specification and they are not normative. Part of #252 Signed-off-by: Evgeny Kokuykin --- reference-implementations/README.md | 89 +++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 reference-implementations/README.md diff --git a/reference-implementations/README.md b/reference-implementations/README.md new file mode 100644 index 00000000..e94de5a2 --- /dev/null +++ b/reference-implementations/README.md @@ -0,0 +1,89 @@ +# ACS reference implementations + +This directory holds the reference implementations of the Agent Control Standard. A reference implementation is working code that shows the ACS wire contract in use. It is a demonstration and a measurement, not a product. + +## What is here + +| Path | What it is | +| --- | --- | +| [`agt/`](agt/README.md) | A Guardian in TypeScript that runs Microsoft's Agent Governance Toolkit (AGT) as its policy engine. The tree also carries host shims for Claude Code and OpenCode, a shared host adapter, an Inspector, and a conformance harness. | + +Guardians in Python, Go, and Rust are under review. Each one lands here as its own directory, with its own README that says how to run it and what it does not yet do. + +## Expectations for Guardian reference implementations + +Status: draft, under review in [#252](https://github.com/GenAI-Security-Project/agent-control-standard/issues/252). + +This section is a working aid for reviewing pull requests that add or change Guardian reference implementations, so that every implementation is reviewed against the same expectations. It is not part of the ACS specification and it is not normative. It describes where the set of implementations is heading, so the tree above does not meet every item yet. + +### Project-level requirements + +#### Maintained implementations + +The project maintains the following Guardian reference implementations: TypeScript, Python, Rust, and Go. Other languages may be supported through community implementations. + +#### Shared host integrations + +Host adapters are maintained separately from Guardian reference implementations and communicate with them through the ACS wire contract. + +Existing shims and client code will be moved to the shared host-adapter area. A new Guardian language does not require a separate host integration. + +#### Shared contract tests + +The project maintains a language-independent contract test suite that exercises Guardians through their HTTP API. + +The suite checks ACS protocol behavior and externally observable guarantees. It does not require each implementation to port the TypeScript conformance toolkit or establish certification beyond its tested scope. + +### Requirements for each maintained implementation + +#### ACS API + +The implementation is expected to follow the ACS wire contract for its supported capabilities and to accurately declare those capabilities through the handshake. + +#### Actual AGT runtime + +Policy evaluation is expected to use the upstream AGT runtime through an official SDK, native binding, or integration with a process or service running AGT. Reimplementing AGT runtime behavior or directly evaluating its policy bundle is not an acceptable substitute. + +#### Architectural boundaries + +Transport handling, ACS processing, AGT integration, state storage, and logging should have clearly defined responsibilities. The Guardian is expected to expose a transport-independent processing entry point. + +Concrete APIs, packages, classes, and file layouts can follow language conventions. Host integrations are outside the Guardian's scope. + +#### Signing keys and secrets + +Implementations are expected to sign and verify ACS messages according to the specification. + +For the HMAC-SHA256 baseline, per-session keys are expected to be derived with HKDF using SHA-256, an empty salt, the `session_id` as info, and a 32-byte output. + +Each configured key has an identifier. The default identifier is `default`. A sender should set `key_id` to the identifier of the key it signed with. A verifier should select the key by `key_id` and treat an unknown `key_id` as an invalid signature. A signed response should carry the same `key_id` as the request it answers. + +Key material is expected to be a string of at least 32 characters, read from a file or an environment variable. Leading and trailing whitespace should be removed. The remaining bytes are the HKDF input keying material. No decoding is applied. + +Key material should be supplied through deployment configuration. It should not be hard-coded and should not appear in ACS messages or logs. + +Documentation is expected to describe how key material is configured and replaced. + +#### Configurable storage + +Session and security state should be accessed through a storage-provider interface selected through configuration. Internal storage schemas and formats are implementation-defined. Cross-implementation storage compatibility and session migration are not required. Supported storage providers and their durability and multi-instance guarantees are expected to be documented. + +#### Concurrency and session consistency + +The Guardian is expected to safely handle concurrent invocations independently of the transport's threading or execution model. + +Concurrent requests within a session should preserve replay protection, audit-chain consistency, and policy state. They should not cause duplicate evaluation of the same request or lost state updates. + +Synchronization mechanisms and internal processing algorithms are implementation-defined. + +#### Bounded processing + +Request waiting and policy evaluation should be bounded by configurable time and resource limits. + +#### Bounded logging + +Retained logs should be subject to a configurable total size limit, enforced by the implementation or its logging infrastructure. Defaults should bound retained log volume. Log formats and rotation mechanisms are implementation-defined. + +#### Verification + +The implementation is expected to pass the applicable shared ACS contract tests. From b3cd04aeea133c6de916a5a992378dd8f067f70a Mon Sep 17 00:00:00 2001 From: Evgeny Kokuykin Date: Sun, 11 Oct 2026 13:44:11 -0700 Subject: [PATCH 2/5] Shorten the reference-implementations README and count key material in bytes The introduction now says only what the directory is. The table of contents and the status line are gone, because both would go stale as implementations land. Key material is at least 32 bytes, not 32 characters. The specification and every implementation count bytes. Part of #252 Signed-off-by: Evgeny Kokuykin --- reference-implementations/README.md | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/reference-implementations/README.md b/reference-implementations/README.md index e94de5a2..3f4d13fc 100644 --- a/reference-implementations/README.md +++ b/reference-implementations/README.md @@ -1,20 +1,10 @@ # ACS reference implementations -This directory holds the reference implementations of the Agent Control Standard. A reference implementation is working code that shows the ACS wire contract in use. It is a demonstration and a measurement, not a product. - -## What is here - -| Path | What it is | -| --- | --- | -| [`agt/`](agt/README.md) | A Guardian in TypeScript that runs Microsoft's Agent Governance Toolkit (AGT) as its policy engine. The tree also carries host shims for Claude Code and OpenCode, a shared host adapter, an Inspector, and a conformance harness. | - -Guardians in Python, Go, and Rust are under review. Each one lands here as its own directory, with its own README that says how to run it and what it does not yet do. +This directory holds the reference implementations of the Agent Control Standard. A reference implementation is working code that shows the ACS wire contract in use. ## Expectations for Guardian reference implementations -Status: draft, under review in [#252](https://github.com/GenAI-Security-Project/agent-control-standard/issues/252). - -This section is a working aid for reviewing pull requests that add or change Guardian reference implementations, so that every implementation is reviewed against the same expectations. It is not part of the ACS specification and it is not normative. It describes where the set of implementations is heading, so the tree above does not meet every item yet. +This section is a working tool for reviewing pull requests that add or change Guardian reference implementations, so that every implementation is reviewed against the same expectations. ### Project-level requirements @@ -58,7 +48,7 @@ For the HMAC-SHA256 baseline, per-session keys are expected to be derived with H Each configured key has an identifier. The default identifier is `default`. A sender should set `key_id` to the identifier of the key it signed with. A verifier should select the key by `key_id` and treat an unknown `key_id` as an invalid signature. A signed response should carry the same `key_id` as the request it answers. -Key material is expected to be a string of at least 32 characters, read from a file or an environment variable. Leading and trailing whitespace should be removed. The remaining bytes are the HKDF input keying material. No decoding is applied. +Key material is expected to be a string of at least 32 bytes, read from a file or an environment variable. Leading and trailing whitespace should be removed. The remaining bytes are the HKDF input keying material. No decoding is applied. Key material should be supplied through deployment configuration. It should not be hard-coded and should not appear in ACS messages or logs. From aac2ec1f63d16ac8f5c5c72190bc047df7a5ea14 Mon Sep 17 00:00:00 2001 From: Evgeny Kokuykin Date: Wed, 14 Oct 2026 13:32:32 -0700 Subject: [PATCH 3/5] Address review: match the TypeScript Guardian's signing and mark targets - Name the policy runtime, agent_control_specification, at the version in agt.lock, and say that AGT's Go module does not qualify. - Set key_id to the session_id and base64-decode the key material, as the TypeScript Guardian in #229 does. - List only TypeScript as maintained. Other languages are added as they merge. - Say that the contract test suite will exist, and make verification depend on it. - Mark bounded processing and bounded logging as targets the TypeScript Guardian does not meet yet. - Add message signing to the architectural boundaries. Part of #252 Signed-off-by: Evgeny Kokuykin --- reference-implementations/README.md | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/reference-implementations/README.md b/reference-implementations/README.md index 3f4d13fc..4338de92 100644 --- a/reference-implementations/README.md +++ b/reference-implementations/README.md @@ -10,7 +10,7 @@ This section is a working tool for reviewing pull requests that add or change Gu #### Maintained implementations -The project maintains the following Guardian reference implementations: TypeScript, Python, Rust, and Go. Other languages may be supported through community implementations. +The project maintains one Guardian reference implementation, in TypeScript. Implementations in other languages are added as they merge. #### Shared host integrations @@ -20,7 +20,7 @@ Existing shims and client code will be moved to the shared host-adapter area. A #### Shared contract tests -The project maintains a language-independent contract test suite that exercises Guardians through their HTTP API. +The project will maintain a language-independent contract test suite that exercises Guardians through their HTTP API. The suite checks ACS protocol behavior and externally observable guarantees. It does not require each implementation to port the TypeScript conformance toolkit or establish certification beyond its tested scope. @@ -32,11 +32,13 @@ The implementation is expected to follow the ACS wire contract for its supported #### Actual AGT runtime -Policy evaluation is expected to use the upstream AGT runtime through an official SDK, native binding, or integration with a process or service running AGT. Reimplementing AGT runtime behavior or directly evaluating its policy bundle is not an acceptable substitute. +Policy evaluation is expected to use AGT's policy runtime, `agent_control_specification`, at the commit and SDK version recorded in [`agt/agt.lock`](agt/agt.lock). It can be reached through an official SDK, a native binding to its Rust core, or a process or service that runs it. Reimplementing the runtime's behavior or directly evaluating its policy bundle is not an acceptable substitute. + +AGT's Go module, `agent-governance-golang`, is a different policy engine and does not qualify. #### Architectural boundaries -Transport handling, ACS processing, AGT integration, state storage, and logging should have clearly defined responsibilities. The Guardian is expected to expose a transport-independent processing entry point. +Transport handling, ACS processing, AGT integration, message signing, state storage, and logging should have clearly defined responsibilities. The Guardian is expected to expose a transport-independent processing entry point. Concrete APIs, packages, classes, and file layouts can follow language conventions. Host integrations are outside the Guardian's scope. @@ -46,9 +48,9 @@ Implementations are expected to sign and verify ACS messages according to the sp For the HMAC-SHA256 baseline, per-session keys are expected to be derived with HKDF using SHA-256, an empty salt, the `session_id` as info, and a 32-byte output. -Each configured key has an identifier. The default identifier is `default`. A sender should set `key_id` to the identifier of the key it signed with. A verifier should select the key by `key_id` and treat an unknown `key_id` as an invalid signature. A signed response should carry the same `key_id` as the request it answers. +A sender should set `key_id` to the `session_id` of the session the message belongs to. A verifier should treat a `key_id` that does not match the session's `session_id` as an invalid signature. A signed response should carry the same `key_id` as the request it answers. -Key material is expected to be a string of at least 32 bytes, read from a file or an environment variable. Leading and trailing whitespace should be removed. The remaining bytes are the HKDF input keying material. No decoding is applied. +Key material is expected to be base64-encoded and to decode to at least 32 bytes. It is read from a file or an environment variable. The decoded bytes are the HKDF input keying material. Key material should be supplied through deployment configuration. It should not be hard-coded and should not appear in ACS messages or logs. @@ -68,12 +70,12 @@ Synchronization mechanisms and internal processing algorithms are implementation #### Bounded processing -Request waiting and policy evaluation should be bounded by configurable time and resource limits. +Request waiting and policy evaluation should be bounded by configurable time and resource limits. This is a target. The TypeScript Guardian does not meet it yet. #### Bounded logging -Retained logs should be subject to a configurable total size limit, enforced by the implementation or its logging infrastructure. Defaults should bound retained log volume. Log formats and rotation mechanisms are implementation-defined. +Retained logs should be subject to a configurable total size limit, enforced by the implementation or its logging infrastructure. Defaults should bound retained log volume. Log formats and rotation mechanisms are implementation-defined. This is a target. The TypeScript Guardian does not meet it yet. #### Verification -The implementation is expected to pass the applicable shared ACS contract tests. +Once the shared contract test suite exists, the implementation is expected to pass the tests that apply to it. From 46a9193c879859c98f2abd16f8588cbbd70c653d Mon Sep 17 00:00:00 2001 From: Evgeny Kokuykin Date: Sat, 17 Oct 2026 02:26:04 -0700 Subject: [PATCH 4/5] Point the signing section at section 10 instead of restating it Review on this pull request asked to link section 10 rather than restate the HMAC key derivation and the meaning of key_id, so the README cannot drift when section 10 changes. #272 adds those rules to section 10. The section keeps only what section 10 does not define: how key material is encoded and read, that it stays out of code and logs, and that each implementation documents how to configure and replace it. Part of #252 Signed-off-by: Evgeny Kokuykin --- reference-implementations/README.md | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/reference-implementations/README.md b/reference-implementations/README.md index 4338de92..91f2d4cd 100644 --- a/reference-implementations/README.md +++ b/reference-implementations/README.md @@ -44,17 +44,13 @@ Concrete APIs, packages, classes, and file layouts can follow language conventio #### Signing keys and secrets -Implementations are expected to sign and verify ACS messages according to the specification. +Implementations are expected to sign and verify ACS messages as [§10 of the specification](../docs/spec/instrument/specification.md#10-cryptographic-signatures) defines, including the HMAC-SHA256 key derivation and the meaning of `key_id`. -For the HMAC-SHA256 baseline, per-session keys are expected to be derived with HKDF using SHA-256, an empty salt, the `session_id` as info, and a 32-byte output. +In addition to the specification, implementations are expected to meet the following: -A sender should set `key_id` to the `session_id` of the session the message belongs to. A verifier should treat a `key_id` that does not match the session's `session_id` as an invalid signature. A signed response should carry the same `key_id` as the request it answers. - -Key material is expected to be base64-encoded and to decode to at least 32 bytes. It is read from a file or an environment variable. The decoded bytes are the HKDF input keying material. - -Key material should be supplied through deployment configuration. It should not be hard-coded and should not appear in ACS messages or logs. - -Documentation is expected to describe how key material is configured and replaced. +- key material is base64-encoded, decodes to at least 32 bytes, and is read from a file or an environment variable; +- key material is not hard-coded and does not appear in ACS messages or logs; +- the documentation says how key material is configured and replaced. #### Configurable storage From e9e3744b61d0b0a330a029d099735e33462e7756 Mon Sep 17 00:00:00 2001 From: rocklambros Date: Wed, 21 Oct 2026 02:28:07 -0600 Subject: [PATCH 5/5] Mark what the TypeScript Guardian does not meet, and settle the review's open points Every expectation the TypeScript Guardian does not meet yet is now marked Not met yet, with the issue that tracks it, not only the two bounded sections. A gap is listed only with an issue, so it stays public and tracked, and the README says which wording blocks a merge. Signing names the two section 10 paragraphs it relies on and lists the key_id checks a reviewer makes, the response's key_id included. The base64 convention says the decoded bytes are the secret and the HKDF input, and which base64 is meant. The runtime is named as agt.lock records it, the cross-language pin is agt_ref, and another evaluator is allowed only as a non-default that names itself on every decision. Replay protection is a blocking expectation, as section 10.3 makes it a MUST. Bounded processing answers a breach with a deny, so it never falls into the fail-open posture, and the log cap never evicts audit records. The host-adapter location, the contract suite and the maintained-set rules point at their issues, and verification until the suite exists matches the root README. Signed-off-by: rocklambros --- reference-implementations/README.md | 70 ++++++++++++++++++----------- 1 file changed, 43 insertions(+), 27 deletions(-) diff --git a/reference-implementations/README.md b/reference-implementations/README.md index 91f2d4cd..b461fc75 100644 --- a/reference-implementations/README.md +++ b/reference-implementations/README.md @@ -6,72 +6,88 @@ This directory holds the reference implementations of the Agent Control Standard This section is a working tool for reviewing pull requests that add or change Guardian reference implementations, so that every implementation is reviewed against the same expectations. +"Is expected to" marks a check that blocks a merge. "Should" marks a check a reviewer raises but that does not block one. + +An expectation an implementation does not meet yet is marked **Not met yet**, with the issue that tracks it. The gap is then public and tracked, so it is handled as an issue rather than as a security report ([SECURITY.md](../SECURITY.md)). A gap without an issue is not a documented gap. + ### Project-level requirements #### Maintained implementations -The project maintains one Guardian reference implementation, in TypeScript. Implementations in other languages are added as they merge. +The project maintains one Guardian reference implementation, in TypeScript, under [`agt/`](agt/). Its own [status table](agt/README.md#what-this-project-is-and-is-not) is the current record of which ACS-Core requirements it meets. Implementations in other languages join when they merge. Who keeps one working after that is decided in issue #318. #### Shared host integrations -Host adapters are maintained separately from Guardian reference implementations and communicate with them through the ACS wire contract. - -Existing shims and client code will be moved to the shared host-adapter area. A new Guardian language does not require a separate host integration. +Host adapters are meant to live apart from Guardian implementations and talk to them only through the ACS wire contract, so a new Guardian language needs no host integration of its own. Today the TypeScript shims sit inside the TypeScript workspace, in [`agt/hosts/`](agt/hosts/) and [`agt/packages/host-adapter/`](agt/packages/host-adapter/), and some ports carry their own. Where shared host adapters live is decided in issue #313. #### Shared contract tests -The project will maintain a language-independent contract test suite that exercises Guardians through their HTTP API. - -The suite checks ACS protocol behavior and externally observable guarantees. It does not require each implementation to port the TypeScript conformance toolkit or establish certification beyond its tested scope. +The project will maintain a language-independent contract test suite that exercises Guardians through their HTTP API, tracked in issue #311. It checks ACS protocol behavior and guarantees a host can observe. It does not require an implementation to port the TypeScript conformance toolkit. ### Requirements for each maintained implementation #### ACS API -The implementation is expected to follow the ACS wire contract for its supported capabilities and to accurately declare those capabilities through the handshake. +The implementation is expected to follow the ACS wire contract, including every ACS-Core requirement in [conformance.md](../docs/spec/conformance.md#acs-core-mandatory-baseline). It is expected to declare its capabilities accurately in the handshake, and to list any ACS-Core requirement it does not meet in its README. + +**Not met yet** by the TypeScript Guardian: its ServerHello is constants, and it does not read the ClientHello (issue #165, issue #312). + +#### Policy evaluation with the AGT runtime -#### Actual AGT runtime +Policy evaluation is expected to use AGT's policy runtime built from the AGT commit `agt_ref` in [`agt/agt.lock`](agt/agt.lock). It is published as `agent-control-specification` on npm, and other languages reach the same runtime through their own package or a native binding to its Rust core. Each implementation records the package and version it uses in its own lock file, and its CI is expected to fail when that commit differs from `agt_ref` (issue #314). -Policy evaluation is expected to use AGT's policy runtime, `agent_control_specification`, at the commit and SDK version recorded in [`agt/agt.lock`](agt/agt.lock). It can be reached through an official SDK, a native binding to its Rust core, or a process or service that runs it. Reimplementing the runtime's behavior or directly evaluating its policy bundle is not an acceptable substitute. +Reimplementing the runtime's behavior, or evaluating its policy bundle directly, is not an acceptable substitute. AGT's Go module, `agent-governance-golang`, is a different policy engine and does not qualify. -AGT's Go module, `agent-governance-golang`, is a different policy engine and does not qualify. +An implementation may also ship another evaluator, under three conditions. AGT is the default, and the implementation's tests and any conformance claim run against AGT. The other evaluator is never used as an automatic fallback when AGT fails to load. Every decision it makes names it in `metadata.evaluator`, so a trace shows which evaluator decided. #### Architectural boundaries -Transport handling, ACS processing, AGT integration, message signing, state storage, and logging should have clearly defined responsibilities. The Guardian is expected to expose a transport-independent processing entry point. +Transport handling, ACS processing, AGT integration, message signing, state storage, and logging should each have a clearly defined responsibility. The Guardian should expose a processing entry point that does not depend on the transport. APIs, packages, classes, and file layouts follow the language's conventions. -Concrete APIs, packages, classes, and file layouts can follow language conventions. Host integrations are outside the Guardian's scope. +**Not met yet** by the TypeScript Guardian: processing sits inside its HTTP handler (issue #312). -#### Signing keys and secrets +#### Signing and verification -Implementations are expected to sign and verify ACS messages as [§10 of the specification](../docs/spec/instrument/specification.md#10-cryptographic-signatures) defines, including the HMAC-SHA256 key derivation and the meaning of `key_id`. +Implementations are expected to sign and verify ACS messages as [§10 of the specification](../docs/spec/instrument/specification.md#10-cryptographic-signatures) defines, in particular its "HMAC key derivation" and "`key_id` for HMAC" paragraphs. A reviewer checks these points. -In addition to the specification, implementations are expected to meet the following: +- `key_id` comes from configuration, has no built-in default, and is neither the `session_id` nor derived from the secret. +- A verifier rejects an unknown `key_id` with `SIGNATURE_INVALID` and never falls back to another secret. +- A signed response uses the `key_id` of the request it answers. +- The secret meets §10's length and randomness rule. +- Configuration maps each `key_id` to one secret and accepts at least two at once, so a secret is replaced without an outage. The documentation describes how. -- key material is base64-encoded, decodes to at least 32 bytes, and is read from a file or an environment variable; -- key material is not hard-coded and does not appear in ACS messages or logs; -- the documentation says how key material is configured and replaced. +These repository conventions sit on top of §10. + +- The secret is stored as standard base64 (RFC 4648 §4), with padding, and with surrounding whitespace ignored. The decoded bytes, not the base64 text, are the secret §10 names and the HKDF input. +- It is read from a file, an environment variable, or a secret store, and is never hard-coded. +- Neither the secret nor any key derived from it appears in ACS messages, error data, logs, or trace exports. + +**Not met yet** by the TypeScript Guardian: it does not sign or verify messages. PR #229 adds signing (issue #184, issue #312). #### Configurable storage -Session and security state should be accessed through a storage-provider interface selected through configuration. Internal storage schemas and formats are implementation-defined. Cross-implementation storage compatibility and session migration are not required. Supported storage providers and their durability and multi-instance guarantees are expected to be documented. +Session and security state should be reached through a storage-provider interface that configuration selects. Storage formats are the implementation's choice, and moving a session between implementations is not required. Each storage provider's durability and multi-instance guarantees are expected to be documented. -#### Concurrency and session consistency +**Not met yet** by the TypeScript Guardian: it has one in-memory store, and only code can swap it (issue #312). -The Guardian is expected to safely handle concurrent invocations independently of the transport's threading or execution model. +#### Concurrency and session consistency -Concurrent requests within a session should preserve replay protection, audit-chain consistency, and policy state. They should not cause duplicate evaluation of the same request or lost state updates. +The Guardian is expected to handle concurrent requests safely, whatever threading model its transport uses. Concurrent requests in one session are expected to keep §10.3's replay protection, the audit chain, and policy state consistent. No request is evaluated twice, and no state update is lost. -Synchronization mechanisms and internal processing algorithms are implementation-defined. +**Not met yet** by the TypeScript Guardian: it rejects no replay (issue #184, PR #229). Two concurrent steps in one session can overwrite each other's information-flow labels (issue #310). #### Bounded processing -Request waiting and policy evaluation should be bounded by configurable time and resource limits. This is a target. The TypeScript Guardian does not meet it yet. +Reading a request and evaluating policy are expected to be bounded by configurable limits on time, body size, and concurrent requests, with documented defaults. The default time limit is below the `timeout_config` the Guardian declares. A request that exceeds a limit gets an honoured `deny` with a reason code, not an error, so it never falls into the host's fail-open posture (§6.4). + +**Not met yet** by the TypeScript Guardian (issue #312). #### Bounded logging -Retained logs should be subject to a configurable total size limit, enforced by the implementation or its logging infrastructure. Defaults should bound retained log volume. Log formats and rotation mechanisms are implementation-defined. This is a target. The TypeScript Guardian does not meet it yet. +Each retained diagnostic log is expected to have a configurable size cap with a finite documented default, and reaching it never blocks a decision. The cap does not apply to the audit events §6.4, §6.5 and §9.2 require, or to the §8 session chain. When audit storage is full, the Guardian answers `deny` rather than drop an audit record. + +**Not met yet** by the TypeScript Guardian (issue #312). #### Verification -Once the shared contract test suite exists, the implementation is expected to pass the tests that apply to it. +Once the shared contract test suite exists (issue #311), an implementation is expected to pass the tests that apply to it. The capabilities it declares in its ServerHello decide which tests apply, and the suite checks that each declared capability behaves as declared. Until then, a port is verified the way the [root README](../README.md#port-it-python-go-rust-codex) describes: `bun run conformance` from `agt/` against the running port.