Failure semantics
Failure semantics
Failure classes
The following are operational failures:
- Deadline exceeded
- Connection refused, reset, or lost
- Backend process launch failure or abnormal exit
- Authentication failure, including credential resolution, acquisition, or refresh failure
- Non-success HTTP response
- Malformed UTF-8, JSON, or JSON-RPC
- Mismatched JSON-RPC request and response IDs
- JSON-RPC error response
- Unsupported protocol version or event
- Missing required result fields
- Unadvertised, unknown, malformed, or conflicting effects
- Backend response received after the deadline
An explicit
denyis not an operational failure.
Failure policy
AHP-FAIL-001 — MUST. Each intercept subscription declares fail-open or fail-closed, and the harness applies that policy to operational failures.
Each intercept subscription MUST explicitly configure one of:
fail-open: Continue unchanged after an operational failure.fail-closed: Deny the operation after an operational failure. Authentication failures follow the same configured policy as other operational failures; they do not unconditionally deny the underlying operation. Fail-open does not permit unauthenticated fallback delivery. There is no implicit default for intercept subscriptions. Requiring an explicit value prevents a security-sensitive deployment from inheriting an unexpected default. Observe subscriptions are non-decision-making and effectively fail open. Their delivery may delay normal completion of the owning hook call, but failure never changes the settled decision. They MUST NOT specifyfailurePolicy. See composition for delivery ownership and interruption.
Synthetic denial
For a fail-closed operational failure, the harness SHOULD present a generic local reason such as “Required policy backend unavailable.” It SHOULD NOT expose network details, credentials, stack traces, or malformed backend content to the model. A synthetic denial generated by fail-closed behavior MUST be distinguishable in local audit records from an explicit backend denial.
Deadlines
AHP-FAIL-002 — MUST. The harness enforces each configured interception deadline; retries remain bounded by the original deadline.
Every intercept subscription MUST specify timeoutMs as a positive integer. A harness MUST enforce the timeout across dispatch-time authentication acquisition or refresh, connection setup, request transmission, backend processing, response parsing, and atomic acceptance. Selected uploads use their separate preparation budget before dispatch.
A harness SHOULD support values from 100 ms through 30,000 ms. Deployments SHOULD choose the smallest value compatible with the backend because interception is on the agent’s critical path.
When the deadline expires, the harness MUST ignore any later response and apply failure policy. Interruption immediately ends pending decision requests and overrides fail-open or accepted approval. Late responses and staged effects MUST NOT revive interrupted work. The host MUST recheck cancellation and the original deadline before publishing acceptance after external authorization callbacks; it must not hold its state lock across blocking authorization. This adds no reverse-resolution or deferred approval channel.
Duplicate delivery and retries
AHP-CORE-004 — MUST. A retry preserves event, session, and tool-call identities and event content, and a backend tolerates duplicate delivery.
A harness MAY retry an intercept request only while the original deadline remains active. Every retry MUST reuse the same event ID, JSON-RPC ID, session ID, call ID, and event contents. Distinct local subscriptions can produce identical deliveries to the same backend. Handling that configuration, including any deduplication or idempotency behavior, is a backend concern; this protocol does not require per-subscription deduplication or introduce a wire delivery discriminator. A backend MAY provide idempotency support according to its configuration. An observer transport MAY retry a failed notification when it can detect delivery failure. Retries MUST preserve the exact subscription payload and identities. Observation remains best effort; This protocol revision does not guarantee at-least-once or exactly-once delivery. A harness MUST NOT retry an explicit denial or a successful empty-effect response.
Enclosing operation budgets and shutdown
A host MAY impose a deadline on the entire hook call in addition to registered per-interceptor deadlines. Queue waits, authentication waits, selected content preparation and uploads, delivery, retries, and owned observations consume that same remaining call budget. A phase transition or retry MUST NOT reset or extend the enclosing deadline. A shorter registered or phase-specific timeout still applies; an outer budget does not replace the existing interception deadline or failure policy.
Budget expiry stops new work and cancels or safely retires owned I/O. Implementations distinguish expiry from explicit cancellation in local diagnostics. Bounded safety cleanup may finish after the processing deadline; implementations MUST NOT use cleanup as permission to continue ordinary delivery or observer processing. Cancellation of one call’s wait on a shared harness auth operation does not cancel unrelated callers. Incomplete or interrupted interception MUST NOT be represented as permission to execute.
Closing a client stops admission of new calls and safely cancels or retires its active owned I/O. SDK-created processes and temporary resources are cleaned up, with bounded process reaping before shutdown completes. Injected shared transports and auth providers remain caller-owned unless ownership was explicitly transferred. Repeated shutdown is safe; calls after shutdown fail locally. A host requiring graceful completion awaits its active calls before closing the client; shutdown does not implicitly wait for ordinary best-effort observation processing.