# AHP 0.8 conformance audit

This audit covers the authoritative Agent Host Protocol `spec/v0.8.0` tag at
commit `7153143f1c6993fa886d7d59870811cdad479d83`, the surface every client
gets. The official Rust crates are pinned as one unit:

```toml
ahp = "=1.0.0"
ahp-types = "=1.0.0"
ahp-ws = "=1.0.0"
```

The machine-readable inventory in
[`../conformance/ahp-0.8.json`](../conformance/ahp-0.8.json) enumerates all 27
commands, 86 actions, and 8 server notifications from that release. The
conformance test rejects omissions, duplicates, unknown entries, version drift,
or any entry not classified as implemented.

Paratenic now builds on the official 1.0.0 crates and negotiates 1.0, 0.9 or
0.8 per connection ([AHP 1.0 with a 0.8 fallback](ahp-1-0.md)). This manifest
is what every client gets, 0.8 clients in 0.8 shapes. The 0.9 and 1.0
additions, such as automation channels, `moveChat` and `chat/turnResume`, are
not implemented yet.

## Conformance summary

| Surface | Coverage |
| --- | --- |
| Commands | 27 / 27 implemented |
| Actions | 86 / 86 implemented through official `StateAction` and reducers |
| Server notifications | 8 / 8 implemented with typed payload validation |
| Public AHP state and wire models | Official `ahp-types = 1.0.0` only; 0.8 shapes for 0.8 clients |
| Protocol negotiation | 1.0 or 0.9 (AHP's ranges), else `0.8.0`; standard unsupported-version errors |

A capability-dependent operation is exposed only when its owning backend
advertises that capability. Calling an unavailable optional operation produces
a standard AHP error; this is conformant non-advertisement, not a private
fallback.

## Transport, ordering, and recovery

Paratenic provides authenticated WebSocket transport, initialization,
connection replacement, initial subscriptions, subscribe/unsubscribe,
monotonic host sequence numbers, bounded process-local replay, and
snapshot-based recovery below the replay floor. Logical client dispatches are
idempotent by `(clientId, clientSeq)`.

Slow WebSocket clients are isolated. Backend ingress never silently evicts
semantic events. Adjacent text and reasoning deltas are coalesced within an
8 ms / 64 KiB bound before reducer entry, while lifecycle, input, tool, and
settlement events retain order. Session durability is sharded and checkpointed
independently; replay is not used as transcript storage.

## Lifecycle and channels

Root, session, chat, terminal, changeset, annotations, and resource-watch
snapshots use official AHP state types and reducers.

Provider-managed session and chat lifecycle includes client-chosen URIs,
creation failure, ready state, disposal, default-chat selection, forks,
side-chat provenance, paged retained turns, and durable backend acceptance.
Registration-only ordinary Pi sessions remain non-disposable because no
lifecycle capability is advertised for them.

Protocol-v6 backend projection supports the complete server-originated action
surface. It accepts typed auxiliary resource snapshots, validates official AHP
actions, confines them to the owning session, reduces them before publication,
and persists changeset and annotations state. Client-originated advanced
actions are restricted to the AHP-defined client-dispatchable set and routed
only to a capable owning backend.

## Input, tools, customization, and MCP

Standard `chat/inputRequested`, `chat/inputCompleted`, and
`SessionState.inputNeeded` are authoritative. Runtime arbitration remains the
settlement authority, so local UI, AHP, timeout, abort, ring, and other input
producers race exactly once.

The complete tool action family is reducer-backed, including parameter deltas,
parameter/result confirmation, client tool execution, authentication-required
and authentication-resolved transitions, content updates, and completion.
Session aggregate input entries are maintained for actionable tool states.

Provider customizations, MCP lifecycle actions, server inventories, metadata,
activity, truncation, and session/chat working-directory actions use official
state and action models. Working-directory mutations are capability-gated and
respect immutable or replaceable primary-directory declarations. MCP start/stop
requests no longer apply optimistic state before backend settlement: refusal
preserves observed state, acceptance emits a correlated state-neutral
`paratenic/mcpLifecycleAccepted`, and backend MCP state events remain lifecycle
authority. Durable unresolved identities prohibit implicit replay after uncertain
delivery or host reconstruction. See `backend-protocol.md` for the extension and
its compatibility/qualification boundary; this is not complete frontend support.

MCP side channels use stable `mcp://` identities, preserve arbitrary JSON-RPC
IDs, enforce method allowlists, and forward advertised list-change
notifications. MCP initialization remains host-owned.

## Authentication

Transport bearer authentication is separate from AHP protected-resource
authentication.

Providers may advertise official RFC 9728 `ProtectedResourceMetadata`.
`authenticate` validates the resource, bounds token size, forwards the token
only to the owning protocol-v6 backend, waits for correlated acceptance, and
never persists the token. Dynamically discovered tool authentication resources
route to the owning live session backend. Typed `auth/required` notifications
are ownership checked before delivery.

## Resources and watches

The host implements bounded read, write, list, copy, delete, move, resolve,
mkdir, request, and resource-watch behavior for advertised confined `file:`
roots. It provides symlink-aware confinement, ETags, atomic replacement,
bounded recursive operations, receiver-assigned connection-owned watch
channels, filters, coalesced change batches, and teardown on unsubscribe or
disconnect.

A host is not required to advertise every URI scheme. Unadvertised resources
return standard not-found or permission errors.

This method/action inventory does not establish end-to-end image support in the
Pi adapters or Culture frontends. Durable image import, rich transcript backfill,
and inline rendering remain separate work; see the
[portable-image audit and proposed contract](portable-images.md).

## Terminals

The PTY subsystem implements catalogue publication, claims, create/dispose,
input, resize, title, clear, data, exit, bounded scrollback, and session-owned
cleanup. Streaming OSC parsing strips control sequences even when split across
read boundaries and projects OSC 7 cwd changes plus OSC 133 shell-integration
availability and command boundaries into the corresponding official terminal
actions.

## Changesets and annotations

Backends can advertise static or templated changeset catalogue entries and
publish official changeset snapshots/actions. The host validates and reduces
status, file, review, content, operation, and clear transitions.
`invokeChangesetOperation` validates operation identity and target scope,
routes to the owner, and waits for correlated backend acceptance.

Annotations channels persist and reduce set/update/remove and entry set/remove
actions. Client review and annotation actions use ordinary dispatch
idempotency and are rejected when out of scope.

## Progress and telemetry

Protocol-v6 providers can advertise OTLP log, trace, and metric channels in
`InitializeResult.telemetry`. Stateless telemetry subscriptions return no
snapshot, as required. Typed OTLP notifications, `root/progress`, and
`auth/required` are validated for method, payload channel, provider ownership,
and subscription before relay. Log channel templates support the protocol's
`{level}` expansions.

## Validation

The release gate runs formatting, strict workspace Clippy, all Rust targets,
Node extension tests, official-client interoperability tests, reconnect and
history tests, protocol inventory checks, terminal parser tests, concurrent
multi-session ingress soak tests, and frontend reducer/render tests.
