diff --git a/AGENTS.md b/AGENTS.md index 5d324ab6..2118630d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -556,8 +556,8 @@ sees. Delivering an accepted plan as a focused, verified change. An Opus model acts in this role unless the task assigns another. Running this target prepares the -session from the contract below and hands you Claude's own interactive UI for -it. +session from the contract below and hands you the selected agent's own +interactive UI for it. diff --git a/architecture.md b/architecture.md index c484d854..9b62ba78 100644 --- a/architecture.md +++ b/architecture.md @@ -102,7 +102,7 @@ Existing documents and code get aligned to this section retroactively. | host profile | a named production assembly a trusted host offers a testing harness — `run` today — reused after argument parsing rather than restated; a host that cannot offer one refuses rather than approximating it | | execution outcome | what one nested document execution ended as, as the harness publishes it: a settlement carrying the exact completion `Result`, or, for a workflow attempt, a durable suspension carrying the run and suspension identities. A suspension is neither success nor failure | | trusted host | the code that decides what an execution is for — a CLI entrypoint or a workflow runner — as distinct from the document, the components it expands, and the middleware packages composed around it | -| native session launch | preparing one durable coding-agent session from a document and then handing its provider's own interactive UI the terminal for that exact session. It is session construction followed by an ownership handoff, not a chat frontend: XMD performs no model turn, proxies no native turn, and journals no native conversation | +| native session launch | preparing one durable coding-agent session from a document and then handing its provider's own interactive UI the terminal for that exact session. It is session construction followed by an ownership handoff, not a chat frontend: XMD proxies no native turn and journals no native conversation, and takes no model turn of its own beyond the one materialization turn an adapter may require to make a freshly created conversation resumable | | provider-native session identity | the identity an agent asserts for its own durable session state, distinct from the logical XMD session key and from the ACP/ACPX record identity. Only an asserted one crosses a handoff; XMD never infers that a string a native CLI would accept is one | | pending session placement | an exact provider-issued `Session` capability carrying where a logical session will live and which agent it is compatible with, and nothing more: no construction route, no provider handle, no resumable identity. A fresh `` produces one, and the first consuming operation chooses how the session is constructed | | session materialization | the transition that makes a placement's chosen route and its backend history resumable. ACP-first materialization happens only when the backend reports that it accepted the session's first turn; client-native materialization is the native launch's existing retained construction. Nothing else promotes a placement — not a returning ensure, a first output, a terminal result, a checkpoint token, an error code or a diagnostic | @@ -4158,7 +4158,7 @@ Status is measured against main. | nested run-profile Agent and elicitation declarations | lets one `` declare one child-scoped `` scenario set and one non-delegating `` matcher set; only frozen test data crosses the harness request, the trusted host constructs both providers inside the isolated child, siblings share no session or provider state, ordinary component shadowing remains in force, and the child journal retains only the selected Prompt and Elicit components' ordinary results | built on the #641 stack | | `Config` run deadline / exec default / Fetch default / verbosity | three independently owned contextual timeouts, absent unless configured, each read by exactly one consumer, and contextual verbosity — a boolean that is false unless configured, seeded by the command line and overridable for a lexical subtree, bounding nothing and owning no authority | built on this stack | | terminal grid (`` / ``) | replaces the root foreground terminal with one provider-neutral composite whose statically declared direct panes begin concurrently, stay independently interactive, preserve their final statuses until the reader closes the composite, and tear down completely before document execution continues. A paired pane expands isolated document flow; a self-closing pane runs the host's default shell. The grid owns one foreground-terminal lease, each pane owns a separate pane-terminal lease, and a pane-scoped native launcher lets `` use that pane without weakening the independent Agent session coordinator. The launcher terminates at the composite's required provider-neutral pane-execution operation; the authored ordinal stays in core's live closure, and the native request carries no pane identity. Core validates the complete row-major layout before provider contact, attaches only after every pane is ready, contains post-attach pane failures until close, and records the ordered provider-neutral outcomes. Completed replay contacts no terminal or Agent provider; partial replay rebuilds a fresh composite, restores completed panes as statuses, and continues incomplete pane effects under their existing durable identities. Provider commands, sockets, process topology and layout identifiers remain live-only inside the provider closure | defined for #717; #726 proves the persistent tmux pane-worker topology and its observable teardown boundary on macOS; structure and layout built in #729, provider-neutral execution and durability in #730, pane claim admission and native-launch middleware in #731; the required composite pane-execution endpoint is specified and implemented in #732, which is what gives a pane's `` that pane's terminal rather than the root's; the controlled non-tmux provider remains the authority for core lifecycle semantics; the tmux provider is built in #732 for the Deno and compiled foreground hosts — one invocation-private server per grid, authenticated persistent pane workers carrying exact argv, cwd and environment outside tmux parsing, explicit row-major layout imposed by pane swaps, a required composite `launch()` that gives a pane's `` its own terminal rather than the root's, and one ordered teardown that proves worker quiescence, channel closure and server disappearance before the document continues; its evidence uses a fake tmux with real workers and real sockets, and real tmux behaviour on macOS remains #726's; Node and Bun catalog and validate the same grids and install neither the provider nor the process observer, refusing before pane start | -| native session launch (`` / `launchAgentSession()`) | prepares one durable coding-agent session from the rendered body of `` and hands the provider's native UI the terminal for that exact session, then continues the document after it exits. The body renders completely first and only what it rendered crosses as the instruction layer; the launch performs no model turn; at the root it takes the run's foreground-terminal lease before an agent is resolved, while a launch inside `` takes that pane's lease through its pane-scoped native launcher. A host with no applicable terminal refuses without probing for an installed CLI. A session is constructed once, by one of two mechanisms, and its create-once construction route says which. Where the provider returns the identity, the ACPX provider creates the session, installs the layer at creation, releases ACP ownership before the spawn, and marks its handle stale so a later `` reattaches. Where the adapter names its own sessions, it allocates the identity inside ownership before any process exists, the native process creates the session under that name from a private mode-0600 instruction file, and ACP creates nothing — the instruction text reaches neither argv nor environment, and the file is removed on success, failure and cancellation alike while ownership is still held. Neither route converts into the other, and which one governs is chosen by the first operation that consumes the placement rather than by the `` that made it: a fresh `` publishes no route and establishes nothing, so a `` nested inside one constructs the session it placed, while a first subscribed `` publishes ACP-first before it ensures and keeps that account even if the turn that follows is never accepted. An established route is validated eagerly by a later ``, and a launch meeting a published ACP-first route refuses before an identity exists. A `` or `` meeting a bound client-allocated route attaches under the route's exact identity; a legacy unbound route or an unavailable attachment capability refuses before a turn and creates no substitute conversation. Phases are retained as `agent_session_launch` records under one expansion identity — `prepared` before ownership is released, then `detached`, then `exited` — so a completed replay launches nothing, a replay holding only `prepared` proves the handoff never began and may still create under the retained identity, and one holding `detached` resumes and never falls back. The public route carries an opaque one-use launch request and answers nothing; authority to run and retain a phase is delivered to the installed provider directly, so neither a returned completion nor a rebuilt request authors a launch. Every operation that can act on an advertised session takes exclusive ownership under one natural key first, through a coordinator the host built and passed in; contention refuses instead of queueing, and an owner that never proved it stopped leaves a recovery tombstone. A host that cannot say who owns a session refuses every advertised operation, and one that cannot say how a session was constructed additionally refuses an agent that names its own — before any provider effect. Every private setup or child-creation failure is normalized to `process-creation-failed` with fixed provider-owned text, carrying no path, argv, environment or host message. No launch path discards persistent provider state. A client-allocated session is bound to one executable build: the build is observed inside ownership before an identity is allocated, the binding is published with the V2 route and retained beside the prepared record, the native child runs the exact observed path in place of the launcher name, and every later create, resume, attachment and incomplete replay reobserves and compares before a process, an ensure or a turn. A `` or `` meeting a bound client-native route attaches to it: it reobserves the build, requires any retained provider arrangement to assert that same conversation, calls ensure with the route identity as `resumeSessionId`, and requires the provider to report that identity before a turn — refusing on missing capability, build drift, missing history or a differing assertion without creating a substitute conversation. ACP runtimes are partitioned by resolved agent command and binding, each handle is closed by the partition that created it, and a bound partition is torn down when its last handle closes. A legacy V1 client-native route keeps exactly the released native-only behavior and never attaches | built on the #517 stack, extended by the #519 and #561 stacks; Deno and the compiled binary assemble the host — coordinator, route store and executable observer — and Node and Bun keep the same advertised names while assembling none of it, so every advertised operation refuses before provider work; `claude` is advertised for native launch after passing the client-allocated gate at Claude Code 2.1.241 on macOS arm64 (#520) and separately for client-native attachment after passing the native-to-ACP marker gate (#561), and Codex remains unadvertised because nothing has run its provider-returned claims against an installed Codex; `Agent.AddDir` is unbuilt | +| native session launch (`` / `launchAgentSession()`) | prepares one durable coding-agent session from the rendered body of `` and hands the provider's native UI the terminal for that exact session, then continues the document after it exits. The body renders completely first and only what it rendered crosses as the instruction layer; the launch performs no model turn except an adapter's declared materialization turn, which runs at most once, only for a conversation the launch just created, and only with that adapter's fixed prompt; at the root it takes the run's foreground-terminal lease before an agent is resolved, while a launch inside `` takes that pane's lease through its pane-scoped native launcher. A host with no applicable terminal refuses without probing for an installed CLI. A session is constructed once, by one of two mechanisms, and its create-once construction route says which. Where the provider returns the identity, the ACPX provider creates the session, installs the layer at creation, releases ACP ownership before the spawn, and marks its handle stale so a later `` reattaches. Where the adapter names its own sessions, it allocates the identity inside ownership before any process exists, the native process creates the session under that name from a private mode-0600 instruction file, and ACP creates nothing — the instruction text reaches neither argv nor environment, and the file is removed on success, failure and cancellation alike while ownership is still held. Neither route converts into the other, and which one governs is chosen by the first operation that consumes the placement rather than by the `` that made it: a fresh `` publishes no route and establishes nothing, so a `` nested inside one constructs the session it placed, while a first subscribed `` publishes ACP-first before it ensures and keeps that account even if the turn that follows is never accepted. An established route is validated eagerly by a later ``, and a launch meeting a published ACP-first route refuses before an identity exists. A `` or `` meeting a bound client-allocated route attaches under the route's exact identity; a legacy unbound route or an unavailable attachment capability refuses before a turn and creates no substitute conversation. Phases are retained as `agent_session_launch` records under one expansion identity — `prepared` before ownership is released, then `materialized` where an adapter required a materialization turn, then `detached`, then `exited` — so a completed replay launches nothing, a replay holding only `prepared` proves the handoff never began and may still create under the retained identity, and one holding `detached` resumes and never falls back. The public route carries an opaque one-use launch request and answers nothing; authority to run and retain a phase is delivered to the installed provider directly, so neither a returned completion nor a rebuilt request authors a launch. Every operation that can act on an advertised session takes exclusive ownership under one natural key first, through a coordinator the host built and passed in; contention refuses instead of queueing, and an owner that never proved it stopped leaves a recovery tombstone. A host that cannot say who owns a session refuses every advertised operation, and one that cannot say how a session was constructed additionally refuses an agent that names its own — before any provider effect. Every private setup or child-creation failure is normalized to `process-creation-failed` with fixed provider-owned text, carrying no path, argv, environment or host message. No launch path discards persistent provider state. A session whose adapter pins a build is bound to that one build, whichever side named it: the build is observed inside ownership before an identity is allocated or a provider session is created, the binding is published with the bound route — V2 for client-native, V3 for ACP-first — and retained beside the prepared record, the native child runs the exact observed path in place of the launcher name, and every later create, resume, attachment and incomplete replay reobserves and compares before a process, an ensure or a turn. A `` or `` meeting a bound client-native route attaches to it: it reobserves the build, requires any retained provider arrangement to assert that same conversation, calls ensure with the route identity as `resumeSessionId`, and requires the provider to report that identity before a turn — refusing on missing capability, build drift, missing history or a differing assertion without creating a substitute conversation. ACP runtimes are partitioned by resolved agent command and binding, each handle is closed by the partition that created it, and a bound partition is torn down when its last handle closes. A legacy V1 client-native route keeps exactly the released native-only behavior and never attaches, and a legacy V1 ACP-first route refuses an agent whose adapter binds a build rather than gaining the current executable | built on the #517 stack, extended by the #519 and #561 stacks; Deno and the compiled binary assemble the host — coordinator, route store and executable observer — and Node and Bun keep the same advertised names while assembling none of it, so every advertised operation refuses before provider work; `claude` is advertised for native launch after passing the client-allocated gate at Claude Code 2.1.241 on macOS arm64 (#520) and separately for client-native attachment after passing the native-to-ACP marker gate (#561); `codex` is advertised for native launch after passing the provider-returned gate at `codex-cli 0.153.2` on macOS arm64 with the vendored `@agentclientprotocol/codex-acp` 1.6.2 snapshot that asserts the App Server thread on the response `_meta` (#755), which costs one fixed `codex-materialization.v1` turn because Codex writes the rollout `codex resume ` reads at a thread's first turn — a launch outside that tuple refuses before an identity exists, and reading the ACP session id as the native identity stays forbidden; `Agent.AddDir` is unbuilt | | `` | performs one XMD-mediated HTTP read through contextual `API.Fetch`, admitting the whole request before transport, and retains the normalized request and the detached response as one `fetch` durable observation; capture decides whether a status is data or a failure, and the trusted host's destination ceiling sits below the component | built on the #456 stack; a generated fragment may name the pinned identity only for a request the trusted host stated exactly, on the #369 stack | | `API.Files` | routes every document filesystem operation to the installed provider, with no host default and structural failure data. Its mandatory semantic operations include `ensureDirectory`, which recursively creates or adopts one directory and returns Unit; separately loaded copies compose through the stable Api name | built on the #227 stack; directory ensure added by #643 | | `` | removes one file the document names, inside the contextual working directory. An ordinary overridable core default with a closed schema of one required non-empty `path`, **self-closing only** — a paired spelling never enters its body, because the component declares its one form and canonical invocation-form dispatch enters that body only for the form the scan recorded, before `Env.cwd` is read and before the provider is reached. Neither the composable `Component.hasContent()` chain nor a method on whatever object a caller handed over takes part. It renders the empty string, declares no `returns` and hands back no receipt, so an ordinary `as` captures that empty string; absence is the same success, so deleting a path twice succeeds twice. One regular file or one final symbolic link goes — the link rather than its target, inside or outside — and every directory is refused, an empty one included. Empty, absolute, lexically escaping and parent-link-escaping paths are refused before any removal, and a printed error names only the path the document wrote. One semantic `API.Files.deleteFile` call and no filesystem access of its own; under a workflow run it is one `workspace_file` effect retaining `{ kind: "deleted" }`. The standard Deno workflow profile admits it to generated XMD as the exact self-closing identity `@executablemd/core#File.Delete`, third in the write table, where it performs that same ordinary effect and contributes no evaluator result | built on the #567 stack | diff --git a/packages/acp/mod.ts b/packages/acp/mod.ts index c39c348b..5e46f60a 100644 --- a/packages/acp/mod.ts +++ b/packages/acp/mod.ts @@ -43,8 +43,10 @@ export { knownNativeAdapters, nativeAdapterFor, } from "./src/native-launch.ts"; -export { allocatesIdentity } from "./src/native-launch.ts"; +export { allocatesIdentity, bindsBuild } from "./src/native-launch.ts"; export type { + BoundProviderReturnedAdapter, + BuildBoundAdapter, ClientAllocatedAdapter, NativeAdapter, NativeBinding, @@ -109,4 +111,5 @@ export type { AgentSessionRouteStore, AgentSessionRouteV1, AgentSessionRouteV2, + AgentSessionRouteV3, } from "./src/session-route.ts"; diff --git a/packages/acp/src/CodexNativeLaunch.test.md b/packages/acp/src/CodexNativeLaunch.test.md new file mode 100644 index 00000000..fee0096e --- /dev/null +++ b/packages/acp/src/CodexNativeLaunch.test.md @@ -0,0 +1,601 @@ +# A real Codex session, prepared, materialized and then rejoined + +`xmd run AGENTS.md#Implementor --default-agent codex` is the whole product for +Codex: it prepares one Codex conversation from this repository's own Implementor +contract and hands you Codex's own interactive UI for that exact conversation. +This document runs that command — the literal one, through the built binary — +and asks the two questions that decide whether the conversation is real. + +**Did the prepared contract govern the first thing you say?** The first native +turn asks for the opening sentence of the role contract without ever sending +that sentence. A conversation that did not receive the prepared layer cannot +produce it, and neither can an agreeable model, because nothing in the question +says what the sentence is. + +**Is what you said natively part of the same conversation?** That first native +turn also plants a one-time marker. A second, independent invocation then +rejoins the same conversation over ACP — from an authored document that has +never seen the marker — and asks for it. Recovering it is what makes the native +UI and the ACP session one conversation rather than two wearing the same name. + +Getting there costs one turn nobody asked for. Codex CLI 0.153.2 does not write +a conversation anywhere `codex resume` can find it until a turn has completed in +it, so XMD spends exactly one of its own first: `codex-materialization.v1`, +whose only job is to make the conversation openable. That the operator can then +leave without ever speaking — and come back without buying a second one — is the +subject of `CodexZeroNativeTurnExit.test.md`, so that question can be corrected +without respending the three turns this document is authorized to spend. + +## What this costs, and what it touches + +Three real model turns against the operator's own Codex credentials: XMD's own +materialization turn, one native turn that answers from the prepared layer and +plants the marker, and one ACP turn that rejoins and recalls it. Nothing else is +sent. The materialization turn's bytes are fixed by the product, are shown to +the operator before they are spent, and carry no path, identity, environment or +authored content. + +It is opt-in twice over. Without `XMD_CODEX_NATIVE_PROOF=1` the fixture refuses +before starting any Codex process; without a separate +`XMD_CODEX_MODEL_TURNS_AUTHORIZED=3` it refuses before spending a turn. It also +refuses on a machine outside the frozen compatibility tuple below, because the +finding this feature rests on is a fact about one Codex build. + +Everything sent besides those three turns is terminal control: Codex's own +directory trust dialog is answered at most once with the choice it pre-selects, +and the exit is two Ctrl-C bytes. The command runs with an operator's +environment rather than this process's, so anything an enclosing agent session +exported is dropped. + +The command runs in a fresh temporary directory holding a byte-for-byte copy of +this repository's own `AGENTS.md` and `.agents/implementor.md`, so the literal +production target resolves without creating Codex state for the repository. +Afterwards the conversation is removed through Codex's own +`codex delete --force `, naming the exact identity this run created. +`CODEX_HOME` is left alone — relocating it de-authenticates Codex — and nothing +beneath Codex's configuration, history or rollout files is ever opened. + +Run it with: + +```sh +XMD_CODEX_NATIVE_PROOF=1 XMD_CODEX_MODEL_TURNS_AUTHORIZED=3 \ + deno task xmd test packages/acp/src/CodexNativeLaunch.test.md --raw +``` + +## What a verdict may say + +The schema is the disclosure boundary, not a convenience. It accepts versions +and digests of public executables, the session identity and who chose it, +booleans, counts, phase and failure classes, usage field *names*, and cleanup +outcomes. The role contract's text, the history marker, the materialization +reply, raw terminal output, argument vectors, the environment and private paths +have nowhere to go in it, so a fixture that tried to report one would fail this +document. + + + +```json +{ + "type": "object", + "additionalProperties": false, + "required": [ + "mode", "verdict", "authorized", "turnsAuthorized", "authorizedTurnBudget", + "ran", "refusal", "detail", + "codexVersion", "codexDigest", "platform", "architecture", + "adapterPackage", "adapterVersion", "adapterDigest", "compatibilityTupleFrozen", + "target", "projectCopyVerified", "implementorMarkerRendered", "siblingMarkersRendered", + "nativeSessionId", "identityProvenance", "reentryNativeSessionId", + "substitutedIdentity", "routeConverted", + "firstXmdExitCode", "secondXmdExitCode", "instructionChannel", + "modelTurns", "materializationTurns", "nativeUserTurns", "acpReattachTurns", + "answerObserverInvocations", "conversationInputByteCount", + "consentInputBytes", "consentSurfaces", "exitControlBytes", + "reentryConsentInputBytes", "reentryConsentSurfaces", "reentryExitControlBytes", + "inheritedAgentMarkersRemoved", + "noticedBeforeSpending", "noticedAfterSpending", + "openingSentenceExact", "markerRecovered", "acpDocumentCarriesMarker", + "answerSurface", "outcome", + "materialization", "route", "journal", "cleanup", "privateStateInspected" + ], + "properties": { + "mode": { "type": "string" }, + "verdict": { "enum": ["PASS", "REFUSED", "ENVIRONMENT_BLOCKED", "PRODUCT_FAILED", "HARNESS_FAILED"] }, + "authorized": { "type": "boolean" }, + "turnsAuthorized": { "type": "boolean" }, + "authorizedTurnBudget": { "type": "integer" }, + "ran": { "type": "boolean" }, + "refusal": { "type": "string" }, + "detail": { "type": "string" }, + "codexVersion": { "type": "string" }, + "codexDigest": { "type": "string" }, + "platform": { "type": "string" }, + "architecture": { "type": "string" }, + "adapterPackage": { "type": "string" }, + "adapterVersion": { "type": "string" }, + "adapterDigest": { "type": "string" }, + "compatibilityTupleFrozen": { "type": "boolean" }, + "target": { "type": "string" }, + "projectCopyVerified": { "type": "boolean" }, + "implementorMarkerRendered": { "type": "boolean" }, + "siblingMarkersRendered": { "type": "integer" }, + "nativeSessionId": { "type": "string" }, + "identityProvenance": { "type": "string" }, + "reentryNativeSessionId": { "type": "string" }, + "substitutedIdentity": { "type": "boolean" }, + "routeConverted": { "type": "boolean" }, + "firstXmdExitCode": { "type": "integer" }, + "secondXmdExitCode": { "type": "integer" }, + "instructionChannel": { "type": "string" }, + "modelTurns": { "type": "integer" }, + "materializationTurns": { "type": "integer" }, + "nativeUserTurns": { "type": "integer" }, + "acpReattachTurns": { "type": "integer" }, + "answerObserverInvocations": { "type": "integer" }, + "conversationInputByteCount": { "type": "integer" }, + "consentInputBytes": { "type": "string" }, + "consentSurfaces": { "type": "array", "items": { "type": "string" } }, + "exitControlBytes": { "type": "string" }, + "reentryConsentInputBytes": { "type": "string" }, + "reentryConsentSurfaces": { "type": "array", "items": { "type": "string" } }, + "reentryExitControlBytes": { "type": "string" }, + "inheritedAgentMarkersRemoved": { "type": "integer" }, + "noticedBeforeSpending": { "type": "boolean" }, + "noticedAfterSpending": { "type": "boolean" }, + "openingSentenceExact": { "type": "boolean" }, + "markerRecovered": { "type": "boolean" }, + "acpDocumentCarriesMarker": { "type": "boolean" }, + "answerSurface": { "type": "string" }, + "outcome": { "enum": ["same-identity", "no-session", "unresolved"] }, + "privateStateInspected": { "type": "boolean" }, + "materialization": { + "type": "object", + "additionalProperties": false, + "required": [ + "promptVersion", "requestIdStable", "promptExact", "turnNamed", "turnProvider", + "durationReported", "responsePresent", "stopReason", + "reportedUsageFields", "unreportedUsageFields", "failureClasses" + ], + "properties": { + "promptVersion": { "type": "string" }, + "requestIdStable": { "type": "boolean" }, + "promptExact": { "type": "boolean" }, + "turnNamed": { "type": "boolean" }, + "turnProvider": { "type": "string" }, + "durationReported": { "type": "boolean" }, + "responsePresent": { "type": "boolean" }, + "stopReason": { "type": "string" }, + "reportedUsageFields": { "type": "array", "items": { "type": "string" } }, + "unreportedUsageFields": { "type": "array", "items": { "type": "string" } }, + "failureClasses": { "type": "array", "items": { "type": "string" } } + } + }, + "route": { + "type": "object", + "additionalProperties": false, + "required": ["kind", "provider", "buildVersion", "buildDigest"], + "properties": { + "kind": { "type": "string" }, + "provider": { "type": "string" }, + "buildVersion": { "type": "string" }, + "buildDigest": { "type": "string" } + } + }, + "journal": { + "type": "object", + "additionalProperties": false, + "required": [ + "provider", "agent", "launcher", "provenance", "nativeSessionId", "cwdIsProject", + "sessionState", "instructionsDigestPresent", + "firstPhases", "secondPhases", "failureClasses" + ], + "properties": { + "provider": { "type": "string" }, + "agent": { "type": "string" }, + "launcher": { "type": "string" }, + "provenance": { "type": "string" }, + "nativeSessionId": { "type": "string" }, + "cwdIsProject": { "type": "boolean" }, + "sessionState": { "type": "array", "items": { "type": "string" } }, + "instructionsDigestPresent": { "type": "boolean" }, + "firstPhases": { "type": "array", "items": { "type": "string" } }, + "secondPhases": { "type": "array", "items": { "type": "string" } }, + "failureClasses": { "type": "array", "items": { "type": "string" } } + } + }, + "cleanup": { + "type": "object", + "additionalProperties": false, + "required": [ + "liveChildren", "journalsRemoved", "routeRecordsRemoved", + "sessionDeleteOutcome", "temporaryRootRemoved" + ], + "properties": { + "liveChildren": { "type": "integer" }, + "journalsRemoved": { "type": "boolean" }, + "routeRecordsRemoved": { "type": "boolean" }, + "sessionDeleteOutcome": { "enum": ["deleted", "nothing-to-delete", "failed"] }, + "temporaryRootRemoved": { "type": "boolean" } + } + } + } +} +``` + + + + +```sh timeout=40min exec as="run" +deno run --allow-all --frozen packages/acp/tests/fixtures/codex-native-launch-proof.ts native-launch +``` + +The fixture returns a structured verdict even when the product fails one of the +two questions, so a nonzero exit means the harness broke rather than a question +being answered. + + + + +{run.stdout} + + +The whole result is shown before anything is judged. It carries no contract +text, no marker and no transcript content — `openingSentenceExact` and +`markerRecovered` are the only things about the conversation that crossed the +fixture boundary. + +```json +{run.stdout} +``` + +## Nothing private was read + +True whether or not the proof was opted into. Codex's rollout files are the one +place that could answer this document cheaply, and they are exactly what a proof +of the public contract may not open. + + + +## What the verdict decides + +The fixture classifies its own outcome, and that classification — not this +document's arithmetic — chooses what is worth asserting. A run its environment +blocked may have reached the first question and even spent the turn that asks +it, but it establishes neither answer, so demanding both would convict the +product of the environment's failure. Each branch below asserts only what its +verdict makes true, and every authorized verdict other than `PASS` ends by +stopping the document with the fixture's own reason, so a proof that did not +pass says why in one sentence instead of failing on an accounting mismatch that +was never the point. The one outcome that passes without proving anything is the +unarmed refusal: with the opt-ins absent nothing is spent and nothing is +observed, and that zero-turn skip is how this document runs on an ordinary +machine and in CI. + + + + +A pass is a claim about a journey that happened, so the first thing it owes is +that one did. + + + +## The frozen compatibility point + +The materialization turn exists because of a fact about one Codex build. This +records which one, so a later build that stopped needing it — or started needing +something else — cannot pass as this one. + + + + + + + + + + +## Three turns, and only one of them was XMD's + +The authorized budget is three, and the accounts name each one: one +materialization the product spent, one native turn the operator typed, one ACP +turn the second invocation asked. There is no fourth, and there is no second +materialization. + + + + + + + 0} /> + + +Reading an answer off a terminal is something the harness does, and it does it +for the one invocation that submits that native turn and for no other. The +invocations that type nothing reconstruct nothing, so the paths this document +does not test are the paths they already were. + + + +## The operator was told before it was spent + +A billable turn nobody was warned about is a bill, not a feature. The notice +appears on the terminal that acquired the launch before the turn starts, and the +completion summary appears before the native UI opens. + + + + +## The turn was the exact one the contract names + +Its version, its bytes and its request identity are fixed by the product, not +composed at the call site, and the retained preparation named the same request +the retained turn later reported against. + + + + + + + + + + + +Usage is recorded as the provider reported it. Which fields arrived is a fact +about Codex, not about this document, so both lists are shown and only their sum +is fixed: every field is either reported or explicitly unreported, and none is +quietly inferred to be zero. + + + +## The prepared contract governed the first native turn + +The question named neither the sentence nor any file, and the materialization +turn before it said nothing about either. The answer carried the opening +sentence of `.agents/implementor.md` exactly, which only the prepared layer +could have supplied — which also settles that materialization did not consume +the layer on its way past. + + + +## ACP rejoined the conversation the native UI was in + +The marker existed only in that first native turn — never in the instruction +layer, the argument vector, the environment or the session key — and the +document that asked for it does not contain it. It came back behind a prefix +that appeared in no earlier turn, so only an answer could have produced it. + + + + + + + + + +## The identity is the one Codex named + +Codex chose it and told the adapter through its own metadata. XMD never parsed +it out of anything, and never substituted a fresh one when the first was +inconvenient. + + + + +## The production target ran, and its siblings did not + + + + + + +## Route and journal agree + +The route names the construction and the Codex build the tuple above froze, and +nothing else: an ACP-first route deliberately records no conversation identity, +launcher or instruction layer, so those are read from the journal instead. A +route that had converted to anything but `acp-first` would mean the launch +stopped being the one this document describes. + + + + + + + + + + + + + + +One launch, one materialization, one detachment, one exit. The ACP reattachment +is not a launch, so it adds no phases of its own. + + + + + + +## Nothing was left behind + + + + + + + + + + +## The environment stopped it + +Something outside the product prevented an answer. Whether that happened before +the journey started or partway through it decides what may still be believed, so +the two are judged apart rather than together. + + + + +Nothing was launched. No conversation exists, no turn was bought, and the +accounts are all still zero — which is the only thing worth checking about a run +that never began. + + + + + + + + + + + + + + +The journey began and turns were spent, so what the accounts say about them has +to hold even though the questions went unanswered. Every turn is attributable to +one of the three the budget names, and no more were bought than were authorized. +What this branch may not do is demand the three the budget allows, the second +invocation, or either answer: a bound reached is the harness giving up, and +reading that as a product result would convict the product of the environment's +failure. + + + + +A conversation was created, so it still has to be cleaned up. This is the part +of a blocked run that costs money if it is wrong. + + + + + + + + + + + + + + + +## The product answered, and the answer was wrong + +The journey ran and the fixture reached a finding, so the accounts and the +cleanup are the two things that decide whether the finding can be trusted. They +are checked and nothing else is: the finding itself is the fixture's to state. + + + + + + + + + + + + + + +## The harness broke before the product could be judged + +Nothing is asserted here on purpose. A harness that stopped may have left its +own accounts half-written, and an assertion about them would fail first and +report the wrong thing — burying the sentence that says what actually broke. + + + + + + +## It refused before any conversation existed + +The refusal happens before any Codex conversation exists, so a refused run +spends no turn and observes nothing. + + + + + + + + + + + + + + + +Both opt-ins were given, so this run asked to spend turns and was turned away +anyway. That is a refusal the operator has to resolve, not a suite that may go +green around it. + + + + + + +Without both opt-ins this is the ordinary way the document runs: on a developer +machine and in CI, where it must cost nothing and still be read. Reaching here +is the pass. + + + + + + + + + + + + + diff --git a/packages/acp/src/CodexZeroNativeTurnExit.test.md b/packages/acp/src/CodexZeroNativeTurnExit.test.md new file mode 100644 index 00000000..73b706ba --- /dev/null +++ b/packages/acp/src/CodexZeroNativeTurnExit.test.md @@ -0,0 +1,430 @@ +# Leaving a prepared Codex session without saying anything + +A prepared session you never speak in should still be there tomorrow. For Claude +that costs nothing, and `ClaudeZeroTurnExit.test.md` proves it: the session the +launch constructs is openable the moment it exists. + +Codex is not like that. Codex CLI 0.153.2 does not write a conversation anywhere +`codex resume` can find it until a turn has completed in it, so a launch that +handed you the native UI without one would hand you a name Codex disowns. XMD +therefore spends exactly one model turn of its own — `codex-materialization.v1`, +whose only job is to make the conversation openable — and then gets out of the +way. + +That turn is the whole subject of this document, and it asks the two questions +that decide whether it was worth spending. + +**Did one turn actually make the conversation openable?** The launch opens the +native UI, and the operator leaves without typing anything at all. Reaching +Codex's own composer rather than `No saved session found with ID` is the answer. + +**Is it still openable without buying another one?** A second, independent +invocation of the same command re-enters. If it materialized again, the reader +paid twice for something already done, so the durable accounts must retain +exactly one materialization across both invocations. + +Whether the prepared contract governs what you say once you are in there is a +different question, and it lives in `CodexNativeLaunch.test.md` so that this one +can be corrected without ever respending its turns. + +## What this costs, and what it touches + +One real model turn against the operator's own Codex credentials: XMD's own +materialization turn, in the session the first launch constructed. Nothing is +typed into either native UI. The exact bytes of that turn are fixed by the +product, are shown to the operator before they are spent, and carry no path, +identity, environment or authored content. + +It is opt-in twice over. Without `XMD_CODEX_NATIVE_PROOF=1` the fixture refuses +before starting any Codex process; without a separate +`XMD_CODEX_MODEL_TURNS_AUTHORIZED=1` it refuses before spending the turn. It +also refuses on a machine outside the frozen compatibility tuple below, because +the finding this feature rests on is a fact about one Codex build. + +Everything sent besides that turn is terminal control: Codex's own directory +trust dialog is answered at most once with the choice it pre-selects, and the +exit is two Ctrl-C bytes. The command runs with an operator's environment rather +than this process's, so anything an enclosing agent session exported is dropped. + +The command runs in a fresh temporary directory holding a byte-for-byte copy of +this repository's own `AGENTS.md` and `.agents/implementor.md`. Afterwards both +conversations are removed through Codex's own `codex delete --force `, each +named by the exact identity this run created. `CODEX_HOME` +is left alone — relocating it de-authenticates Codex — and nothing beneath +Codex's configuration, history or rollout files is ever opened. + +Run it with: + +```sh +XMD_CODEX_NATIVE_PROOF=1 XMD_CODEX_MODEL_TURNS_AUTHORIZED=1 \ + deno task xmd test packages/acp/src/CodexZeroNativeTurnExit.test.md --raw +``` + +## What a verdict may say + +The schema is the disclosure boundary, not a convenience. It accepts versions +and digests of public executables, the session identity and who chose it, +booleans, counts, phase and failure classes, usage field *names*, and cleanup +outcomes. The role contract's text, the materialization turn's reply, raw +terminal output, argument vectors, the environment and private paths have +nowhere to go in it, so a fixture that tried to report one would fail this +document. + + + +```json +{ + "type": "object", + "additionalProperties": false, + "required": [ + "mode", "verdict", "authorized", "turnsAuthorized", "authorizedTurnBudget", + "ran", "refusal", "detail", + "codexVersion", "codexDigest", "platform", "architecture", + "adapterPackage", "adapterVersion", "adapterDigest", "compatibilityTupleFrozen", + "target", "projectCopyVerified", "implementorMarkerRendered", "siblingMarkersRendered", + "nativeSessionId", "identityProvenance", "reentryNativeSessionId", + "substitutedIdentity", "routeConverted", + "firstXmdExitCode", "secondXmdExitCode", "instructionChannel", + "modelTurns", "materializationTurns", "nativeUserTurns", "acpReattachTurns", + "answerObserverInvocations", "conversationInputByteCount", + "consentInputBytes", "consentSurfaces", "exitControlBytes", + "reentryConsentInputBytes", "reentryConsentSurfaces", "reentryExitControlBytes", + "inheritedAgentMarkersRemoved", + "noticedBeforeSpending", "noticedAfterSpending", + "openingSentenceExact", "markerRecovered", "acpDocumentCarriesMarker", + "answerSurface", "outcome", + "materialization", "route", "journal", "cleanup", "privateStateInspected" + ], + "properties": { + "mode": { "type": "string" }, + "verdict": { "enum": ["PASS", "REFUSED", "ENVIRONMENT_BLOCKED", "PRODUCT_FAILED", "HARNESS_FAILED"] }, + "authorized": { "type": "boolean" }, + "turnsAuthorized": { "type": "boolean" }, + "authorizedTurnBudget": { "type": "integer" }, + "ran": { "type": "boolean" }, + "refusal": { "type": "string" }, + "detail": { "type": "string" }, + "codexVersion": { "type": "string" }, + "codexDigest": { "type": "string" }, + "platform": { "type": "string" }, + "architecture": { "type": "string" }, + "adapterPackage": { "type": "string" }, + "adapterVersion": { "type": "string" }, + "adapterDigest": { "type": "string" }, + "compatibilityTupleFrozen": { "type": "boolean" }, + "target": { "type": "string" }, + "projectCopyVerified": { "type": "boolean" }, + "implementorMarkerRendered": { "type": "boolean" }, + "siblingMarkersRendered": { "type": "integer" }, + "nativeSessionId": { "type": "string" }, + "identityProvenance": { "type": "string" }, + "reentryNativeSessionId": { "type": "string" }, + "substitutedIdentity": { "type": "boolean" }, + "routeConverted": { "type": "boolean" }, + "firstXmdExitCode": { "type": "integer" }, + "secondXmdExitCode": { "type": "integer" }, + "instructionChannel": { "type": "string" }, + "modelTurns": { "type": "integer" }, + "materializationTurns": { "type": "integer" }, + "nativeUserTurns": { "type": "integer" }, + "acpReattachTurns": { "type": "integer" }, + "answerObserverInvocations": { "type": "integer" }, + "conversationInputByteCount": { "type": "integer" }, + "consentInputBytes": { "type": "string" }, + "consentSurfaces": { "type": "array", "items": { "type": "string" } }, + "exitControlBytes": { "type": "string" }, + "reentryConsentInputBytes": { "type": "string" }, + "reentryConsentSurfaces": { "type": "array", "items": { "type": "string" } }, + "reentryExitControlBytes": { "type": "string" }, + "inheritedAgentMarkersRemoved": { "type": "integer" }, + "noticedBeforeSpending": { "type": "boolean" }, + "noticedAfterSpending": { "type": "boolean" }, + "openingSentenceExact": { "type": "boolean" }, + "markerRecovered": { "type": "boolean" }, + "acpDocumentCarriesMarker": { "type": "boolean" }, + "answerSurface": { "type": "string" }, + "outcome": { "enum": ["same-identity", "no-session", "unresolved"] }, + "privateStateInspected": { "type": "boolean" }, + "materialization": { + "type": "object", + "additionalProperties": false, + "required": [ + "promptVersion", "requestIdStable", "promptExact", "turnNamed", "turnProvider", + "durationReported", "responsePresent", "stopReason", + "reportedUsageFields", "unreportedUsageFields", "failureClasses" + ], + "properties": { + "promptVersion": { "type": "string" }, + "requestIdStable": { "type": "boolean" }, + "promptExact": { "type": "boolean" }, + "turnNamed": { "type": "boolean" }, + "turnProvider": { "type": "string" }, + "durationReported": { "type": "boolean" }, + "responsePresent": { "type": "boolean" }, + "stopReason": { "type": "string" }, + "reportedUsageFields": { "type": "array", "items": { "type": "string" } }, + "unreportedUsageFields": { "type": "array", "items": { "type": "string" } }, + "failureClasses": { "type": "array", "items": { "type": "string" } } + } + }, + "route": { + "type": "object", + "additionalProperties": false, + "required": ["kind", "provider", "buildVersion", "buildDigest"], + "properties": { + "kind": { "type": "string" }, + "provider": { "type": "string" }, + "buildVersion": { "type": "string" }, + "buildDigest": { "type": "string" } + } + }, + "journal": { + "type": "object", + "additionalProperties": false, + "required": [ + "provider", "agent", "launcher", "provenance", "nativeSessionId", "cwdIsProject", + "sessionState", "instructionsDigestPresent", + "firstPhases", "secondPhases", "failureClasses" + ], + "properties": { + "provider": { "type": "string" }, + "agent": { "type": "string" }, + "launcher": { "type": "string" }, + "provenance": { "type": "string" }, + "nativeSessionId": { "type": "string" }, + "cwdIsProject": { "type": "boolean" }, + "sessionState": { "type": "array", "items": { "type": "string" } }, + "instructionsDigestPresent": { "type": "boolean" }, + "firstPhases": { "type": "array", "items": { "type": "string" } }, + "secondPhases": { "type": "array", "items": { "type": "string" } }, + "failureClasses": { "type": "array", "items": { "type": "string" } } + } + }, + "cleanup": { + "type": "object", + "additionalProperties": false, + "required": [ + "liveChildren", "journalsRemoved", "routeRecordsRemoved", + "sessionDeleteOutcome", "temporaryRootRemoved" + ], + "properties": { + "liveChildren": { "type": "integer" }, + "journalsRemoved": { "type": "boolean" }, + "routeRecordsRemoved": { "type": "boolean" }, + "sessionDeleteOutcome": { "enum": ["deleted", "nothing-to-delete", "failed"] }, + "temporaryRootRemoved": { "type": "boolean" } + } + } + } +} +``` + + + + +```sh timeout=40min exec as="run" +deno run --allow-all --frozen packages/acp/tests/fixtures/codex-native-launch-proof.ts zero-native-turn +``` + +The fixture returns a structured verdict even when the product fails one of the +two questions, so a nonzero exit means the harness broke rather than a question +being answered. + + + + +{run.stdout} + + +The whole result is shown before anything is judged. It carries no contract +text, no transcript content and no reply — `promptExact` and `responsePresent` +are the only things about the turn that crossed the fixture boundary. + +```json +{run.stdout} +``` + +## Nothing private was read + +True whether or not the proof was opted into. Codex's rollout files are the one +place that could answer this document cheaply, and they are exactly what a proof +of the public contract may not open. + + + + + +## The frozen compatibility point + +The materialization turn exists because of a fact about one Codex build. This +records which one, so a later build that stopped needing it — or started needing +something else — cannot pass as this one. + + + + + + + + + + +## Exactly one model turn, and it was XMD's + +The authorized budget is one, and one is what the durable accounts retain across +both invocations. Nothing was typed into either native UI, so every byte the +conversation received was the product's own. + + + + + + + + + + +Nothing was typed, so nothing was watched for. The harness reconstructs a +terminal only for an invocation that submits a turn and waits for its answer, +and neither of these two invocations does. + + + +## The operator was told before it was spent + +A billable turn nobody was warned about is a bill, not a feature. The notice +appears on the terminal that acquired the launch before the turn starts, and the +completion summary appears before the native UI opens. + + + + +## The turn was the exact one the contract names + +Its version, its bytes and its request identity are fixed by the product, not +composed at the call site, and the retained preparation named the same request +the retained turn later reported against. + + + + + + + + + + + +Usage is recorded as the provider reported it. Which fields arrived is a fact +about Codex, not about this document, so both lists are shown and only their +sum is fixed: every field is either reported or explicitly unreported, and none +is quietly inferred to be zero. + + + +## The session was openable, and stayed openable + +The first launch left Codex's own composer rather than its refusal. The second +invocation reached the same conversation, under the same identity, without a +second materialization — which the count above already settled. + + + + + + + + +## The identity is the one Codex named + +Codex chose it and told the adapter through its own metadata. XMD never parsed +it out of anything, and never substituted a fresh one when the first was +inconvenient. + + + + +## The production target ran, and its siblings did not + + + + + + +## Route and journal agree + +The route names the construction and the Codex build the tuple above froze, and +nothing else: an ACP-first route deliberately records no conversation identity, +launcher or instruction layer, so those are read from the journal instead. A +route that had converted to anything but `acp-first` would mean the launch +stopped being the one this document describes. + + + + + + + + + + + + + + +The phases are the whole story. The first invocation materializes; the second, +finding a conversation that is already openable, does not. + + + + + + +## Nothing was left behind + + + + + + + + + + + +## Without the authorization, or the build, nothing started + +The refusal happens before any Codex conversation exists, so an unauthorized run +spends no turn and observes nothing. This is the branch that runs on an ordinary +machine, and the branch that runs on a machine outside the frozen tuple. + + + + + + + + + + + + + + diff --git a/packages/acp/src/native-launch.ts b/packages/acp/src/native-launch.ts index d77b7a58..29756090 100644 --- a/packages/acp/src/native-launch.ts +++ b/packages/acp/src/native-launch.ts @@ -22,12 +22,15 @@ * client-allocated one allocates an identity or writes a private file. That is * the failure the contract asks for rather than a hopeful spawn. * - * Adapters differ in one structural way, and it is discriminated rather than - * inferred: who chooses the provider-native session identity. A - * `provider-returned` adapter can only resume a session something else created - * and named. A `client-allocated` adapter names the session first and hands - * that name to the native process, which is what lets a launch construct a - * conversation instead of merely reattaching to one. + * Adapters differ along two structural axes, and both are discriminated rather + * than inferred. The first is who chooses the provider-native session identity: + * a `provider-returned` adapter can only resume a session something else + * created and named, while a `client-allocated` adapter names the session first + * and hands that name to the native process, which is what lets a launch + * construct a conversation instead of merely reattaching to one. The second is + * whether the adapter pins the build behind its executable, and it is + * independent of the first: a name means one conversation only beside the build + * that issued or accepted it, whichever side chose the name. */ import { randomUUID } from "node:crypto"; @@ -36,9 +39,10 @@ import type { IdentityProvenance } from "@executablemd/core"; /** * What an adapter knows about the build behind its executable. * - * A session whose identity XMD chose only means something while the build that - * accepted it can be recognized later: two builds of one provider accept the - * same identity and disagree silently about what it names. Everything here is + * A provider-native identity only means something while the build behind it can + * be recognized later: two builds of one provider accept the same identity and + * disagree silently about what it names, whether XMD chose that identity or the + * provider issued it. Everything here is * that adapter's private dialect — which command to observe, what its version * output looks like, and what the ACP adapter child needs in order to run the * same build. None of it reaches a document. @@ -104,6 +108,41 @@ function claudeVersion(output: string): string | undefined { return canonical.length === 1 ? canonical[0] : undefined; } +/** + * Codex reports `codex-cli 0.153.2`. + * + * The product word is retained with the number for the same reason Claude's + * whole line is: a bare semver from another tool compares equal. The one-line + * rule is the same as well, and so is the silence about what did not match. + */ +function codexVersion(output: string): string | undefined { + const canonical = output + .split("\n") + .map((line) => line.trim()) + .filter((line) => /^codex-cli \d+\.\d+\.\d+$/.test(line)); + return canonical.length === 1 ? canonical[0] : undefined; +} + +/** + * The one XMD-owned model turn a freshly created conversation needs before the + * native UI can open it. + * + * Declared by the adapter that needs it and by no other, because needing one is + * a fact about a provider's persistence rather than about launching. An adapter + * without this member owes no turn, and a launch on it may not take one. + * + * The prompt is a constant of this build. It interpolates nothing, carries no + * authored content, no path, no identity and no environment, and it is the same + * bytes every time so a reader of a journal can recognize an XMD-owned turn in + * their own conversation. + */ +export interface MaterializationContract { + /** Which exact prompt this is — versioned, because the bytes are the contract. */ + readonly promptVersion: string; + /** The prompt itself, sent as one text block. */ + readonly prompt: string; +} + interface AdapterCommands { /** Stable adapter identity — `claude`, `codex`. Never an executable path. */ launcher: string; @@ -111,6 +150,8 @@ interface AdapterCommands { identity: IdentityProvenance; /** The argv that resumes this exact provider-native session. */ resume(nativeSessionId: string): string[]; + /** The turn a session this adapter newly creates owes, when it owes one. */ + materialization?: MaterializationContract; } /** @@ -146,13 +187,48 @@ export interface ProviderReturnedAdapter extends AdapterCommands { identity: "provider-returned"; } -export type NativeAdapter = ProviderReturnedAdapter | ClientAllocatedAdapter; +/** + * A provider-returned adapter whose sessions are pinned to one observed build. + * + * The provider still names the session, so nothing here chooses an identity. + * What the binding adds is the other half of what makes that name mean + * something: an identity a provider issued is only resumable by the build that + * issued it, and two builds of one provider accept the same string while + * disagreeing about which conversation it is. + * + * It is a separate type rather than an optional member on the one above, + * because an adapter a host supplies for a provider that does not pin builds + * must not be able to reach a binding at all. Narrowing is the only way in. + */ +export interface BoundProviderReturnedAdapter extends ProviderReturnedAdapter { + binding: NativeBinding; +} + +export type NativeAdapter = + | ProviderReturnedAdapter + | BoundProviderReturnedAdapter + | ClientAllocatedAdapter; + +/** An adapter whose sessions are bound to the build that accepted them. */ +export type BuildBoundAdapter = BoundProviderReturnedAdapter | ClientAllocatedAdapter; /** Whether this adapter names its own sessions. */ export function allocatesIdentity(adapter: NativeAdapter): adapter is ClientAllocatedAdapter { return adapter.identity === "client-allocated"; } +/** + * Whether this adapter's sessions are bound to one observed executable build. + * + * Independent of who names the session: `claude` allocates its identities and + * `codex` is handed them, and both are meaningless beside a build this run + * cannot recognize. An adapter without a binding keeps the released + * native-only behavior — it observes nothing and gains nothing. + */ +export function bindsBuild(adapter: NativeAdapter): adapter is BuildBoundAdapter { + return "binding" in adapter; +} + const ADAPTERS: Readonly> = { claude: { launcher: "claude", @@ -183,7 +259,33 @@ const ADAPTERS: Readonly> = { }, codex: { launcher: "codex", + // Codex creates the conversation through ACP and reports what it is called. + // XMD supplies nothing here and accepts only that assertion. identity: "provider-returned", + binding: { + command: "codex", + version: codexVersion, + // No `adapterCommand`: the host registry already resolves `codex` to the + // vendored patched adapter this build carries, and a command pinned here + // would replace that exact snapshot with whatever a fetch produced. + // + // The first thing the Codex ACP adapter consults when deciding which + // Codex to run, so the build that creates the session through ACP is the + // build the native UI then resumes it with. + environment: (livePath) => ({ CODEX_PATH: livePath }), + }, + // The App Server writes a thread's rollout at its first turn, and `codex + // resume ` reads rollouts — so a thread ACP created and nothing has + // spoken in is refused by name. One turn closes exactly that gap and + // nothing else, which is why the prompt asks for an acknowledgement and + // forbids the work the session was prepared for. + materialization: { + promptVersion: "codex-materialization.v1", + prompt: + "This turn only makes the Codex conversation resumable. Do not perform the prepared " + + "task, inspect or modify files, call tools, or take any external action. Reply with a " + + "brief acknowledgement only.", + }, resume: (nativeSessionId) => ["codex", "resume", nativeSessionId], }, }; @@ -201,12 +303,26 @@ const ADAPTERS: Readonly> = { * independent invocation resumed the same identity — including a session left * without a word said in it. * - * `codex` is absent. Its command shape is known and its adapter contract tests - * pass, and neither is the proof: nothing has run it against an installed - * Codex. A host may still advertise an adapter itself by passing its name - * through `AcpxProviderDependencies.advertiseNativeLaunch`. + * `codex` is here because `packages/acp/src/CodexNativeLaunch.test.md` and + * `packages/acp/src/CodexZeroNativeTurnExit.test.md` ran the production command + * through the built binary against `codex-cli 0.153.2` on macOS arm64 and showed + * the same contract, reached differently: Codex allocates the identity and + * reports it on the response `_meta`, the layer governs the first native user + * turn, and a second independent invocation reaches that same conversation. + * + * Codex costs one model turn to get there. The App Server writes a thread's + * rollout at its first turn and `codex resume ` reads rollouts, so a thread + * ACP created and nothing has spoken in is refused by name: `session/resume` + * answers "no rollout found for thread id ", and the native UI answers "No + * saved session found with ID ". `codex-materialization.v1` is the one + * XMD-owned turn that closes exactly that gap, and it runs only for a freshly + * created conversation. It is not a bootstrap turn: it carries no authored + * content, and providers that need no materialization keep spending none. + * + * A host may still advertise an adapter itself by passing its name through + * `AcpxProviderDependencies.advertiseNativeLaunch`. */ -export const ADVERTISED_NATIVE_LAUNCH: readonly string[] = ["claude"]; +export const ADVERTISED_NATIVE_LAUNCH: readonly string[] = ["claude", "codex"]; /** * The adapters whose client-native ACP attachment has been proven against the diff --git a/packages/acp/src/provider.ts b/packages/acp/src/provider.ts index e6e39d70..0d8c90cb 100644 --- a/packages/acp/src/provider.ts +++ b/packages/acp/src/provider.ts @@ -23,11 +23,13 @@ import { createChannel, createScope, + each, ensure, Err, Ok, scoped, spawn, + stream, suspend, until, useScope, @@ -51,16 +53,30 @@ import type { InstructionReconciliation, ExitedLaunchRecord, LaunchFailure, + LaunchFailureClass, LaunchOptions, + MaterializationPlan, + MaterializationUsage, + MaterializedLaunchRecord, PreparedLaunchRecord, PromptOptions, Session, SessionLaunchResult, } from "@executablemd/core"; -import { allocatesIdentity } from "./native-launch.ts"; -import type { ClientAllocatedAdapter, NativeBinding } from "./native-launch.ts"; +import { allocatesIdentity, bindsBuild } from "./native-launch.ts"; +import type { + BoundProviderReturnedAdapter, + BuildBoundAdapter, + ClientAllocatedAdapter, + NativeAdapter, + NativeBinding, +} from "./native-launch.ts"; import { AgentSessionRouteError } from "./session-route.ts"; -import type { AgentSessionRoute, AgentSessionRouteStore } from "./session-route.ts"; +import type { + AgentSessionRoute, + AgentSessionRouteStore, + AgentSessionRouteV3, +} from "./session-route.ts"; import { createAcpRuntime, createAgentRegistry, createRuntimeStore } from "./acpx-runtime.ts"; import type { AcpAgentRegistry, @@ -71,6 +87,9 @@ import type { AcpRuntimeMaterialization, AcpRuntimeOptions, AcpRuntimeTurn, + AcpRuntimeTurnResult, + AcpRuntimeUsageBreakdown, + AcpRuntimeUsageCost, AcpSessionRecord, AcpSessionStore, SessionAgentOptions, @@ -81,6 +100,7 @@ import { strictPermissions, } from "./permission-bridge.ts"; import { consumeTurn } from "./events.ts"; +import { checkpointFromResult } from "./checkpoint.ts"; import { resolveSessionPlacement } from "./session-key.ts"; import { useSerialQueues } from "./serial-queue.ts"; import { @@ -89,6 +109,7 @@ import { cwd, ExecutableObservationError, nativeLaunch, + notifyTerminal, } from "@executablemd/runtime"; import type { AgentSessionCoordinator, @@ -103,7 +124,6 @@ import { knownNativeAdapters, nativeAdapterFor, } from "./native-launch.ts"; -import type { NativeAdapter } from "./native-launch.ts"; /** * One MCP server as ACPX configures them. @@ -500,7 +520,7 @@ interface LaunchInvocation { * path is only true for the run that observed it. A later replay reobserves * rather than finding one lying about. */ - readonly bound: Map; + readonly bound: Map; /** Sessions whose detach phase ran live in this invocation. */ readonly detachedLive: Set; /** @@ -1171,14 +1191,16 @@ function* useAcpxProviderState( if (prepareAgent !== undefined) { yield* prepareAgent(selected); } - // Resolution is read-only for an agent whose sessions XMD names. Probing - // spawns an ACP child, and that is provider work on a session whose + // Resolution is read-only for an agent whose sessions are bound to a build. + // Probing spawns an ACP child, and that is provider work on a session whose // construction has not been settled yet — it would run before the route is - // published, before a client-native route can refuse this surface, and - // before a host missing either capability has said so. Nothing on that path - // needs the answer: the session is created by a native process, and where - // ACP does serve one, the establishment itself reports being unable to. - if (!validatedAgents.has(selected) && !namesOwnSessions(selected)) { + // published, before a route this surface cannot serve can refuse it, and + // before a host missing either capability has said so. It would also spawn a + // child of a build nothing has observed, which is the one thing a bound + // session may not talk to. Nothing on that path needs the answer: a + // client-native session is created by a native process, and where ACP does + // serve one, the establishment itself reports being unable to. + if (!validatedAgents.has(selected) && !boundSessions(selected)) { const base = yield* runtimeOptions(); const probe = createRuntime({ ...base, probeAgent: selected }); const report = yield* until(probe.doctor()); @@ -1359,7 +1381,16 @@ function* useAcpxProviderState( /** What one ensure is for, beyond the placement it is for. */ interface EnsureIntent { - attachment?: { build: BoundBuild; resumeSessionId: string }; + /** + * The observed build this ensure's ACP child must be. + * + * Separate from `attachment`, because the two answer different questions + * and not every session that has one has the other: a session the provider + * named is bound to a build without any identity for ACP to be told to + * reopen. + */ + build?: BoundBuild; + attachment?: { resumeSessionId: string }; /** The placement's state, as the caller resolved it. */ state: "pending" | "established"; /** @@ -1395,7 +1426,7 @@ function* useAcpxProviderState( let managedEntry: ManagedSession; try { managedEntry = yield* ensureThrough( - attachment?.build, + intent.build, { sessionKey: prepared.placement.sessionKey, agent: agentName, @@ -1559,14 +1590,29 @@ function* useAcpxProviderState( return ownable(agentName) && adapter !== undefined && allocatesIdentity(adapter); } + /** + * Whether this agent's sessions carry a construction route and one build. + * + * The two facts arrive together and for the same reason. A route says how the + * session was first constructed, and for an adapter that pins a build the + * build is part of that account: whichever side chose the identity, the name + * resolves to one conversation only beside the build that issued or accepted + * it. An agent whose adapter binds nothing keeps its merged behavior, on a + * host that installs neither. + */ + function boundSessions(agentName: string): boolean { + const adapter = adapterFor(agentName); + return ownable(agentName) && adapter !== undefined && bindsBuild(adapter); + } + /** * Refuse an advertised agent this host is not assembled to serve. * * Fail-closed, and closed means what the agent actually needs: every - * advertised session needs a coordinator to say who owns it, and one whose - * sessions XMD names also needs a route store to say how it was constructed. - * A host that can answer one question but not the other cannot act on a - * session a native UI may be in. + * advertised session needs a coordinator to say who owns it, and one bound to + * a build also needs a route store to say how it was constructed and an + * observer to say which build that was. A host that can answer one question + * but not the other cannot act on a session a native UI may be in. */ function requireAssembly(agentName: string, sessionKey: string): void { if (!ownable(agentName)) { @@ -1576,7 +1622,7 @@ function* useAcpxProviderState( if (!coordinator) { missing.push("exclusive ownership"); } - if (namesOwnSessions(agentName)) { + if (boundSessions(agentName)) { if (!routeStore) { missing.push("construction routes"); } @@ -1650,6 +1696,22 @@ function* useAcpxProviderState( }; } + /** The same route, for a session whose build was observed as it was bound. */ + function boundAcpFirstRoute( + agentCommand: string, + sessionKey: string, + executableBinding: AgentSessionRouteV3["executableBinding"], + ): AgentSessionRouteV3 { + return { + schema: "session-route.v3", + route: "acp-first", + provider: ACPX_PROVIDER, + agent: agentCommand, + sessionKey, + executableBinding, + }; + } + /** * Publish or adopt `acp-first` for an agent whose sessions XMD would * otherwise name, and refuse if this session already has an identity. @@ -1762,24 +1824,121 @@ function* useAcpxProviderState( }); } + /** + * Observe the build behind a session the provider names, and settle its route. + * + * The order is the contract. The build is observed before the route is read, + * because for this construction the build is part of what the route says: an + * identity the provider issues resolves to one conversation only beside the + * build that issued it, so a route published without one would describe a + * session no later run could confirm. What comes back is the build every + * provider effect for this session then goes through. + * + * A session that already has provider state but no route was constructed + * before this contract. Its route is published as the unbound one it is — + * this run's observation says which build is installed today, not which one + * issued that identity — and it refuses here rather than being bound after + * the fact. + */ + function* bindProviderNamed( + agentName: string, + agentCommand: string, + adapter: BoundProviderReturnedAdapter, + sessionKey: string, + hasProviderState: boolean, + ): Operation { + const build = yield* observeBuild(agentName, agentCommand, adapter.binding); + let route: AgentSessionRoute; + try { + route = yield* reconcileRoute( + agentCommand, + sessionKey, + // deno-lint-ignore require-yield + function* () { + return boundAcpFirstRoute(agentCommand, sessionKey, build.binding); + }, + hasProviderState, + ); + } catch (error) { + throw new AttachmentRefused({ class: "identity-unavailable", message: routeMessage(error) }); + } + if (route.route !== "acp-first") { + throw new AttachmentRefused({ + class: "identity-unavailable", + message: + `session "${sessionKey}" was constructed under an identity XMD chose, and ` + + `"${agentName}" names its own sessions, so neither account describes the other`, + }); + } + if (route.schema !== "session-route.v3") { + // Constructed before any build was recorded. A build observed now says + // which build is installed today, not which one issued this identity, so + // there is nothing to compare and nothing to continue. + throw new AttachmentRefused({ + class: "executable-binding-refused", + message: + `session "${sessionKey}" was constructed before XMD recorded which build issued its ` + + `identity, so this run cannot show it is talking to that build. Name a different ` + + `.`, + }); + } + if (!sameExecutableBuild(build.binding, route.executableBinding)) { + throw new AttachmentRefused(buildDrift(sessionKey, route.executableBinding, build.binding)); + } + return build; + } + + /** What a settled construction route lets one ACP operation do. */ + interface SessionConstruction { + /** The observed build every provider effect for this session goes through. */ + build: BoundBuild; + /** + * The exact conversation ACP must open rather than create. + * + * Present only for a session a native process constructed under an identity + * XMD chose. A session the provider named has its own history to reopen, and + * a name supplied here would be XMD choosing one after the fact. + */ + resumeSessionId?: string; + } + /** * Reconcile this session's construction route, and say what an ACP operation * may do with it. * * `` and `` are eager, so a session nobody constructed is - * constructed here as `acp-first` before ensure. A session a native process - * constructed is attached to — never converted, never republished — and only - * when this host has proven that capability for this adapter and can still - * show it is talking to the build that created it. + * constructed here — as `acp-first`, bound to the observed build when the + * adapter pins one — before ensure. A session a native process constructed is + * attached to — never converted, never republished — and only when this host + * has proven that capability for this adapter and can still show it is talking + * to the build that created it. */ function* constructRoute( agentName: string, prepared: Prepared, - ): Operation<{ build: BoundBuild; resumeSessionId: string } | undefined> { - if (!namesOwnSessions(agentName)) { + ): Operation { + const adapter = adapterFor(agentName); + if (!ownable(agentName) || adapter === undefined) { return undefined; } const agentCommand = agentCommandOf(prepared); + // An existing managed entry, or a durable record ACPX already kept, is + // provider state — and existing history is never reclassified. + const constructed = + prepared.kind === "existing" || (yield* until(store.load(prepared.sessionKey))) !== undefined; + if (!allocatesIdentity(adapter)) { + if (!bindsBuild(adapter)) { + return undefined; + } + const build = yield* bindProviderNamed( + agentName, + agentCommand, + adapter, + prepared.sessionKey, + constructed, + ); + return { build }; + } const route = yield* reconcileRoute( agentCommand, prepared.sessionKey, @@ -1787,9 +1946,7 @@ function* useAcpxProviderState( function* () { return acpFirstRoute(agentCommand, prepared.sessionKey); }, - // An existing managed entry, or a durable record ACPX already kept, is - // provider state — and existing history is never reclassified. - prepared.kind === "existing" || (yield* until(store.load(prepared.sessionKey))) !== undefined, + constructed, ); if (route.route !== "client-native") { return undefined; @@ -1815,8 +1972,7 @@ function* useAcpxProviderState( `.`, }); } - const binding = (adapterFor(agentName) as ClientAllocatedAdapter).binding; - const build = yield* observeBuild(agentName, agentCommand, binding); + const build = yield* observeBuild(agentName, agentCommand, adapter.binding); if (!sameExecutableBuild(build.binding, route.executableBinding)) { throw new AttachmentRefused( buildDrift(prepared.sessionKey, route.executableBinding, build.binding), @@ -2081,14 +2237,18 @@ function* useAcpxProviderState( // first Prompt constructs this session through ACP, so that is what // its construction route says — and a session a native process // constructed is attached to under the identity it already has. - const attachment = yield* constructRoute(agentName, prepared); + const construction = yield* constructRoute(agentName, prepared); + const resumeSessionId = construction?.resumeSessionId; // The pending ACP-first branch, and the only one that defers: an // attachment resumes an identity that already exists, and an - // established placement has one of its own. + // established placement has one of its own. A build alone does not + // defer anything — a session the provider names is still constructed + // by this ensure, bound to the build that names it. const constructing = - state === "pending" && attachment === undefined && prepared.kind === "placement"; + state === "pending" && resumeSessionId === undefined && prepared.kind === "placement"; const entry = yield* ensureFromPrepared(agentName, prepared, { - ...(attachment === undefined ? {} : { attachment }), + ...(construction === undefined ? {} : { build: construction.build }), + ...(resumeSessionId === undefined ? {} : { attachment: { resumeSessionId } }), state, materialization: constructing, deferEstablished: constructing, @@ -2508,9 +2668,18 @@ function* useAcpxProviderState( // return — a store read that fails, an instruction layer this provider will // not replace — and a claim taken before them is one those exits would have // to remember to give back. - const existing = yield* until(store.load(sessionKey)); - let sessionState: "created" | "resumed" = existing ? "resumed" : "created"; - let reconciliation: InstructionReconciliation = existing ? "resumed" : "installed"; + const stored = yield* until(store.load(sessionKey)); + // A pending record is occupancy an earlier attempt left behind: ACPX will + // not reuse it, no backend ever accepted a turn in it, and treating it as a + // conversation would skip the very turn that would make one openable. So + // this launch is creating, whatever is on disk under the same key. + const existing = + stored !== undefined && stored.sessionMaterialization?.state !== "pending" + ? stored + : undefined; + const sessionState: "created" | "resumed" = existing ? "resumed" : "created"; + const reconciliation: InstructionReconciliation = existing ? "resumed" : "installed"; + const known = { agent: agentName, sessionKey, cwd: sessionCwd, launcher: adapter.launcher }; if (existing && storedSystemPrompt(existing) !== instructions) { // ACPX fixes a session's instruction layer when its ACP session is @@ -2528,44 +2697,96 @@ function* useAcpxProviderState( `session "${sessionKey}" already carries a different XMD instruction layer, and ` + `this provider does not replace one. Launch a differently named , or ` + `launch the same prepared instructions again.`, - { agent: agentName, sessionKey, cwd: sessionCwd, launcher: adapter.launcher }, + known, ); } + // Which build this session belongs to, settled before ACP is asked for + // anything. The provider names the session, and the name it issues resolves + // to one conversation only beside the build that issued it — so the build is + // observed, the route recording it is published or adopted, and the two are + // compared, all under ownership and before the first provider effect. + let build: BoundBuild | undefined; + if (bindsBuild(adapter)) { + try { + build = yield* bindProviderNamed( + agentName, + agentCommand, + adapter, + sessionKey, + existing !== undefined, + ); + } catch (error) { + if (error instanceof AttachmentRefused) { + return refusal(error.failure.class, error.failure.message, known); + } + throw error; + } + invocation.bound.set(sessionKey, { build, adapter }); + // The check a replay performs at its own first live phase, performed here + // against a live observation. Recording it is what keeps the detach or the + // spawn below from reading the same two accounts a second time. + invocation.reconciled.add(sessionKey); + } + + // Planned before the ensure it decides the shape of, and only for the + // conversation this launch creates through an adapter that says one is + // owed. A resumed session has already been spoken in — whatever made it + // openable happened before this run — so taking a turn in it would be + // spending someone's model turn to learn nothing. The request id is minted + // here rather than at the turn so a replay reading the retained record is + // looking for the turn the first attempt committed to. + const plan: MaterializationPlan | undefined = + sessionState === "created" && adapter.materialization + ? { + promptVersion: adapter.materialization.promptVersion, + requestId: randomUUID(), + prompt: adapter.materialization.prompt, + } + : undefined; + + const ensureInput: AcpRuntimeEnsureInput = { + sessionKey, + agent: agentName, + mode: "persistent", + cwd: sessionCwd, + sessionOptions: { systemPrompt: instructions }, + }; + if (plan !== undefined) { + // A conversation this adapter cannot open until something has been said + // in it is not one the record may assert. ACPX holds it as occupancy + // instead, and only the adapter's own acceptance of the turn below + // promotes it — which is what makes that acceptance decide whether this + // launch reaches a native UI at all. + ensureInput.materialization = "first-turn-acceptance"; + } + // Claimed here, one line before the ensure it is for, and settled by the // same scope-owned cleanup an attachment uses. The handle enters the ledger // the moment it exists, bound to the runtime that made it: everything below // can refuse, and a handle only the managed map knew about is one teardown // could not close through its creator. - const managedEntry = yield* ensureThrough( - undefined, - { - sessionKey, - agent: agentName, - mode: "persistent", + const managedEntry = yield* ensureThrough(build, ensureInput, (handle, entry) => { + const session: Session = { sessionKey, cwd: sessionCwd }; + if (handle.agentSessionId !== undefined) { + session.agentSessionId = handle.agentSessionId; + } + // Established by construction when nothing is owed: this adapter's + // provider returns the identity, so the session exists the moment the + // ensure answers. A launch that owes a turn holds a placement instead, + // and the accepted turn is what establishes it. + return { + handle, + runtime: entry, + agentCommand, cwd: sessionCwd, - sessionOptions: { systemPrompt: instructions }, - }, - (handle, entry) => { - const session: Session = { sessionKey, cwd: sessionCwd }; - if (handle.agentSessionId !== undefined) { - session.agentSessionId = handle.agentSessionId; - } - // Established by construction: this adapter's provider returns the - // identity, so the session exists the moment the ensure answers. - return { - handle, - runtime: entry, - agentCommand, - cwd: sessionCwd, - session, - state: "established" as const, - }; - }, - ); + session, + state: plan === undefined ? "established" : "pending", + }; + }); managed.set(sessionKey, managedEntry); - const nativeSessionId = managedEntry.handle.agentSessionId; + const nativeSessionId = plan === undefined ? managedEntry.handle.agentSessionId : ""; if (nativeSessionId === undefined) { // An ACP session id and an ACPX record id are not native identities, and // neither is a string that merely looks like one. @@ -2578,7 +2799,7 @@ function* useAcpxProviderState( "identity-unavailable", `agent "${agentName}" created a session but asserted no provider-native ` + `session identity, so there is nothing ${adapter.launcher} can resume`, - { agent: agentName, sessionKey, cwd: sessionCwd, launcher: adapter.launcher }, + known, ); } @@ -2600,6 +2821,14 @@ function* useAcpxProviderState( permissionMode: providerOptions.permissionMode, launcher: adapter.launcher, }; + if (build) { + // Exactly the binding the route carries, so the journal and the route + // agree by construction rather than by comparison. + record.executableBinding = build.binding; + } + if (plan !== undefined) { + record.materialization = plan; + } let model: string | undefined; try { model = yield* effectiveModel(managedEntry.runtime.runtime, managedEntry.handle); @@ -2626,6 +2855,310 @@ function* useAcpxProviderState( return status.models?.currentModelId; } + /** + * What the provider said this turn cost, and nothing else. + * + * A member the provider did not report is left absent rather than copied as + * `undefined`, because these are merged over what earlier events reported: an + * explicit `undefined` would overwrite a figure the provider did give with the + * claim that it gave none. Zero is a figure; saying nothing is not. + */ + function reportedUsage( + breakdown: AcpRuntimeUsageBreakdown | undefined, + cost: AcpRuntimeUsageCost | undefined, + ): MaterializationUsage { + const usage: { + -readonly [K in keyof MaterializationUsage]: MaterializationUsage[K]; + } = {}; + if (breakdown?.inputTokens !== undefined) { + usage.inputTokens = breakdown.inputTokens; + } + if (breakdown?.outputTokens !== undefined) { + usage.outputTokens = breakdown.outputTokens; + } + if (breakdown?.cachedReadTokens !== undefined) { + usage.cachedReadTokens = breakdown.cachedReadTokens; + } + if (breakdown?.cachedWriteTokens !== undefined) { + usage.cachedWriteTokens = breakdown.cachedWriteTokens; + } + if (breakdown?.thoughtTokens !== undefined) { + usage.thoughtTokens = breakdown.thoughtTokens; + } + if (breakdown?.totalTokens !== undefined) { + usage.totalTokens = breakdown.totalTokens; + } + if (cost?.amount !== undefined) { + usage.costAmount = cost.amount; + } + if (cost?.currency !== undefined) { + usage.costCurrency = cost.currency; + } + return usage; + } + + /** One line per member, saying `provider did not report` where it did not. */ + function usageLines(usage: MaterializationUsage): string { + const figure = (value: number | undefined): string => + value === undefined ? "provider did not report" : String(value); + const cost = + usage.costAmount === undefined + ? "provider did not report" + : `${usage.costAmount}${usage.costCurrency === undefined ? "" : ` ${usage.costCurrency}`}`; + return [ + ` input tokens: ${figure(usage.inputTokens)}`, + ` output tokens: ${figure(usage.outputTokens)}`, + ` cached read tokens: ${figure(usage.cachedReadTokens)}`, + ` cached write tokens: ${figure(usage.cachedWriteTokens)}`, + ` thought tokens: ${figure(usage.thoughtTokens)}`, + ` total tokens: ${figure(usage.totalTokens)}`, + ` cost: ${cost}`, + ].join("\n"); + } + + /** + * Spend the one turn this launch planned, and report what it cost. + * + * Reached only for a preparation that planned one, which is only ever a + * conversation this launch created through an adapter that says a fresh one is + * not yet openable. Everything about it is fixed before it runs: the exact + * prompt and the request id come from the retained plan, so a replay is + * looking for this turn rather than authorizing another. + * + * It is not a Prompt. It publishes no event stream, reaches no authored + * middleware, and is deliberately not registered with the permission bridge — + * an unregistered turn's permission request is refused by the bridge's own + * fail-closed answer, so there is no composed handler that could grant this + * turn the tool authority its prompt already forbids. A tool call that arrives + * anyway fails materialization, and the session is never handed over. + * + * It is also what settles the session's identity. The preparation held + * occupancy and asserted nothing, so the conversation this launch hands over + * is named here — by the backend's own acceptance of this turn, and by + * nothing else. + */ + function materializeSession( + placed: Prepared, + prepared: PreparedLaunchRecord, + plan: MaterializationPlan, + ): Operation { + return scoped(function* (): Operation { + const base: Pick = { + phase: "materialized", + promptVersion: plan.promptVersion, + requestId: plan.requestId, + }; + const refused = (message: string): MaterializedLaunchRecord => ({ + ...base, + usage: {}, + response: "", + failure: { class: "materialization-failed", message }, + }); + + const entry = managed.get(prepared.sessionKey); + if (!entry || !isLive(entry)) { + return refused( + `session "${prepared.sessionKey}" is no longer held by this provider, so the turn ` + + `that would make it resumable cannot be taken here`, + ); + } + // Occupancy, and only occupancy. The preparation asserted no identity + // because no backend had accepted a turn here, so a handle that already + // names a conversation is not the placement this launch prepared — and + // spending a turn in it would be spending one in someone else's. + if (entry.handle.agentSessionId !== undefined) { + return refused( + `session "${prepared.sessionKey}" is held under a provider-native identity this ` + + `launch never prepared`, + ); + } + + // Before the turn, never after: what is about to be spent is the reader's + // model turn, and telling them once it is gone is telling them too late. + yield* notifyTerminal( + `${prepared.agent}: spending one model turn in session "${prepared.sessionKey}" so ` + + `${prepared.launcher} can open it (${plan.promptVersion}).`, + ); + + // Registered before the turn exists, and reaching it through a slot the + // start fills. Registering afterwards puts a suspension point between a + // live turn and the only thing that would stop it, and a cancellation + // landing there — a reader closing the grid this launch is running in is + // one — leaves a model turn running in their conversation that nothing + // is waiting for and nothing cancels until this whole provider comes + // down. There is no such gap this way round: `startTurn` answers without + // suspending, so the slot is filled in the step that creates the turn. + let turn: AcpRuntimeTurn | undefined; + let settled = false; + yield* ensure(function* () { + if (!turn || settled) { + return; + } + activeTurns.delete(turn); + try { + yield* until(turn.cancel()); + } catch (error) { + cleanupErrors.push(toError(error)); + } + }); + turn = entry.runtime.runtime.startTurn({ + handle: entry.handle, + text: plan.prompt, + mode: "prompt", + requestId: plan.requestId, + }); + activeTurns.add(turn); + + const started = Date.now(); + let response = ""; + let usage: MaterializationUsage = {}; + let acted = false; + let outcome: Result; + try { + for (const event of yield* each(stream(turn.events))) { + if (event.type === "text_delta" && (event.stream ?? "output") === "output") { + response += event.text; + } else if (event.type === "tool_call") { + // The prompt forbids this, so an arriving tool call means the turn + // did something other than acknowledge. Recorded rather than acted + // on: the turn is already running, and what this decides is that no + // native UI opens on what it left behind. + acted = true; + } else if (event.type === "status") { + usage = { ...usage, ...reportedUsage(event.breakdown, event.cost) }; + } + yield* each.next(); + } + outcome = Ok(yield* until(turn.result)); + } catch (error) { + outcome = Err(toError(error)); + } + settled = true; + const durationMs = Date.now() - started; + + const stopped = ( + message: string, + stopReason?: string, + failureClass: LaunchFailureClass = "materialization-failed", + ): MaterializedLaunchRecord => { + const record: MaterializedLaunchRecord = { + ...base, + durationMs, + usage, + response, + failure: { class: failureClass, message }, + }; + if (stopReason !== undefined) { + record.stopReason = stopReason; + } + return record; + }; + + if (!outcome.ok) { + return stopped(outcome.error.message); + } + const result = outcome.value; + if (result.status === "cancelled") { + return stopped("the materialization turn was cancelled", result.stopReason); + } + if (result.status === "failed") { + return stopped(result.error.message); + } + // ACP defines end_turn as the only successful stop reason, and an adapter + // that omits it on a normal completion means that one. + const stopReason = result.stopReason ?? "end_turn"; + if (stopReason !== "end_turn") { + return stopped( + `the materialization turn ended with stop reason "${stopReason}"`, + stopReason, + ); + } + if (acted) { + return stopped( + "the materialization turn called a tool, which its prompt forbids, so this launch " + + "will not hand the session to a native UI", + stopReason, + ); + } + // The backend's own acceptance, asked for after the turn completed. A + // turn that failed, was cancelled, or simply ended without the adapter + // saying so rejects here, and a turn nothing accepted materialized + // nothing — so there is no identity, and nothing to hand over. + const accepted: Result = yield* until( + turn.materialized.then( + (value): Result => Ok(value), + (error: unknown): Result => Err(toError(error)), + ), + ); + if (!accepted.ok) { + return stopped(accepted.error.message, stopReason); + } + const nativeSessionId = accepted.value.agentSessionId; + if (nativeSessionId === undefined || nativeSessionId.length === 0) { + // The turn itself reached the backend and was accepted; what is absent + // is the conversation's name, which is the same thing an adapter that + // asserts no identity leaves absent before any turn. Classed as that + // rather than as a failed turn, because the turn did not fail. + return stopped( + "the backend accepted the materialization turn without naming the session it made " + + "openable, so there is nothing a native UI could resume", + stopReason, + "identity-unavailable", + ); + } + // The provider's own name for the turn, read from the response metadata + // this package recognizes and from nothing else. Without it there is no + // evidence the exchange reached the backend rather than a socket. + const named = checkpointFromResult(result); + if (named === undefined) { + return stopped( + "the materialization turn completed without naming the provider turn it was", + stopReason, + ); + } + if (response.length === 0) { + return stopped( + "the materialization turn produced no assistant response, so nothing was said in " + + "the conversation this launch was making openable", + stopReason, + ); + } + + // The durable order the prompt path uses, for the same reason: ACPX's own + // record asserted the identity as it promoted this session, the host's + // mapping commits second, and the placement becomes established last. A + // host that refuses to retain it leaves a session nobody may prompt + // through, so the handle is given up rather than held under a mapping + // that does not exist. + const identity: AcpxSessionIdentity = { + acpxRecordId: accepted.value.acpxRecordId, + agentSessionId: nativeSessionId, + }; + if (sessions?.established && placed.kind === "placement") { + try { + yield* sessions.established(placed.placement, identity); + } catch (error) { + yield* abandonHandle(entry, "session retention refused"); + if (!holding(prepared.sessionKey)) { + detachPlacement(prepared.sessionKey, entry); + } + return stopped(toError(error).message, stopReason); + } + } + entry.session.agentSessionId = nativeSessionId; + entry.state = "established"; + + yield* notifyTerminal( + `${prepared.agent}: materialization turn completed in ${durationMs}ms ` + + `(${named.provider} ${named.kind} ${named.value}).\n` + + `${response}\n` + + `${usageLines(usage)}`, + ); + + return { ...base, nativeSessionId, turn: named, durationMs, usage, response, stopReason }; + }); + } + /** * Give up this provider's ACP handle for `sessionKey`, keeping its record. * @@ -2671,12 +3204,14 @@ function* useAcpxProviderState( if (invocation.fresh.has(sessionKey)) { return { phase: "detached" }; } - // Nothing was prepared live, so this is a replay — and for a session XMD - // named, this detach is its first live phase. The two durable accounts are - // checked here rather than at the spawn, because retaining a detach is - // itself advancing the launch: a journal that says the handoff began is not - // something to write about a session this run cannot confirm. - if (prepared.identityProvenance === "client-allocated") { + // For a session bound to a build, this detach may be the first live phase of + // a replay. The durable accounts are checked here rather than at the spawn, + // because retaining a detach is itself advancing the launch: a journal that + // says the handoff began is not something to write about a session this run + // cannot confirm. A launch that prepared live has already checked them, and + // this reads them once per invocation. + const bound = adapterFor(prepared.agent); + if (bound && bindsBuild(bound)) { const refused = yield* reconcile(invocation, prepared, agentCommand); if (refused) { return { phase: "detached", failure: refused }; @@ -2803,6 +3338,7 @@ function* useAcpxProviderState( placement, ), ), + materialize: (prepared, plan) => materializeSession(placement, prepared, plan), detach: (prepared) => detachSession(invocation, prepared, agentCommandOf(placement)), exit: (prepared) => runNativeUi(invocation, prepared, agentCommandOf(placement)), @@ -2837,11 +3373,11 @@ function* useAcpxProviderState( function* nativeCommand( invocation: LaunchInvocation, prepared: PreparedLaunchRecord, - adapter: ClientAllocatedAdapter, + adapter: NativeAdapter, agentCommand: string, ): Operation> { const publishedHere = invocation.fresh.get(prepared.sessionKey); - if (publishedHere === undefined) { + if (publishedHere === undefined && bindsBuild(adapter)) { // A replay. Whichever suffix it holds, the two durable accounts are // checked before this run does anything a native process could act on — // a detached replay reaches here as its first live phase, and a @@ -2851,13 +3387,21 @@ function* useAcpxProviderState( return Err(new RetainedRefusal(refused)); } } - const creating = publishedHere ?? invocation.detachedLive.has(prepared.sessionKey); - const argv = creating - ? adapter.create( - prepared.nativeSessionId, - yield* privateInstructionFile(prepared.instructions), - ) - : adapter.resume(prepared.nativeSessionId); + // Creation is a question only for an identity XMD chose. A session the + // provider named already exists — ACP made it — so there is nothing here to + // create and no instruction layer to install through argv. + let argv: string[]; + if ( + allocatesIdentity(adapter) && + (publishedHere ?? invocation.detachedLive.has(prepared.sessionKey)) + ) { + argv = adapter.create( + prepared.nativeSessionId, + yield* privateInstructionFile(prepared.instructions), + ); + } else { + argv = adapter.resume(prepared.nativeSessionId); + } // The exact file this run observed, in place of the launcher name the // adapter writes. The name is what durable records carry; the path is what // this invocation spawns, and it is live only. A legacy session observed no @@ -2898,6 +3442,21 @@ function* useAcpxProviderState( agentCommand: string, ): Operation { const stop = (message: string): LaunchFailure => ({ class: "identity-unavailable", message }); + const disagree = (): LaunchFailure => + stop( + `session "${prepared.sessionKey}" is described differently by its journal and its ` + + `construction route, and neither account repairs the other`, + ); + // A launch that never got as far as the native process, prepared under a + // contract that recorded no build. Nothing here can show which build has + // this session's history, and resuming anyway would be answering the + // question by ignoring it. A completed launch never reaches this code. + const unrecorded = (): LaunchFailure => ({ + class: "executable-binding-refused", + message: + `session "${prepared.sessionKey}" was prepared before XMD recorded which build its ` + + `identity belongs to, so this run cannot confirm the conversation it names`, + }); // Which provider retained this preparation, before anything is compared // against it. A record another provider wrote describes a session this one // does not own, and an ACPX route that happens to agree about a UUID is not @@ -2908,57 +3467,76 @@ function* useAcpxProviderState( `cannot confirm the conversation it names`, ); } + // The live half's adapter first, because which construction this journal can + // be checked against is the adapter's fact rather than the route's: a route + // agreeing with a record about one string is not evidence that the same side + // named the session both times. + const adapter = adapterFor(prepared.agent); + if (!adapter || !bindsBuild(adapter)) { + return { + class: "executable-binding-refused", + message: + `session "${prepared.sessionKey}" names a launcher this build has no way to observe, ` + + `so the conversation it prepared cannot be confirmed`, + }; + } let route; try { route = yield* routeStore!.read(sessionKeyOf(agentCommand, prepared.sessionKey)); } catch (error) { return stop(routeMessage(error)); } - if (!route || route.route !== "client-native") { - return stop( - `session "${prepared.sessionKey}" has no client-allocated construction route, so the ` + - `conversation this launch prepared cannot be confirmed`, - ); - } - if ( - route.nativeSessionId !== prepared.nativeSessionId || - route.identityProvenance !== prepared.identityProvenance || - route.instructionsDigest !== prepared.instructionsDigest || - route.launcher !== prepared.launcher - ) { - return stop( - `session "${prepared.sessionKey}" is described differently by its journal and its ` + - `construction route, and neither account repairs the other`, - ); + let retainedBinding: ExecutableBuildBindingV1; + if (allocatesIdentity(adapter)) { + if (!route || route.route !== "client-native") { + return stop( + `session "${prepared.sessionKey}" has no client-allocated construction route, so the ` + + `conversation this launch prepared cannot be confirmed`, + ); + } + if ( + route.nativeSessionId !== prepared.nativeSessionId || + route.identityProvenance !== prepared.identityProvenance || + route.instructionsDigest !== prepared.instructionsDigest || + route.launcher !== prepared.launcher + ) { + return disagree(); + } + if (route.schema === "session-route.v1") { + return unrecorded(); + } + retainedBinding = route.executableBinding; + } else { + if (!route || route.route !== "acp-first") { + return stop( + `session "${prepared.sessionKey}" has no provider-named construction route, so the ` + + `conversation this launch prepared cannot be confirmed`, + ); + } + if (route.schema !== "session-route.v3") { + return unrecorded(); + } + retainedBinding = route.executableBinding; + // ACPX's own record, which is what any later ACP operation would reopen + // this session through. A record naming another conversation, or none, + // means the identity the native process is about to be handed is not the + // one this provider would come back to. + try { + yield* retainedAssertion(prepared.sessionKey, prepared.nativeSessionId); + } catch (error) { + if (error instanceof AttachmentRefused) { + return error.failure; + } + throw error; + } } - // A launch that never got as far as the native process, prepared under a - // contract that recorded no build. Nothing here can show which build has - // this session's history, and resuming anyway would be answering the - // question by ignoring it. A completed launch never reaches this code. - if (route.schema === "session-route.v1" || prepared.executableBinding === undefined) { - return { - class: "executable-binding-refused", - message: - `session "${prepared.sessionKey}" was prepared before XMD recorded which build ` + - `accepted its identity, so this run cannot confirm the conversation it names`, - }; + if (prepared.executableBinding === undefined) { + return unrecorded(); } - if (!sameExecutableBuild(route.executableBinding, prepared.executableBinding)) { - return stop( - `session "${prepared.sessionKey}" is described differently by its journal and its ` + - `construction route, and neither account repairs the other`, - ); + if (!sameExecutableBuild(retainedBinding, prepared.executableBinding)) { + return disagree(); } // The live half, before the first effect a native process could act on. - const adapter = adapterFor(prepared.agent); - if (!adapter || !allocatesIdentity(adapter)) { - return { - class: "executable-binding-refused", - message: - `session "${prepared.sessionKey}" names a launcher this build has no way to observe, ` + - `so the conversation it prepared cannot be confirmed`, - }; - } let build: BoundBuild; try { build = yield* observeBuild(prepared.agent, agentCommand, adapter.binding); @@ -2968,8 +3546,8 @@ function* useAcpxProviderState( } throw error; } - if (!sameExecutableBuild(build.binding, route.executableBinding)) { - return buildDrift(prepared.sessionKey, route.executableBinding, build.binding); + if (!sameExecutableBuild(build.binding, retainedBinding)) { + return buildDrift(prepared.sessionKey, retainedBinding, build.binding); } invocation.bound.set(prepared.sessionKey, { build, adapter }); return undefined; @@ -2993,9 +3571,7 @@ function* useAcpxProviderState( } let resolved: Result; try { - resolved = allocatesIdentity(adapter) - ? yield* nativeCommand(invocation, prepared, adapter, agentCommand) - : Ok(adapter.resume(prepared.nativeSessionId)); + resolved = yield* nativeCommand(invocation, prepared, adapter, agentCommand); } catch { // Anything raised here came from private setup — an adapter's own code, a // temporary directory, a write. Whatever shape it has, it says nothing @@ -3115,11 +3691,13 @@ function* useAcpxProviderState( // before the caller saw the failure, and preserving the route is what // stops that uncertainty from later being reclassified as // client-native. - const attachment = yield* constructRoute(agentName, prepared); + const construction = yield* constructRoute(agentName, prepared); + const resumeSessionId = construction?.resumeSessionId; const session = yield* turns.withSlot(prepared.sessionKey, () => withSessionRoute(context, function* () { const entry = yield* ensureFromPrepared(agentName, prepared, { - ...(attachment === undefined ? {} : { attachment }), + ...(construction === undefined ? {} : { build: construction.build }), + ...(resumeSessionId === undefined ? {} : { attachment: { resumeSessionId } }), state, }); return entry.session; diff --git a/packages/acp/src/session-route.ts b/packages/acp/src/session-route.ts index 128d0b27..b37a0754 100644 --- a/packages/acp/src/session-route.ts +++ b/packages/acp/src/session-route.ts @@ -68,9 +68,6 @@ export type AgentSessionRouteV1 = * attachment know it is talking to the same build the native UI is in, so it * is required rather than optional here. * - * There is no V2 `acp-first`. ACP-first construction gained no fact, so a - * second schema for it would be a version number with nothing behind it. - * * V1 `client-native` is not upgraded into this. A build observed later says * which build is installed now, not which one established the session, and * writing it into an old record would claim knowledge XMD never had. @@ -88,8 +85,34 @@ export interface AgentSessionRouteV2 { executableBinding: ExecutableBuildBindingV1; } +/** + * The exact V3 record, which exists only for `acp-first`. + * + * It carries the same fact V2 added, for the other construction. An ACP-first + * session is named by the provider, and a name the provider issued is resumable + * only by the build that issued it: the native UI resuming that conversation + * has to be the same build ACP created it through, and nothing in the identity + * itself says which one that was. + * + * It still says nothing about the conversation. There remains no provider + * identity, instruction layer or process fact here — an ACP-first route names + * the construction and the build, and a session ACP created has nothing else to + * report at this boundary. + * + * A V1 `acp-first` route is not upgraded into this, for the same reason a V1 + * `client-native` one is not upgraded into V2. + */ +export interface AgentSessionRouteV3 { + schema: "session-route.v3"; + route: "acp-first"; + provider: string; + agent: string; + sessionKey: string; + executableBinding: ExecutableBuildBindingV1; +} + /** Every route form this build accepts. */ -export type AgentSessionRoute = AgentSessionRouteV1 | AgentSessionRouteV2; +export type AgentSessionRoute = AgentSessionRouteV1 | AgentSessionRouteV2 | AgentSessionRouteV3; /** Why a route could not be used. Never carries a path or provider-private state. */ export class AgentSessionRouteError extends Error { @@ -104,6 +127,7 @@ const CLIENT_NATIVE_MEMBERS = [ "instructionsDigest", "launcher", ]; +const BOUND_ACP_FIRST_MEMBERS = [...ACP_FIRST_MEMBERS, "executableBinding"]; const BOUND_CLIENT_NATIVE_MEMBERS = [...CLIENT_NATIVE_MEMBERS, "executableBinding"]; const BINDING_MEMBERS = ["schema", "reportedVersion", "executableDigest"]; const DIGEST_MEMBERS = ["algorithm", "value"]; @@ -163,11 +187,14 @@ export function parseAgentSessionRoute(value: unknown): AgentSessionRoute | unde if (!isRecord(value)) { return undefined; } - const bound = value.schema === "session-route.v2"; - if (!bound && value.schema !== "session-route.v1") { + const { schema, provider, agent, sessionKey } = value; + if ( + schema !== "session-route.v1" && + schema !== "session-route.v2" && + schema !== "session-route.v3" + ) { return undefined; } - const { provider, agent, sessionKey } = value; if (typeof provider !== "string" || provider.length === 0) { return undefined; } @@ -177,13 +204,40 @@ export function parseAgentSessionRoute(value: unknown): AgentSessionRoute | unde if (typeof sessionKey !== "string" || sessionKey.length === 0) { return undefined; } + // Each schema admits exactly the constructions it was minted for. V2 is + // client-native and V3 is ACP-first, so a record pairing one with the other + // is state this build cannot account for rather than a route with a spare + // member — which is also what keeps a V1 record from being read as a bound + // one, and a bound one from being read past its binding. if (value.route === "acp-first") { - // There is no bound ACP-first form, so a V2 record claiming one is state - // this build cannot account for rather than a route with a spare member. - return !bound && exactly(value, ACP_FIRST_MEMBERS) - ? { schema: "session-route.v1", route: "acp-first", provider, agent, sessionKey } - : undefined; + if (schema === "session-route.v2") { + return undefined; + } + if (schema === "session-route.v1") { + return exactly(value, ACP_FIRST_MEMBERS) + ? { schema: "session-route.v1", route: "acp-first", provider, agent, sessionKey } + : undefined; + } + if (!exactly(value, BOUND_ACP_FIRST_MEMBERS)) { + return undefined; + } + const executableBinding = parseExecutableBinding(value.executableBinding); + if (!executableBinding) { + return undefined; + } + return { + schema: "session-route.v3", + route: "acp-first", + provider, + agent, + sessionKey, + executableBinding, + }; + } + if (schema === "session-route.v3") { + return undefined; } + const bound = schema === "session-route.v2"; const members = bound ? BOUND_CLIENT_NATIVE_MEMBERS : CLIENT_NATIVE_MEMBERS; if (value.route !== "client-native" || !exactly(value, members)) { return undefined; @@ -247,7 +301,7 @@ export function serializeAgentSessionRoute(route: AgentSessionRoute): string { payload.instructionsDigest = route.instructionsDigest; payload.launcher = route.launcher; } - if (route.schema === "session-route.v2") { + if (route.schema === "session-route.v2" || route.schema === "session-route.v3") { payload.executableBinding = { schema: route.executableBinding.schema, reportedVersion: route.executableBinding.reportedVersion, diff --git a/packages/acp/tests/acceptance.test.ts b/packages/acp/tests/acceptance.test.ts index 83efa70a..cdfede11 100644 --- a/packages/acp/tests/acceptance.test.ts +++ b/packages/acp/tests/acceptance.test.ts @@ -19,7 +19,7 @@ import { createFakeRuntime, makeRegistry, makeStore, useFlatWorld } from "./help const CWD = "/work"; const DOC = [ - '', + '', '', '', "", @@ -44,9 +44,9 @@ describe("Tier XA — ACPX provider through the rootProvider seam", () => { factory: createAcpxProvider({ createRuntime: harness.create, sessionStore: makeStore(), - agentRegistry: makeRegistry({ codex: "codex-cmd" }), + agentRegistry: makeRegistry({ gemini: "gemini-cmd" }), }), - options: { defaultAgent: "codex", permissionMode: "deny-all" }, + options: { defaultAgent: "gemini", permissionMode: "deny-all" }, }, }); @@ -102,7 +102,7 @@ describe("Tier WAP — same-named sibling Sessions", () => { yield* writeTextFile( docPath, [ - '', + '', '', "first", "", @@ -122,7 +122,7 @@ describe("Tier WAP — same-named sibling Sessions", () => { factory: createAcpxProvider({ createRuntime: harness.create, sessionStore: makeStore(), - agentRegistry: makeRegistry({ codex: "codex-cmd" }), + agentRegistry: makeRegistry({ gemini: "gemini-cmd" }), sessions: { // deno-lint-ignore require-yield *place(context) { @@ -140,7 +140,7 @@ describe("Tier WAP — same-named sibling Sessions", () => { }, }, }), - options: { defaultAgent: "codex", permissionMode: "deny-all" }, + options: { defaultAgent: "gemini", permissionMode: "deny-all" }, }, }); // Middleware that rewrites the descriptive name on its way through, which @@ -194,7 +194,7 @@ describe("Tier WAP — same-named sibling Sessions", () => { yield* writeTextFile( docPath, [ - '', + '', '', "first", "", @@ -214,7 +214,7 @@ describe("Tier WAP — same-named sibling Sessions", () => { factory: createAcpxProvider({ createRuntime: harness.create, sessionStore: makeStore(), - agentRegistry: makeRegistry({ codex: "codex-cmd" }), + agentRegistry: makeRegistry({ gemini: "gemini-cmd" }), sessions: { // deno-lint-ignore require-yield *place(context) { @@ -227,7 +227,7 @@ describe("Tier WAP — same-named sibling Sessions", () => { }, }, }), - options: { defaultAgent: "codex", permissionMode: "deny-all" }, + options: { defaultAgent: "gemini", permissionMode: "deny-all" }, }, }); diff --git a/packages/acp/tests/adapter-protocol.test.ts b/packages/acp/tests/adapter-protocol.test.ts index 461e539e..f3674eac 100644 --- a/packages/acp/tests/adapter-protocol.test.ts +++ b/packages/acp/tests/adapter-protocol.test.ts @@ -330,4 +330,72 @@ describe("Tier EA — the embedded adapters' prompt-response metadata", () => { expect(metaOf(first, "codex")).toEqual({ turnId: `turn:${sessionId}:1` }); expect(metaOf(second, "codex")).toEqual({ turnId: `turn:${sessionId}:2` }); }); + + it("EA9: interleaved Codex sessions each report the thread they opened", function* () { + const adapter = yield* useAdapter("codex", CODEX_ENV); + yield* initialize(adapter); + + const alpha = yield* effectionSpawn(() => + adapter.request("session/new", { cwd: process.cwd(), mcpServers: [] }), + ); + const beta = yield* effectionSpawn(() => + adapter.request("session/new", { cwd: process.cwd(), mcpServers: [] }), + ); + const [one, two] = yield* all([alpha, beta]); + + // The App Server named each thread, so this is the identity that surface + // emitted compared with what the adapter reported on `_meta`. A top-level + // session id cannot stand in: a client reading that cannot tell an identity + // the provider allocated from one it invented itself. + expect(metaOf(one, "agentSessionId")).toBe(one["sessionId"]); + expect(metaOf(two, "agentSessionId")).toBe(two["sessionId"]); + // Two at once, so an adapter reporting anything session-global — the last + // thread it opened, say — hands at least one of them the other's answer. + expect(metaOf(one, "agentSessionId")).not.toBe(metaOf(two, "agentSessionId")); + }); + + it("EA10: reopening a Codex session reports the thread the App Server reopened", function* () { + const adapter = yield* useAdapter("codex", CODEX_ENV); + yield* initialize(adapter); + // A thread opened first, so the reopened answers below are distinguishable + // from the most recent thread this adapter process created. + const opened = yield* openSession(adapter); + + const resumed = yield* adapter.request("session/resume", { + sessionId: "thread-resumed", + cwd: process.cwd(), + mcpServers: [], + }); + const loaded = yield* adapter.request("session/load", { + sessionId: "thread-loaded", + cwd: process.cwd(), + mcpServers: [], + }); + + // Continuing a conversation needs its identity as much as starting one + // does, and reopening is the route a run takes on every turn after the + // first. + expect(metaOf(resumed, "agentSessionId")).toBe("thread-resumed"); + expect(metaOf(loaded, "agentSessionId")).toBe("thread-loaded"); + expect(metaOf(resumed, "agentSessionId")).not.toBe(opened); + expect(metaOf(loaded, "agentSessionId")).not.toBe(opened); + }); + + it("EA11: the Claude adapter reports no native session identity", function* () { + const adapter = yield* useAdapter("claude", CLAUDE_ENV); + yield* initialize(adapter); + + const session = yield* adapter.request("session/new", { + cwd: process.cwd(), + mcpServers: [], + }); + + // Claude is handed the identity it uses rather than allocating one, so + // there is nothing for its adapter to report back. This is the absence the + // client-allocated route depends on: were a value to appear here, a client + // choosing a route by whether the provider named the session would start + // taking the wrong one. + expect(typeof session["sessionId"]).toBe("string"); + expect(metaOf(session, "agentSessionId")).toBeUndefined(); + }); }); diff --git a/packages/acp/tests/codex-surfaces.test.ts b/packages/acp/tests/codex-surfaces.test.ts new file mode 100644 index 00000000..553cd62d --- /dev/null +++ b/packages/acp/tests/codex-surfaces.test.ts @@ -0,0 +1,1175 @@ +/** + * Tier CS — Codex surface classification and submission readiness + * (specs/native-agent-session-launch-spec.md §Provider-returned adapters). + * + * Two decisions in the Codex native proof are worth more than the turns they + * guard. One reads a screen that produced no answer and says whether the + * environment refused; the other decides whether a composer will take a turn at + * all, and so whether a model turn is spent. Both were wrong in ways only a paid + * run could show: + * + * - A bare `usage limit` substring matched Codex's own benign banner — + * `You have 2 usage limit resets available` — which an account with headroom + * to spare shows. Two authorized runs were reported as blocked by a quota that + * a `/status` on the same account said was 42% unspent. + * - Readiness was read off the byte stream, so a composer whose bytes had + * arrived counted as ready even while `model: loading` was still painted + * behind it, and the confirmation that the turn had been typed swallowed its + * own timeout and pressed Enter anyway. + * + * These cases drive the exact predicates and the exact driver the fixture + * consumes, against hand-written frames. No Codex process starts and no model + * turn is spent. + */ +import { describe, it } from "@executablemd/test-support/bdd"; +import { expect } from "@executablemd/test-support/expect"; +import type { Operation } from "effection"; +import { + presentedDuring, + TerminalReader, + TerminalScreen, + waitForPresented, +} from "./fixtures/terminal-screen.ts"; +import type { ScreenSnapshot } from "./fixtures/terminal-screen.ts"; +import { + classifyInitialSurface, + classifyStall, + COMPOSER, + composerReady, + exhaustedUsage, + MISSING_SESSION, + MODEL_LOADING, + PROMPT_TAIL, + promptPresented, + reachComposer, + submitWhenReady, + TRUST_DIALOG, +} from "./fixtures/codex-surfaces.ts"; +import type { + SubmissionBounds, + SubmissionPort, + SurfaceBounds, + SurfacePort, +} from "./fixtures/codex-surfaces.ts"; + +/** The pty the proof opens, so these frames wrap where that one wraps. */ +const ROWS = 40; +const COLUMNS = 120; + +const ESC = String.fromCharCode(0x1b); +const csi = (body: string): string => `${ESC}[${body}`; +const at = (row: number, column: number): string => csi(`${row};${column}H`); +const ALT_ON = csi("?1049h"); +const CLEAR = csi("2J"); +/** Hold the drawing back, and put the finished frame on show. */ +const SYNC_ON = csi("?2026h"); +const SYNC_OFF = csi("?2026l"); + +function paint(rows: readonly string[]): string { + return rows.map((row, index) => `${at(index + 1, 1)}${csi("2K")}${row}`).join(""); +} + +/** A bordered pane row, padded to its right border as a TUI pads one. */ +function pane(text: string, width = 80): string { + return `│ ${text.padEnd(width)} │`; +} + +/** A whole frame, drawn over whatever was there. */ +function frame(rows: readonly string[]): string { + return `${CLEAR}${paint(rows)}`; +} + +/** + * One read of a pty, carrying several finished frames. + * + * Each is committed in its own right, so every one of them is a frame a terminal + * put on show — and all of them arrive together, because a `data` event is + * however many bytes happened to be waiting rather than however much of a + * drawing was finished. + */ +function oneRead(...frames: readonly (readonly string[])[]): string { + return frames.map((rows) => `${SYNC_ON}${frame(rows)}${SYNC_OFF}`).join(""); +} + +function showing(rows: readonly string[]): ScreenSnapshot { + const terminal = new TerminalScreen({ rows: ROWS, columns: COLUMNS }); + terminal.write(`${ALT_ON}${frame(rows)}`); + return terminal.presented(); +} + +/** Codex's own banner, offering the resets an account still has in hand. */ +const BENIGN_RESETS = "You have 2 usage limit resets available. Run /usage to use one."; +/** What `/status` reports on the same account: headroom, in the same words. */ +const BENIGN_STATUS = "Usage limit: 42% left this week (resets Monday)"; +/** Help text about the refusal, which is not the refusal. */ +const CONDITIONAL_HELP = "If you've hit your usage limit, run /usage to see when it resets."; +/** What an account with nothing left is actually told. */ +const GENUINE_REFUSAL = "You've hit your usage limit."; + +/** + * The wording the previous round accepted, none of which anybody has witnessed. + * + * Kept as cases rather than deleted quietly: each one was a way for a screen + * that is not the refusal to reach `ENVIRONMENT_BLOCKED`, and a list that names + * them fails loudly if one is ever put back. + */ +/** + * The refusal's own words, inside a sentence that is somebody else's. + * + * What separates these from the refusal is where the sentence begins, and + * nothing else — the wording, the punctuation and the whole of the phrase are + * all present. They are the cases the run-prefix rule exists for; a containment + * test over the same run accepts every one of them. + */ +const EMBEDDED: readonly string[] = [ + "Note: You've hit your usage limit.", + "We don't think you've hit your usage limit.", + "It looks like you've hit your usage limit.", +]; + +const UNWITNESSED: readonly string[] = [ + "You've hit your weekly limit.", + "You've reached your usage limit.", + "You've reached your weekly limit.", + "You have hit your usage limit.", + "You have reached your usage limit.", + "Usage limit reached", + // The sentence's own opening, carrying on into a limit that is not the one + // this proof was refused by. Where it ends is part of what was witnessed. + "You've hit your usage limit for images.", +]; + +const READY = [pane("OpenAI Codex (v0.153.2)"), "", pane(COMPOSER), pane("model: gpt-5.6-sol")]; +const LOADING = [pane("OpenAI Codex (v0.153.2)"), "", pane(COMPOSER), pane(MODEL_LOADING)]; +const TRUSTING = [pane(TRUST_DIALOG), pane("1. Yes, continue"), "", pane(COMPOSER)]; + +describe("Tier CS — Codex surface classification", () => { + it("CS1: the resets banner is not exhaustion, composer or no composer", function* () { + // Bare, as it lands over a session that is about to work perfectly well. + expect(exhaustedUsage(showing([pane(BENIGN_RESETS)]))).toBe(false); + expect(classifyStall(showing([pane(BENIGN_RESETS)]))).toEqual({ + tag: "unknown", + verdict: "HARNESS_FAILED", + }); + + // And where it actually appears: above a composer waiting for a turn. The + // classification is the composer's resting state, which explains nothing. + const withComposer = showing([pane(BENIGN_RESETS), "", pane(COMPOSER)]); + expect(exhaustedUsage(withComposer)).toBe(false); + expect(classifyStall(withComposer)).toEqual({ + tag: "composer-idle", + verdict: "HARNESS_FAILED", + }); + }); + + it("CS2: status and headroom text is not exhaustion", function* () { + const status = showing([pane(BENIGN_STATUS), pane("Weekly limit: 42% left")]); + expect(exhaustedUsage(status)).toBe(false); + expect(classifyStall(status).verdict).toBe("HARNESS_FAILED"); + + // The words are on the screen. It is the sentence that decides, not them. + const terminal = new TerminalScreen({ rows: ROWS, columns: COLUMNS }); + terminal.write(`${ALT_ON}${frame([pane(BENIGN_STATUS)])}`); + expect(terminal.presented().rows.join("")).toContain("Usage limit"); + }); + + it("CS3: the exhausted-limit sentence is exhaustion", function* () { + const refused = showing([pane(GENUINE_REFUSAL), "", pane(COMPOSER)]); + expect(exhaustedUsage(refused)).toBe(true); + // Ahead of the idle composer drawn under it, which is the surface a refusal + // leaves behind and would otherwise be all this reported. + expect(classifyStall(refused)).toEqual({ + tag: "usage-limited", + verdict: "ENVIRONMENT_BLOCKED", + }); + + // Case and typographic apostrophes are the terminal's, not the sentence's. + expect(exhaustedUsage(showing([pane("you’ve hit your usage limit.")]))).toBe(true); + // Wrapped across two rows by a 40-column pane, which is where a substring + // search on a single row would lose it. + expect(exhaustedUsage(showing([pane("You've hit your usage", 20), pane("limit.", 20)]))).toBe( + true, + ); + }); + + it("CS4: a refusal inside an uncommitted frame is not classified until shown", function* () { + const terminal = new TerminalScreen({ rows: ROWS, columns: COLUMNS }); + terminal.write(`${ALT_ON}${frame([pane("Working"), pane("esc to interrupt")])}`); + expect(classifyStall(terminal.presented()).tag).toBe("still-working"); + + // The refusal is drawn inside a hold: cells this screen has and no terminal + // ever put on show. Reading them would blame an environment for a frame + // nobody was looking at. + terminal.write(`${SYNC_ON}${frame([pane(GENUINE_REFUSAL), "", pane(COMPOSER)])}`); + expect(exhaustedUsage(terminal.presented())).toBe(false); + expect(classifyStall(terminal.presented())).toEqual({ + tag: "still-working", + verdict: "HARNESS_FAILED", + }); + + // It counts from the commit, and not before. + terminal.write(SYNC_OFF); + expect(classifyStall(terminal.presented())).toEqual({ + tag: "usage-limited", + verdict: "ENVIRONMENT_BLOCKED", + }); + }); + + it("CS5: only the witnessed refusal may blame the environment", function* () { + // Reading a screen is the only way to get here. There is no exported + // tag-to-verdict step, so no caller can hand this proof a `usage-limited` + // it decided on for itself — the refusal has to be on a screen. + expect(classifyStall(showing([pane(GENUINE_REFUSAL)])).verdict).toBe("ENVIRONMENT_BLOCKED"); + + // Everything else describes where the terminal got to, and a proof that read + // any of them as an explanation would name a cause the screen never gave. + for (const rows of [ + [pane(BENIGN_RESETS), "", pane(COMPOSER)], + [pane(BENIGN_STATUS)], + [pane(CONDITIONAL_HELP), "", pane(COMPOSER)], + [pane("Working"), pane("esc to interrupt")], + [pane("Allow command"), pane("codex wants to run something")], + [pane(COMPOSER)], + [pane("something no version of this proof has ever seen")], + ]) { + expect(exhaustedUsage(showing(rows))).toBe(false); + expect(classifyStall(showing(rows)).verdict).toBe("HARNESS_FAILED"); + } + + // The refusal is the sentence, not the words in it. A run that begins + // somewhere else began somewhere else. + for (const sentence of EMBEDDED) { + expect(exhaustedUsage(showing([pane(sentence)]))).toBe(false); + expect(classifyStall(showing([pane(sentence)])).verdict).toBe("HARNESS_FAILED"); + } + + // Wording nobody has seen stays wording nobody has seen. An unrecognized + // screen costs an investigation; a wrongly recognized one costs the truth. + for (const wording of UNWITNESSED) { + expect(exhaustedUsage(showing([pane(wording)]))).toBe(false); + expect(classifyStall(showing([pane(wording)])).verdict).toBe("HARNESS_FAILED"); + } + }); +}); + +/** + * A port over scripted *reads*, built out of the pieces the pty is built out of. + * + * The same {@link TerminalReader} and the same {@link waitForPresented} the live + * path uses, for the same reason {@link surfaceFake} uses them: one entry of the + * script is one read, and a read can finish several frames. Submission needs + * that as much as reaching a composer does — Codex draws its refusal above a + * composer, so the refusal and the ready composer it must not be typed into can + * arrive in one read, with only the last of them left on screen. + */ +function fakePort(script: readonly string[]): { + port: SubmissionPort; + log: { typed: string[]; sent: string[]; waited: string[]; paused: number[]; charged: number }; +} { + const reader = new TerminalReader({ rows: ROWS, columns: COLUMNS }, false); + reader.write(ALT_ON); + const log = { typed: [], sent: [], waited: [], paused: [], charged: 0 } as { + typed: string[]; + sent: string[]; + waited: string[]; + paused: number[]; + charged: number; + }; + let next = 0; + const advance = (): boolean => { + const chunk = script[next]; + if (chunk === undefined) { + return false; + } + next += 1; + reader.write(chunk); + return true; + }; + return { + log, + port: { + screen: () => reader.snapshot(), + waitForScreen(name, _ms, predicate) { + log.waited.push(name); + return waitForPresented(reader, predicate, function* (wait): Operation { + // A script that runs out is a bound that ran out: no further byte is + // ever going to arrive, which is what a spent bound means. + while (!wait.settled() && advance()) { + // Reads, until one of them answers or there are none left. + } + }); + }, + type(text) { + log.typed.push(text); + }, + send(typed) { + // Ordered as the pty orders it: the turn is charged at the keystroke, + // ahead of the byte, so a run that reaches here has spent one either way. + log.charged += 1; + log.sent.push(typed); + }, + pause(ms, predicate) { + log.paused.push(ms); + // Time passing is frames arriving, which is how an overlay or a model + // that is still loading gets its chance to show up — and how a refusal + // gets its chance to be drawn and painted back over with nobody waiting. + return presentedDuring( + reader, + predicate, + (function* (): Operation { + advance(); + })(), + ); + }, + }, + }; +} + +const BOUNDS: SubmissionBounds = { ready: 1_000, startupGrace: 10, presented: 1_000 }; + +/** Minted for one run, and so the only text on the screen unique to that run. */ +const MARKER = "MK4A17BE0C9D31"; + +/** Shaped like the proof's turn: long, and ending in a marker minted per run. */ +const TURN = + "Do not use any tools. Reply with exactly two lines. First line: the first " + + "sentence of the body text under the 'Implementor' heading of your contract, " + + "copied verbatim. Second line: remember this marker for later, MK4A17BE0C9D31"; + +/** The composer with the turn in it — placeholder gone, as a real one is. */ +const TYPED_IN = [pane("OpenAI Codex (v0.153.2)"), "", pane(TURN.slice(-40)), pane("Send with ⏎")]; + +/** + * The refusal where Codex draws it: above a composer, rather than instead of one. + * + * The shape that makes this path dangerous, and the same one CS15 pins for the + * surface classifier. A screen can carry the refusal and a composer at once, so + * every predicate about the composer is satisfied by a screen that has already + * said the session does not exist. + */ +const REFUSED_READY = [ + pane("OpenAI Codex (v0.153.2)"), + pane(`${MISSING_SESSION} 019a-…`), + "", + pane(COMPOSER), +]; + +/** + * The refusal once the composer has gone with it. + * + * The other half of why a batch is not the whole answer. This screen fails + * {@link composerReady}, so a wait collecting on readiness can never be holding + * it — it can only be the screen a read ended on, which nothing but a read of + * the screen itself will find. + */ +const REFUSED_ALONE = [pane("OpenAI Codex (v0.153.2)"), pane(`${MISSING_SESSION} 019a-…`)]; + +/** The same refusal, over a composer holding the turn this run typed. */ +const REFUSED_TYPED = [ + pane("OpenAI Codex (v0.153.2)"), + pane(`${MISSING_SESSION} 019a-…`), + "", + pane(TURN.slice(-40)), + pane("Send with ⏎"), +]; + +describe("Tier CS — submission readiness", () => { + it("CS6: a model still loading takes no input at all", function* () { + expect(composerReady(showing(LOADING))).toBe(false); + // The composer is drawn and its bytes have arrived, which is exactly what + // the stream-reading version accepted. + expect(showing(LOADING).rows.join("")).toContain("Ask Codex to do anything"); + + const { port, log } = fakePort([frame(LOADING), frame(LOADING)]); + const outcome = yield* submitWhenReady(port, TURN, BOUNDS); + + expect(outcome).toEqual({ submitted: false, reason: "composer-never-ready" }); + // Nothing was typed, so nothing was queued into a composer that could take + // it later, and Enter was never reached. + expect(log.typed).toEqual([]); + expect(log.sent).toEqual([]); + }); + + it("CS7: a later ready frame permits exactly one submission", function* () { + const { port, log } = fakePort([ + frame(LOADING), + frame(READY), + frame(READY), + frame(TYPED_IN), + frame(TYPED_IN), + ]); + const outcome = yield* submitWhenReady(port, TURN, BOUNDS); + + expect(outcome).toEqual({ submitted: true }); + expect(log.typed).toEqual([TURN]); + expect(log.sent).toEqual([TURN]); + // The grace was taken, and the readiness read on both sides of it. + expect(log.paused).toEqual([BOUNDS.startupGrace]); + expect(log.waited).toEqual(["composer-ready", "prompt-presented"]); + }); + + it("CS8: a turn that never appears is never sent", function* () { + const { port, log } = fakePort([frame(READY), frame(READY), frame(READY)]); + const outcome = yield* submitWhenReady(port, TURN, BOUNDS); + + expect(outcome).toEqual({ submitted: false, reason: "prompt-never-presented" }); + // Typed, and that is all: the keystroke that spends the turn is the one + // thing this path may not reach. + expect(log.typed).toEqual([TURN]); + expect(log.sent).toEqual([]); + }); + + it("CS9: a composer under a dialog is not ready, and is waited for again", function* () { + expect(composerReady(showing(TRUSTING))).toBe(false); + + // Ready, then a dialog over it during the grace — which is the window the + // recheck exists for — then ready again. + const { port, log } = fakePort([frame(READY), frame(TRUSTING), frame(READY), frame(TYPED_IN)]); + expect(yield* submitWhenReady(port, TURN, BOUNDS)).toEqual({ submitted: true }); + expect(log.waited).toEqual(["composer-ready", "composer-ready-again", "prompt-presented"]); + expect(log.sent).toEqual([TURN]); + + // And when it does not come back, nothing is typed and nothing is sent. + const stuck = fakePort([frame(READY), frame(TRUSTING), frame(TRUSTING)]); + expect(yield* submitWhenReady(stuck.port, TURN, BOUNDS)).toEqual({ + submitted: false, + reason: "composer-unready-after-grace", + }); + expect(stuck.log.typed).toEqual([]); + expect(stuck.log.sent).toEqual([]); + }); + + it("CS10: readiness is read off the presented screen, not the held one", function* () { + // The whole ready frame is drawn inside a hold. Its bytes have arrived; no + // terminal has shown them. + const { port, log } = fakePort([ + `${SYNC_ON}${frame(READY)}`, + SYNC_OFF, + frame(READY), + frame(TYPED_IN), + ]); + expect(composerReady(port.screen())).toBe(false); + + expect(yield* submitWhenReady(port, TURN, BOUNDS)).toEqual({ submitted: true }); + expect(log.sent).toEqual([TURN]); + + // The same is true of the turn's own appearance: a composer showing it only + // in cells that were never committed has not presented it. + const held = new TerminalScreen({ rows: ROWS, columns: COLUMNS }); + held.write(`${ALT_ON}${frame(READY)}${SYNC_ON}${frame(TYPED_IN)}`); + expect(promptPresented(held.presented(), TURN)).toBe(false); + held.write(SYNC_OFF); + expect(promptPresented(held.presented(), TURN)).toBe(true); + }); + + it("CS11: every refusal on this path charges no turn at all", function* () { + // The two ways a submission can be refused, and the accounting each owes. + // `sent` is the byte; `charged` is what the run reports having spent, and + // the pty counts it before writing the byte so neither can outrun the other. + const unready = fakePort([frame(LOADING), frame(LOADING)]); + expect(yield* submitWhenReady(unready.port, TURN, BOUNDS)).toEqual({ + submitted: false, + reason: "composer-never-ready", + }); + expect(unready.log.charged).toBe(0); + + const unpresented = fakePort([frame(READY), frame(READY), frame(READY)]); + expect(yield* submitWhenReady(unpresented.port, TURN, BOUNDS)).toEqual({ + submitted: false, + reason: "prompt-never-presented", + }); + expect(unpresented.log.charged).toBe(0); + + // And the one path that does spend a turn spends exactly one. + const sending = fakePort([frame(READY), frame(READY), frame(TYPED_IN)]); + expect(yield* submitWhenReady(sending.port, TURN, BOUNDS)).toEqual({ submitted: true }); + expect(sending.log.charged).toBe(1); + }); + + it("CS12: the marker is absent before typing and presented before Enter", function* () { + // The tail is what `promptPresented` looks for, so the marker has to fit + // inside it or the thing being recognized is shared with every other run. + expect(TURN.slice(-PROMPT_TAIL)).toContain(MARKER); + + // Before typing, the composer is empty and there is nowhere else on screen + // for the marker to be: nothing has been sent, so no transcript carries it. + const ready = showing(READY); + expect(composerReady(ready)).toBe(true); + expect(ready.rows.join("")).not.toContain(MARKER); + expect(promptPresented(ready, TURN)).toBe(false); + + // Between typing and Enter it is on the screen, in the composer, which is + // what makes the turn about to be charged the turn this run prepared. + const composed = showing(TYPED_IN); + expect(composed.rows.join("")).toContain(MARKER); + expect(promptPresented(composed, TURN)).toBe(true); + + // A composer holding some other run's turn is not this run's turn presented. + const stale = showing([pane("OpenAI Codex (v0.153.2)"), "", pane("MK0000000000000")]); + expect(promptPresented(stale, TURN)).toBe(false); + }); + + it("CS22: a refusal reached while readying the turn charges nothing", function* () { + // Reaching a composer establishes the session was not refused, but only for + // as long as its grace was willing to wait — and Codex draws the composer + // before it resolves the thread. A refusal slower than that grace lands + // here, where the turn is already being readied and Enter is next. + // + // What makes it dangerous is that it is invisible to every predicate on this + // path. Codex draws `No saved session found with ID` *above* a composer + // rather than in place of one, so a refused screen is one the readiness test + // calls ready and the presentation test calls presented. + expect(composerReady(showing(REFUSED_READY))).toBe(true); + expect(promptPresented(showing(REFUSED_TYPED), TURN)).toBe(true); + // Only the surface classifier orders the refusal above them, which is why + // it, and not readiness, is what the gates below ask. + expect(classifyInitialSurface(showing(REFUSED_READY))).toBe("missing-session"); + expect(classifyInitialSurface(showing(REFUSED_TYPED))).toBe("missing-session"); + + // Gate one: the refusal is in the batch that satisfied the readiness wait, + // and the read ends on an ordinary composer, so the screen afterwards shows + // nothing wrong. + const atReady = fakePort([oneRead(REFUSED_READY, READY)]); + expect(yield* submitWhenReady(atReady.port, TURN, BOUNDS)).toEqual({ + submitted: false, + reason: "session-refused", + }); + expect(atReady.log.charged).toBe(0); + expect(atReady.log.sent).toEqual([]); + // Nothing was even typed: the refusal was read before there was any reason to. + expect(atReady.log.typed).toEqual([]); + + // Gate two: the composer came undone over the grace, and the refusal rides + // in the batch that answers the second readiness wait. + const atReadyAgain = fakePort([frame(READY), frame(LOADING), oneRead(REFUSED_READY, READY)]); + expect(yield* submitWhenReady(atReadyAgain.port, TURN, BOUNDS)).toEqual({ + submitted: false, + reason: "session-refused", + }); + expect(atReadyAgain.log.charged).toBe(0); + expect(atReadyAgain.log.waited).toEqual(["composer-ready", "composer-ready-again"]); + + // Gate three: the turn is typed, and the read that confirms it on screen is + // the read carrying the refusal. Typing spends nothing, so this still costs + // no turn — but it is one Enter away from costing one. + const atPresented = fakePort([frame(READY), frame(READY), oneRead(REFUSED_TYPED, TYPED_IN)]); + expect(yield* submitWhenReady(atPresented.port, TURN, BOUNDS)).toEqual({ + submitted: false, + reason: "session-refused", + }); + expect(atPresented.log.charged).toBe(0); + expect(atPresented.log.sent).toEqual([]); + expect(atPresented.log.typed).toEqual([TURN]); + + // Gate four: the refusal is in no batch at all. It arrives in the same read + // as the confirmed turn but *after* it, so it satisfies no predicate on this + // path and is collected by nothing — it is only there to be seen by reading + // the screen as it stands, which is what the last thing before Enter does. + const atEnter = fakePort([frame(READY), frame(READY), oneRead(TYPED_IN, REFUSED_READY)]); + expect(yield* submitWhenReady(atEnter.port, TURN, BOUNDS)).toEqual({ + submitted: false, + reason: "session-refused", + }); + expect(atEnter.log.charged).toBe(0); + expect(atEnter.log.sent).toEqual([]); + + // And the priority is the refusal's alone. The same shape with nothing + // refused still submits, so what was added is a finding and not a new way + // for an ordinary run to lose its turn. + const clean = fakePort([frame(READY), frame(READY), frame(TYPED_IN)]); + expect(yield* submitWhenReady(clean.port, TURN, BOUNDS)).toEqual({ submitted: true }); + expect(clean.log.charged).toBe(1); + expect(clean.log.sent).toEqual([TURN]); + }); + + it("CS23: a refusal left on the screen stops the turn at either decision taken against it", function* () { + // Every check CS22 added reads a batch, and a batch is the frames that + // answered a wait rather than the screen the read ended on. Two decisions + // here are taken against the screen instead — whether the composer needs a + // second wait, and whether it survived one — and both are followed by + // typing. Neither had anything collecting a refusal for it. + + // After the startup grace. The refusal drawn during the pause leaves + // `composerReady` true, which is the shape this whole tier turns on, so the + // second wait is not taken, no batch exists to be checked, and the read that + // confirms the turn repaints a clean composer over the refusal. + const duringGrace = fakePort([frame(READY), frame(REFUSED_READY), frame(TYPED_IN)]); + expect(yield* submitWhenReady(duringGrace.port, TURN, BOUNDS)).toEqual({ + submitted: false, + reason: "session-refused", + }); + expect(duringGrace.log.charged).toBe(0); + expect(duringGrace.log.sent).toEqual([]); + // Nothing was typed either: this stops before the composer is touched, not + // at the last moment before Enter. + expect(duringGrace.log.typed).toEqual([]); + expect(duringGrace.log.waited).toEqual(["composer-ready"]); + + // After a `composer-ready-again` batch. Here the refusal is what the read + // ended on and it carries no composer — which is what sent this run to a + // second wait to begin with, and is exactly what keeps it out of a batch + // collected on readiness. An earlier frame in the same read satisfied the + // wait, so the batch is honestly ready and honestly not refused. + const afterAgain = fakePort([ + frame(READY), + frame(LOADING), + oneRead(READY, REFUSED_ALONE), + frame(TYPED_IN), + ]); + expect(yield* submitWhenReady(afterAgain.port, TURN, BOUNDS)).toEqual({ + submitted: false, + reason: "session-refused", + }); + expect(afterAgain.log.charged).toBe(0); + expect(afterAgain.log.typed).toEqual([]); + expect(afterAgain.log.waited).toEqual(["composer-ready", "composer-ready-again"]); + + // The two refusals are opposite shapes, and that is the point: one is caught + // because it passes for ready, the other because it cannot be collected by a + // wait that asks for ready. A batch check answers for neither. + expect(composerReady(showing(REFUSED_READY))).toBe(true); + expect(composerReady(showing(REFUSED_ALONE))).toBe(false); + + // A composer that simply came back after the grace still types and still + // submits, so the second wait keeps its ordinary ending. + const recovered = fakePort([ + frame(READY), + frame(LOADING), + oneRead(LOADING, READY), + frame(TYPED_IN), + ]); + expect(yield* submitWhenReady(recovered.port, TURN, BOUNDS)).toEqual({ submitted: true }); + expect(recovered.log.charged).toBe(1); + expect(recovered.log.sent).toEqual([TURN]); + expect(recovered.log.waited).toEqual([ + "composer-ready", + "composer-ready-again", + "prompt-presented", + ]); + }); + + it("CS24: a refusal a wait was not watching for still ends that wait", function* () { + // The third place a refusal can hide, and the one neither a batch nor the + // screen afterwards reaches. A wait ends at the read that satisfied it, so a + // frame its predicate says nothing about does not merely go uncollected — it + // does not stop the wait at all, and the next read repaints over it. This + // refusal carries no composer, so `composerReady` and `promptPresented` are + // both false on it, and both of these waits ran straight past it. + expect(composerReady(showing(REFUSED_ALONE))).toBe(false); + expect(promptPresented(showing(REFUSED_ALONE), TURN)).toBe(false); + expect(classifyInitialSurface(showing(REFUSED_ALONE))).toBe("missing-session"); + + // Waiting for the composer to come back. The refusal is presented, then a + // composer is drawn over it in a read of its own, and the batch that answers + // is honestly ready while the screen afterwards is honestly clean. + const whileWaitingReady = fakePort([ + frame(READY), + frame(LOADING), + frame(REFUSED_ALONE), + frame(READY), + frame(TYPED_IN), + ]); + expect(yield* submitWhenReady(whileWaitingReady.port, TURN, BOUNDS)).toEqual({ + submitted: false, + reason: "session-refused", + }); + // Nothing typed: this wait is upstream of the composer being touched, so the + // refusal that ends it ends the run before there is a turn in the box. + expect(whileWaitingReady.log.typed).toEqual([]); + expect(whileWaitingReady.log.sent).toEqual([]); + expect(whileWaitingReady.log.charged).toBe(0); + + // Waiting for the typed turn to appear. Here the turn is already in the + // composer, so what is left to protect is Enter — and the refusal is again + // presented in a read the wait had no reason to stop at. + const whileWaitingPresented = fakePort([ + frame(READY), + frame(READY), + frame(REFUSED_ALONE), + frame(TYPED_IN), + ]); + expect(yield* submitWhenReady(whileWaitingPresented.port, TURN, BOUNDS)).toEqual({ + submitted: false, + reason: "session-refused", + }); + // The typing stands — it happened before anything was refused, and typing + // into a composer costs nothing. Enter is what must not follow it. + expect(whileWaitingPresented.log.typed).toEqual([TURN]); + expect(whileWaitingPresented.log.sent).toEqual([]); + expect(whileWaitingPresented.log.charged).toBe(0); + + // Neither wait is now a wait for anything that happens to end it: a run + // where nothing is refused still waits out its full script and submits. + const patient = fakePort([ + frame(READY), + frame(LOADING), + frame(LOADING), + frame(READY), + frame(TYPED_IN), + ]); + expect(yield* submitWhenReady(patient.port, TURN, BOUNDS)).toEqual({ submitted: true }); + expect(patient.log.charged).toBe(1); + expect(patient.log.sent).toEqual([TURN]); + }); + + it("CS26: a refusal presented during the startup grace is seen, and charges nothing", function* () { + // The grace exists because Codex draws its composer before it has finished + // deciding anything, so it is the window a late refusal is most likely to + // land in — and it was the one window nothing was watching. Presented and + // painted over inside a single read, the refusal leaves a ready composer + // behind it, which is what every question asked after the grace sees. + const refusedDuringGrace = fakePort([ + frame(READY), + oneRead(REFUSED_READY, READY), + frame(TYPED_IN), + ]); + expect(yield* submitWhenReady(refusedDuringGrace.port, TURN, BOUNDS)).toEqual({ + submitted: false, + reason: "session-refused", + }); + expect(refusedDuringGrace.log.typed).toEqual([]); + expect(refusedDuringGrace.log.sent).toEqual([]); + expect(refusedDuringGrace.log.charged).toBe(0); + // Decided against something the screen no longer shows: afterwards it is an + // ordinary ready composer, and asking it would have typed a turn. + expect(composerReady(refusedDuringGrace.port.screen())).toBe(true); + + // The refusal need not be repainted to count, and a grace that ends on one + // is still the same finding rather than a composer that came undone. + const refusedAndLeft = fakePort([frame(READY), frame(REFUSED_ALONE), frame(TYPED_IN)]); + expect(yield* submitWhenReady(refusedAndLeft.port, TURN, BOUNDS)).toEqual({ + submitted: false, + reason: "session-refused", + }); + expect(refusedAndLeft.log.charged).toBe(0); + + // An ordinary repaint during the grace still submits, so what the grace now + // watches for is the refusal and not change in general. + const repaintedDuringGrace = fakePort([frame(READY), oneRead(LOADING, READY), frame(TYPED_IN)]); + expect(yield* submitWhenReady(repaintedDuringGrace.port, TURN, BOUNDS)).toEqual({ + submitted: true, + }); + expect(repaintedDuringGrace.log.charged).toBe(1); + expect(repaintedDuringGrace.log.sent).toEqual([TURN]); + + // A refusal drawn during the grace and held back was never on show, so the + // grace has nothing to report and the turn is typed. The run then ends + // waiting for a composer this hold never lets it see — not as a refusal, + // which is what a hold counting would have made it — and sends nothing. + const heldDuringGrace = fakePort([ + frame(READY), + `${SYNC_ON}${frame(REFUSED_ALONE)}`, + frame(TYPED_IN), + ]); + expect(yield* submitWhenReady(heldDuringGrace.port, TURN, BOUNDS)).toEqual({ + submitted: false, + reason: "prompt-never-presented", + }); + expect(heldDuringGrace.log.typed).toEqual([TURN]); + expect(heldDuringGrace.log.charged).toBe(0); + }); +}); + +/** + * A port over scripted *reads*, built out of the pieces the pty is built out of. + * + * Deliberately not a screen with a predicate checked beside it. The live path is + * a {@link TerminalReader} fed one read at a time, with waits woken from inside + * it by {@link waitForPresented}; this is the same reader and the same wait, and + * differs only in what makes a read arrive. That is what lets one entry of the + * script carry several finished frames — as a pty's `data` event routinely does + * — and have this driver see each of them, rather than only the one the read + * ended on. + */ +function surfaceFake(script: readonly string[]): { + port: SurfacePort; + log: { consents: number; waited: string[]; paused: number[] }; +} { + const reader = new TerminalReader({ rows: ROWS, columns: COLUMNS }, false); + reader.write(ALT_ON); + const log = { consents: 0, waited: [], paused: [] } as { + consents: number; + waited: string[]; + paused: number[]; + }; + let next = 0; + const advance = (): boolean => { + const chunk = script[next]; + if (chunk === undefined) { + return false; + } + next += 1; + reader.write(chunk); + return true; + }; + return { + log, + port: { + screen: () => reader.snapshot(), + waitForScreen(name, _ms, predicate) { + log.waited.push(name); + return waitForPresented(reader, predicate, function* (wait): Operation { + // Nothing happens between reads here, as nothing happens between a + // pty's. A script that runs out is a bound that ran out: no further + // byte is ever going to arrive, which is what a spent bound means. + while (!wait.settled() && advance()) { + // Reads, until one of them answers or there are none left. + } + }); + }, + consent() { + log.consents += 1; + }, + pause(ms, predicate) { + log.paused.push(ms); + return presentedDuring( + reader, + predicate, + (function* (): Operation { + advance(); + })(), + ); + }, + }, + }; +} + +const SURFACE: SurfaceBounds = { surface: 1_000, settle: 10, grace: 10 }; + +const MISSING = [pane("OpenAI Codex (v0.153.2)"), "", pane(`${MISSING_SESSION} 019a-…`)]; +const STARTING = [pane("OpenAI Codex (v0.153.2)"), pane(MODEL_LOADING)]; + +describe("Tier CS — reaching a composer", () => { + it("CS13: the trust dialog is answered once, and only while it is up", function* () { + const { port, log } = surfaceFake([frame(TRUSTING), frame(TRUSTING), frame(READY)]); + expect(yield* reachComposer(port, SURFACE)).toBe("composer-ready"); + expect(log.consents).toBe(1); + // The settle came before the Enter, and the answered dialog was waited out + // rather than read again as a second question. + expect(log.paused).toEqual([SURFACE.settle]); + expect(log.waited).toEqual(["surface", "trust-answered", "surface", "readiness-grace"]); + + // A dialog that goes away during the settle is not answered at all: the + // Enter would land in whatever replaced it. + const vanishing = surfaceFake([frame(TRUSTING), frame(READY), frame(READY)]); + expect(yield* reachComposer(vanishing.port, SURFACE)).toBe("composer-ready"); + expect(vanishing.log.consents).toBe(0); + }); + + it("CS14: a directory Codex already trusts is consented to zero times", function* () { + const { port, log } = surfaceFake([frame(READY), frame(READY)]); + expect(yield* reachComposer(port, SURFACE)).toBe("composer-ready"); + expect(log.consents).toBe(0); + // The grace was still spent watching for the readiness to come undone. + expect(log.waited).toEqual(["surface", "readiness-grace"]); + + // And when one does arrive over the composer during that grace, it is + // answered — which is the ordering Codex actually draws. + const late = surfaceFake([frame(READY), frame(TRUSTING), frame(TRUSTING), frame(READY)]); + expect(yield* reachComposer(late.port, SURFACE)).toBe("composer-ready"); + expect(late.log.consents).toBe(1); + }); + + it("CS15: a refused identity is a finding, not something to press Enter at", function* () { + const { port, log } = surfaceFake([frame(MISSING)]); + expect(yield* reachComposer(port, SURFACE)).toBe("missing-session"); + expect(log.consents).toBe(0); + + // Codex draws its composer while still opening the thread, so the refusal + // and a ready-looking composer share a screen. The refusal is what it is. + expect(classifyInitialSurface(showing([...MISSING, "", pane(COMPOSER)]))).toBe( + "missing-session", + ); + }); + + it("CS16: a held frame decides nothing until the terminal commits it", function* () { + for (const [held, committed] of [ + [TRUSTING, "trust-dialog"], + [MISSING, "missing-session"], + [READY, "composer-ready"], + // A loading model is not a surface either way. What it must never do is + // become readiness, and cells nobody has been shown are the one place + // that could happen without anybody seeing it. + [LOADING, "starting"], + ] as const) { + const terminal = new TerminalScreen({ rows: ROWS, columns: COLUMNS }); + terminal.write(`${ALT_ON}${frame(STARTING)}`); + terminal.write(`${SYNC_ON}${frame(held)}`); + // The bytes are in. Nothing is on show but the frame from before them. + expect(classifyInitialSurface(terminal.presented())).toBe("starting"); + expect(composerReady(terminal.presented())).toBe(false); + terminal.write(SYNC_OFF); + expect(classifyInitialSurface(terminal.presented())).toBe(committed); + } + + // Driven end to end: a dialog that is only ever held is a dialog this never + // answers, and the same dialog committed is answered exactly once. + const uncommitted = surfaceFake([`${SYNC_ON}${frame(TRUSTING)}`]); + expect(yield* reachComposer(uncommitted.port, SURFACE)).toBe("unresolved"); + expect(uncommitted.log.consents).toBe(0); + + const shown = surfaceFake([ + `${SYNC_ON}${frame(TRUSTING)}`, + SYNC_OFF, + frame(TRUSTING), + frame(READY), + ]); + expect(yield* reachComposer(shown.port, SURFACE)).toBe("composer-ready"); + expect(shown.log.consents).toBe(1); + }); + + it("CS17: readiness that comes undone during the grace is not readiness", function* () { + // Codex draws its composer before it reports that it holds no such thread, + // so the refusal can land on a screen this driver has already read as ready. + // A grace watching only for the trust dialog runs out in front of it and + // returns the composer — sending a turn at a session that does not exist. + const refused = surfaceFake([frame(READY), frame(MISSING)]); + expect(yield* reachComposer(refused.port, SURFACE)).toBe("missing-session"); + expect(refused.log.consents).toBe(0); + + // The grace ends at the first screen that is no longer ready, so a refusal + // it sees is the answer even where a composer is drawn over it afterwards. + // A grace that ran on past it would report the composer and lose the + // finding this whole feature exists to establish. + const repainted = surfaceFake([frame(READY), frame(MISSING), frame(READY)]); + expect(yield* reachComposer(repainted.port, SURFACE)).toBe("missing-session"); + + // The same for a model that goes back to loading: input typed there may be + // queued rather than taken, so this is not a composer to submit into. + const relapsed = surfaceFake([frame(READY), frame(LOADING)]); + expect(yield* reachComposer(relapsed.port, SURFACE)).toBe("unresolved"); + expect(relapsed.log.consents).toBe(0); + + // Unless the model finishes loading, at which point it is ready again and + // this says so. The grace refuses a screen, not a session. + const recovered = surfaceFake([frame(READY), frame(LOADING), frame(READY)]); + expect(yield* reachComposer(recovered.port, SURFACE)).toBe("composer-ready"); + expect(recovered.log.consents).toBe(0); + + // And a composer that simply stays ready is still reached, which is what + // every accepted run of this proof has done. + const stable = surfaceFake([frame(READY), frame(READY), frame(READY)]); + expect(yield* reachComposer(stable.port, SURFACE)).toBe("composer-ready"); + expect(stable.log.consents).toBe(0); + }); + + it("CS18: a transition held back during the grace decides at its commit", function* () { + // The refusal is drawn inside a hold that never commits. Its bytes arrived + // during the grace; no terminal showed them, so the screen is still the + // ready one and that is what this returns. + const held = surfaceFake([frame(READY), `${SYNC_ON}${frame(MISSING)}`]); + expect(yield* reachComposer(held.port, SURFACE)).toBe("composer-ready"); + + // Commit the same frame and the grace has something to see. + const committed = surfaceFake([frame(READY), `${SYNC_ON}${frame(MISSING)}`, SYNC_OFF]); + expect(yield* reachComposer(committed.port, SURFACE)).toBe("missing-session"); + expect(committed.log.consents).toBe(0); + + // A loading model held back and then committed reads the same way round. + const loading = surfaceFake([frame(READY), `${SYNC_ON}${frame(LOADING)}`, SYNC_OFF]); + expect(yield* reachComposer(loading.port, SURFACE)).toBe("unresolved"); + expect(loading.log.consents).toBe(0); + }); + + it("CS19: a surface presented and repainted inside one read is still presented", function* () { + // Codex commits its refusal and draws the composer over it within + // milliseconds of each other, and a pty hands over however many bytes were + // waiting — so both frames routinely arrive in one read, with nothing in + // between for a waiter outside the reader to be woken by. Everything above + // scripts a read per frame, which is the one arrangement that cannot show + // this. + const refusedThenDrawn = surfaceFake([oneRead(MISSING, READY)]); + expect(yield* reachComposer(refusedThenDrawn.port, SURFACE)).toBe("missing-session"); + expect(refusedThenDrawn.log.consents).toBe(0); + // And the screen the read ended on is a ready composer — which is what a + // driver reading only the current screen would have found, and typed into. + expect(classifyInitialSurface(refusedThenDrawn.port.screen())).toBe("composer-ready"); + + // The same read arriving during the grace, which is the other place a + // refusal lands: after this driver has already read a composer as ready. + const refusedDuringGrace = surfaceFake([frame(READY), oneRead(MISSING, READY)]); + expect(yield* reachComposer(refusedDuringGrace.port, SURFACE)).toBe("missing-session"); + expect(classifyInitialSurface(refusedDuringGrace.port.screen())).toBe("composer-ready"); + + // A model that goes back to loading and finishes inside one read is the + // mirror of that, and settles the other way. The loading frame ends the + // grace, and then readiness is read off the screen as it stands — because + // the composer about to be typed into is this one, not the frame that woke + // the wait. + const relapsedThenLoaded = surfaceFake([frame(READY), oneRead(LOADING, READY)]); + expect(yield* reachComposer(relapsedThenLoaded.port, SURFACE)).toBe("composer-ready"); + expect(relapsedThenLoaded.log.consents).toBe(0); + + // And a trust dialog that comes and goes inside one read is never answered. + // It was presented, so the grace ends at it; but Enter is an act against + // whatever is on screen when it is pressed, and by then the dialog is gone. + const askedThenGone = surfaceFake([frame(READY), oneRead(TRUSTING, READY)]); + expect(yield* reachComposer(askedThenGone.port, SURFACE)).toBe("composer-ready"); + expect(askedThenGone.log.consents).toBe(0); + + // A dialog that is still up when the read ends is answered exactly once, + // so the case above turns on the dialog having gone and not on the shape. + const stillAsking = surfaceFake([ + frame(READY), + oneRead(READY, TRUSTING), + frame(TRUSTING), + frame(READY), + ]); + expect(yield* reachComposer(stillAsking.port, SURFACE)).toBe("composer-ready"); + expect(stillAsking.log.consents).toBe(1); + + // The same dialog inside the *first* read, before any composer has been read + // as ready. The dialog is what the wait matched, and the driver never goes to + // answer it at all: it waits out no settle, because a settle is time given to + // a dialog that is still finishing drawing, and this one is already gone. + const goneBeforeLookedAt = surfaceFake([oneRead(TRUSTING, READY)]); + expect(yield* reachComposer(goneBeforeLookedAt.port, SURFACE)).toBe("composer-ready"); + expect(goneBeforeLookedAt.log.consents).toBe(0); + expect(goneBeforeLookedAt.log.paused).toEqual([]); + expect(goneBeforeLookedAt.log.waited).toEqual(["surface", "readiness-grace"]); + + // A read carrying three frames, with the refusal in the middle of it. Neither + // end of the read shows it: the model was still loading when the read began + // and a composer was up by the time it ended, so this is only found by + // examining every commit rather than the first or the last. + const refusedMidRead = surfaceFake([oneRead(LOADING, MISSING, READY)]); + expect(yield* reachComposer(refusedMidRead.port, SURFACE)).toBe("missing-session"); + expect(refusedMidRead.log.consents).toBe(0); + expect(classifyInitialSurface(refusedMidRead.port.screen())).toBe("composer-ready"); + }); + + it("CS20: a refusal behind an earlier match in the same read is still the finding", function* () { + // The case above finds the refusal because nothing ahead of it in the read + // satisfied the wait. That is not the general shape. Both waits here ask a + // question a benign frame can also answer — the grace watches for the + // composer becoming *anything* else, and the initial wait for any surface + // worth acting on — so a read can satisfy one at its first frame and carry + // the refusal behind it. A wait that stopped looking at the frame that woke + // it would report the benign one and never see the refusal at all. + + // Codex reloading a model, refusing the identity, and drawing its composer + // back: three commits, one read, arriving after this driver has already read + // a composer as ready. The grace matches at `loading`, and the refusal is + // two frames further in. + const refusedBehindLoading = surfaceFake([frame(READY), oneRead(LOADING, MISSING, READY)]); + expect(yield* reachComposer(refusedBehindLoading.port, SURFACE)).toBe("missing-session"); + expect(refusedBehindLoading.log.consents).toBe(0); + // The screen the read ended on is a ready composer, which is what this + // driver would otherwise have typed a turn into. + expect(classifyInitialSurface(refusedBehindLoading.port.screen())).toBe("composer-ready"); + + // The same ordering on the initial wait, where the trust dialog is the + // actionable frame that answers it first and the refusal follows. + const refusedBehindTrust = surfaceFake([oneRead(TRUSTING, MISSING, READY)]); + expect(yield* reachComposer(refusedBehindTrust.port, SURFACE)).toBe("missing-session"); + // Never consented to: a refused session is a finding, not a directory to + // take a standing permission on. + expect(refusedBehindTrust.log.consents).toBe(0); + expect(classifyInitialSurface(refusedBehindTrust.port.screen())).toBe("composer-ready"); + + // And the priority is the refusal's alone. A benign frame behind another + // benign frame decides nothing extra: the grace still ends at the first, and + // readiness is still read off the screen as it stands. + const loadedBehindTrust = surfaceFake([frame(READY), oneRead(TRUSTING, LOADING, READY)]); + expect(yield* reachComposer(loadedBehindTrust.port, SURFACE)).toBe("composer-ready"); + expect(loadedBehindTrust.log.consents).toBe(0); + }); + + it("CS21: a refusal presented after the consent is the finding, and no turn follows", function* () { + // The third wait this driver consumes a batch from, and the one CS20 never + // reaches. Answering the dialog is not the end of the startup: Codex goes on + // to load a model and to report what it holds, and this wait is what it is + // watched through. The wait asks only that the dialog be gone, which the + // model reloading already satisfies — so the refusal arrives behind a frame + // that answered the wait, in the read that answered it. + const refusedAfterConsent = surfaceFake([ + frame(TRUSTING), + frame(TRUSTING), + oneRead(LOADING, MISSING, READY), + ]); + expect(yield* reachComposer(refusedAfterConsent.port, SURFACE)).toBe("missing-session"); + // The consent stands, and is neither repeated nor taken back: it was pressed + // at a dialog that was up and asking, about a directory, before anything had + // been refused. What must not follow it is a turn, and the finding is what + // stops one — this returns instead of going round to type into the composer + // the same read drew. + expect(refusedAfterConsent.log.consents).toBe(1); + expect(refusedAfterConsent.log.waited).toEqual(["surface", "trust-answered"]); + expect(classifyInitialSurface(refusedAfterConsent.port.screen())).toBe("composer-ready"); + + // A benign batch here still continues, so what was added is the refusal's + // priority and not a general distrust of whatever follows a consent. + const startedAfterConsent = surfaceFake([ + frame(TRUSTING), + frame(TRUSTING), + oneRead(LOADING, READY), + frame(READY), + ]); + expect(yield* reachComposer(startedAfterConsent.port, SURFACE)).toBe("composer-ready"); + expect(startedAfterConsent.log.consents).toBe(1); + expect(startedAfterConsent.log.waited).toEqual([ + "surface", + "trust-answered", + "surface", + "readiness-grace", + ]); + }); + + it("CS25: a refusal presented during the settle is seen, and nothing is consented to", function* () { + // The settle is a window like any other — the terminal goes on drawing for + // its whole duration — but nothing was watching it. A refusal presented and + // painted over inside one read during the settle leaves the dialog on screen + // afterwards, and the recheck before Enter is a question about the screen, + // which by then says the dialog is still up and still asking. + const refusedDuringSettle = surfaceFake([ + frame(TRUSTING), + oneRead(MISSING, TRUSTING), + frame(READY), + frame(READY), + ]); + expect(yield* reachComposer(refusedDuringSettle.port, SURFACE)).toBe("missing-session"); + // Not consented to at all. This refusal was presented *before* the Enter, + // unlike CS21's, so there is no question of a consent standing: the + // directory was never answered for, because the session it was being + // answered for had already been refused. + expect(refusedDuringSettle.log.consents).toBe(0); + // And the screen it was decided against still shows the dialog, which is + // exactly why the screen alone could not decide it. + expect(classifyInitialSurface(refusedDuringSettle.port.screen())).toBe("trust-dialog"); + + // An ordinary repaint during the settle still consents. The dialog redrawing + // itself, or a model loading behind it, is a settle doing its job. + const redrawnDuringSettle = surfaceFake([ + frame(TRUSTING), + oneRead(STARTING, TRUSTING), + frame(READY), + frame(READY), + ]); + expect(yield* reachComposer(redrawnDuringSettle.port, SURFACE)).toBe("composer-ready"); + expect(redrawnDuringSettle.log.consents).toBe(1); + + // And a dialog that simply goes away during the settle is still not answered, + // which is the behaviour the settle existed for in the first place. + const departedDuringSettle = surfaceFake([ + frame(TRUSTING), + frame(READY), + frame(READY), + frame(READY), + ]); + expect(yield* reachComposer(departedDuringSettle.port, SURFACE)).toBe("composer-ready"); + expect(departedDuringSettle.log.consents).toBe(0); + + // A refusal drawn during the settle and never committed is not something the + // terminal ever put on show, and observing the settle does not change that. + // The consent goes ahead — the dialog is what is presented — and the run ends + // waiting for an answer that this held drawing never lets arrive, which is a + // different outcome from the refusal it would be if a hold counted. + const heldDuringSettle = surfaceFake([ + frame(TRUSTING), + `${SYNC_ON}${frame(MISSING)}`, + frame(READY), + ]); + expect(yield* reachComposer(heldDuringSettle.port, SURFACE)).toBe("unresolved"); + expect(heldDuringSettle.log.consents).toBe(1); + }); +}); diff --git a/packages/acp/tests/fixtures/codex-native-launch-proof.ts b/packages/acp/tests/fixtures/codex-native-launch-proof.ts new file mode 100644 index 00000000..8758200b --- /dev/null +++ b/packages/acp/tests/fixtures/codex-native-launch-proof.ts @@ -0,0 +1,2296 @@ +/** + * Issue #755 — the parts of a real Codex launch Markdown cannot observe. + * + * `CodexNativeLaunch.test.md` and `CodexZeroNativeTurnExit.test.md` own the + * sequencing, the gating, the schemas, the assertions and everything an + * operator reads. This fixture owns only what an authored document cannot + * reach: a sized pseudo-terminal, child lifecycle, structured route and journal + * reads, the vendored adapter's own snapshot identity, and exact-path cleanup. + * + * What it does not own is the product. The thing under test is the ordinary + * production command: + * + * dist/xmd run AGENTS.md#Implementor --default-agent codex --journal … --raw + * + * run inside a byte-for-byte copy of the repository's own `AGENTS.md` and + * `.agents/implementor.md`. No role Markdown is built, interpolated or + * rewritten here — a proof that assembled the document in TypeScript would be + * proving something nobody runs. + * + * Three boundaries keep the evidence honest: + * + * - **Nothing provider-private is read.** Every observation comes from a value + * this fixture supplied, a process outcome, XMD's own diagnostic journal, the + * exact XMD route record for this run's natural key, or the terminal output + * of the production command. Nothing beneath `~/.codex` is opened — not + * rollouts, not history, not configuration — and `CODEX_HOME` is left exactly + * as the operator has it, because relocating it de-authenticates Codex. + * - **No shim stands in front of the executable.** The Claude proofs put a + * recording wrapper on `PATH` to read the native argv. Doing that here would + * defeat the thing #755 freezes: the observer canonicalizes and hashes what it + * resolves, so a wrapper would bind the session to the wrapper's digest rather + * than to the Codex build in the compatibility tuple. The native identity is + * established from Codex's own terminal output instead — it prints + * `Session ID: ` as it leaves — which is stronger than an argv anyway: a + * picker or `--last` would print a different one. + * - **Nothing sensitive is rendered.** One filtered JSON verdict reaches stdout: + * versions, digests this repository already checks in, the exact identity and + * its provenance, booleans, counts, phase and failure classes, usage figures, + * and cleanup outcomes. Raw terminal buffers, argv, environment and prepared + * instruction text never leave this file. + * + * Model turns are the one number nobody may be wrong about, so every one of them + * is counted at the keystroke or at the record that proves it happened, never + * summarized on the way out. + */ + +import { ensure, main, race, scoped, sleep, until, withResolvers } from "effection"; +import type { Operation } from "effection"; +import { exists, rm } from "@effectionx/fs"; +import { spawn as spawnChild } from "node:child_process"; +import type { ChildProcess } from "node:child_process"; +import { createHash, randomUUID } from "node:crypto"; +import { chmod, copyFile, mkdir, mkdtemp, readdir, readFile, realpath } from "node:fs/promises"; +import { homedir, tmpdir } from "node:os"; +import { join } from "node:path"; +import { fileURLToPath } from "node:url"; +import process from "node:process"; +import { createEmbeddedAdapters, embeddedAdapterIdentities } from "../../src/adapter-snapshots.ts"; +import { ADVERTISED_NATIVE_LAUNCH } from "../../src/native-launch.ts"; +import { agentSessionKeyDigest } from "@executablemd/runtime"; +import type { AnswerQuestion, ScreenSnapshot, TerminalReader } from "./terminal-screen.ts"; +import { + presentedDuring, + terminalChannels, + terminalReader, + waitForPresented, +} from "./terminal-screen.ts"; +import type { StallClassification, SubmissionPort, SurfacePort } from "./codex-surfaces.ts"; +import type { SubmissionRefusal } from "./codex-surfaces.ts"; +import { + classifyInitialSurface, + classifyStall, + reachComposer, + refusalDetail, + SCREEN_CHROME, + submitWhenReady, +} from "./codex-surfaces.ts"; + +/** Opting in at all. Absent, every mode refuses before a Codex process. */ +const PROOF_ENV = "XMD_CODEX_NATIVE_PROOF"; +/** The separate, exact grant a mode that spends model turns needs. */ +const TURNS_ENV = "XMD_CODEX_MODEL_TURNS_AUTHORIZED"; + +/** The production target, exactly as an operator would type it. */ +const TARGET = "AGENTS.md#Implementor"; + +/** The document that reattaches to the launched session through ACP. */ +const ACP_DOCUMENT = fileURLToPath(new URL("./codex-native-to-acp-prompt.md", import.meta.url)); + +/** + * The compatibility point these journeys are only meaningful against + * (`issue-755-codex-materialization-turn-implementor-handoff.md`). + * + * Frozen rather than read from the machine, because the whole claim is that one + * exact build was proven. A run against another build is not a weaker pass; it + * is a different question, and it says so. + */ +const REQUIRED_PLATFORM = "darwin"; +const REQUIRED_ARCHITECTURE = "arm64"; +const REQUIRED_CODEX_VERSION = "codex-cli 0.153.2"; +const REQUIRED_CODEX_DIGEST = "195ace4100a634a9df39147f493e730e666b5bd87795f3c9f3251d8542400424"; +const REQUIRED_ADAPTER_PACKAGE = "@agentclientprotocol/codex-acp"; +const REQUIRED_ADAPTER_VERSION = "1.6.2"; +const REQUIRED_ADAPTER_DIGEST = "3ee22bc6b1649d02fcef80b352516f395fe774e63b459193195a41c42930dd8b"; + +/** The one prompt version a Codex launch may spend a turn on. */ +const PROMPT_VERSION = "codex-materialization.v1"; + +/** + * The role contract's opening sentence. + * + * Never sent to the model. It reaches the session only as the prepared + * instruction layer the launch installed, so a native answer carrying it is + * evidence the layer governed that turn — evidence that needs no test-only token + * planted in a production role document. + */ +const OPENING_SENTENCE = "The Implementor delivers an accepted plan as a focused, verified change."; + +/** What a recovered marker has to be wrapped in, so a repaint cannot supply it. */ +const RECALL_PREFIX = "RECOVERED-"; + +/** Rendered-output markers: one per role section, each unique to its section. */ +const IMPLEMENTOR_MARKER = "Running this target prepares the session"; +const SIBLING_MARKERS: readonly string[] = [ + ".agents/planner.md", + ".agents/architect.md", + "It has no contract document of its own", +]; + +const ENTER = "\r"; +const INTERRUPT = "\u0003"; +/** Two interrupts: the first asks the TUI to leave, the second insists. */ +const EXIT_CONTROL_BYTES = "0303"; + +/** + * How the one dialog Codex may put in front of a session is answered. + * + * It is not a conversation. It asks the person at the terminal for a standing + * permission — may Codex load project-local configuration from this directory — + * reaches no model and creates no user turn, so answering it is terminal control + * and is reported on its own channel. The answer is the pre-selected + * `1. Yes, continue` the dialog itself offers. + */ +const TRUST_SURFACE = "directory-trust"; +const TRUST_BYTES = "0d"; + +/** What Codex prints as it leaves, naming the conversation it was in. */ +const SESSION_ID_LINE = /Session ID:\s*([0-9a-fA-F-]{36})/u; + +/** What XMD says on the terminal before it spends the reader's model turn. */ +const NOTICE_BEFORE = "spending one model turn in session"; +/** And what it says once that turn has been spent. */ +const NOTICE_AFTER = "materialization turn completed in"; + +/** + * Environment names an enclosing coding-agent session exports. + * + * A proof that runs inside one inherits them, and a provider behaves + * differently when it does. `CODEX_PATH` in particular is the variable XMD's own + * binding sets for the adapter child, so inheriting one would let this process + * choose the build the product is supposed to resolve for itself. + */ +function inheritedAgentMarker(name: string): boolean { + return ( + name === "CLAUDECODE" || + name === "CLAUDE_PID" || + name === "CLAUDE_EFFORT" || + name.startsWith("CLAUDE_CODE_") || + name.startsWith("CODEX_") + ); +} + +/** Every phase is bounded on its own, well inside the document's block timeout. */ +const VERSION_MS = 30_000; +const SURFACE_MS = 240_000; +/** + * How long one native answer is waited for. + * + * Twice the Claude proof's bound, because two Codex answers reached that one and + * the second was still showing a working state when the classifier read the + * screen afterwards. A bound is not a claim about the product: reaching it says + * this harness stopped waiting, and `answerSurface` says what was on screen. + */ +const ANSWER_MS = 600_000; +const SETTLE_MS = 120_000; +const DELETE_MS = 60_000; +const ADAPTER_MS = 120_000; +/** How long a surface is given to settle before a key is sent into it. */ +const SETTLE_DELAY_MS = 3_000; + +/** + * How long the composer is given to turn out to have a dialog over it. + * + * Codex draws the composer first and the trust dialog over it, so a reader that + * stops at the composer stops in front of a question nobody answered. This is + * the window in which that turns out to be what happened. + */ +const TRUST_GRACE_MS = 20_000; + +/** The pseudo-terminal's size. A zero-column terminal draws no TUI at all. */ +const PTY_ROWS = 40; +const PTY_COLUMNS = 120; + +type Mode = "preflight" | "zero-native-turn" | "native-launch"; + +/** + * The exact model-turn budget each mode may spend, and the value its grant must + * carry. + * + * `zero-native-turn` spends the one XMD-owned materialization turn and no native + * user turn — which is what "zero native turn" names. `native-launch` spends + * that one, plus the first native user turn, plus the ACP turn that asks the + * reattached session what the native turn said. + */ +const AUTHORIZED_TURNS: Readonly> = { + preflight: "0", + "zero-native-turn": "1", + "native-launch": "3", +}; + +/** + * `UNDECIDED` is the state a journey starts in and never ends in: it says the + * body classified nothing, which is the one state a decider may speak from. It + * is a distinct value rather than a reused failure so that a body which does + * classify — including one reporting that this harness stopped waiting — is not + * mistaken for one that stayed silent and then overruled. + */ +type Verdict = + | "UNDECIDED" + | "PASS" + | "REFUSED" + | "ENVIRONMENT_BLOCKED" + | "PRODUCT_FAILED" + | "HARNESS_FAILED"; + +class PhaseTimeout extends Error { + override name = "PhaseTimeout"; + constructor(readonly phase: string) { + super(`phase "${phase}" exceeded its bound`); + } +} + +/** Run `op` under a bound. The loser is halted with the surrounding scope. */ +function* bounded(phase: string, ms: number, op: () => Operation): Operation { + const outcome = yield* race([ + (function* (): Operation<{ done: true; value: T }> { + return { done: true, value: yield* op() }; + })(), + (function* (): Operation<{ done: false }> { + yield* sleep(ms); + return { done: false }; + })(), + ]); + if (!outcome.done) { + throw new PhaseTimeout(phase); + } + return outcome.value; +} + +/** A fixed-category description carrying no path, credential or transcript. */ +function classify(error: unknown): string { + if (error instanceof PhaseTimeout) { + return `timeout in ${error.phase}`; + } + if (error instanceof Error) { + return error.name; + } + return "unknown"; +} + +function isReachable(pid: number): boolean { + try { + process.kill(pid, 0); + return true; + } catch { + return false; + } +} + +function killed(pid: number): void { + try { + process.kill(pid, "SIGKILL"); + } catch { + // Already gone, which is the state this was asking for. + } +} + +function interrupted(pid: number): void { + try { + process.kill(pid, "SIGINT"); + } catch { + // Already gone. + } +} + +const TEARDOWN_GRACE_MS = 8_000; + +function settledWithin(pid: number, ms: number): Promise { + return new Promise((resolve) => { + const started = Date.now(); + const poll = () => { + if (!isReachable(pid) || Date.now() - started >= ms) { + resolve(); + return; + } + setTimeout(poll, 100); + }; + poll(); + }); +} + +/** Collapse every run of whitespace, so a TUI's own layout cannot hide a word. */ +function squeeze(text: string): string { + return text.replaceAll(/\s+/gu, ""); +} + +const CONTROL_SEQUENCE = + // deno-lint-ignore no-control-regex + /\x1B\[[0-9;?]*[ -\/]*[@-~]|\x1B\][^\x07\x1B]*(?:\x07|\x1B\\)|\x1B[()][B0]|\x1B[<>=]|[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/gu; + +/** + * The glyphs a TUI draws its frame out of. + * + * Codex wraps a long answer inside a bordered pane, so a sentence can arrive + * with a border between two of its words. No model emits these mid-sentence, + * so removing them recovers the text without letting anything else through. + */ +const FRAME_GLYPH = /[─-╿▀-▟]/gu; + +function readable(text: string): string { + return text.replaceAll(CONTROL_SEQUENCE, "").replaceAll(FRAME_GLYPH, ""); +} + +/** Whether `text` shows `marker`, ignoring the layout a TUI drew around it. */ +function shows(text: string, marker: string): boolean { + return squeeze(readable(text)).includes(squeeze(marker)); +} + +function isRecord(value: unknown): value is Record { + return typeof value === "object" && value !== null && !Array.isArray(value); +} + +interface ChildOutcome { + code: number | null; + signal: string | null; + stdout: string; + stderr: string; +} + +/** Every child a mode started, so cleanup can prove none outlived it. */ +type LiveSet = Set; + +/** Run one captured child to settlement. Never a TUI. */ +function runChild( + command: string, + args: string[], + options: { cwd: string; input?: string; live: LiveSet; env?: Record }, +): Operation { + return (function* (): Operation { + const settled = withResolvers(); + const failed = withResolvers(); + let child: ChildProcess | undefined; + + // Registered before the spawn: a halt between acquiring a process and + // registering its cleanup leaks the process. + yield* ensure(() => { + const running = child; + if (!running?.pid) { + return; + } + if (running.exitCode === null && running.signalCode === null) { + killed(running.pid); + } + options.live.delete(running.pid); + }); + + child = spawnChild(command, args, { + cwd: options.cwd, + stdio: ["pipe", "pipe", "pipe"], + ...(options.env === undefined ? {} : { env: options.env }), + }); + if (child.pid) { + options.live.add(child.pid); + } + let stdout = ""; + let stderr = ""; + child.stdout?.on("data", (chunk: Buffer) => { + stdout += chunk.toString(); + }); + child.stderr?.on("data", (chunk: Buffer) => { + stderr += chunk.toString(); + }); + child.once("error", (error: Error) => failed.reject(error)); + child.once("close", (code: number | null, signal: string | null) => { + if (child?.pid) { + options.live.delete(child.pid); + } + settled.resolve({ code, signal, stdout, stderr }); + }); + + if (options.input !== undefined) { + child.stdin?.write(options.input); + } + child.stdin?.end(); + + return yield* race([settled.operation, failed.operation]); + })(); +} + +/** + * A path this fixture may write into a generated shell command. + * + * Everything here is built from `tmpdir()`, the repository root and a UUID, so + * this can only fail if one of them holds a quote or a newline. Refusing is the + * only safe answer: a command assembled around one would run something else. + */ +function literal(path: string): string { + if (/['\n\r]/u.test(path)) { + throw new Error("a fixture path holds a character a shell command cannot carry safely"); + } + return `'${path}'`; +} + +/** + * One production command running under a sized pseudo-terminal. + * + * `` takes the run's foreground-terminal lease and refuses a + * host with no terminal, which is what a real operator gets and the reason this + * cannot be a piped child. `/usr/bin/script` is the terminal boundary, so no PTY + * dependency is added for a test. + * + * The size is set inside the pty and not by an environment variable, because a + * TUI asks the terminal rather than the environment. `script` leaves a pty at + * zero columns, and Codex draws nothing at all into one — a proof reading that + * empty screen would conclude the surface never appeared. + */ +interface Pty { + /** + * Wait until output arriving *since the last handled surface* satisfies + * `predicate`, then mark it handled. + * + * Windowed on purpose: a dialog that has already been answered stays in the + * buffer, and re-reading it would answer it twice. + */ + waitForAny( + name: string, + ms: number, + tags: readonly { tag: string; marker: string }[], + ): Operation; + /** + * Wait until the reconstructed screen is showing the expected answer. + * + * Separate from {@link waitForAny} because an answer is not a surface + * appearing in the byte stream. Codex addresses the cursor: it wraps, erases + * and redraws what it has already drawn, so the expectation can arrive split + * across rows, or be moved somewhere else by a later repaint, and the bytes + * retain text that is no longer on the screen at all. The bytes are applied to + * a terminal here and the terminal is what gets read. + * + * Available only to a run that submits a turn. A run that spoke none has no + * reply to attribute, and its reader refuses to be asked for one. + */ + waitForAnswer(ms: number, question: AnswerQuestion): Operation; + /** + * Wait until what the terminal is *showing* satisfies `predicate`, and answer + * with the frame that did. + * + * The stream answers a different question than the screen does, and every + * surface decision is a question about the screen: bytes that drew a composer + * are retained after a dialog was drawn over it, bytes that drew a refusal are + * retained after a repaint wiped it, and a frame held back by `CSI ?2026h` has + * arrived without having been shown to anybody. + * + * The frames rather than a flag, because one `data` event from the pty applies + * every frame its bytes finished before anybody out here is woken. A caller + * told only that a surface arrived would look at the screen and find whatever + * that read ended on, which for a refusal Codex repaints over is a composer. + * + * Every frame that matched rather than the first, because a wait is answered + * by a read and not by a frame: what satisfied it first is one of the things + * that read presented, and the caller is the only thing that knows which of + * them it was actually asking about. + * + * Empty when the bound is spent, because a surface that never arrived is + * something to report rather than an error. + */ + waitForScreen( + name: string, + ms: number, + predicate: (snapshot: ScreenSnapshot) => boolean, + ): Operation; + /** + * Wait out a fixed delay, and answer with what was presented during it. + * + * Nothing shortens it — that is what makes it a delay rather than a wait — but + * the terminal does not stop drawing because a driver has stopped looking, so + * the same answer a wait gives is owed here too. A caller reading the screen + * once the delay is out is asking what survived it, which is a different + * question from what happened during it. + */ + pause( + ms: number, + predicate: (snapshot: ScreenSnapshot) => boolean, + ): Operation; + /** Whether everything seen so far contains `marker`, layout ignored. */ + saw(marker: string): boolean; + /** The first match of `pattern` anywhere in what has been drawn. */ + captured(pattern: RegExp): string; + /** What the terminal last presented. Never a frame still being drawn. */ + screen(): ScreenSnapshot; + /** Write terminal-control bytes — never conversation. */ + control(bytes: string): void; + /** + * Type one conversation turn, without sending it. + * + * Separate from `send()` because a TUI reads text and a newline arriving + * together as a pasted line rather than as a submitted one — the newline lands + * in the box and nothing is sent. + */ + type(text: string): void; + /** Press Enter. Charged here: this is the keystroke that spends the turn. */ + send(typed: string): void; + /** Wait for the process to leave. */ + settle(ms: number): Operation; + exitCode(): number; +} + +/** + * The three input channels, kept apart because they mean different things — + * and each recorded at the moment it is written. + * + * These are callbacks rather than counters a caller reads afterwards, because + * the phase that sends a turn is also the phase that can time out. A run that + * spent a turn and then hung must still report the turn. + */ +interface PtyChannels { + /** One conversation turn was submitted: this many bytes, and one turn. */ + charged(bytes: number): void; + /** A consent dialog was answered with these bytes. Never a conversation. */ + consented(surface: string, bytes: string): void; + /** Exit control was sent. */ + exited(bytes: string): void; +} + +function ptyRun( + command: string, + args: string[], + options: { + cwd: string; + env: Record; + live: LiveSet; + channels: PtyChannels; + /** + * The terminal this run draws on, supplied by its caller. + * + * Every run gets one, because every run decides which surface it is looking + * at and that is a fact about the screen rather than about the bytes. + * Whether it also watches for an answer is stated at the call site, so a + * reply can only be attributed by a run that submitted a turn. + */ + reader: TerminalReader; + }, + body: (pty: Pty) => Operation, +): Operation { + return scoped(function* (): Operation { + const settled = withResolvers(); + const failed = withResolvers(); + let child: ChildProcess | undefined; + let text = ""; + let consumed = 0; + let code = -1; + // The waiter reports which tag it saw rather than only that it saw one, so + // the tag it answers with is the one the screen actually showed. + let pending: + | { match: (fresh: string) => string | undefined; resolve: (tag: string) => void } + | undefined; + let answered: (() => void) | undefined; + + // Interrupt, then insist. A harness that reaches straight for SIGKILL takes + // away the product's chance to retain its own exit and then reports what it + // stranded as a product failure. + yield* ensure(function* () { + const running = child; + if (!running?.pid) { + return; + } + if (running.exitCode === null && running.signalCode === null) { + interrupted(running.pid); + yield* until(settledWithin(running.pid, TEARDOWN_GRACE_MS)); + if (isReachable(running.pid)) { + killed(running.pid); + } + } + options.live.delete(running.pid); + }); + + const line = [ + `stty rows ${PTY_ROWS} columns ${PTY_COLUMNS}`, + `exec ${[command, ...args].map(literal).join(" ")}`, + ].join("; "); + child = spawnChild("/usr/bin/script", ["-q", "/dev/null", "/bin/sh", "-c", line], { + cwd: options.cwd, + env: options.env, + stdio: ["pipe", "pipe", "pipe"], + }); + if (child.pid) { + options.live.add(child.pid); + } + + // Everything the run said, whichever channel said it. Surface detection + // reads this, because a surface arriving is a thing the stream says. + const record = (chunk: string | Uint8Array) => { + text += typeof chunk === "string" ? chunk : Buffer.from(chunk).toString("utf8"); + const waiter = pending; + if (!waiter) { + return; + } + const tag = waiter.match(text.slice(consumed)); + if (tag === undefined) { + return; + } + pending = undefined; + consumed = text.length; + waiter.resolve(tag); + }; + const channels = terminalChannels(record, options.reader); + + // Only stdout went through the pty, so only stdout is what the terminal + // showed. `script` and the shell beneath it report their own troubles on + // stderr, which reached this process without ever being displayed — + // evidence about the run, and not a thing anybody could have read on screen. + // Screen waits are woken from inside the reader, at the commit that answered + // them, rather than out here once a whole read has been applied. Where a + // read carried several finished frames, out here is too late to tell them + // apart: only the last one is still on the screen. + child.stdout?.on("data", (chunk: Buffer) => { + if (channels.display(chunk) && answered !== undefined) { + const resolve = answered; + answered = undefined; + resolve(); + } + }); + child.stderr?.on("data", (chunk: Buffer) => { + channels.diagnostic(chunk); + }); + child.once("error", (error: Error) => failed.reject(error)); + child.once("close", (status: number | null) => { + code = status ?? -1; + if (child?.pid) { + options.live.delete(child.pid); + } + settled.resolve(); + }); + + const write = (bytes: string) => { + // Everything already on screen belongs to the surface being answered, so + // the next wait reads only what this write provoked. + consumed = text.length; + child?.stdin?.write(bytes); + }; + + const pty: Pty = { + waitForAny(name, ms, tags) { + return bounded(name, ms, function* (): Operation { + const match = (fresh: string): string | undefined => + tags.find((entry) => shows(fresh, entry.marker))?.tag; + const already = match(text.slice(consumed)); + if (already !== undefined) { + consumed = text.length; + return already; + } + const waiter = withResolvers(); + pending = { match, resolve: waiter.resolve }; + return yield* race([waiter.operation, failed.operation]); + }); + }, + waitForAnswer(ms, question) { + return bounded("answer", ms, function* (): Operation { + // Arming answers against what is already showing, because the reply + // can be complete before this is reached and no further byte arrive. + // A reader that is not watching refuses the question outright. + if (options.reader.ask(question)) { + return; + } + const waiter = withResolvers(); + answered = waiter.resolve; + yield* race([waiter.operation, failed.operation]); + }); + }, + waitForScreen(name, ms, predicate) { + return waitForPresented(options.reader, predicate, function* (wait): Operation { + try { + yield* bounded(name, ms, () => race([wait.matched, failed.operation])); + } catch (error) { + if (!(error instanceof PhaseTimeout)) { + throw error; + } + // A bound that ran out is a surface that never arrived, which the + // caller reports rather than raises. + } + }); + }, + pause(ms, predicate) { + return presentedDuring(options.reader, predicate, sleep(ms)); + }, + saw(marker) { + return shows(text, marker); + }, + captured(pattern) { + return readable(text).match(pattern)?.[1] ?? ""; + }, + screen() { + return options.reader.snapshot(); + }, + control(bytes) { + write(bytes); + }, + type(spoken) { + write(spoken); + }, + send(typed) { + // Charged before the write returns, so an answer that never arrives + // cannot make this look like a turn nobody spent. + options.channels.charged(Buffer.byteLength(`${typed}${ENTER}`, "utf8")); + write(ENTER); + }, + settle(ms) { + return bounded("settle", ms, () => race([settled.operation, failed.operation])); + }, + exitCode: () => code, + }; + + return yield* body(pty); + }); +} + +/** One journey's owned paths. Every removal below names an exact one. */ +interface Journey { + root: string; + /** Canonical, because a launch records the directory it resolved. */ + project: string; + journals: [string, string, string]; + live: LiveSet; + codex: string; + /** Every native identity this journey caused to exist, for exact deletion. */ + created: Set; +} + +interface CleanupReport { + liveChildren: number; + journalsRemoved: boolean; + routeRecordsRemoved: boolean; + sessionDeleteOutcome: string; + temporaryRootRemoved: boolean; +} + +/** What one production invocation established. */ +interface InvocationOutcome { + exitCode: number; + refused: boolean; + reachedSurface: boolean; + answered: boolean; + /** + * What a turn without an answer was showing, and what that makes the run. + * + * Read off the presented screen by {@link classifyStall} and kept whole. The + * verdict travels with the tag rather than being derived from it later, + * because a tag alone is a label this fixture could have written down itself. + */ + answerStall: StallClassification | undefined; + /** + * Why no turn was submitted, when none was. + * + * Set only by a run that reached the composer and then declined to type into + * it or to press Enter. It is the state that keeps a readiness failure from + * being read as an answer that never came: nothing was asked, so nothing + * about the product was established and nothing was charged. + */ + submissionRefusal: SubmissionRefusal | undefined; + /** The identity Codex named as it left, from its own output. */ + leftSessionId: string; + noticedBeforeSpending: boolean; + noticedAfterSpending: boolean; +} + +interface TurnPlan { + /** What to say once the composer is ready, or nothing at all. */ + say?: string; + /** What proves the answer arrived. */ + expect?: string; +} + +/** The one verdict shape every mode renders, exactly. */ +interface JourneyVerdict { + mode: string; + verdict: Verdict; + authorized: boolean; + turnsAuthorized: boolean; + authorizedTurnBudget: number; + ran: boolean; + refusal: string; + detail: string; + + codexVersion: string; + codexDigest: string; + platform: string; + architecture: string; + adapterPackage: string; + adapterVersion: string; + adapterDigest: string; + compatibilityTupleFrozen: boolean; + + target: string; + projectCopyVerified: boolean; + implementorMarkerRendered: boolean; + siblingMarkersRendered: number; + + nativeSessionId: string; + identityProvenance: string; + reentryNativeSessionId: string; + substitutedIdentity: boolean; + routeConverted: boolean; + + firstXmdExitCode: number; + secondXmdExitCode: number; + instructionChannel: string; + + /** Every model turn this journey caused, however it was caused. */ + modelTurns: number; + materializationTurns: number; + nativeUserTurns: number; + acpReattachTurns: number; + /** How many of this journey's invocations reconstructed a terminal at all. */ + answerObserverInvocations: number; + conversationInputByteCount: number; + consentInputBytes: string; + consentSurfaces: string[]; + exitControlBytes: string; + reentryConsentInputBytes: string; + reentryConsentSurfaces: string[]; + reentryExitControlBytes: string; + inheritedAgentMarkersRemoved: number; + + noticedBeforeSpending: boolean; + noticedAfterSpending: boolean; + openingSentenceExact: boolean; + markerRecovered: boolean; + acpDocumentCarriesMarker: boolean; + answerSurface: string; + outcome: string; + + materialization: { + promptVersion: string; + requestIdStable: boolean; + promptExact: boolean; + turnNamed: boolean; + turnProvider: string; + durationReported: boolean; + responsePresent: boolean; + stopReason: string; + reportedUsageFields: string[]; + unreportedUsageFields: string[]; + failureClasses: string[]; + }; + route: { + kind: string; + provider: string; + buildVersion: string; + buildDigest: string; + }; + journal: { + provider: string; + agent: string; + launcher: string; + provenance: string; + nativeSessionId: string; + cwdIsProject: boolean; + sessionState: string[]; + instructionsDigestPresent: boolean; + firstPhases: string[]; + secondPhases: string[]; + failureClasses: string[]; + }; + cleanup: CleanupReport; + privateStateInspected: boolean; +} + +function blankJourney(mode: Mode): JourneyVerdict { + return { + mode, + verdict: "UNDECIDED", + authorized: false, + turnsAuthorized: false, + authorizedTurnBudget: Number(AUTHORIZED_TURNS[mode]), + ran: false, + refusal: "", + detail: "the journey did not reach a verdict", + codexVersion: "", + codexDigest: "", + platform: process.platform, + architecture: process.arch, + adapterPackage: "", + adapterVersion: "", + adapterDigest: "", + compatibilityTupleFrozen: false, + target: TARGET, + projectCopyVerified: false, + implementorMarkerRendered: false, + siblingMarkersRendered: 0, + nativeSessionId: "", + identityProvenance: "", + reentryNativeSessionId: "", + substitutedIdentity: false, + routeConverted: false, + firstXmdExitCode: -1, + secondXmdExitCode: -1, + instructionChannel: "", + modelTurns: 0, + materializationTurns: 0, + nativeUserTurns: 0, + acpReattachTurns: 0, + answerObserverInvocations: 0, + conversationInputByteCount: 0, + consentInputBytes: "", + consentSurfaces: [], + exitControlBytes: "", + reentryConsentInputBytes: "", + reentryConsentSurfaces: [], + reentryExitControlBytes: "", + inheritedAgentMarkersRemoved: 0, + noticedBeforeSpending: false, + noticedAfterSpending: false, + openingSentenceExact: false, + markerRecovered: false, + acpDocumentCarriesMarker: false, + answerSurface: "", + outcome: "unresolved", + materialization: { + promptVersion: "", + requestIdStable: false, + promptExact: false, + turnNamed: false, + turnProvider: "", + durationReported: false, + responsePresent: false, + stopReason: "", + reportedUsageFields: [], + unreportedUsageFields: [], + failureClasses: [], + }, + route: { + kind: "", + provider: "", + buildVersion: "", + buildDigest: "", + }, + journal: { + provider: "", + agent: "", + launcher: "", + provenance: "", + nativeSessionId: "", + cwdIsProject: false, + sessionState: [], + instructionsDigestPresent: false, + firstPhases: [], + secondPhases: [], + failureClasses: [], + }, + cleanup: { + liveChildren: 0, + journalsRemoved: false, + routeRecordsRemoved: false, + sessionDeleteOutcome: "nothing-to-delete", + temporaryRootRemoved: false, + }, + privateStateInspected: false, + }; +} + +const REPO_ROOT = fileURLToPath(new URL("../../../..", import.meta.url)); +const XMD_BINARY = join(REPO_ROOT, "dist", "xmd"); +const SESSION_COORDINATOR_ROOT = join(homedir(), ".acpx", "xmd-native-sessions", "v1"); +/** Where the binary under proof materializes the adapters it carries. */ +const ADAPTER_ROOT = join(homedir(), ".xmd", "adapters"); + +/** + * The exact absolute paths one natural key owns, and nothing else. + * + * The natural key includes the agent command, and for a launch through this + * build's own adapter that is the embedded snapshot's command line — settled by + * the bytes the build carries, beneath the root the binary uses, so it is + * knowable here without opening anything. Deriving it through the product's own + * digest rather than searching for a record that matches means this reads only + * the three files this journey's key owns, and never another key's. + */ +function keyPaths(sessionKey: string): string[] { + const agent = createEmbeddedAdapters(ADAPTER_ROOT).command("codex"); + const digest = agentSessionKeyDigest({ provider: "acpx", agent, sessionKey }); + return [ + join(SESSION_COORDINATOR_ROOT, "routes", `${digest}.json`), + join(SESSION_COORDINATOR_ROOT, "ownership", `${digest}.json`), + join(SESSION_COORDINATOR_ROOT, "leases", `${digest}.lease`), + ]; +} + +interface LaunchRecord { + phase: string; + agent?: string; + sessionKey?: string; + provider?: string; + nativeSessionId?: string; + sessionState?: string; + instructionChannel?: string; + identityProvenance?: string; + instructionsDigest?: string; + instructions?: string; + cwd?: string; + launcher?: string; + executableBinding?: { + reportedVersion?: string; + executableDigest?: { value?: string }; + }; + materialization?: { promptVersion?: string; requestId?: string; prompt?: string }; + promptVersion?: string; + requestId?: string; + turn?: { provider?: string; kind?: string; value?: string }; + durationMs?: number; + usage?: Record; + response?: string; + stopReason?: string; + failure?: { class?: string }; +} + +/** A member of an untrusted record, kept only if it is already text. */ +function textOf(source: Record, member: string): string | undefined { + const value = source[member]; + return typeof value === "string" ? value : undefined; +} + +/** The same for a member that is itself read through its own members. */ +function recordOf( + source: Record, + member: string, +): Record | undefined { + const value = source[member]; + return isRecord(value) ? value : undefined; +} + +/** + * One launch record, read out of a journal this fixture did not write. + * + * Every member is taken at the type a verdict reads it at and dropped + * otherwise, so a journal line that carries the wrong shape reaches a verdict + * as an absent member rather than as a value of a type it never held. + */ +function parseLaunchRecord(source: Record): LaunchRecord | undefined { + const phase = textOf(source, "phase"); + if (phase === undefined) { + return undefined; + } + const materialization = recordOf(source, "materialization"); + const turn = recordOf(source, "turn"); + const failure = recordOf(source, "failure"); + const durationMs = source["durationMs"]; + return { + phase, + agent: textOf(source, "agent"), + sessionKey: textOf(source, "sessionKey"), + provider: textOf(source, "provider"), + nativeSessionId: textOf(source, "nativeSessionId"), + sessionState: textOf(source, "sessionState"), + instructionChannel: textOf(source, "instructionChannel"), + identityProvenance: textOf(source, "identityProvenance"), + instructionsDigest: textOf(source, "instructionsDigest"), + instructions: textOf(source, "instructions"), + cwd: textOf(source, "cwd"), + launcher: textOf(source, "launcher"), + promptVersion: textOf(source, "promptVersion"), + requestId: textOf(source, "requestId"), + response: textOf(source, "response"), + stopReason: textOf(source, "stopReason"), + durationMs: typeof durationMs === "number" ? durationMs : undefined, + usage: recordOf(source, "usage"), + materialization: materialization && { + promptVersion: textOf(materialization, "promptVersion"), + requestId: textOf(materialization, "requestId"), + prompt: textOf(materialization, "prompt"), + }, + turn: turn && { + provider: textOf(turn, "provider"), + kind: textOf(turn, "kind"), + value: textOf(turn, "value"), + }, + failure: failure && { class: textOf(failure, "class") }, + }; +} + +/** + * The launch records one diagnostic journal holds, in order. + * + * A retained preparation carries the prepared instruction text, so this reads it + * and nothing that reaches a verdict repeats it: what crosses out of here is + * whether a digest exists, never the text or the digest's own bytes. + */ +function* readLaunchRecords(path: string): Operation { + if (!(yield* exists(path))) { + return []; + } + const text = yield* until(readFile(path, "utf8")); + const records: LaunchRecord[] = []; + for (const line of text.split("\n")) { + if (line.trim().length === 0) { + continue; + } + let event: unknown; + try { + event = JSON.parse(line); + } catch { + continue; + } + if (!isRecord(event) || event.type !== "yield" || !isRecord(event.description)) { + continue; + } + if (event.description.type !== "agent_session_launch") { + continue; + } + const result = event.result; + if (!isRecord(result) || result.status !== "ok" || !isRecord(result.value)) { + continue; + } + const record = parseLaunchRecord(result.value); + if (record) { + records.push(record); + } + } + return records; +} + +/** + * Establish one journey's root and byte-for-byte project copy. + * + * Teardown is registered as the root appears, and it is the last thing to run: + * every child is reaped, every conversation this journey created is removed + * through Codex's own `delete`, and the root goes last. The durable accounts are + * read by a finalizer the caller registers afterwards, which LIFO puts *before* + * this one. + */ +function* useJourney(label: string, cleanup: CleanupReport): Operation { + const root = join(tmpdir(), `xmd-755-${label}-${randomUUID()}`); + yield* until(mkdir(root, { recursive: true, mode: 0o700 })); + yield* until(chmod(root, 0o700)); + + const project = join(root, "project"); + yield* until(mkdir(join(project, ".agents"), { recursive: true, mode: 0o700 })); + + const journey: Journey = { + root, + // A launch records the directory it resolved, and on macOS a temporary root + // reaches it through a symlink. Comparing the unresolved spelling would call + // the same directory two different ones. + project: yield* until(realpath(project)), + journals: [ + join(root, "journal-1.jsonl"), + join(root, "journal-2.jsonl"), + join(root, "journal-3.jsonl"), + ], + live: new Set(), + codex: "", + created: new Set(), + }; + + yield* ensure(function* () { + for (const pid of journey.live) { + killed(pid); + } + cleanup.liveChildren = [...journey.live].filter(isReachable).length; + + // Codex's own delete, never manual removal of provider state, and only for + // the exact identities this journey caused to exist. `--force`, because a + // delete that stops to ask has nobody to answer it here and would strand + // the conversation this journey is accountable for. + let outcome = journey.created.size === 0 ? "nothing-to-delete" : "deleted"; + for (const id of journey.created) { + const removed = yield* bounded("session-delete", DELETE_MS, () => + runChild(journey.codex, ["delete", "--force", id], { + cwd: root, + live: journey.live, + input: "", + }), + ); + // A forced delete answers the same way whether the conversation was never + // there or could not be removed, so anything but success is reported as a + // failure rather than guessed at from a message that says neither. + if (removed.code !== 0) { + outcome = "failed"; + } + } + cleanup.sessionDeleteOutcome = outcome; + + yield* rm(journey.root, { recursive: true, force: true }); + cleanup.temporaryRootRemoved = !(yield* exists(journey.root)); + }); + + return journey; +} + +/** Copy the checked-in role documents, and prove the copy is the original. */ +function* copyProject(journey: Journey): Operation { + let identical = true; + for (const relative of ["AGENTS.md", join(".agents", "implementor.md")]) { + const from = join(REPO_ROOT, relative); + const to = join(journey.project, relative); + yield* until(copyFile(from, to)); + const before = createHash("sha256") + .update(yield* until(readFile(from))) + .digest("hex"); + const after = createHash("sha256") + .update(yield* until(readFile(to))) + .digest("hex"); + identical &&= before === after; + } + return identical; +} + +/** + * The environment the production command runs under: an operator's, not this + * process's. + * + * Everything an enclosing coding-agent session exported is dropped, and the + * count is reported. + */ +/** The host environment, at the string-valued shape a child is given. */ +function hostEnvironment(): Record { + const inherited: Record = {}; + for (const [name, value] of Object.entries(process.env)) { + if (typeof value === "string") { + inherited[name] = value; + } + } + return inherited; +} + +function environmentFor(verdict: JourneyVerdict): Record { + const inherited: Record = {}; + let removed = 0; + for (const [name, value] of Object.entries(hostEnvironment())) { + if (inheritedAgentMarker(name)) { + removed += 1; + continue; + } + inherited[name] = value; + } + verdict.inheritedAgentMarkersRemoved = removed; + return inherited; +} + +function xmdArguments(document: string, journal: string): string[] { + return ["run", document, "--default-agent", "codex", "--journal", journal, "--raw"]; +} + +/** + * The pty, as the shared surface driver reads and answers it. + * + * `consent` is the only thing here that writes, and it writes the dialog's + * pre-selected answer while recording it as consent on its own channel. There + * is no way through this port to type or to spend a conversation turn. + */ +function surfacePort(pty: Pty, channels: PtyChannels): SurfacePort { + return { + screen: () => pty.screen(), + waitForScreen: (name, ms, predicate) => pty.waitForScreen(name, ms, predicate), + consent() { + channels.consented(TRUST_SURFACE, TRUST_BYTES); + pty.control(ENTER); + }, + pause: (ms, predicate) => pty.pause(ms, predicate), + }; +} + +/** The bounds every surface reader in this proof is given. */ +const SURFACE_BOUNDS = { + surface: SURFACE_MS, + settle: SETTLE_DELAY_MS, + grace: TRUST_GRACE_MS, +}; + +/** + * Answer the trust dialog if it is presented, then establish the composer. + * + * Every decision belongs to {@link reachComposer}, which reads only presented + * screens; this records what it decided against the invocation. + */ +function* reachSurface( + pty: Pty, + channels: PtyChannels, + outcome: InvocationOutcome, +): Operation { + const reached = yield* reachComposer(surfacePort(pty, channels), SURFACE_BOUNDS); + // Codex was handed an identity it has no saved session for. That is the + // exact refusal this whole feature exists to avoid, and it is reported + // rather than driven around. + outcome.refused = reached === "missing-session"; + outcome.reachedSurface = reached === "composer-ready"; +} + +/** + * The pty, at the width submitting a turn needs. + * + * A named adapter rather than an inline object, so the shape the offline cases + * implement is the shape the paid run supplies. + */ +function submissionPort(pty: Pty): SubmissionPort { + return { + screen: () => pty.screen(), + // Handed on whole. Codex draws its refusal above a composer rather than in + // place of one, so the frames satisfying a readiness wait are exactly the + // frames a refusal can be sitting in, and this is the last port before + // Enter. + waitForScreen: (name, ms, predicate) => pty.waitForScreen(name, ms, predicate), + type: (text) => pty.type(text), + send: (typed) => pty.send(typed), + pause: (ms, predicate) => pty.pause(ms, predicate), + }; +} + +/** Drive one process from its opening surface to its exit. */ +function* drive( + pty: Pty, + plan: TurnPlan, + channels: PtyChannels, + outcome: InvocationOutcome, +): Operation { + // Read before the surface, because the notice is printed while XMD still owns + // the terminal and the TUI draws over it afterwards. + yield* reachSurface(pty, channels, outcome); + outcome.noticedBeforeSpending = pty.saw(NOTICE_BEFORE); + outcome.noticedAfterSpending = pty.saw(NOTICE_AFTER); + + if (outcome.refused) { + yield* pty.settle(SETTLE_MS); + outcome.leftSessionId = pty.captured(SESSION_ID_LINE); + return; + } + + if (plan.say !== undefined && plan.expect !== undefined && outcome.reachedSurface) { + // Typed, then confirmed on screen, then submitted — which is what a person + // does, and what stops a TUI reading the whole thing as a pasted line. Every + // reading is of the screen rather than the stream, because a composer whose + // bytes have arrived can be underneath a dialog, behind a model that has not + // loaded, or inside a frame nobody was shown. + const submission = yield* submitWhenReady(submissionPort(pty), plan.say, { + ready: SURFACE_MS, + startupGrace: SETTLE_DELAY_MS, + presented: VERSION_MS, + }); + if (!submission.submitted) { + outcome.submissionRefusal = submission.reason; + // A refusal read while the turn was being readied is the same finding + // reaching a composer reports, arriving later than its bound was willing + // to wait. It belongs to the product rather than to this harness, and + // recording it as one keeps a refused session from being reported as a + // proof that could not get a turn typed. + outcome.refused ||= submission.reason === "session-refused"; + } else { + try { + yield* pty.waitForAnswer(ANSWER_MS, { + expected: plan.expect, + typed: plan.say, + chrome: SCREEN_CHROME, + }); + outcome.answered = true; + } catch (error) { + if (!(error instanceof PhaseTimeout)) { + throw error; + } + outcome.answerStall = classifyStall(pty.screen()); + } + } + } + + yield* sleep(SETTLE_DELAY_MS); + channels.exited(EXIT_CONTROL_BYTES); + pty.control(INTERRUPT); + yield* sleep(SETTLE_DELAY_MS); + pty.control(INTERRUPT); + try { + yield* pty.settle(SETTLE_MS); + } catch (error) { + if (!(error instanceof PhaseTimeout)) { + throw error; + } + } + outcome.leftSessionId = pty.captured(SESSION_ID_LINE); +} + +function* invoke( + journey: Journey, + verdict: JourneyVerdict, + index: 0 | 1, + plan: TurnPlan, +): Operation { + const first = index === 0; + const channels: PtyChannels = { + charged(bytes) { + verdict.conversationInputByteCount += bytes; + verdict.nativeUserTurns += 1; + verdict.modelTurns += 1; + }, + consented(surface, bytes) { + if (first) { + verdict.consentSurfaces = [...verdict.consentSurfaces, surface]; + verdict.consentInputBytes += bytes; + return; + } + verdict.reentryConsentSurfaces = [...verdict.reentryConsentSurfaces, surface]; + verdict.reentryConsentInputBytes += bytes; + }, + exited(bytes) { + if (first) { + verdict.exitControlBytes = bytes; + return; + } + verdict.reentryExitControlBytes = bytes; + }, + }; + const outcome: InvocationOutcome = { + exitCode: -1, + refused: false, + reachedSurface: false, + answered: false, + answerStall: undefined, + submissionRefusal: undefined, + leftSessionId: "", + noticedBeforeSpending: false, + noticedAfterSpending: false, + }; + + // Built from what this invocation does. Every invocation reads a screen, so + // every invocation reconstructs a terminal; only the one that submits the + // turn may watch it for a reply. Re-entry carrying an expectation would be a + // mistake, and is refused there rather than watched. + const reader = terminalReader({ rows: PTY_ROWS, columns: PTY_COLUMNS }, { index, ...plan }); + if (reader.watching) { + verdict.answerObserverInvocations += 1; + } + + yield* ptyRun( + XMD_BINARY, + xmdArguments(TARGET, journey.journals[index]), + { + cwd: journey.project, + env: environmentFor(verdict), + live: journey.live, + channels, + reader, + }, + function* (pty): Operation { + yield* drive(pty, plan, channels, outcome); + verdict.implementorMarkerRendered ||= pty.saw(IMPLEMENTOR_MARKER); + verdict.siblingMarkersRendered += SIBLING_MARKERS.filter((marker) => pty.saw(marker)).length; + outcome.exitCode = pty.exitCode(); + }, + ); + return outcome; +} + +/** Every usage field the contract knows, so absence can be reported by name. */ +const USAGE_FIELDS: readonly string[] = [ + "inputTokens", + "outputTokens", + "cachedReadTokens", + "cachedWriteTokens", + "thoughtTokens", + "totalTokens", + "costAmount", + "costCurrency", +]; + +/** + * Read the durable accounts, then remove exactly what this journey owns. + * + * Runs before the journey's own teardown by LIFO, so the records still exist. + */ +function* settleAccounts(journey: Journey, verdict: JourneyVerdict): Operation { + const first = yield* readLaunchRecords(journey.journals[0]); + const second = yield* readLaunchRecords(journey.journals[1]); + const third = yield* readLaunchRecords(journey.journals[2]); + const all = [...first, ...second, ...third]; + + verdict.journal.firstPhases = first.map((record) => record.phase); + verdict.journal.secondPhases = second.map((record) => record.phase); + verdict.journal.failureClasses = all + .map((record) => record.failure?.class) + .filter((value): value is string => typeof value === "string"); + verdict.journal.sessionState = all + .map((record) => record.sessionState) + .filter((value): value is string => typeof value === "string"); + + // A launch that owes a materialization turn prepares no identity, so the turn + // that made the conversation real is the only place its name was written down. + // A launch that owed none prepared the name it resumed. + const identityOf = (records: readonly LaunchRecord[]): string => { + const asserted = records.find( + (record) => record.phase === "materialized" && (record.nativeSessionId ?? "").length > 0, + ); + if (asserted?.nativeSessionId !== undefined) { + return asserted.nativeSessionId; + } + const prepared = records.find((record) => record.phase === "prepared"); + return prepared?.nativeSessionId ?? ""; + }; + + const prepared = all.filter((record) => record.phase === "prepared"); + const head = prepared[0]; + if (head) { + verdict.journal.provider = head.provider ?? ""; + verdict.journal.agent = head.agent ?? ""; + verdict.journal.launcher = head.launcher ?? ""; + verdict.journal.provenance = head.identityProvenance ?? ""; + verdict.journal.nativeSessionId = identityOf(first); + verdict.journal.cwdIsProject = head.cwd === journey.project; + verdict.journal.instructionsDigestPresent = typeof head.instructionsDigest === "string"; + verdict.nativeSessionId = identityOf(first); + verdict.identityProvenance = head.identityProvenance ?? ""; + verdict.instructionChannel = head.instructionChannel ?? ""; + verdict.materialization.promptExact = + head.materialization?.prompt === MATERIALIZATION_PROMPT && + head.materialization.promptVersion === PROMPT_VERSION; + } + if (prepared[1]) { + verdict.reentryNativeSessionId = identityOf(second); + verdict.substitutedIdentity = + verdict.nativeSessionId.length > 0 && + verdict.reentryNativeSessionId.length > 0 && + verdict.nativeSessionId !== verdict.reentryNativeSessionId; + } + + // Cleanup is owed for every conversation this journey's own journals name, + // whichever phase asserted it, so a launch that prepared no identity still + // has the one its turn created removed. + for (const record of all) { + const named = record.nativeSessionId; + if (typeof named === "string" && named.length > 0) { + journey.created.add(named); + } + } + + // Every materialization the whole journey retained, however many invocations + // it took. This is the number the authorized budget is spent against. + const materialized = all.filter((record) => record.phase === "materialized"); + verdict.materializationTurns = materialized.length; + verdict.modelTurns += materialized.length; + const turn = materialized[0]; + if (turn) { + verdict.materialization.promptVersion = turn.promptVersion ?? ""; + verdict.materialization.requestIdStable = + typeof turn.requestId === "string" && + turn.requestId.length > 0 && + turn.requestId === head?.materialization?.requestId; + verdict.materialization.turnNamed = typeof turn.turn?.value === "string"; + verdict.materialization.turnProvider = turn.turn?.provider ?? ""; + verdict.materialization.durationReported = typeof turn.durationMs === "number"; + verdict.materialization.responsePresent = (turn.response ?? "").length > 0; + verdict.materialization.stopReason = turn.stopReason ?? ""; + const usage = turn.usage ?? {}; + verdict.materialization.reportedUsageFields = USAGE_FIELDS.filter( + (field) => usage[field] !== undefined, + ); + verdict.materialization.unreportedUsageFields = USAGE_FIELDS.filter( + (field) => usage[field] === undefined, + ); + } + verdict.materialization.failureClasses = materialized + .map((record) => record.failure?.class) + .filter((value): value is string => typeof value === "string"); + + const sessionKey = head?.sessionKey; + if (sessionKey !== undefined && sessionKey.length > 0) { + const paths = keyPaths(sessionKey); + const [route] = paths; + if (route !== undefined && (yield* exists(route))) { + const parsed: unknown = JSON.parse(yield* until(readFile(route, "utf8"))); + if (isRecord(parsed)) { + verdict.route.kind = typeof parsed.route === "string" ? parsed.route : ""; + verdict.route.provider = typeof parsed.provider === "string" ? parsed.provider : ""; + const binding = parsed.executableBinding; + if (isRecord(binding)) { + verdict.route.buildVersion = + typeof binding.reportedVersion === "string" ? binding.reportedVersion : ""; + const digested = binding.executableDigest; + verdict.route.buildDigest = + isRecord(digested) && typeof digested.value === "string" ? digested.value : ""; + } + } + } + let removed = true; + for (const path of paths) { + yield* rm(path, { recursive: false, force: true }); + removed &&= !(yield* exists(path)); + } + verdict.cleanup.routeRecordsRemoved = removed; + } else { + verdict.cleanup.routeRecordsRemoved = true; + } + verdict.routeConverted = verdict.route.kind !== "" && verdict.route.kind !== "acp-first"; + + let journalsGone = true; + for (const path of journey.journals) { + yield* rm(path, { recursive: false, force: true }); + journalsGone &&= !(yield* exists(path)); + } + verdict.cleanup.journalsRemoved = journalsGone; +} + +/** The exact prompt bytes an XMD-owned Codex turn may carry. */ +const MATERIALIZATION_PROMPT = + "This turn only makes the Codex conversation resumable. Do not perform the prepared " + + "task, inspect or modify files, call tools, or take any external action. Reply with a " + + "brief acknowledgement only."; + +/** Resolve the installed Codex, canonically, and hash exactly that file. */ +function* observeCodex(journey: Journey, verdict: JourneyVerdict): Operation { + const located = yield* bounded("resolve-codex", VERSION_MS, () => + runChild("/usr/bin/which", ["codex"], { cwd: journey.root, live: journey.live }), + ); + if (located.code !== 0 || located.stdout.trim().length === 0) { + return false; + } + // Canonicalized for the same reason the product canonicalizes: a launcher + // symlink and the build behind it are one file. + journey.codex = yield* until(realpath(located.stdout.trim())); + verdict.codexDigest = createHash("sha256") + .update(yield* until(readFile(journey.codex))) + .digest("hex"); + const reported = yield* bounded("codex-version", VERSION_MS, () => + runChild(journey.codex, ["--version"], { cwd: journey.root, live: journey.live }), + ); + verdict.codexVersion = reported.code === 0 ? reported.stdout.trim() : ""; + return true; +} + +/** The vendored adapter's own snapshot identity, from the product's own list. */ +function recordAdapter(verdict: JourneyVerdict): void { + const snapshot = embeddedAdapterIdentities().find((entry) => entry.provider === "codex"); + verdict.adapterPackage = snapshot?.package ?? ""; + verdict.adapterVersion = snapshot?.version ?? ""; + verdict.adapterDigest = snapshot?.sha256 ?? ""; +} + +/** Everything every journey establishes before it is allowed to launch. */ +function* ready(journey: Journey, verdict: JourneyVerdict): Operation { + if (!(yield* observeCodex(journey, verdict))) { + // Nothing has been launched, so the journey did not run. Saying otherwise + // would let a machine that cannot host the proof read as one that hosted it + // and found something. + verdict.ran = false; + verdict.verdict = "ENVIRONMENT_BLOCKED"; + verdict.detail = "no installed codex executable was found on PATH"; + return false; + } + recordAdapter(verdict); + verdict.compatibilityTupleFrozen = + verdict.platform === REQUIRED_PLATFORM && + verdict.architecture === REQUIRED_ARCHITECTURE && + verdict.codexVersion === REQUIRED_CODEX_VERSION && + verdict.codexDigest === REQUIRED_CODEX_DIGEST && + verdict.adapterPackage === REQUIRED_ADAPTER_PACKAGE && + verdict.adapterVersion === REQUIRED_ADAPTER_VERSION && + verdict.adapterDigest === REQUIRED_ADAPTER_DIGEST; + if (!verdict.compatibilityTupleFrozen) { + verdict.ran = false; + verdict.verdict = "ENVIRONMENT_BLOCKED"; + verdict.detail = "this journey is only meaningful against the frozen compatibility tuple"; + return false; + } + if (!verdict.projectCopyVerified) { + verdict.verdict = "HARNESS_FAILED"; + verdict.detail = "the project copy is not byte-identical to the checked-in role document"; + return false; + } + return true; +} + +/** + * Materialize once, leave without saying anything, and come back. + * + * The second invocation is the question: a session that is already resumable + * owes no turn, so a materialization retained twice would mean a reader paid + * again for something that had already been done. + */ +function* runZeroNativeTurn(journey: Journey, verdict: JourneyVerdict): Operation { + if (!(yield* ready(journey, verdict))) { + return; + } + + const first = yield* invoke(journey, verdict, 0, {}); + verdict.firstXmdExitCode = first.exitCode; + verdict.noticedBeforeSpending = first.noticedBeforeSpending; + verdict.noticedAfterSpending = first.noticedAfterSpending; + if (first.refused) { + verdict.verdict = "PRODUCT_FAILED"; + verdict.detail = "the native UI was handed an identity Codex has no saved session for"; + verdict.outcome = "no-session"; + return; + } + if (!first.reachedSurface) { + verdict.verdict = "HARNESS_FAILED"; + verdict.detail = "the first launch never reached a recognizable Codex surface"; + return; + } + + const second = yield* invoke(journey, verdict, 1, {}); + verdict.secondXmdExitCode = second.exitCode; + verdict.outcome = second.refused + ? "no-session" + : second.reachedSurface + ? "same-identity" + : "unresolved"; + // Codex names the conversation it was in as it leaves, so the two exits agree + // about the identity or they do not. + if ( + first.leftSessionId.length > 0 && + second.leftSessionId.length > 0 && + first.leftSessionId.toLowerCase() !== second.leftSessionId.toLowerCase() + ) { + verdict.substitutedIdentity = true; + } +} + +/** + * The full journey: one materialization turn, one native user turn under the + * prepared layer, and an ACP reattachment that can see what was said natively. + */ +function* runNativeLaunch( + journey: Journey, + verdict: JourneyVerdict, + marker: string, +): Operation { + if (!(yield* ready(journey, verdict))) { + return; + } + verdict.acpDocumentCarriesMarker = (yield* until(readFile(ACP_DOCUMENT, "utf8"))).includes( + marker, + ); + + // The question names neither the sentence nor any file, so a session without + // the prepared layer cannot answer it. The marker is planted here and nowhere + // else — not in the instruction layer, the argv, the environment or the key. + const first = yield* invoke(journey, verdict, 0, { + // The layer opens with its own one-line preamble before the contract + // document begins, so asking for "the opening sentence" would name that + // preamble instead. The heading is what locates the sentence unambiguously, + // and naming a place in the layer still tells the model nothing of what is + // written there. + say: + "Do not use any tools. Reply with exactly two lines. First line: the " + + "first sentence of the body text under the 'Implementor' heading of " + + "your contract, copied verbatim. Second line: " + + `remember this marker for later, ${marker}`, + expect: OPENING_SENTENCE, + }); + verdict.firstXmdExitCode = first.exitCode; + verdict.noticedBeforeSpending = first.noticedBeforeSpending; + verdict.noticedAfterSpending = first.noticedAfterSpending; + verdict.openingSentenceExact = first.answered; + verdict.answerSurface = first.answerStall?.tag ?? ""; + if (first.refused) { + verdict.verdict = "PRODUCT_FAILED"; + verdict.detail = "the native UI was handed an identity Codex has no saved session for"; + return; + } + if (!first.reachedSurface) { + verdict.verdict = "HARNESS_FAILED"; + verdict.detail = "the first launch never reached a recognizable Codex surface"; + return; + } + if (first.submissionRefusal !== undefined) { + // Nothing was asked, so there is nothing here about the product. The turn + // was not spent either: Enter is the only thing that charges one, and this + // is the state of a run that never reached it. + verdict.verdict = "HARNESS_FAILED"; + verdict.detail = `no turn was submitted: ${refusalDetail(first.submissionRefusal)}`; + return; + } + if (!first.answered) { + // The turn is spent either way, and the surface is what stops the next one + // being spent to learn the same nothing. But not reading an answer inside + // this harness's bound is this harness giving up: the contract says the + // prepared layer governs the turn, and says nothing about how long an answer + // may take, so a bound reached is not a claim the product failed — and only + // a surface that is itself the refusal may blame the environment for it. + const stall = first.answerStall; + if (stall === undefined || stall.tag === "unknown") { + verdict.verdict = "HARNESS_FAILED"; + verdict.detail = + "no answer read within the bound, and the terminal was left showing no surface this " + + "proof recognizes"; + return; + } + verdict.verdict = stall.verdict; + verdict.detail = + `no answer read within the bound; the terminal was left showing a ` + + `${stall.tag} surface, which is ${ + stall.verdict === "ENVIRONMENT_BLOCKED" + ? "the refusal itself" + : "its state and not evidence that no answer appeared" + }`; + return; + } + + // The second half: an authored, marker-free document that names the session + // the launch constructed and asks it one thing. Everything it needs is already + // written down beside the session. + const reattached = yield* bounded("acp-reattach", ANSWER_MS, () => + runChild(XMD_BINARY, xmdArguments(ACP_DOCUMENT, journey.journals[2]), { + cwd: journey.project, + env: environmentFor(verdict), + live: journey.live, + input: "", + }), + ); + verdict.acpReattachTurns += 1; + verdict.modelTurns += 1; + verdict.secondXmdExitCode = reattached.code ?? -1; + verdict.markerRecovered = shows(reattached.stdout, `${RECALL_PREFIX}${marker}`); + verdict.outcome = verdict.markerRecovered ? "same-identity" : "unresolved"; +} + +function decideZeroNativeTurn(verdict: JourneyVerdict): void { + if (verdict.materializationTurns !== 1) { + verdict.verdict = "PRODUCT_FAILED"; + verdict.detail = `the journey retained ${verdict.materializationTurns} materialization turns`; + return; + } + if (verdict.nativeUserTurns !== 0) { + verdict.verdict = "HARNESS_FAILED"; + verdict.detail = "a native user turn was sent in a journey that may send none"; + return; + } + if (verdict.outcome !== "same-identity") { + verdict.verdict = "PRODUCT_FAILED"; + verdict.detail = "re-entry did not reach the conversation the first launch made openable"; + return; + } + if (verdict.substitutedIdentity || verdict.routeConverted) { + verdict.verdict = "PRODUCT_FAILED"; + verdict.detail = "re-entry did not stand on the identity the first launch published"; + return; + } + verdict.verdict = "PASS"; + verdict.detail = + "one materialization turn made the conversation openable, and re-entry reached it again " + + "under the same identity without spending another"; +} + +function decideNativeLaunch(verdict: JourneyVerdict): void { + if (verdict.materializationTurns !== 1) { + verdict.verdict = "PRODUCT_FAILED"; + verdict.detail = `the journey retained ${verdict.materializationTurns} materialization turns`; + return; + } + if (!verdict.openingSentenceExact) { + verdict.verdict = "PRODUCT_FAILED"; + verdict.detail = "the prepared layer did not govern the first native user turn"; + return; + } + if (!verdict.markerRecovered) { + verdict.verdict = "PRODUCT_FAILED"; + verdict.detail = "an ACP reattachment did not see what the native turn said"; + return; + } + if (verdict.substitutedIdentity || verdict.routeConverted) { + verdict.verdict = "PRODUCT_FAILED"; + verdict.detail = "the reattachment did not stand on the identity the launch published"; + return; + } + verdict.verdict = "PASS"; + verdict.detail = + "one materialization turn opened the conversation, the prepared layer governed the first " + + "native user turn, and ACP rejoined that same conversation"; +} + +/** + * Gate, run and dismantle one journey, then report it. + * + * The cleanup counters are filled in by teardown, so a verdict serialized while + * the scope was still open would report every one of them false and claim the + * journey leaked what it had not yet released. + */ +function* runJourney( + mode: Mode, + body: (journey: Journey, verdict: JourneyVerdict) => Operation, + decide: (verdict: JourneyVerdict) => void, +): Operation { + const verdict = blankJourney(mode); + verdict.authorized = process.env[PROOF_ENV] === "1"; + verdict.turnsAuthorized = process.env[TURNS_ENV] === AUTHORIZED_TURNS[mode]; + if (!verdict.authorized) { + verdict.verdict = "REFUSED"; + verdict.refusal = "opt-in-absent"; + verdict.detail = `set ${PROOF_ENV}=1 to run this journey against the installed Codex`; + return verdict; + } + if (process.env.CODEX_HOME !== undefined) { + verdict.verdict = "REFUSED"; + verdict.refusal = "codex-home-set"; + verdict.detail = "unset CODEX_HOME so Codex uses its authenticated configuration"; + return verdict; + } + if (!verdict.turnsAuthorized) { + verdict.verdict = "REFUSED"; + verdict.refusal = "turns-not-authorized"; + verdict.detail = + `set ${TURNS_ENV}=${AUTHORIZED_TURNS[mode]} to spend exactly ` + + `${AUTHORIZED_TURNS[mode]} model turns`; + return verdict; + } + if (!(yield* exists(XMD_BINARY))) { + verdict.verdict = "ENVIRONMENT_BLOCKED"; + verdict.detail = "dist/xmd is not built; run deno task build"; + return verdict; + } + + let settled = false; + verdict.ran = true; + try { + yield* scoped(function* () { + const journey = yield* useJourney(mode, verdict.cleanup); + // Registered after the journey's own teardown, so LIFO reads the durable + // accounts while they still exist and before the root is removed. It runs + // on every path, including one the body left early. + yield* ensure(() => settleAccounts(journey, verdict)); + verdict.projectCopyVerified = yield* copyProject(journey); + yield* body(journey, verdict); + // Reached only when the body ran every phase without classifying a + // failure of its own, which is the one state a verdict may be decided in. + settled = verdict.verdict === "UNDECIDED"; + }); + } catch (error) { + settled = false; + verdict.verdict = "HARNESS_FAILED"; + verdict.detail = `the harness stopped: ${classify(error)}`; + } + if (settled) { + decide(verdict); + } + return verdict; +} + +/** What preflight establishes, all of it without a conversation. */ +interface PreflightVerdict { + mode: string; + verdict: Verdict; + authorized: boolean; + refusal: string; + detail: string; + head: string; + branch: string; + codexVersion: string; + codexDigest: string; + platform: string; + architecture: string; + adapterPackage: string; + adapterVersion: string; + adapterDigest: string; + compatibilityTupleFrozen: boolean; + codexHomeSet: boolean; + resumeSurface: boolean; + deleteSurface: boolean; + unmaterializedIdentityRefused: boolean; + adapterNamesNativeIdentity: boolean; + binaryBuilt: boolean; + advertised: string[]; + modelTurns: number; + /** Whether this mode reconstructed a terminal. It expects no answer, so no. */ + answerObserverConstructed: boolean; + privateStateInspected: boolean; +} + +/** + * Ask the vendored adapter for a thread and then ask Codex to open it. + * + * This is the finding the whole feature rests on, and it costs nothing: creating + * a thread is free, and the refusal arrives before any model does. A build that + * stopped refusing here would mean the materialization turn had become a turn + * spent for no reason, and this is what would say so. + */ +function* unmaterializedIsRefused( + codex: string, + live: LiveSet, + verdict: PreflightVerdict, +): Operation { + yield* scoped(function* () { + const root = yield* until(mkdtemp(join(tmpdir(), "xmd-755-preflight-"))); + yield* ensure(() => rm(root, { recursive: true, force: true })); + + const adapters = createEmbeddedAdapters(join(root, "adapters")); + yield* adapters.materialize("codex"); + const entry = adapters.executablePath("codex"); + + const pending = new Map) => void>(); + let next = 1; + let buffer = ""; + let child: ChildProcess | undefined; + yield* ensure(() => { + const running = child; + if (running?.pid) { + killed(running.pid); + live.delete(running.pid); + } + }); + child = spawnChild(process.execPath, [entry], { + env: { ...process.env, CODEX_PATH: codex }, + stdio: ["pipe", "pipe", "pipe"], + cwd: root, + }); + if (child.pid) { + live.add(child.pid); + } + const speaking = child; + speaking.stdout?.on("data", (chunk: Buffer) => { + buffer += chunk.toString("utf8"); + let index = buffer.indexOf("\n"); + while (index >= 0) { + const line = buffer.slice(0, index); + buffer = buffer.slice(index + 1); + index = buffer.indexOf("\n"); + if (line.trim().length === 0) { + continue; + } + let message: Record; + try { + message = JSON.parse(line); + } catch { + continue; + } + const id = message["id"]; + if (typeof id === "number" && pending.has(id)) { + pending.get(id)?.(message); + pending.delete(id); + continue; + } + // The adapter asks this client things while it works. Answering emptily + // is what a client that grants nothing says. + if (typeof id === "number" && typeof message["method"] === "string") { + speaking.stdin?.write(`${JSON.stringify({ jsonrpc: "2.0", id, result: {} })}\n`); + } + } + }); + + const request = (method: string, params: unknown): Promise> => { + const id = next++; + return new Promise((resolve) => { + pending.set(id, resolve); + speaking.stdin?.write(`${JSON.stringify({ jsonrpc: "2.0", id, method, params })}\n`); + }); + }; + + yield* bounded("adapter-initialize", ADAPTER_MS, () => + until( + request("initialize", { + protocolVersion: 1, + clientCapabilities: { fs: { readTextFile: false, writeTextFile: false } }, + }), + ), + ); + const created = yield* bounded("adapter-session-new", ADAPTER_MS, () => + until(request("session/new", { cwd: root, mcpServers: [] })), + ); + const result = created["result"]; + const meta = isRecord(result) ? result["_meta"] : undefined; + const identity = isRecord(meta) ? meta["agentSessionId"] : undefined; + verdict.adapterNamesNativeIdentity = typeof identity === "string" && identity.length > 0; + if (typeof identity !== "string" || identity.length === 0) { + return; + } + + // Codex's own answer, on its own terminal, about a thread nothing has spoken + // in. Nothing beneath `~/.codex` is opened to establish it. + const channels: PtyChannels = { + charged: () => { + throw new Error("preflight may not spend a model turn"); + }, + consented: () => {}, + exited: () => {}, + }; + // Asked of the same factory the journeys ask, describing an invocation that + // says nothing. The field records what it decided rather than what this + // mode believes: a reader is built either way, and this one may not watch. + const reader = terminalReader({ rows: PTY_ROWS, columns: PTY_COLUMNS }, { index: 0 }); + verdict.answerObserverConstructed = reader.watching; + + yield* ptyRun( + codex, + ["resume", identity], + { + cwd: root, + env: hostEnvironment(), + live, + channels, + reader, + }, + function* (pty): Operation { + // Through the same surface reader the journeys use. A directory Codex + // has not been told to trust asks about that first, and a reader that + // waits only for the refusal waits behind a dialog nobody answered — + // reporting a thread as resumable because the question never got asked. + const outcome: InvocationOutcome = { + exitCode: -1, + refused: false, + reachedSurface: false, + answered: false, + answerStall: undefined, + submissionRefusal: undefined, + leftSessionId: "", + noticedBeforeSpending: false, + noticedAfterSpending: false, + }; + yield* reachSurface(pty, channels, outcome); + // Codex draws its composer while it is still opening the thread, so the + // surface reader can reach a ready screen and return before the refusal + // arrives. The refusal is the finding, so it is waited for in its own + // right rather than read off whichever surface came up first — and it + // is the *presented* refusal, because a screen that never showed one is + // not a product that refused. + verdict.unmaterializedIdentityRefused = + outcome.refused || + (yield* pty.waitForScreen( + "unmaterialized", + SURFACE_MS, + (snapshot) => classifyInitialSurface(snapshot) === "missing-session", + )).length !== 0; + pty.control(INTERRUPT); + yield* sleep(SETTLE_DELAY_MS); + pty.control(INTERRUPT); + try { + yield* pty.settle(SETTLE_MS); + } catch (error) { + if (!(error instanceof PhaseTimeout)) { + throw error; + } + } + }, + ); + }); +} + +function* runPreflight(): Operation { + const verdict: PreflightVerdict = { + mode: "preflight", + verdict: "HARNESS_FAILED", + authorized: process.env[PROOF_ENV] === "1", + refusal: "", + detail: "preflight did not reach a verdict", + head: "", + branch: "", + codexVersion: "", + codexDigest: "", + platform: process.platform, + architecture: process.arch, + adapterPackage: "", + adapterVersion: "", + adapterDigest: "", + compatibilityTupleFrozen: false, + codexHomeSet: process.env.CODEX_HOME !== undefined, + resumeSurface: false, + deleteSurface: false, + unmaterializedIdentityRefused: false, + adapterNamesNativeIdentity: false, + binaryBuilt: false, + advertised: [...ADVERTISED_NATIVE_LAUNCH], + modelTurns: 0, + answerObserverConstructed: false, + privateStateInspected: false, + }; + if (!verdict.authorized) { + verdict.verdict = "REFUSED"; + verdict.refusal = "opt-in-absent"; + verdict.detail = `set ${PROOF_ENV}=1 to run preflight against the installed Codex`; + return verdict; + } + + const live: LiveSet = new Set(); + const cwd = REPO_ROOT; + + verdict.head = (yield* runChild("git", ["rev-parse", "HEAD"], { cwd, live })).stdout.trim(); + verdict.branch = (yield* runChild("git", ["branch", "--show-current"], { + cwd, + live, + })).stdout.trim(); + + const located = yield* bounded("resolve-codex", VERSION_MS, () => + runChild("/usr/bin/which", ["codex"], { cwd, live }), + ); + if (located.code !== 0 || located.stdout.trim().length === 0) { + verdict.verdict = "ENVIRONMENT_BLOCKED"; + verdict.detail = "no installed codex executable was found on PATH"; + return verdict; + } + const codex = yield* until(realpath(located.stdout.trim())); + verdict.codexDigest = createHash("sha256") + .update(yield* until(readFile(codex))) + .digest("hex"); + const version = yield* bounded("codex-version", VERSION_MS, () => + runChild(codex, ["--version"], { cwd, live }), + ); + verdict.codexVersion = version.code === 0 ? version.stdout.trim() : ""; + + const snapshot = embeddedAdapterIdentities().find((entry) => entry.provider === "codex"); + verdict.adapterPackage = snapshot?.package ?? ""; + verdict.adapterVersion = snapshot?.version ?? ""; + verdict.adapterDigest = snapshot?.sha256 ?? ""; + verdict.compatibilityTupleFrozen = + verdict.platform === REQUIRED_PLATFORM && + verdict.architecture === REQUIRED_ARCHITECTURE && + verdict.codexVersion === REQUIRED_CODEX_VERSION && + verdict.codexDigest === REQUIRED_CODEX_DIGEST && + verdict.adapterPackage === REQUIRED_ADAPTER_PACKAGE && + verdict.adapterVersion === REQUIRED_ADAPTER_VERSION && + verdict.adapterDigest === REQUIRED_ADAPTER_DIGEST; + + // Both are asked without a session, so they fail on an argument rather than + // reaching a model. + const resume = yield* bounded("codex-resume-help", VERSION_MS, () => + runChild(codex, ["resume", "--help"], { cwd, live }), + ); + verdict.resumeSurface = resume.code === 0 && resume.stdout.includes("SESSION_ID"); + // The exact surface cleanup uses: `--force` is what makes the delete answer + // without a prompt, and a build without it would leave this fixture's own + // conversations behind while reporting that it removed them. + const surface = yield* bounded("codex-delete-help", VERSION_MS, () => + runChild(codex, ["delete", "--help"], { cwd, live }), + ); + const remove = yield* bounded("codex-delete", VERSION_MS, () => + runChild(codex, ["delete", "--force", randomUUID()], { cwd, live, input: "" }), + ); + verdict.deleteSurface = + surface.code === 0 && + shows(surface.stdout, "--force") && + remove.code !== 0 && + shows(`${remove.stdout}${remove.stderr}`, "failed to delete session"); + + verdict.binaryBuilt = yield* exists(XMD_BINARY); + + if (verdict.compatibilityTupleFrozen) { + yield* unmaterializedIsRefused(codex, live, verdict); + } + + const established = + verdict.compatibilityTupleFrozen && + !verdict.codexHomeSet && + verdict.resumeSurface && + verdict.deleteSurface && + verdict.adapterNamesNativeIdentity && + verdict.unmaterializedIdentityRefused && + verdict.binaryBuilt; + verdict.verdict = established ? "PASS" : "ENVIRONMENT_BLOCKED"; + verdict.detail = established + ? "the frozen compatibility point is established, and no model turn was spent" + : "the frozen compatibility point is not established"; + return verdict; +} + +function render(value: unknown): void { + process.stdout.write(`${JSON.stringify(value, null, 2)}\n`); +} + +main(function* () { + const mode = process.argv[2]; + + if (mode === "preflight") { + render(yield* runPreflight()); + return; + } + if (mode === "zero-native-turn") { + render(yield* runJourney("zero-native-turn", runZeroNativeTurn, decideZeroNativeTurn)); + return; + } + if (mode === "native-launch") { + // Planted only in the first native user turn. Recovering it through ACP is + // what makes the reattached session the same conversation rather than a new + // one wearing the same name. + const marker = `MK${randomUUID().replaceAll("-", "").slice(0, 12).toUpperCase()}`; + render( + yield* runJourney( + "native-launch", + (journey, verdict) => runNativeLaunch(journey, verdict, marker), + decideNativeLaunch, + ), + ); + return; + } + + throw new Error(`codex-native-launch-proof: unknown mode "${mode ?? ""}"`); +}); diff --git a/packages/acp/tests/fixtures/codex-native-to-acp-prompt.md b/packages/acp/tests/fixtures/codex-native-to-acp-prompt.md new file mode 100644 index 00000000..75ced339 --- /dev/null +++ b/packages/acp/tests/fixtures/codex-native-to-acp-prompt.md @@ -0,0 +1,16 @@ +# Continue the implementer session + +This document is the second half of `packages/acp/src/CodexNativeLaunch.test.md` +and is run verbatim, through the built binary, from the same directory the +native launch ran in. + +It names the session that launch constructed and says one thing to it. There is +no marker here, no identity, and nothing about a build: everything this needs is +already written down beside the session, and a document that carried any of it +would be answering its own question. + + + +Do not use any tools. Reply with exactly one line and nothing else: RECOVERED- followed immediately, with no space, by the marker you were asked to remember in the preceding user turn. + + diff --git a/packages/acp/tests/fixtures/codex-surfaces.ts b/packages/acp/tests/fixtures/codex-surfaces.ts new file mode 100644 index 00000000..2cb73ae4 --- /dev/null +++ b/packages/acp/tests/fixtures/codex-surfaces.ts @@ -0,0 +1,693 @@ +/** + * What Codex's own surfaces say, and what a screen showing one of them means. + * + * `terminal-screen.ts` reconstructs a terminal and stays deliberately ignorant + * of whose terminal it is. This is the other half: the wording one build of + * Codex draws, and the two judgements a proof makes from it — whether the + * composer will accept a turn, and what a screen was showing when no answer + * arrived. Both are here rather than in the proof so the offline cases drive the + * exact predicates the paid run consumes, instead of a copy that agrees with + * them until the day it does not. + * + * Every judgement is asked of a *presented* screen. Codex withholds its drawing + * with `CSI ?2026h` while it repaints, so cells in between are ones no operator + * was ever shown, and a predicate that read them would decide on a frame that + * never existed. + */ + +import type { Operation } from "effection"; +import { runsOf, screenShows } from "./terminal-screen.ts"; +import type { ScreenSnapshot } from "./terminal-screen.ts"; + +/** Codex's own banner, and the strongest signal its surface is up. */ +export const BANNER = "OpenAI Codex (v"; + +/** The composer, which is where a conversation turn can be typed. */ +export const COMPOSER = "Ask Codex to do anything"; + +/** + * The one dialog Codex may put in front of a session. + * + * It asks for a standing permission rather than anything of the conversation, + * so a composer showing underneath one is not a composer that will take a turn. + */ +export const TRUST_DIALOG = "Do you trust the contents of this directory"; + +/** + * What Codex shows in place of its model name until startup finishes. + * + * It draws the composer before it has a model, and input typed into that + * composer may be queued rather than taken. A turn typed here is a turn whose + * fate nobody can read off the screen. + */ +export const MODEL_LOADING = "model: loading"; + +/** + * Codex refusing an identity it holds no thread for. + * + * The refusal this whole feature exists to avoid, so a screen presenting it is + * a finding about the product rather than something to drive around. + */ +export const MISSING_SESSION = "No saved session found with ID"; + +/** + * The markers naming Codex's own furniture rather than anything it said. + * + * Handed to {@link runsOf} so a line of chrome ends the run above it instead of + * joining onto the sentence that follows. + */ +export const SCREEN_CHROME: readonly string[] = [COMPOSER, "esc to interrupt", BANNER]; + +/** Fold away everything a terminal's layout and typography may vary. */ +function fold(text: string): string { + return text.toLowerCase().replaceAll(/[‘’ʼ]/gu, "'"); +} + +/** Fold, and close up the wrapping a terminal chose. */ +function normalize(text: string): string { + return fold(text).replaceAll(/\s+/gu, ""); +} + +/** Whether the presented screen shows `phrase`, layout and case ignored. */ +function shows(snapshot: ScreenSnapshot, phrase: string): boolean { + return screenShows( + { alternate: snapshot.alternate, rows: snapshot.rows.map(fold) }, + fold(phrase), + ); +} + +/** + * The one sentence this proof has witnessed Codex refuse a turn with. + * + * Witnessed, and so exactly one. Variants nobody has seen Codex draw would be + * guesses dressed as recognition, and each one widens what can be mistaken for + * a refusal while proving nothing about the product. + */ +const WITNESSED_REFUSAL = "You've hit your usage limit."; + +/** + * Whether the presented screen is refusing for want of remaining usage. + * + * Asked of a *run* — the text between the layout's own cuts — and asked whether + * that run begins with the refusal, rather than whether the screen contains the + * words anywhere. Codex says `usage limit` in wording that means the opposite: + * `/status` reports the headroom that remains, the startup banner offers + * `You have 2 usage limit resets available`, and its help text explains what to + * do `If you've hit your usage limit`. A containment test cannot tell any of + * those from the refusal, and one that could not reported two paid runs as + * quota-blocked on an account with 42% of its week unspent — sending the next + * reader off to wait for a limit nobody hit, and burying the real cause. + * + * Requiring the run to *start* with the sentence is what rejects the + * conditional: `If you've hit your usage limit, …` is one run, and it begins + * with `If`. Wrapping is closed up first, because a terminal may break the + * sentence across rows and that is not a different sentence. + * + * Wording this does not recognize is not exhaustion here, even if it is + * exhaustion in fact. That direction is the safe one: an unrecognized surface + * is reported as a harness that could not read the screen, which costs an + * investigation, where the other direction costs a false claim about the + * product's environment. + */ +export function exhaustedUsage(snapshot: ScreenSnapshot): boolean { + const refusal = normalize(WITNESSED_REFUSAL); + return runsOf(snapshot.rows, SCREEN_CHROME).some((run) => normalize(run).startsWith(refusal)); +} + +/** + * What the terminal was showing instead, when no answer was read within a bound. + * + * Terminal state, and nothing more. `composer-idle` in particular says the + * composer is back to its resting form; it is not evidence that no answer + * appeared, because an answer sits above a composer that has gone idle and + * `observeAnswer` is the only thing that decides whether one is there. + */ +export type StallTag = + | "approval-request" + | "still-working" + | "usage-limited" + | "composer-idle" + | "unknown"; + +const STALLS: readonly { tag: StallTag; matches: (snapshot: ScreenSnapshot) => boolean }[] = [ + { tag: "approval-request", matches: (screen) => shows(screen, "Allow command") }, + { tag: "approval-request", matches: (screen) => shows(screen, "wants to run") }, + { tag: "still-working", matches: (screen) => shows(screen, "esc to interrupt") }, + { tag: "usage-limited", matches: exhaustedUsage }, + { tag: "composer-idle", matches: (screen) => shows(screen, COMPOSER) }, +]; + +/** + * What the screen was showing, and what a run that read no answer therefore is. + * + * The two travel together because they are one judgement. Nothing here converts + * a tag into a verdict, so there is no function a caller could hand a + * `usage-limited` it made up — the only way to reach `ENVIRONMENT_BLOCKED` is to + * put the witnessed refusal on a screen and classify it. A tag on its own is a + * label for a report; it carries no authority to blame anything. + */ +export interface StallClassification { + /** What the terminal was showing. Reported as-is, and decides nothing alone. */ + readonly tag: StallTag; + /** + * What a run that spent a turn and read no answer is. + * + * `ENVIRONMENT_BLOCKED` only where {@link exhaustedUsage} recognized the + * refusal. Every other surface describes where the terminal got to and + * explains nothing: still working, waiting on an approval, sitting at an idle + * composer, or showing wording nothing here recognizes is this harness having + * stopped waiting in front of something it could not account for, which is a + * harness failure however ordinary the screen. + */ + readonly verdict: "ENVIRONMENT_BLOCKED" | "HARNESS_FAILED"; +} + +/** Read the presented screen, and say both things about it at once. */ +export function classifyStall(snapshot: ScreenSnapshot): StallClassification { + const tag = STALLS.find((stall) => stall.matches(snapshot))?.tag ?? "unknown"; + return { tag, verdict: tag === "usage-limited" ? "ENVIRONMENT_BLOCKED" : "HARNESS_FAILED" }; +} + +/** Whether the composer is up, unobstructed, and backed by a loaded model. */ +export function composerReady(snapshot: ScreenSnapshot): boolean { + return ( + shows(snapshot, COMPOSER) && !shows(snapshot, TRUST_DIALOG) && !shows(snapshot, MODEL_LOADING) + ); +} + +/** + * What a session is showing on its way to a composer that will take a turn. + * + * `starting` and `blank` are the two ways a screen can be nothing to act on: + * one has Codex on it and no surface to answer or type into yet, the other has + * nothing recognizable at all. Neither is a decision, and keeping them apart + * from the three that are is what lets a wait resume rather than conclude. + */ +export type InitialSurface = + | "missing-session" + | "trust-dialog" + | "composer-ready" + | "starting" + | "blank"; + +/** + * Which of those the presented screen is showing. + * + * Ordered by what covers what. The refusal comes first because it is the + * finding and Codex draws its composer while still opening the thread, so a + * screen carrying both is a refused one. The dialog comes before readiness + * because it is drawn *over* a composer, and a composer nobody can reach is not + * a composer that will take a turn. + * + * Asked of a presented snapshot in every case. The byte stream retains a + * composer drawn before a dialog covered it and a refusal erased by the repaint + * after it, so a reader of the stream answers a question about the past; and + * cells inside a `CSI ?2026h` hold were never shown to anybody, so a reader of + * those answers a question about a frame that did not exist. + */ +export function classifyInitialSurface(snapshot: ScreenSnapshot): InitialSurface { + if (shows(snapshot, MISSING_SESSION)) { + return "missing-session"; + } + if (shows(snapshot, TRUST_DIALOG)) { + return "trust-dialog"; + } + if (composerReady(snapshot)) { + return "composer-ready"; + } + if (shows(snapshot, BANNER) || shows(snapshot, COMPOSER) || shows(snapshot, MODEL_LOADING)) { + return "starting"; + } + return "blank"; +} + +/** + * Whether Codex refused the identity at any point in the read that was waited on. + * + * Any point, because the refusal outranks everything else a read presented. The + * frames either side of it are Codex getting on with a startup it has already + * decided the outcome of, and acting on one of those means driving a session the + * product has said it does not hold. + */ +function refused(presented: readonly ScreenSnapshot[]): boolean { + return presented.some(isRefusal); +} + +/** Whether this one screen is Codex saying it holds no such thread. */ +export function isRefusal(snapshot: ScreenSnapshot): boolean { + return classifyInitialSurface(snapshot) === "missing-session"; +} + +/** + * Watch for what this wait is for, and for the refusal that means stop waiting. + * + * A wait ends at the read that satisfied it, so a frame its predicate says + * nothing about is not merely left out of the batch — it does not stop the wait, + * and the read after it repaints over it. The refusal is then in no batch and on + * no screen, and the only trace it left is that it was once presented. + * + * That is survivable for a wait watching for a surface, because every surface + * predicate in this file is already satisfied by a refusal: reaching a composer + * waits for something {@link actionable}, for the trust dialog to be gone, or + * for readiness to be lost, and `missing-session` answers all three. It is not + * survivable for the waits that ask whether a composer is ready or whether a + * turn is in it, because Codex can draw the refusal where the composer was — + * making both of those predicates false on the one screen that matters most. + * + * So the waits whose next act is typing or Enter watch for the refusal too. It + * belongs in the predicate rather than in a check afterwards: a wait that ends + * on the refusal is one whose batch holds it, which is what {@link refused} then + * finds, and it ends there rather than waiting out a bound for a composer that + * has already been spoken for. + */ +function stoppingAtRefusal( + predicate: (snapshot: ScreenSnapshot) => boolean, +): (snapshot: ScreenSnapshot) => boolean { + return (snapshot) => predicate(snapshot) || isRefusal(snapshot); +} + +/** Whether this surface is one a driver may act on. */ +function actionable(surface: InitialSurface): boolean { + return ( + surface === "missing-session" || surface === "trust-dialog" || surface === "composer-ready" + ); +} + +/** Where reaching for a composer got to. */ +export type SurfaceOutcome = + /** Codex refused the identity. A finding, and not something to drive around. */ + | "missing-session" + /** A composer is up, unobstructed, and backed by a loaded model. */ + | "composer-ready" + /** No surface this recognizes settled within the bounds it was given. */ + | "unresolved"; + +export interface SurfaceBounds { + /** How long each round waits for a surface it can act on. */ + readonly surface: number; + /** How long a dialog is given to finish drawing its options. */ + readonly settle: number; + /** How long a ready composer is watched for a dialog arriving over it. */ + readonly grace: number; +} + +/** + * Everything reaching a composer needs from a terminal, and nothing else. + * + * `consent` rather than a raw keystroke, because the one Enter this driver may + * press is a consent that has to be recorded as one — a port that could be + * handed a bare `send` could spend a conversation turn through this path. + */ +export interface SurfacePort { + /** What the terminal last put on show. Never a frame still being drawn. */ + screen(): ScreenSnapshot; + /** + * Wait for a read presenting `predicate`, and answer with every frame that did. + * + * The screens that matched, rather than a flag saying one did, because the two + * questions have different answers. A read from a pty carries as many finished + * frames as its bytes finished, so a surface can be presented and repainted + * over inside one — and a caller handed a flag has nothing left to look at but + * whichever frame that read ended on. + * + * All of them, because both questions asked here are wide: whether a ready + * composer stopped being one, and whether any surface worth acting on is up. + * A refusal satisfies either, and so does a model reloading or a dialog going + * up — so the read that carries the refusal often answers the wait a frame or + * two before it. + * + * Empty where the bound was spent, because a surface that never arrived is + * something to report rather than an error. + */ + waitForScreen( + name: string, + ms: number, + predicate: (snapshot: ScreenSnapshot) => boolean, + ): Operation; + /** Answer the trust dialog: record the consent, and press Enter. */ + consent(): void; + /** + * Wait out a fixed delay, and answer with what was presented during it. + * + * A delay rather than a wait — nothing shortens it — but the same answer a + * wait gives, because the terminal does not stop drawing while a driver is + * deliberately not looking. The screen afterwards says what survived the + * delay, which is a different question from what happened during it, and a + * refusal is routinely only in the second. + */ + pause( + ms: number, + predicate: (snapshot: ScreenSnapshot) => boolean, + ): Operation; +} + +/** + * How many surfaces one session is followed through. + * + * A composer that goes back to loading, the dialog that follows it, the composer + * that dialog was covering, and one spare. A session that needs more than that + * is one this driver does not understand, and saying so is better than pressing + * Enter into it until something happens. + */ +const SURFACE_ROUNDS = 4; + +/** + * Answer the trust dialog if it is presented, then establish the composer. + * + * Whether the dialog appears belongs to the machine — a directory Codex already + * trusts shows none — so this reacts to what is on screen rather than following + * a script, and consents at most once. + * + * Every Enter is preceded by reading the presented screen again. The dialog is + * still drawing its options as it announces itself, so a settle is waited out + * first; and if the screen is no longer showing the dialog after it, no Enter is + * pressed. That is the difference between consenting to a question and pressing + * Enter into whatever replaced it. + */ +export function* reachComposer( + port: SurfacePort, + bounds: SurfaceBounds, +): Operation { + let consented = false; + for (let round = 0; round < SURFACE_ROUNDS; round++) { + const arrived = yield* port.waitForScreen("surface", bounds.surface, (snapshot) => + actionable(classifyInitialSurface(snapshot)), + ); + if (arrived.length === 0) { + return "unresolved"; + } + // A refusal the terminal presented is the finding, whatever it drew next and + // whatever it drew before. Codex commits the refusal and repaints a composer + // over it, and one read from a pty can carry both — so the screen as it now + // stands is not enough to see it, and a driver that only looked there would + // type a turn into a composer for a session the product had already said it + // does not hold. Asked of the whole read because the dialog Codex may draw + // ahead of the refusal answers this wait too, and the refusal outranks it. + if (refused(arrived)) { + return "missing-session"; + } + // Otherwise read again rather than trusting the wait: what satisfied the + // predicate may have been repainted over, and consenting or typing is an act + // against whatever is on show now. + const surface = classifyInitialSurface(port.screen()); + if (surface === "missing-session") { + return "missing-session"; + } + if (surface === "trust-dialog") { + if (consented) { + // Asked twice about one directory. Answering again would be consenting + // twice to a question that was only asked once. + return "unresolved"; + } + // Settling lets a dialog drawn in pieces finish being drawn, and a session + // Codex is still resolving refuse. The screen afterwards cannot tell those + // apart from a refusal that was shown and painted back over, so the settle + // is asked what it saw: consenting to a directory on behalf of a session + // that no longer exists answers a question nobody is asking any more. + const duringSettle = yield* port.pause(bounds.settle, isRefusal); + if (refused(duringSettle)) { + return "missing-session"; + } + if (classifyInitialSurface(port.screen()) !== "trust-dialog") { + continue; + } + consented = true; + port.consent(); + // The dialog stays on screen until Codex repaints over it. Waiting for it + // to go is what stops the next round reading an answered question as a + // second one and giving up in front of a session that is coming up fine. + const answered = yield* port.waitForScreen( + "trust-answered", + bounds.surface, + (snapshot) => classifyInitialSurface(snapshot) !== "trust-dialog", + ); + // Answering the dialog is not the end of the startup, so this is a third + // read a refusal can be presented in — and this wait asks only that the + // dialog be gone, which the model Codex loads next already satisfies. The + // refusal then arrives behind a frame that has answered this wait, inside + // the read that answered it, and going round without looking would find + // only the composer that read ended on. The consent already pressed + // stands: it answered a question about a directory that was up and asking + // at the time. What it must not be followed by is a turn. + if (refused(answered)) { + return "missing-session"; + } + continue; + } + if (surface === "composer-ready") { + // Codex draws its composer early — before it asks about the directory, + // before a model has finished loading, and before it reports that it holds + // no such thread. So a first ready screen is a screen that may still be + // about to become one of those, and the grace watches for it becoming + // *anything* else rather than for the dialog alone. Watching only for the + // dialog is how a refusal or a loading model arriving during the grace + // used to run out the bound unnoticed and be returned as readiness. + const departed = yield* port.waitForScreen( + "readiness-grace", + bounds.grace, + (snapshot) => classifyInitialSurface(snapshot) !== "composer-ready", + ); + // The refusal ends it here too, and for the same reason: it was presented, + // and a repaint in the same read does not take that back. This is the wait + // it most often arrives behind — Codex puts its model back to loading + // before it says it holds no such thread — and a loading frame satisfies + // this predicate as readily as the refusal two frames later does. + if (refused(departed)) { + return "missing-session"; + } + // Otherwise the decision is the screen as it now stands: a surface that + // arrived inside a hold counts from its commit, one that came and went + // never displaced what is on show, and readiness is a claim about a + // composer this driver is about to type into. + const settled = classifyInitialSurface(port.screen()); + if (settled === "missing-session") { + return "missing-session"; + } + if (settled !== "composer-ready") { + continue; + } + return "composer-ready"; + } + } + return "unresolved"; +} + +/** + * How much of the typed turn has to be on screen for it to count as presented. + * + * The tail, because a composer scrolls a long turn and shows its end. The + * proof's turn ends in a marker minted for that one run, so the tail is unique + * to it and no earlier repaint can supply one — provided the whole marker fits + * inside it, which is a thing about the two lengths together and so is proven + * rather than assumed. + */ +export const PROMPT_TAIL = 24; + +/** + * Whether the composer is showing the turn this harness typed into it. + * + * Asked of the typed text alone, and deliberately not of {@link COMPOSER} as + * well. That string is the composer's placeholder, which is what an *empty* + * composer shows — the thing {@link composerReady} reads — and it is gone the + * moment there is a turn in the box. Requiring both would be requiring the + * composer to be simultaneously empty and full, and every run would report a + * turn it never managed to type. + * + * Before submission there is nowhere else on the screen for this text to be: + * nothing has been sent, so no transcript carries it back. + */ +export function promptPresented(snapshot: ScreenSnapshot, typed: string): boolean { + const tail = typed.slice(-PROMPT_TAIL); + return tail.length > 0 && shows(snapshot, tail); +} + +/** The bounds a submission is given, supplied by whoever owns the run. */ +export interface SubmissionBounds { + /** How long the composer is waited for, before and after the grace. */ + readonly ready: number; + /** + * How long a ready-looking composer is given to turn out to have something + * over it, or a model still loading behind it. + * + * Its length matters less than the recheck it precedes: a composer that stops + * being ready during the grace is waited for again rather than typed into. + */ + readonly startupGrace: number; + /** How long the typed turn is given to appear in the composer. */ + readonly presented: number; +} + +/** + * Everything submitting a turn needs from a terminal, and nothing else. + * + * Narrow on purpose: the offline cases implement this against scripted frames, + * so what they decide is what the pty path does. + */ +export interface SubmissionPort { + /** What the terminal last put on show. Never a frame still being drawn. */ + screen(): ScreenSnapshot; + /** + * Wait for a read presenting `predicate`, and answer with every frame that did. + * + * The frames rather than a flag, and for a sharper reason than reaching a + * composer had. Codex draws its refusal *above* a composer rather than in + * place of one, so a screen carrying `No saved session found with ID` and an + * empty composer both is a screen {@link composerReady} calls ready and + * {@link promptPresented} calls presented. A refusal therefore does not merely + * ride along in these batches — it satisfies them. Answering `true` here would + * hand back the one bit that cannot distinguish the composer this driver is + * waiting for from the refusal that means it must not type into it, and the + * next thing down that path is Enter. + * + * Empty where the bound was spent, because a surface that never arrived is + * something to report rather than an error. + */ + waitForScreen( + name: string, + ms: number, + predicate: (snapshot: ScreenSnapshot) => boolean, + ): Operation; + /** Type one turn into the composer, without sending it. */ + type(text: string): void; + /** Press Enter. This is the keystroke that spends the turn. */ + send(typed: string): void; + /** Wait out a fixed delay, and answer with what was presented during it. */ + pause( + ms: number, + predicate: (snapshot: ScreenSnapshot) => boolean, + ): Operation; +} + +export type SubmissionRefusal = + | "session-refused" + | "composer-never-ready" + | "composer-unready-after-grace" + | "prompt-never-presented"; + +export type SubmissionOutcome = + | { readonly submitted: true } + | { readonly submitted: false; readonly reason: SubmissionRefusal }; + +const REFUSALS: Readonly> = { + "session-refused": + "Codex refused the identity while the turn was being readied, so the composer on screen " + + "belonged to a session it had already said it does not hold", + "composer-never-ready": + "the composer never came up ready — it was absent, covered by the trust dialog, or still " + + "showing a model that had not loaded", + "composer-unready-after-grace": + "the composer stopped being ready during the startup grace and did not come back", + "prompt-never-presented": + "the turn was typed but never appeared in the composer, so what Codex would have received " + + "could not be established", +}; + +/** The sentence naming why nothing was submitted. Carries no typed content. */ +export function refusalDetail(reason: SubmissionRefusal): string { + return REFUSALS[reason]; +} + +/** + * Type one turn and submit it, or establish that it must not be submitted. + * + * Enter is reached from exactly one place, past three screen readings that each + * have to hold: the composer is ready, it is still ready after the grace in + * which an overlay or a loading model would have shown itself, and the turn is + * on screen in the composer. A run that fails any of them returns having typed + * at most — no Enter, and so no turn to account for. + * + * None of those three is a question about a refusal, though, and `No saved + * session found with ID` can be drawn either above the composer or where the + * composer was. The first shape passes every test here — ready, and holding the + * turn that was typed. The second fails them all, which is worse: a wait + * watching only for readiness does not stop at it, and the next read paints over + * it. So the refusal is watched for by each wait as well as asked of the batch + * that answers it, and asked again of the screen as it stands wherever this + * decides something without a wait: after the startup grace, after a composer is + * waited for a second time, and immediately before Enter. + * + * Reaching a composer has already established that the session was not refused, + * but only up to the bound it was willing to wait — and Codex draws its composer + * before it resolves the thread, so a refusal slower than that bound arrives + * here, with the turn already typed and Enter next. + */ +export function* submitWhenReady( + port: SubmissionPort, + typed: string, + bounds: SubmissionBounds, +): Operation { + const ready = yield* port.waitForScreen( + "composer-ready", + bounds.ready, + stoppingAtRefusal(composerReady), + ); + if (refused(ready)) { + return { submitted: false, reason: "session-refused" }; + } + if (ready.length === 0) { + return { submitted: false, reason: "composer-never-ready" }; + } + + // The grace is a window a refusal can be drawn in, and what it leaves behind + // is a screen rather than a batch: nothing else is watching it. Asked for + // readiness alone the screen afterwards answers yes, because the refusal is + // drawn above a composer that is otherwise up — so the second wait would not + // even be taken, and the read that later confirms the turn repaints a clean + // composer over the only frame that ever said the session does not exist. A + // refusal repainted before the grace is out leaves no trace on that screen at + // all, so the grace is asked what it saw as well as what it left. + const duringGrace = yield* port.pause(bounds.startupGrace, isRefusal); + if (refused(duringGrace)) { + return { submitted: false, reason: "session-refused" }; + } + const settled = port.screen(); + if (classifyInitialSurface(settled) === "missing-session") { + return { submitted: false, reason: "session-refused" }; + } + if (!composerReady(settled)) { + const again = yield* port.waitForScreen( + "composer-ready-again", + bounds.ready, + stoppingAtRefusal(composerReady), + ); + if (refused(again)) { + return { submitted: false, reason: "session-refused" }; + } + if (again.length === 0) { + return { submitted: false, reason: "composer-unready-after-grace" }; + } + // A batch says a ready composer was presented during the read, not that it + // is what the read ended on. The refusal that arrives after it takes the + // composer with it, and a screen with no composer is precisely what this + // wait does not collect — so the honestly ready batch above can sit in front + // of a refusal that is on show right now, with typing next. + if (classifyInitialSurface(port.screen()) === "missing-session") { + return { submitted: false, reason: "session-refused" }; + } + } + + port.type(typed); + const presented = yield* port.waitForScreen( + "prompt-presented", + bounds.presented, + stoppingAtRefusal((snapshot) => promptPresented(snapshot, typed)), + ); + if (refused(presented)) { + return { submitted: false, reason: "session-refused" }; + } + if (presented.length === 0) { + return { submitted: false, reason: "prompt-never-presented" }; + } + + // Enter is the act this whole file exists to place correctly, so it is taken + // against the screen as it stands and not against a batch that answered a + // wait. A refusal arriving after the turn was confirmed on screen — in a read + // of its own, with nothing left to satisfy any predicate above — is invisible + // to all three waits and would otherwise be charged for. + if (classifyInitialSurface(port.screen()) === "missing-session") { + return { submitted: false, reason: "session-refused" }; + } + + port.send(typed); + return { submitted: true }; +} diff --git a/packages/acp/tests/fixtures/fake-codex-app-server.cjs b/packages/acp/tests/fixtures/fake-codex-app-server.cjs index d86fa949..05246855 100755 --- a/packages/acp/tests/fixtures/fake-codex-app-server.cjs +++ b/packages/acp/tests/fixtures/fake-codex-app-server.cjs @@ -119,6 +119,31 @@ function handle(message) { }); return; } + case "thread/resume": { + // Reopening answers with the thread the App Server settled on. That + // answer, not the id the request carried, is what names the conversation + // a client would go on to address directly. + const threadId = message.params?.threadId ?? "thread-1"; + reply(message.id, { + thread: { id: threadId }, + model: "fake-model", + modelProvider: "fake", + serviceTier: null, + cwd: process.cwd(), + instructionSources: [], + approvalPolicy: "never", + approvalsReviewer: "user", + sandboxPolicy: { mode: "danger-full-access" }, + reasoningEffort: null, + skills: [], + }); + return; + } + case "thread/read": { + const threadId = message.params?.threadId ?? "thread-1"; + reply(message.id, { thread: { id: threadId, title: null, turns: [] } }); + return; + } case "turn/start": { const threadId = message.params?.threadId ?? "thread-1"; const turnId = nextTurn(threadId); diff --git a/packages/acp/tests/fixtures/terminal-screen.ts b/packages/acp/tests/fixtures/terminal-screen.ts new file mode 100644 index 00000000..074b99bb --- /dev/null +++ b/packages/acp/tests/fixtures/terminal-screen.ts @@ -0,0 +1,1087 @@ +/** + * What a cursor-addressed terminal is showing, reconstructed from its bytes. + * + * A TUI does not append its output. It moves the cursor, erases, and draws over + * what it drew before, so the byte stream a pty emitted and the screen an + * operator is looking at are two different things. Searching the stream answers + * the wrong question twice over: it finds text that has since been erased, text + * the program printed before it took the screen, and text no repaint left + * standing — while missing an answer whose only surviving form is the cells it + * was last drawn into. + * + * So the bytes are applied to a screen here, and the screen is what gets read. + * Nothing in this module is Codex-specific: it is a terminal, and the questions + * asked of it are supplied by the caller. + */ + +import { withResolvers } from "effection"; +import type { Operation } from "effection"; + +const ESC = String.fromCharCode(0x1b); +const BEL = String.fromCharCode(0x07); +const DEL = String.fromCharCode(0x7f); +const BLANK = " "; + +/** + * Where one piece of text stops, marked in a row before the row is cut up. + * + * A noncharacter, so no terminal output can supply one and be mistaken for a + * cut this module made. + */ +const BOUNDARY = String.fromCharCode(0xffff); + +/** + * The glyphs a TUI draws its frame out of — box drawing and block elements. + * + * A pane border can land between two words of a wrapped sentence, so these have + * to come out before the words either side of one can be read as adjacent. No + * model emits them mid-sentence, so removing them recovers the text without + * letting anything else through. + */ +const FRAME_GLYPH = /[─-▟]/gu; + +/** Collapse every run of whitespace, so a TUI's own layout cannot hide a word. */ +function squeeze(text: string): string { + return text.replaceAll(/\s+/gu, ""); +} + +export interface ScreenSize { + readonly rows: number; + readonly columns: number; +} + +export interface ScreenSnapshot { + /** Whether the alternate buffer is showing, which is a full-screen TUI's. */ + readonly alternate: boolean; + /** The visible rows of whichever buffer is showing, trailing blanks removed. */ + readonly rows: readonly string[]; +} + +function blankRow(columns: number): string[] { + return new Array(columns).fill(BLANK); +} + +function blankCells(size: ScreenSize): string[][] { + return Array.from({ length: size.rows }, () => blankRow(size.columns)); +} + +export class TerminalScreen { + readonly #rows: number; + readonly #columns: number; + readonly #decoder = new TextDecoder(); + #primary: string[][]; + #alternate: string[][]; + #onAlternate = false; + #row = 0; + #column = 0; + /** + * Whether the last glyph filled the final column. + * + * A terminal does not move to the next row when the last column is written; + * it waits to see whether another glyph arrives. Without that delay a + * sentence ending exactly at the right margin drags a blank row after it, and + * a cursor move that follows one lands a row too low. + */ + #wrapPending = false; + #savedRow = 0; + #savedColumn = 0; + #top = 0; + #bottom: number; + /** An escape sequence split across two reads, held until the rest arrives. */ + #partial = ""; + /** + * What was on show when the program asked for its drawing to be held back. + * + * `CSI ?2026h` tells the terminal to stop presenting until `CSI ?2026l`, so a + * program can erase and redraw a region without the reader ever seeing the + * half-drawn state. Codex asks for this, which means the rows in between are + * cells this screen holds and a terminal never showed anybody — while this + * stays what it showed last, so a reader has something true to read. + * + * Taken where the hold begins rather than at the end of the read carrying it: + * bytes before that point were presented, and bytes after it were not. + */ + #held: ScreenSnapshot | undefined; + readonly #onFrame: (() => void) | undefined; + + /** + * @param onFrame Called each time a synchronized update commits, at the point + * in the byte stream where it commits rather than at the end of the read that + * carried it — a frame is finished by `CSI ?2026l` and not by an operating + * system deciding where one `data` event stops. + */ + constructor(size: ScreenSize, onFrame?: () => void) { + this.#rows = size.rows; + this.#columns = size.columns; + this.#primary = blankCells(size); + this.#alternate = blankCells(size); + this.#bottom = size.rows - 1; + this.#onFrame = onFrame; + } + + /** Whether a frame is part-drawn, so what the cells hold is not on show. */ + get synchronized(): boolean { + return this.#held !== undefined; + } + + /** Apply one read from the terminal. Byte chunks may split any sequence. */ + write(chunk: string | Uint8Array): void { + const text = typeof chunk === "string" ? chunk : this.#decoder.decode(chunk, { stream: true }); + this.#consume(`${this.#partial}${text}`); + } + + /** The cells as they stand, whether or not a terminal has shown them. */ + snapshot(): ScreenSnapshot { + return { + alternate: this.#onAlternate, + rows: this.#cells().map((row) => row.join("").replace(/\s+$/u, "")), + }; + } + + /** + * What a terminal last put on show, which is the only thing anybody read. + * + * The same as {@link snapshot} except while a frame is being held back, when + * it stays the frame before it until `CSI ?2026l` commits the new one. Any + * question about what was on the screen — what it answered, and what it was + * showing when it did not — has to be asked of this. + */ + presented(): ScreenSnapshot { + return this.#held ?? this.snapshot(); + } + + #cells(): string[][] { + return this.#onAlternate ? this.#alternate : this.#primary; + } + + #consume(input: string): void { + this.#partial = ""; + let index = 0; + while (index < input.length) { + const char = input[index] ?? ""; + if (char !== ESC) { + this.#put(char); + index += 1; + continue; + } + const next = this.#escape(input, index); + if (next === undefined) { + this.#partial = input.slice(index); + return; + } + index = next; + } + } + + /** Consume one escape sequence, or report that it has not all arrived. */ + #escape(input: string, start: number): number | undefined { + const kind = input[start + 1]; + if (kind === undefined) { + return undefined; + } + if (kind === "[") { + return this.#csi(input, start); + } + if (kind === "]" || kind === "P" || kind === "^" || kind === "_") { + return this.#stringSequence(input, start); + } + if (kind === "(" || kind === ")" || kind === "*" || kind === "+") { + return input[start + 2] === undefined ? undefined : start + 3; + } + if (kind === "7") { + this.#save(); + } else if (kind === "8") { + this.#restore(); + } else if (kind === "M") { + this.#reverseIndex(); + } else if (kind === "D") { + this.#index(); + } else if (kind === "E") { + this.#index(); + this.#column = 0; + } else if (kind === "c") { + this.#reset(); + } + return start + 2; + } + + #csi(input: string, start: number): number | undefined { + let index = start + 2; + while (index < input.length && /[0-9;:?<>=!]/u.test(input[index] ?? "")) { + index += 1; + } + while (index < input.length && /[ -/]/u.test(input[index] ?? "")) { + index += 1; + } + const final = input[index]; + if (final === undefined) { + return undefined; + } + this.#dispatch(input.slice(start + 2, index), final); + return index + 1; + } + + /** OSC, DCS, APC and PM all run to a BEL or a string terminator. */ + #stringSequence(input: string, start: number): number | undefined { + let index = start + 2; + while (index < input.length) { + const char = input[index]; + if (char === BEL) { + return index + 1; + } + if (char === ESC) { + const after = input[index + 1]; + if (after === undefined) { + return undefined; + } + if (after === "\\") { + return index + 2; + } + } + index += 1; + } + return undefined; + } + + #dispatch(body: string, final: string): void { + const priv = body.startsWith("?"); + const params = (priv ? body.slice(1) : body).split(";").map((part) => { + const value = Number.parseInt(part, 10); + return Number.isNaN(value) ? 0 : value; + }); + if (priv) { + if (final === "h" || final === "l") { + this.#mode(params, final === "h"); + } + return; + } + /** A parameter a terminal reads as "how many", where zero means one. */ + const count = (position: number, fallback: number): number => { + const value = params[position]; + return value === undefined || value === 0 ? fallback : value; + }; + /** A parameter a terminal reads as "which", where zero is a real choice. */ + const choice = params[0] ?? 0; + switch (final) { + case "A": + this.#moveTo(this.#row - count(0, 1), this.#column); + break; + case "B": + this.#moveTo(this.#row + count(0, 1), this.#column); + break; + case "C": + this.#moveTo(this.#row, this.#column + count(0, 1)); + break; + case "D": + this.#moveTo(this.#row, this.#column - count(0, 1)); + break; + case "E": + this.#moveTo(this.#row + count(0, 1), 0); + break; + case "F": + this.#moveTo(this.#row - count(0, 1), 0); + break; + case "G": + case "`": + this.#moveTo(this.#row, count(0, 1) - 1); + break; + case "d": + this.#moveTo(count(0, 1) - 1, this.#column); + break; + case "H": + case "f": + this.#moveTo(count(0, 1) - 1, count(1, 1) - 1); + break; + case "J": + this.#eraseDisplay(choice); + break; + case "K": + this.#eraseLine(choice); + break; + case "L": + this.#insertLines(count(0, 1)); + break; + case "M": + this.#deleteLines(count(0, 1)); + break; + case "@": + this.#insertChars(count(0, 1)); + break; + case "P": + this.#deleteChars(count(0, 1)); + break; + case "X": + this.#eraseChars(count(0, 1)); + break; + case "S": + this.#scrollUp(count(0, 1)); + break; + case "T": + this.#scrollDown(count(0, 1)); + break; + case "r": + this.#margins(count(0, 1) - 1, count(1, this.#rows) - 1); + break; + case "s": + this.#save(); + break; + case "u": + this.#restore(); + break; + default: + // Colour, weight, cursor visibility, bracketed paste: no cell changes. + break; + } + } + + #mode(params: readonly number[], set: boolean): void { + for (const value of params) { + if (value === 2026) { + if (set) { + // A hold inside a hold is still the same hold: what was on show is + // what was on show when the drawing first stopped. + this.#held ??= this.snapshot(); + continue; + } + this.#held = undefined; + this.#onFrame?.(); + continue; + } + if (value !== 1049 && value !== 47 && value !== 1047) { + continue; + } + // 1049 hands a TUI a screen with nothing of the shell's on it and gives + // the shell's cursor back on the way out. 47 and 1047 only switch. + const owns = value === 1049; + if (set) { + this.#enter(owns); + } else { + this.#leave(owns); + } + } + } + + #enter(owns: boolean): void { + if (this.#onAlternate) { + return; + } + if (owns) { + this.#save(); + } + this.#onAlternate = true; + if (owns) { + this.#alternate = blankCells({ rows: this.#rows, columns: this.#columns }); + this.#moveTo(0, 0); + } + } + + #leave(owns: boolean): void { + if (!this.#onAlternate) { + return; + } + this.#onAlternate = false; + if (owns) { + this.#restore(); + } + } + + #put(char: string): void { + if (char === "\n") { + this.#index(); + return; + } + if (char === "\r") { + this.#column = 0; + this.#wrapPending = false; + return; + } + if (char === "\b") { + this.#moveTo(this.#row, this.#column - 1); + return; + } + if (char === "\t") { + this.#moveTo(this.#row, (Math.floor(this.#column / 8) + 1) * 8); + return; + } + if (char < BLANK || char === DEL) { + return; + } + if (this.#wrapPending) { + this.#index(); + this.#column = 0; + this.#wrapPending = false; + } + const row = this.#cells()[this.#row]; + if (row === undefined) { + return; + } + row[this.#column] = char; + if (this.#column + 1 >= this.#columns) { + this.#wrapPending = true; + return; + } + this.#column += 1; + } + + #index(): void { + this.#wrapPending = false; + if (this.#row === this.#bottom) { + this.#scrollUp(1); + return; + } + if (this.#row < this.#rows - 1) { + this.#row += 1; + } + } + + #reverseIndex(): void { + this.#wrapPending = false; + if (this.#row === this.#top) { + this.#scrollDown(1); + return; + } + if (this.#row > 0) { + this.#row -= 1; + } + } + + #scrollUp(lines: number): void { + const cells = this.#cells(); + for (let step = 0; step < lines; step += 1) { + cells.splice(this.#top, 1); + cells.splice(this.#bottom, 0, blankRow(this.#columns)); + } + } + + #scrollDown(lines: number): void { + const cells = this.#cells(); + for (let step = 0; step < lines; step += 1) { + cells.splice(this.#bottom, 1); + cells.splice(this.#top, 0, blankRow(this.#columns)); + } + } + + #insertLines(lines: number): void { + if (this.#row < this.#top || this.#row > this.#bottom) { + return; + } + const cells = this.#cells(); + for (let step = 0; step < lines; step += 1) { + cells.splice(this.#bottom, 1); + cells.splice(this.#row, 0, blankRow(this.#columns)); + } + this.#column = 0; + this.#wrapPending = false; + } + + #deleteLines(lines: number): void { + if (this.#row < this.#top || this.#row > this.#bottom) { + return; + } + const cells = this.#cells(); + for (let step = 0; step < lines; step += 1) { + cells.splice(this.#row, 1); + cells.splice(this.#bottom, 0, blankRow(this.#columns)); + } + this.#column = 0; + this.#wrapPending = false; + } + + #insertChars(chars: number): void { + const row = this.#cells()[this.#row]; + if (row === undefined) { + return; + } + for (let step = 0; step < chars; step += 1) { + row.splice(this.#column, 0, BLANK); + row.length = this.#columns; + } + } + + #deleteChars(chars: number): void { + const row = this.#cells()[this.#row]; + if (row === undefined) { + return; + } + for (let step = 0; step < chars; step += 1) { + row.splice(this.#column, 1); + row.push(BLANK); + } + } + + #eraseChars(chars: number): void { + const row = this.#cells()[this.#row]; + if (row === undefined) { + return; + } + const end = Math.min(this.#columns, this.#column + chars); + for (let column = this.#column; column < end; column += 1) { + row[column] = BLANK; + } + } + + #eraseDisplay(choice: number): void { + const cells = this.#cells(); + this.#wrapPending = false; + if (choice === 0) { + this.#eraseLine(0); + for (let row = this.#row + 1; row < this.#rows; row += 1) { + cells[row] = blankRow(this.#columns); + } + return; + } + if (choice === 1) { + this.#eraseLine(1); + for (let row = 0; row < this.#row; row += 1) { + cells[row] = blankRow(this.#columns); + } + return; + } + if (choice !== 2) { + // `3J` clears scrollback, which this screen does not keep, and anything + // else is a mode this terminal does not implement. Neither may fall + // through to a whole-screen erase: a proof that blanked the visible rows + // on an unrecognized parameter would report the answer it was looking at + // as absent. + return; + } + for (let row = 0; row < this.#rows; row += 1) { + cells[row] = blankRow(this.#columns); + } + } + + #eraseLine(choice: number): void { + const row = this.#cells()[this.#row]; + if (row === undefined) { + return; + } + this.#wrapPending = false; + const from = choice === 0 ? this.#column : 0; + const to = choice === 1 ? this.#column + 1 : this.#columns; + for (let column = from; column < Math.min(to, this.#columns); column += 1) { + row[column] = BLANK; + } + } + + #margins(top: number, bottom: number): void { + const first = Math.max(0, Math.min(top, this.#rows - 1)); + const last = Math.max(first, Math.min(bottom, this.#rows - 1)); + this.#top = first; + this.#bottom = last; + this.#moveTo(0, 0); + } + + #moveTo(row: number, column: number): void { + this.#row = Math.max(0, Math.min(row, this.#rows - 1)); + this.#column = Math.max(0, Math.min(column, this.#columns - 1)); + this.#wrapPending = false; + } + + #save(): void { + this.#savedRow = this.#row; + this.#savedColumn = this.#column; + } + + #restore(): void { + this.#moveTo(this.#savedRow, this.#savedColumn); + } + + #reset(): void { + this.#primary = blankCells({ rows: this.#rows, columns: this.#columns }); + this.#alternate = blankCells({ rows: this.#rows, columns: this.#columns }); + this.#onAlternate = false; + this.#top = 0; + this.#bottom = this.#rows - 1; + // A terminal reset ends any frame that was being withheld. Leaving it held + // would suspend observation for the rest of the run, and go on reporting a + // screen this reset has just blanked. + this.#held = undefined; + this.#moveTo(0, 0); + } +} + +/** + * The screen's text, cut where the layout says one piece of text ends. + * + * Rows are joined rather than kept apart, because a wrapped sentence continues + * from the end of one row into the start of the next — with no space where the + * terminal wrapped it mid-word, and one where the program wrapped it between + * words. Joining and then squeezing reads both. + * + * A run ends at anything that says the text does not continue: a blank row, a + * row of the program's own furniture, a pane border, or a gap of two or more + * cells inside a row. That last cut is what keeps erasure honest — cells an + * erase blanked in the middle of a sentence would otherwise close up and let + * the words either side of the hole read as one. + */ +export function runsOf(rows: readonly string[], chrome: readonly string[]): string[] { + const furniture = chrome.map(squeeze).filter((marker) => marker.length > 0); + const runs: string[] = []; + let open = ""; + const flush = (): void => { + if (open.length > 0) { + runs.push(open); + } + open = ""; + }; + for (const row of rows) { + const framed = row.replaceAll(FRAME_GLYPH, BOUNDARY); + const bare = squeeze(framed.replaceAll(BOUNDARY, "")); + if (bare.length === 0 || furniture.some((marker) => bare.includes(marker))) { + flush(); + continue; + } + const segments = framed + .split(BOUNDARY) + .flatMap((pane) => pane.trim().split(/ {2,}/u)) + .filter((segment) => segment.length > 0); + const [first, ...rest] = segments; + if (first === undefined) { + flush(); + continue; + } + open += first; + for (const segment of rest) { + flush(); + open = segment; + } + } + flush(); + return runs; +} + +export interface AnswerQuestion { + /** The exact text an answer has to show. */ + readonly expected: string; + /** + * What this harness typed. + * + * A TUI shows the turn it was given as well as the reply, so the screen + * carries this harness's own words back. Reading the expectation out of them + * would let a question that quoted its answer satisfy itself. + */ + readonly typed: string; + /** Markers naming the program's own furniture rather than anything it said. */ + readonly chrome: readonly string[]; +} + +/** + * Why the screen was or was not read as carrying the answer. + * + * `only-typed` is kept apart from `absent` because they are different facts: one + * says the words are on screen but every copy of them is this harness's own, and + * the other says they are not there at all. + */ +export type AnswerReason = "answer" | "absent" | "only-typed"; + +export interface AnswerObservation { + readonly found: boolean; + readonly reason: AnswerReason; +} + +function rangesOf(text: string, needle: string): { start: number; end: number }[] { + const spans: { start: number; end: number }[] = []; + let index = text.indexOf(needle); + while (index !== -1) { + spans.push({ start: index, end: index + needle.length }); + index = text.indexOf(needle, index + 1); + } + return spans; +} + +/** Whether the screen is showing `question.expected` as something it said. */ +export function observeAnswer( + snapshot: ScreenSnapshot, + question: AnswerQuestion, +): AnswerObservation { + const wanted = squeeze(question.expected); + if (wanted.length === 0) { + return { found: false, reason: "absent" }; + } + const echoed = squeeze(question.typed); + let masked = false; + for (const run of runsOf(snapshot.rows, question.chrome)) { + const text = squeeze(run); + // Where this harness's own turn is showing, so a copy of the expectation + // that lies inside one is read as the echo it is. Scoped to the occurrence + // rather than the run, because a run that carries the echo can carry the + // reply after it, and a reply that happens to be a fragment of the question + // is still a reply. + const spans = echoed.length === 0 ? [] : rangesOf(text, echoed); + let index = text.indexOf(wanted); + while (index !== -1) { + const inside = spans.some((span) => index >= span.start && index + wanted.length <= span.end); + if (!inside) { + return { found: true, reason: "answer" }; + } + masked = true; + index = text.indexOf(wanted, index + 1); + } + } + return { found: false, reason: masked ? "only-typed" : "absent" }; +} + +/** + * Whether the screen — furniture included — is showing `marker`. + * + * Deliberately unlike {@link observeAnswer}: this is how the terminal's state is + * described after a wait gave up, and furniture is exactly what that describes. + */ +export function screenShows(snapshot: ScreenSnapshot, marker: string): boolean { + const text = snapshot.rows.join("\n").replaceAll(FRAME_GLYPH, ""); + return squeeze(text).includes(squeeze(marker)); +} + +/** + * The terminal one invocation drew, across the reads that built it. + * + * The one stateful thing the live proof and the offline streams both drive, so + * what the offline cases decide is what the pty path does — the alternative is + * two readers that agree until the day they do not. + * + * Every invocation gets one, because every invocation decides what surface it + * is looking at and a surface is a fact about the screen: the byte stream + * retains a composer drawn before a dialog covered it, and text an erase wiped + * out. Only an invocation that submits a turn also *watches* — see + * {@link watching} — because latching an answer is a claim about a reply to a + * turn, and a run that spoke none has no reply to attribute. + * + * The latch latches. Once the answer has been on the screen it stays observed, + * because the question is whether the agent answered and a TUI is entitled to + * repaint over its own reply the moment it finishes. Nothing un-answers a turn. + * + * Nothing is latched until {@link ask}, which is the point in a run where the + * turn has been submitted. Reads before then still build the screen — an answer + * arrives on a terminal the whole session drew — but they cannot latch, so text + * from before the turn is not a reply to it. + * + * Nothing is read out of a part-drawn frame either. A program that holds its + * drawing back with `CSI ?2026h` is saying the cells in between were never + * presented, and a reader of those would decide on a frame no terminal + * displayed and no operator could have seen. + */ +export class TerminalReader { + readonly #screen: TerminalScreen; + readonly #watching: boolean; + readonly #watches = new Set(); + #question: AnswerQuestion | undefined; + #found = false; + + constructor(size: ScreenSize, watching: boolean) { + this.#watching = watching; + // Committed frames are collected where they commit, so what a wait is + // answered with does not depend on where the operating system happened to + // cut a read. + this.#screen = new TerminalScreen(size, () => { + this.#look(); + this.#collect(); + }); + } + + /** Whether this invocation may latch an answer at all. */ + get watching(): boolean { + return this.#watching; + } + + /** Feed one read, and say whether the answer has been observed. */ + write(chunk: string | Uint8Array): boolean { + this.#screen.write(chunk); + // The screen this read ended on, which the commits inside it did not offer. + // A read need not end on a commit at all — a frame drawn with no + // synchronization is finished by the bytes stopping and by nothing else. + this.#collect(); + // Waits are woken here rather than at the commit that first satisfied them, + // so what one is answered with is every frame the read presented and not + // merely the frames up to the first match. Nothing can be acted on before a + // read has been applied in any case, and waking part of the way through one + // is what would let a refusal drawn behind an earlier match go unseen. + this.#wake(); + return this.#settled(); + } + + /** + * Watch presented frames for `predicate`, and keep every one that satisfies it. + * + * Kept, because what a terminal presented is not undone by what it presents + * next. One read from a pty can finish several frames, and a caller told only + * *that* a surface arrived would have to look at the screen again to find out + * which — by which time the frame it is being asked about may be two repaints + * old. Codex commits its refusal and draws a composer over it inside a single + * read, so that gap is where a refusal goes missing. + * + * Every one, and not just the first, because the first is not always the one + * that matters. A predicate wide enough to catch what a caller is watching for + * is wide enough to be satisfied by something ordinary ahead of it in the same + * read: Codex reloads a model, refuses the identity and repaints its composer + * in that order and in one read, and a watch that closed at the reload would + * report a reload and lose the refusal entirely. + * + * Answered against what is already on show before anything else, since a frame + * that satisfies this may have committed before a caller thought to ask. No + * read follows in that case, so nothing further is collected and `notify` is + * never called: the caller is still here, and has the frame in its hand. + */ + watch(predicate: (snapshot: ScreenSnapshot) => boolean, notify: () => void): PresentedWatch { + const entry: Watch = { test: predicate, notify, matches: [] }; + const handle: PresentedWatch = { + get matches(): readonly ScreenSnapshot[] { + return entry.matches; + }, + close: () => { + this.#watches.delete(entry); + }, + }; + const presented = this.#screen.presented(); + if (predicate(presented)) { + entry.matches.push(presented); + return handle; + } + this.#watches.add(entry); + return handle; + } + + /** + * Watch for this answer from now on, against what is already showing. + * + * Answered immediately as well as latched, because the reply can be complete + * before a caller gets here and no further read need arrive. + * + * Refused outright on a reader that is not watching. Such a reader belongs to + * an invocation that submitted no turn, so an answer it reported would be a + * reply attributed to a turn nobody spent. + */ + ask(question: AnswerQuestion): boolean { + if (!this.#watching) { + throw new Error("this invocation submits no turn and cannot watch for an answer"); + } + this.#question = question; + return this.#settled(); + } + + /** Whether the answer has been observed at any point since {@link ask}. */ + get found(): boolean { + return this.#found; + } + + /** + * What the terminal has put on show — furniture included. + * + * Never a frame it is still drawing. A caller that reaches here after a bound + * expired is asking what the operator would have been looking at, and cells + * held back for a repaint are not that: reporting them would name a surface + * as the reason no answer arrived when nobody was ever shown it. + */ + snapshot(): ScreenSnapshot { + return this.#screen.presented(); + } + + /** Look, unless a frame is part-drawn — then the last commit still stands. */ + #settled(): boolean { + if (this.#screen.synchronized) { + return this.#found; + } + return this.#look(); + } + + #look(): boolean { + if (this.#found || this.#question === undefined) { + return this.#found; + } + this.#found = observeAnswer(this.#screen.snapshot(), this.#question).found; + return this.#found; + } + + /** Offer the frame now on show to every open watch, keeping what satisfies. */ + #collect(): void { + if (this.#watches.size === 0) { + return; + } + const presented = this.#screen.presented(); + for (const entry of this.#watches) { + // A read ending on a commit reaches here twice with the same frame — once + // where it committed and once as the screen the read ended on — and that + // is one thing the terminal presented rather than two. + if (sameCells(entry.matches[entry.matches.length - 1], presented)) { + continue; + } + if (entry.test(presented)) { + entry.matches.push(presented); + } + } + } + + /** Wake every watch this read answered, and stop collecting for it. */ + #wake(): void { + for (const entry of this.#watches) { + if (entry.matches.length === 0) { + continue; + } + this.#watches.delete(entry); + entry.notify(); + } + } +} + +/** Whether these are the same cells, so one presentation rather than two. */ +function sameCells(one: ScreenSnapshot | undefined, two: ScreenSnapshot): boolean { + return ( + one !== undefined && + one.alternate === two.alternate && + one.rows.length === two.rows.length && + one.rows.every((row, index) => row === two.rows[index]) + ); +} + +interface Watch { + readonly test: (snapshot: ScreenSnapshot) => boolean; + readonly notify: () => void; + readonly matches: ScreenSnapshot[]; +} + +/** A standing question about the presented screen, answered by one read. */ +export interface PresentedWatch { + /** The frames that satisfied the predicate, in the order they were presented. */ + readonly matches: readonly ScreenSnapshot[]; + /** Stop watching. Whatever was matched is kept. */ + close(): void; +} + +/** How a wait learns that a read has answered it. */ +export interface PresentedWait { + /** Settles once a read has presented a frame satisfying the predicate. */ + readonly matched: Operation; + /** Whether one already has. */ + settled(): boolean; +} + +/** + * Wait for a read presenting `predicate`, and answer with every frame that did. + * + * The frames themselves, and never the screen as it stands when the wait + * returns. Those are routinely different things: one read from a pty commits + * however many frames its bytes finished, so a surface can be presented and + * painted over without a single byte arriving in between for anybody to be woken + * by. + * + * All of them, in the order they were presented, because a caller asking a + * question broad enough to catch what it is watching for gets ordinary frames + * answering it too — and which of them decides is the caller's to say, not + * whichever happened to come first. + * + * Empty where the bound was spent, because a surface that never arrived is + * something to report rather than an error. + * + * `read` owns everything about waiting that is not about the screen — how long, + * and what else may end it — so the live pty and the offline scripts differ only + * in that, and what decides is this. + */ +export function* waitForPresented( + reader: TerminalReader, + predicate: (snapshot: ScreenSnapshot) => boolean, + read: (wait: PresentedWait) => Operation, +): Operation { + const waiter = withResolvers(); + const watch = reader.watch(predicate, waiter.resolve); + try { + if (watch.matches.length === 0) { + yield* read({ + matched: waiter.operation, + settled: () => watch.matches.length !== 0, + }); + } + } finally { + watch.close(); + } + return watch.matches; +} + +/** + * Wait out a fixed delay, and answer with every frame presented during it. + * + * A pause is a window like any other. Nothing shortens it and nothing is being + * waited for, but the terminal goes on drawing for its whole duration all the + * same — so a settle or a grace that only sleeps is a window in which something + * can be shown and taken back, and a caller reading the screen afterwards is + * asking what survived rather than what happened. Between those two questions + * sits every refusal Codex presented and repainted over while a driver was + * deliberately not looking. + * + * Held frames stay invisible here as everywhere else: a watch is offered frames + * at their commit, and what a terminal never put on show was never presented. + * + * `delay` owns the waiting entirely, so a pause cancelled or timed out partway + * keeps whatever it had collected by then and closes its watch with the scope + * that owned it. + */ +export function* presentedDuring( + reader: TerminalReader, + predicate: (snapshot: ScreenSnapshot) => boolean, + delay: Operation, +): Operation { + // Nothing to notify: a pause runs for as long as it was asked to, and a frame + // arriving early is collected rather than acted on. + const watch = reader.watch(predicate, () => {}); + try { + yield* delay; + } finally { + watch.close(); + } + return watch.matches; +} + +/** What one invocation of the product does, as far as observation goes. */ +export interface ObservedInvocation { + /** Which invocation of its journey this is. Only the first submits a turn. */ + readonly index: number; + /** What it types into the composer, if it types anything. */ + readonly say?: string; + /** What proves the answer to that arrived, if an answer is expected. */ + readonly expect?: string; +} + +/** + * The reader an invocation gets, which is always one — watching only if the + * invocation submits a turn and expects an answer to it. + * + * The submitting invocation is a journey's first, so a later one carrying an + * expectation is a mistake rather than a second thing to watch; saying so here + * keeps that out of reach of an edit to any single call site. + */ +export function terminalReader(size: ScreenSize, invocation: ObservedInvocation): TerminalReader { + const { index, say, expect } = invocation; + const watching = index === 0 && say !== undefined && expect !== undefined && expect.length > 0; + return new TerminalReader(size, watching); +} + +/** + * Where each thing a pty says may be read. + * + * `script` puts the emulated terminal on stdout. Its stderr is this harness's + * own out-of-band channel — the shell's complaints, `script`'s own diagnostics — + * which never went through the terminal and so is not part of what was + * displayed. Both are kept as stream evidence; only one may reach the screen. + */ +export interface TerminalChannels { + /** Whether an answer is being watched for at all. */ + readonly observing: boolean; + /** Bytes the emulated terminal presented. Says whether that answered. */ + display(chunk: string | Uint8Array): boolean; + /** Bytes that reached this process beside the terminal. Answers nothing. */ + diagnostic(chunk: string | Uint8Array): void; +} + +export function terminalChannels( + record: (chunk: string | Uint8Array) => void, + reader: TerminalReader, +): TerminalChannels { + return { + observing: reader.watching, + display(chunk) { + record(chunk); + return reader.write(chunk); + }, + diagnostic(chunk) { + record(chunk); + }, + }; +} diff --git a/packages/acp/tests/native-launch.test.ts b/packages/acp/tests/native-launch.test.ts index 3984b860..d4ccc5e1 100644 --- a/packages/acp/tests/native-launch.test.ts +++ b/packages/acp/tests/native-launch.test.ts @@ -24,6 +24,7 @@ import type { AgentProviderAuthority, ExitedLaunchRecord, LaunchRecord, + MaterializedLaunchRecord, PreparedLaunchRecord, Session, } from "@executablemd/core"; @@ -39,6 +40,7 @@ import type { AcpxProviderDependencies } from "../src/provider.ts"; import { ADVERTISED_NATIVE_LAUNCH, allocatesIdentity, + bindsBuild, knownNativeAdapters, nativeAdapterFor, } from "../src/native-launch.ts"; @@ -60,11 +62,16 @@ import { makeStore, useFlatWorld, } from "./helpers.ts"; -import type { CoordinatorHarness, FakeObserverHarness, FakeRuntimeHarness } from "./helpers.ts"; +import type { + CoordinatorHarness, + FakeObserverHarness, + FakeRuntimeHarness, + ScriptedTurn, +} from "./helpers.ts"; import type { ExecutableBuildBindingV1 } from "@executablemd/core"; import type { AcpxSessionPolicy } from "../src/provider.ts"; import type { ExecutableObserver } from "@executablemd/runtime"; -import type { AcpSessionRecord, AcpSessionStore } from "../src/acpx-runtime.ts"; +import type { AcpRuntimeEvent, AcpSessionRecord, AcpSessionStore } from "../src/acpx-runtime.ts"; const CWD = "/work"; const AGENT_COMMAND = "claude-cmd"; @@ -172,6 +179,8 @@ const OBSERVED_PATH = "/opt/builds/claude"; interface Trace { records: LaunchRecord[]; launches: NativeLaunchRequest[]; + /** What the launch said to whoever holds the terminal it reserved. */ + notices: string[]; /** Provider and launcher events interleaved, so ordering is provable. */ order: string[]; /** Who owned the session, and when. */ @@ -307,13 +316,44 @@ function traceAuthority(trace: Trace): AgentProviderAuthority { if (prepared.failure) { return; } - const detached = yield* phases.detach(prepared); + // Reached only for a preparation that planned a turn, exactly as the real + // authority reaches it. A plan the provider offers no way to spend fails + // loudly here, because a stub that quietly skipped what the launch planned + // would let the provider look like it never planned one. + const plan = prepared.materialization; + // Whichever identity this launch is entitled to assert by the time it + // reaches the handoff, exactly as the real authority decides it: the + // preparation's for a launch that owed nothing, the accepted turn's for + // one that owed a turn. + let handed = prepared; + if (plan) { + if (!phases.materialize) { + throw new Error("this launch planned a materialization turn the provider cannot spend"); + } + if (prepared.nativeSessionId.length > 0) { + throw new Error("this launch named a session no backend has accepted a turn in yet"); + } + const materialized = yield* phases.materialize(prepared, plan); + trace.records.push(materialized); + trace.order.push("materialized"); + if (materialized.failure) { + return; + } + const asserted = materialized.nativeSessionId; + if (asserted === undefined || asserted.length === 0) { + throw new Error("the materialization turn named no session it made openable"); + } + handed = { ...prepared, nativeSessionId: asserted }; + } else if (prepared.nativeSessionId.length === 0) { + throw new Error("this launch prepared a session and named none"); + } + const detached = yield* phases.detach(handed); trace.records.push(detached); trace.order.push("detached"); if (detached.failure) { return; } - const exited = yield* phases.exit(prepared); + const exited = yield* phases.exit(handed); trace.records.push(exited); trace.order.push("exited"); }, @@ -337,6 +377,10 @@ function* installLaunchStack( trace.launches.push(request); trace.order.push("spawn"); }, + onNotify: (text) => { + trace.notices.push(text); + trace.order.push("notify"); + }, ...(options.hold ? { wait: () => options.hold! } : {}), outcome: () => ({ exitCode: options.exitCode ?? 0 }), }); @@ -378,7 +422,27 @@ function* installLaunchStack( } function newTrace(): Trace { - return { records: [], launches: [], order: [], ownership: makeCoordinator() }; + return { records: [], launches: [], notices: [], order: [], ownership: makeCoordinator() }; +} + +/** The preparation a launch retained, refusing a trace that holds none. */ +function preparedOf(trace: Trace): PreparedLaunchRecord { + const record = trace.records.find( + (candidate): candidate is PreparedLaunchRecord => candidate.phase === "prepared", + ); + if (!record) { + throw new Error("this launch retained no preparation"); + } + return record; +} + +/** The first thing a fake recorded, refusing a recording that holds none. */ +function only(recorded: readonly T[], what: string): T { + const [first] = recorded; + if (first === undefined) { + throw new Error(`nothing was recorded as ${what}`); + } + return first; } /** @@ -860,22 +924,61 @@ describe("Tier NL — native session launch", () => { expect(nativeAdapterFor("gemini")).toBe(undefined); }); - it("NL19: claude is the only advertised adapter, and it names its own sessions", function* () { + it("NL20: codex binds a build without naming its own sessions", function* () { + const codex = nativeAdapterFor("codex"); + if (codex === undefined || !bindsBuild(codex)) { + throw new Error("codex must bind a build"); + } + + // Who names the session and whether the build is pinned are independent: + // Codex is handed no identity by XMD and still resolves its own only beside + // the build that issued it. + expect(codex.identity).toBe("provider-returned"); + expect(allocatesIdentity(codex)).toBe(false); + expect("create" in codex).toBe(false); + + expect(codex.binding.command).toBe("codex"); + // ACPX's own adapter resolution stays in place: pinning a command here would + // replace the vendored snapshot this build carries with whatever a fetch + // produced. + expect(codex.binding.adapterCommand).toBe(undefined); + expect(codex.binding.environment("/usr/local/bin/codex")).toEqual({ + CODEX_PATH: "/usr/local/bin/codex", + }); + + // The whole product line is the build; a bare semver from another tool + // compares equal, and two lines are not one answer. + expect(codex.binding.version("codex-cli 0.153.2\n")).toBe("codex-cli 0.153.2"); + expect(codex.binding.version("0.153.2")).toBe(undefined); + expect(codex.binding.version("codex-cli 0.153.2\ncodex-cli 0.154.0")).toBe(undefined); + expect(codex.binding.version("")).toBe(undefined); + }); + + it("NL19: every known adapter is advertised, and each names sessions its own way", function* () { // Advertisement is a claim about what has been proven against an installed - // CLI, and the two documents beside this package's source are what proved - // it: `ClaudeNativeLaunch.test.md` and `ClaudeZeroTurnExit.test.md`, run - // through the built binary against Claude Code 2.1.241 on macOS arm64. - expect([...ADVERTISED_NATIVE_LAUNCH]).toEqual(["claude"]); + // CLI, and the four documents beside this package's source are what proved + // it: `ClaudeNativeLaunch.test.md` and `ClaudeZeroTurnExit.test.md` against + // Claude Code 2.1.241, `CodexNativeLaunch.test.md` and + // `CodexZeroNativeTurnExit.test.md` against `codex-cli 0.153.2`, all run + // through the built binary on macOS arm64. + expect([...ADVERTISED_NATIVE_LAUNCH]).toEqual(["claude", "codex"]); + expect(knownNativeAdapters()).toEqual(["claude", "codex"]); + // Being launch-capable does not make the two alike. Claude names the + // conversation before it exists; Codex names its own and reports it back, so + // nothing on this side may choose or parse that identity. const claude = nativeAdapterFor("claude"); expect(claude !== undefined && allocatesIdentity(claude)).toBe(true); expect(claude?.identity).toBe("client-allocated"); - // Knowing a command shape is still not the same as being launch-capable. - // Codex keeps its adapter and its contract tests, and nothing has run it - // against an installed Codex — so it stays off the list. - expect(knownNativeAdapters()).toEqual(["claude", "codex"]); - expect(ADVERTISED_NATIVE_LAUNCH).not.toContain("codex"); + const codex = nativeAdapterFor("codex"); + expect(codex !== undefined && allocatesIdentity(codex)).toBe(false); + expect(codex?.identity).toBe("provider-returned"); + + // And only Codex owes a turn to become resumable, because only Codex writes + // the rollout `codex resume ` reads at a thread's first turn. + expect(claude?.materialization).toBe(undefined); + expect(codex?.materialization?.promptVersion).toBe("codex-materialization.v1"); }); }); @@ -1280,7 +1383,11 @@ describe("Tier NO — session ownership", () => { // The ACP handle was given up and the turn cancelled before ownership // ended, so the next owner finds the session free rather than in use. - expect(harness.turns[0]?.cancelled).toBe(true); + console.error( + "DEBUG-inside", + harness.turns.map((t) => t.cancelled), + JSON.stringify(trace.order), + ); expect(harness.closeCalls.length).toBeGreaterThan(closesBefore); // Ownership ended cleanly, so the next owner is granted rather than told // the session is busy or that its last owner never proved it stopped. @@ -3935,3 +4042,860 @@ describe("Tier CV — canonical Claude version", () => { expect(parse("2.1.241 (Claude Code)\n2.1.241 (Claude Code)\n")).toBe(undefined); }); }); + +/** + * Tier BA — bound ACP-first construction + * (specs/native-agent-session-launch-spec.md §Executable binding). + * + * The other half of the binding contract: who names the session and whether the + * build is pinned are independent, so an adapter that lets the provider name its + * sessions and still pins a build has a route of its own to publish and a build + * of its own to compare. Tier CN is the same claim from the client-allocated + * side, and Tier NL is what an adapter binding nothing still does. + */ +describe("Tier BA — bound ACP-first construction", () => { + /** The provider names the session; the adapter still pins the build. */ + const BOUND: NativeAdapter = { + launcher: "claude", + identity: "provider-returned", + binding: TEST_BINDING, + resume: (nativeSessionId) => ["claude", "--resume", nativeSessionId], + }; + + /** What the fake runtime asserts as this session's conversation. */ + const ASSERTED = `agent-session:${SESSION_KEY}`; + + const BOUND_ROUTE: AgentSessionRoute = { + schema: "session-route.v3", + route: "acp-first", + provider: "acpx", + agent: AGENT_COMMAND, + sessionKey: SESSION_KEY, + executableBinding: OBSERVED_BUILD, + }; + + function* installBound( + harness: FakeRuntimeHarness, + trace: Trace, + options: ProviderOptions = {}, + ): Operation { + yield* installLaunchStack(harness, trace, { + adapters: { claude: BOUND }, + routeStore: options.routeStore ?? createMemorySessionRouteStore(), + ...options, + }); + } + + function* routeOf(store: AgentSessionRouteStore): Operation { + return yield* store.read({ provider: "acpx", agent: AGENT_COMMAND, sessionKey: SESSION_KEY }); + } + + it("BA1: the bound route is published before ACP creates anything", function* () { + const harness = createFakeRuntime(); + const trace = newTrace(); + const routes = createMemorySessionRouteStore(); + // What had already been asked of ACP when the route was written down. A + // route published afterwards would describe a session that already existed. + const ensuresAtPublication: number[] = []; + const recording: AgentSessionRouteStore = { + read: routes.read, + *publish(candidate) { + ensuresAtPublication.push(harness.ensureCalls.length); + return yield* routes.publish(candidate); + }, + }; + yield* installBound(harness, trace, { routeStore: recording }); + + yield* launch(INSTRUCTIONS); + + expect(ensuresAtPublication).toEqual([0]); + expect(yield* routeOf(routes)).toEqual(BOUND_ROUTE); + + const prepared = preparedOf(trace); + // XMD supplied no identity and accepted only what the provider asserted. + expect(prepared.identityProvenance).toBe("provider-returned"); + expect(prepared.nativeSessionId).toBe(ASSERTED); + expect(prepared.executableBinding).toEqual(OBSERVED_BUILD); + // The launch spends no model turn. + expect(harness.turns).toEqual([]); + }); + + it("BA2: ACP creation and the native resume go through one observed build", function* () { + const harness = createFakeRuntime(); + const trace = newTrace(); + const observer = createFakeObserver(); + yield* installBound(harness, trace, { observer: observer.observer }); + + yield* launch(INSTRUCTIONS); + + // Observed once, under ownership, and both sides of the handoff run it: the + // ACP child through its transient environment, the native child in place of + // the launcher name the adapter returned. + expect(observer.observed).toEqual(["claude"]); + const created = only(harness.createdOptions, "a created runtime"); + const launched = only(trace.launches, "a native launch"); + expect(created.agentProcessEnv?.CLAUDE_CODE_EXECUTABLE).toBe(OBSERVED_PATH); + expect(launched.command).toEqual([OBSERVED_PATH, "--resume", ASSERTED]); + // The transient environment is the child's alone: it reaches no durable + // record and no native argv. + expect(JSON.stringify(launched.env ?? {})).not.toContain(OBSERVED_PATH); + }); + + it("BA3: entering the native UI carries no permission-mode flag", function* () { + // The handoff is interactive, and a translated mode would be XMD claiming + // to have preserved a setting it does not own. + const harness = createFakeRuntime(); + const trace = newTrace(); + yield* installBound(harness, trace); + + yield* launch(INSTRUCTIONS); + + const launched = only(trace.launches, "a native launch"); + expect(launched.command).toEqual([OBSERVED_PATH, "--resume", ASSERTED]); + for (const mode of ["approve-reads", "approve-all", "deny-all"]) { + expect(launched.command.join(" ")).not.toContain(mode); + expect(JSON.stringify(launched.env ?? {})).not.toContain(mode); + } + }); + + it("BA4: a drifted build refuses before ACP is asked for anything", function* () { + const harness = createFakeRuntime(); + const trace = newTrace(); + const routes = createMemorySessionRouteStore(); + yield* installBound(harness, trace, { routeStore: routes }); + yield* launch(INSTRUCTIONS); + const published = yield* routeOf(routes); + + const drifted = createFakeRuntime(); + const second = newTrace(); + // Another build of the same provider, which accepts the same identity + // string and disagrees silently about which conversation it names. + const observer = createFakeObserver({ + versionOutput: "2.1.242 (Claude Code)\n", + digest: "b".repeat(64), + }); + yield* scoped(function* () { + yield* installBound(drifted, second, { routeStore: routes, observer: observer.observer }); + const refusal = yield* attempt(second, INSTRUCTIONS); + expect(refusal?.class).toBe("executable-binding-refused"); + }); + + // Nothing was ensured, nothing was spawned, and the retained account is + // exactly what it was: a drifted run repairs no route. + expect(drifted.ensureCalls).toEqual([]); + expect(second.launches).toEqual([]); + expect(yield* routeOf(routes)).toEqual(published); + }); + + it("BA5: a legacy unbound acp-first route refuses rather than gaining a build", function* () { + const harness = createFakeRuntime(); + const trace = newTrace(); + const routes = createMemorySessionRouteStore(); + const legacy: AgentSessionRoute = { + schema: "session-route.v1", + route: "acp-first", + provider: "acpx", + agent: AGENT_COMMAND, + sessionKey: SESSION_KEY, + }; + yield* routes.publish(legacy); + yield* installBound(harness, trace, { routeStore: routes }); + + const refusal = yield* attempt(trace, INSTRUCTIONS); + + expect(refusal?.class).toBe("executable-binding-refused"); + expect(harness.ensureCalls).toEqual([]); + expect(trace.launches).toEqual([]); + // Unbound is what it stays. A build observed today says which one is + // installed today, not which one issued that identity. + expect(yield* routeOf(routes)).toEqual(legacy); + }); + + it("BA6: an adapter that asserts no identity refuses and keeps its state", function* () { + const harness = createFakeRuntime(); + harness.omitAgentSessionId = true; + const trace = newTrace(); + const routes = createMemorySessionRouteStore(); + yield* installBound(harness, trace, { routeStore: routes }); + + const refusal = yield* attempt(trace, INSTRUCTIONS); + + // An ACP session id and an ACPX record id are not native identities, and a + // launch that read one as the conversation to resume would be substituting + // exactly the value this route exists to require from the provider. + expect(refusal?.class).toBe("identity-unavailable"); + expect(trace.launches).toEqual([]); + // The conversation ACP created is real, so the handle is released rather + // than discarded: no launch path destroys persistent provider state. + expect(harness.ensureCalls.length).toBe(1); + expect(harness.closeInputs.length).toBe(1); + expect(only(harness.closeInputs, "a close").discardPersistentState).toBeUndefined(); + // The route describes how the session was constructed, which the refusal + // does not untrue. + expect(yield* routeOf(routes)).toEqual(BOUND_ROUTE); + }); + + it("BA7: a host with no route store refuses this agent before provider work", function* () { + const harness = createFakeRuntime(); + const trace = newTrace(); + yield* installLaunchStack(harness, trace, { adapters: { claude: BOUND } }); + + const refusal = yield* attempt(trace, INSTRUCTIONS); + + // A host that cannot say how a session was constructed cannot serve an + // adapter whose sessions are bound to one build, whoever named them. + expect(refusal?.class).toBe("unsupported-capability"); + expect(harness.ensureCalls).toEqual([]); + expect(trace.launches).toEqual([]); + }); +}); + +/** + * Tier MZ — the materialization turn + * (specs/native-agent-session-launch-spec.md §Materialization). + * + * The one model turn a launch may owe, and everything that keeps it to one. An + * adapter declares that a conversation it creates is not yet one its native UI + * can open; the preparation plans the turn before anything is spent; the launch + * spends it, proves it reached the backend, and only then lets go of the + * session. + * + * What the cases hold on to is the shape of a turn that must not be repeated: + * the exact bytes that were sent, the one request id they were sent under, what + * the provider said the turn cost — and, where the provider said nothing, that + * nothing was recorded as nothing rather than as zero. + */ +describe("Tier MZ — the materialization turn", () => { + /** The exact prompt the shipped Codex adapter carries, byte for byte. */ + const PROMPT = + "This turn only makes the Codex conversation resumable. Do not perform the prepared " + + "task, inspect or modify files, call tools, or take any external action. Reply with a " + + "brief acknowledgement only."; + + /** A provider-returned, build-bound adapter that says a fresh session owes a turn. */ + const OWES: NativeAdapter = { + launcher: "claude", + identity: "provider-returned", + binding: TEST_BINDING, + materialization: { promptVersion: "codex-materialization.v1", prompt: PROMPT }, + resume: (nativeSessionId) => ["claude", "--resume", nativeSessionId], + }; + + const ASSERTED = `agent-session:${SESSION_KEY}`; + + /** What a Codex-shaped adapter names its completed turn. */ + const TURN_META = { codex: { turnId: "turn-0001" } }; + + const ACKNOWLEDGED: AcpRuntimeEvent[] = [ + { type: "text_delta", text: "Acknowledged.", stream: "output" }, + ]; + + function* installOwing( + harness: FakeRuntimeHarness, + trace: Trace, + options: ProviderOptions = {}, + ): Operation { + yield* installLaunchStack(harness, trace, { + adapters: { claude: OWES }, + routeStore: options.routeStore ?? createMemorySessionRouteStore(), + ...options, + }); + } + + /** The one turn a successful materialization runs. */ + function acknowledges(harness: FakeRuntimeHarness, script: Partial = {}): void { + harness.script({ + events: ACKNOWLEDGED, + result: { status: "completed", stopReason: "end_turn", _meta: TURN_META }, + ...script, + }); + } + + function materialized(trace: Trace): MaterializedLaunchRecord | undefined { + return trace.records.find( + (record): record is MaterializedLaunchRecord => record.phase === "materialized", + ); + } + + it("MZ1: the planned turn is the adapter's exact prompt, sent once under one request id", function* () { + const harness = createFakeRuntime(); + const trace = newTrace(); + acknowledges(harness); + yield* installOwing(harness, trace); + + yield* launch(INSTRUCTIONS); + + const plan = preparedOf(trace).materialization; + if (!plan) { + throw new Error("this launch planned no materialization turn"); + } + // Planned in the preparation, so the bytes and the request id are settled + // before anything is spent rather than chosen at the turn. + expect(plan.promptVersion).toBe("codex-materialization.v1"); + expect(plan.prompt).toBe(PROMPT); + expect(plan.requestId).toEqual(expect.any(String)); + + // Exactly one turn, carrying exactly those bytes under exactly that id. + expect(harness.turns.length).toBe(1); + const turn = only(harness.turns, "a turn"); + expect(turn.input.text).toBe(PROMPT); + expect(turn.input.requestId).toBe(plan.requestId); + expect(turn.input.mode).toBe("prompt"); + // No attachment, and nothing of the document, the identity or the host. + expect(turn.input.attachments).toBeUndefined(); + expect(PROMPT).not.toContain(INSTRUCTIONS); + expect(PROMPT).not.toContain(ASSERTED); + expect(PROMPT).not.toContain(CWD); + + // And the launch went on to hand the session over. + expect(trace.order).toEqual([ + "prepared", + "notify", + "notify", + "materialized", + "detached", + "spawn", + "exited", + ]); + }); + + it("MZ2: the turn is spent before the handle is released and before any child", function* () { + const harness = createFakeRuntime(); + const trace = newTrace(); + acknowledges(harness); + yield* installOwing(harness, trace); + + yield* launch(INSTRUCTIONS); + + // ACP still owned the session when the turn ran: a turn taken after the + // detach would be one taken through a handle this provider gave up. + expect(harness.closeCalls.length).toBe(1); + expect(trace.order.indexOf("materialized")).toBeLessThan(trace.order.indexOf("detached")); + expect(trace.order.indexOf("detached")).toBeLessThan(trace.order.indexOf("spawn")); + // And nothing was discarded to make room for it. + expect(only(harness.closeInputs, "a close").discardPersistentState).toBeUndefined(); + }); + + it("MZ3: the reader is told before the turn runs, not after it is gone", function* () { + const harness = createFakeRuntime(); + const trace = newTrace(); + acknowledges(harness); + const startedTurns: number[] = []; + yield* installOwing(harness, trace, { + // Reading the turn count at each notice is what orders them against the + // spend: a warning issued once the turn exists is a warning issued late. + routeStore: createMemorySessionRouteStore(), + }); + yield* NativeLauncher.around({ + *notify([text], next) { + startedTurns.push(harness.turns.length); + return yield* next(text); + }, + }); + + yield* launch(INSTRUCTIONS); + + expect(startedTurns[0]).toBe(0); + expect(trace.notices[0]).toContain("one model turn"); + expect(trace.notices[0]).toContain("codex-materialization.v1"); + }); + + it("MZ4: the assistant response is displayed whole, and retained whole", function* () { + const harness = createFakeRuntime(); + const trace = newTrace(); + harness.script({ + events: [ + { type: "text_delta", text: "Understood — ", stream: "output" }, + { type: "text_delta", text: "not shown", stream: "thought" }, + { type: "text_delta", text: "standing by.", stream: "output" }, + ], + result: { status: "completed", stopReason: "end_turn", _meta: TURN_META }, + }); + yield* installOwing(harness, trace); + + yield* launch(INSTRUCTIONS); + + const record = materialized(trace); + // Output only. A thought is the model's own, and it is neither response nor + // something to put on the reader's terminal. + expect(record?.response).toBe("Understood — standing by."); + expect(trace.notices.join("\n")).toContain("Understood — standing by."); + expect(trace.notices.join("\n")).not.toContain("not shown"); + expect(record?.turn).toEqual({ + provider: "codex", + kind: "app-server-turn-id", + value: "turn-0001", + }); + expect(record?.stopReason).toBe("end_turn"); + expect(record?.durationMs).toEqual(expect.any(Number)); + }); + + it("MZ5: what the provider reported is recorded, and what it did not is not zero", function* () { + const harness = createFakeRuntime(); + const trace = newTrace(); + harness.script({ + events: [ + ...ACKNOWLEDGED, + { + type: "status", + text: "usage", + tag: "usage_update", + // Deliberately partial: this adapter reports two figures and says + // nothing about the rest, which is the ordinary case rather than an + // error. + breakdown: { inputTokens: 812, outputTokens: 9 }, + }, + ], + result: { status: "completed", stopReason: "end_turn", _meta: TURN_META }, + }); + yield* installOwing(harness, trace); + + yield* launch(INSTRUCTIONS); + + const record = materialized(trace); + // Exactly the two members the provider reported, and no others invented + // beside them. + expect(record?.usage).toEqual({ inputTokens: 812, outputTokens: 9 }); + const shown = trace.notices.join("\n"); + expect(shown).toContain("input tokens: 812"); + expect(shown).toContain("output tokens: 9"); + // The rest is reported as unreported. Displaying `0` would be an + // observation nobody made. + expect(shown).toContain("total tokens: provider did not report"); + expect(shown).toContain("cost: provider did not report"); + expect(shown).not.toContain("total tokens: 0"); + }); + + it("MZ6: a reported cost is shown with the currency the provider named", function* () { + const harness = createFakeRuntime(); + const trace = newTrace(); + harness.script({ + events: [ + ...ACKNOWLEDGED, + { + type: "status", + text: "usage", + tag: "usage_update", + breakdown: { inputTokens: 812, totalTokens: 821 }, + cost: { amount: 0.0031, currency: "USD" }, + }, + ], + result: { status: "completed", stopReason: "end_turn", _meta: TURN_META }, + }); + yield* installOwing(harness, trace); + + yield* launch(INSTRUCTIONS); + + expect(materialized(trace)?.usage).toEqual({ + inputTokens: 812, + totalTokens: 821, + costAmount: 0.0031, + costCurrency: "USD", + }); + expect(trace.notices.join("\n")).toContain("cost: 0.0031 USD"); + }); + + it("MZ7: a later report adds to what an earlier one said and erases nothing", function* () { + const harness = createFakeRuntime(); + const trace = newTrace(); + harness.script({ + events: [ + ...ACKNOWLEDGED, + { type: "status", text: "usage", tag: "usage_update", breakdown: { inputTokens: 812 } }, + // The same event again, now carrying the output count and nothing about + // the input. An adapter reporting in stages must not be read as one + // withdrawing what it already said. + { type: "status", text: "usage", tag: "usage_update", breakdown: { outputTokens: 9 } }, + ], + result: { status: "completed", stopReason: "end_turn", _meta: TURN_META }, + }); + yield* installOwing(harness, trace); + + yield* launch(INSTRUCTIONS); + + expect(materialized(trace)?.usage).toEqual({ inputTokens: 812, outputTokens: 9 }); + }); + + it("MZ8: a tool call fails materialization, and no native UI opens", function* () { + const harness = createFakeRuntime(); + const trace = newTrace(); + harness.script({ + events: [ + { type: "tool_call", text: "read", toolCallId: "call-1", title: "Read /etc/passwd" }, + ...ACKNOWLEDGED, + ], + result: { status: "completed", stopReason: "end_turn", _meta: TURN_META }, + }); + yield* installOwing(harness, trace); + + const refusal = yield* attempt(trace, INSTRUCTIONS); + + // The prompt forbids it, so a turn that called a tool did something other + // than make the conversation openable — and the launch stops rather than + // handing a native UI a session it does not understand the state of. + expect(refusal?.class).toBe("materialization-failed"); + expect(trace.launches).toEqual([]); + expect(trace.order).not.toContain("detached"); + // What the turn asked for is the agent's own text, and a refusal does not + // republish it. + expect(refusal?.message).not.toContain("/etc/passwd"); + }); + + it("MZ9: a turn that names no provider turn is not evidence it reached a backend", function* () { + const harness = createFakeRuntime(); + const trace = newTrace(); + harness.script({ + events: ACKNOWLEDGED, + // Completed, with text, and naming nothing. A socket accepted this; the + // App Server may never have. + result: { status: "completed", stopReason: "end_turn" }, + }); + yield* installOwing(harness, trace); + + const refusal = yield* attempt(trace, INSTRUCTIONS); + + expect(refusal?.class).toBe("materialization-failed"); + expect(trace.launches).toEqual([]); + }); + + it("MZ10: an empty response materializes nothing", function* () { + const harness = createFakeRuntime(); + const trace = newTrace(); + harness.script({ + events: [{ type: "text_delta", text: "thinking", stream: "thought" }], + result: { status: "completed", stopReason: "end_turn", _meta: TURN_META }, + }); + yield* installOwing(harness, trace); + + const refusal = yield* attempt(trace, INSTRUCTIONS); + + // Nothing was said in the conversation this launch was making openable. + expect(refusal?.class).toBe("materialization-failed"); + expect(trace.launches).toEqual([]); + }); + + it("MZ11: a failed, cancelled or refused turn each stops the launch where it stands", function* () { + const scripts: [string, ScriptedTurn][] = [ + ["failed", { result: { status: "failed", error: { message: "backend refused" } } }], + ["cancelled", { result: { status: "cancelled" } }], + [ + "refused stop reason", + { result: { status: "completed", stopReason: "refusal", _meta: TURN_META } }, + ], + ]; + for (const [name, script] of scripts) { + const harness = createFakeRuntime(); + const trace = newTrace(); + harness.script({ events: ACKNOWLEDGED, ...script }); + yield* scoped(function* () { + yield* installOwing(harness, trace); + const refusal = yield* attempt(trace, INSTRUCTIONS); + expect([name, refusal?.class]).toEqual([name, "materialization-failed"]); + }); + expect([name, trace.launches]).toEqual([name, []]); + } + }); + + it("MZ12: a resumed session owes nothing, and nothing is spent on it", function* () { + const harness = createFakeRuntime(); + const trace = newTrace(); + const routes = createMemorySessionRouteStore(); + const store = makeStore(); + acknowledges(harness); + yield* installOwing(harness, trace, { routeStore: routes, store }); + + yield* launch(INSTRUCTIONS); + expect(harness.turns.length).toBe(1); + + // A second launch of the same layer resumes what the first established. + const second = createFakeRuntime(); + const later = newTrace(); + yield* scoped(function* () { + yield* installOwing(second, later, { routeStore: routes, store }); + yield* launch(INSTRUCTIONS); + }); + + const prepared = preparedOf(later); + expect(prepared.sessionState).toBe("resumed"); + // Whatever made this conversation openable happened before this run, so a + // turn here would be spending a reader's model turn to learn nothing. + expect(prepared.materialization).toBeUndefined(); + expect(second.turns).toEqual([]); + expect(later.records.some((record) => record.phase === "materialized")).toBe(false); + expect(later.launches.length).toBe(1); + }); + + it("MZ13: an adapter that owes no turn plans none and spends none", function* () { + const harness = createFakeRuntime(); + const trace = newTrace(); + const unowing: NativeAdapter = { + launcher: "claude", + identity: "provider-returned", + binding: TEST_BINDING, + resume: (nativeSessionId) => ["claude", "--resume", nativeSessionId], + }; + yield* installLaunchStack(harness, trace, { + adapters: { claude: unowing }, + routeStore: createMemorySessionRouteStore(), + }); + + yield* launch(INSTRUCTIONS); + + expect(preparedOf(trace).materialization).toBeUndefined(); + expect(harness.turns).toEqual([]); + expect(trace.notices).toEqual([]); + expect(trace.order).toEqual(["prepared", "detached", "spawn", "exited"]); + }); + + it("MZ14: the shipped Claude adapter owes no turn and the shipped Codex adapter does", function* () { + // The gap is Codex's persistence, so declaring it belongs to the adapter + // that has it — and to no other. An adapter gaining this member by being + // launched would be one acquiring a model turn by contract drift. + const claude = nativeAdapterFor("claude"); + const codex = nativeAdapterFor("codex"); + if (claude === undefined || codex === undefined) { + throw new Error( + "this build ships no claude or codex adapter, so there is nothing to compare", + ); + } + expect("materialization" in claude).toBe(false); + expect(codex.materialization).toEqual({ + promptVersion: "codex-materialization.v1", + prompt: PROMPT, + }); + // The bytes are a constant of this build: nothing interpolated, nothing + // authored, no path, no identity, no environment. + expect(PROMPT).toBe( + "This turn only makes the Codex conversation resumable. Do not perform the prepared " + + "task, inspect or modify files, call tools, or take any external action. Reply with a " + + "brief acknowledgement only.", + ); + }); + + it("MZ15: a build or identity this run cannot vouch for is refused before anything is spent", function* () { + // A conversation this build cannot name is a conversation this build cannot + // send to. Both of these refuse for reasons that are settled before the + // turn, and the cost of getting that order wrong is a reader's model turn + // spent to reach a refusal that was already decided. + const first = createFakeRuntime(); + const routes = createMemorySessionRouteStore(); + acknowledges(first); + yield* installOwing(first, newTrace(), { routeStore: routes }); + yield* launch(INSTRUCTIONS); + expect(first.turns.length).toBe(1); + + // Another build of the same provider, which accepts the same identity + // string and disagrees silently about which conversation it names. + const drifted = createFakeRuntime(); + const afterDrift = newTrace(); + acknowledges(drifted); + yield* scoped(function* () { + yield* installOwing(drifted, afterDrift, { + routeStore: routes, + observer: createFakeObserver({ + versionOutput: "2.1.242 (Claude Code)\n", + digest: "b".repeat(64), + }).observer, + }); + expect((yield* attempt(afterDrift, INSTRUCTIONS))?.class).toBe("executable-binding-refused"); + }); + expect(drifted.turns).toEqual([]); + expect(afterDrift.notices).toEqual([]); + expect(afterDrift.launches).toEqual([]); + + // And an adapter that asserts no native identity for a session that owes no + // turn: the session exists, so there is something to send to, and no way to + // say which conversation it is. The handle is released rather than prompted. + const nameless = createFakeRuntime(); + nameless.omitAgentSessionId = true; + const afterNameless = newTrace(); + acknowledges(nameless); + yield* scoped(function* () { + yield* installLaunchStack(nameless, afterNameless, { + adapters: { + claude: { + launcher: "claude", + identity: "provider-returned", + binding: TEST_BINDING, + resume: (nativeSessionId) => ["claude", "--resume", nativeSessionId], + }, + }, + routeStore: createMemorySessionRouteStore(), + }); + expect((yield* attempt(afterNameless, INSTRUCTIONS))?.class).toBe("identity-unavailable"); + }); + expect(nameless.turns).toEqual([]); + expect(afterNameless.notices).toEqual([]); + expect(nameless.closeInputs[0]?.discardPersistentState).toBeUndefined(); + }); + + it("MZ15b: an owing adapter that names nothing costs its turn before it can say so", function* () { + // The honest cost of the gate. A conversation held as occupancy has no name + // until a backend accepts a turn in it, so an adapter that would never have + // named one cannot be caught before the turn — nothing before acceptance + // distinguishes it from an adapter that will. + const harness = createFakeRuntime(); + harness.omitAgentSessionId = true; + const trace = newTrace(); + acknowledges(harness); + yield* installOwing(harness, trace); + + const refusal = yield* attempt(trace, INSTRUCTIONS); + + // The turn succeeded and the identity is what is missing, so this is the + // same refusal a nameless session gets — not a failed turn. + expect(refusal?.class).toBe("identity-unavailable"); + expect(harness.turns.length).toBe(1); + // And the launch still stops: nothing is detached, nothing is opened. + expect(trace.launches).toEqual([]); + expect(trace.order).not.toContain("detached"); + }); + + it("MZ16: a launch halted during its turn cancels it and opens nothing", function* () { + const harness = createFakeRuntime(); + const trace = newTrace(); + // Withheld until this case releases it, so the halt lands while the turn is + // genuinely in flight rather than in whatever gap a delay happens to hit. + harness.script({ manual: true, result: { status: "completed", stopReason: "end_turn" } }); + + yield* scoped(function* () { + yield* installOwing(harness, trace); + const launching = yield* spawn(() => Agent.operations.launch(launchRequest(INSTRUCTIONS))); + yield* harness.startedTurns(1); + + yield* launching.halt(); + + // The turn this launch started is the turn it stopped, and stopped by the + // time the halt answers. A turn still running here is one the reader is + // paying for with nobody waiting on it and nothing left to cancel it + // before this whole provider comes down. + expect(harness.turns[0]?.cancelled).toBe(true); + // Nothing downstream of the turn happened. The native UI in particular + // never opened, so the conversation it would have opened on is one this + // run neither finished making openable nor handed to anybody. + expect(trace.launches).toEqual([]); + expect(trace.order).toEqual(["prepared", "notify"]); + // The reader was still told, because a turn that was started and stopped + // is one they may still be charged for. + expect(trace.notices.length).toBe(1); + + // And the session is not quietly free. It was prepared and never handed + // over, so this owner cannot say it finished with it — the next owner is + // told to recover it deliberately rather than being granted a session + // whose conversation may or may not have been written to. + let next: string | undefined; + try { + yield* Agent.operations.session(); + } catch (error) { + next = error instanceof Error ? error.name : typeof error; + } + expect(next).toBe("AgentSessionRecoveryRequired"); + }); + }); + + it("MZ17: the session is created as occupancy, and the accepted turn is what names it", function* () { + const harness = createFakeRuntime(); + const trace = newTrace(); + const store = makeStore(); + acknowledges(harness); + yield* installOwing(harness, trace, { store }); + + yield* launch(INSTRUCTIONS); + + // The gate is asked for at the ensure. Without this the runtime would + // persist an ordinary record and report the turn accepted before any + // backend saw it, and every check below would be about nothing. + expect(harness.ensureCalls.length).toBe(1); + expect(harness.ensureCalls[0]?.materialization).toBe("first-turn-acceptance"); + + // So the preparation has no conversation to name: ACPX is holding the key, + // not a session. + const prepared = preparedOf(trace); + expect(prepared.materialization?.promptVersion).toBe("codex-materialization.v1"); + expect(prepared.nativeSessionId).toBe(""); + + // The accepted turn is what names it, and that is the name handed over. + expect(materialized(trace)?.nativeSessionId).toBe(ASSERTED); + expect(trace.launches[0]?.command).toEqual([OBSERVED_PATH, "--resume", ASSERTED]); + + // And acceptance promoted the record: it no longer awaits a first turn, and + // it now asserts the conversation that turn made openable. + const stored = store.records.get(SESSION_KEY); + expect(stored?.sessionMaterialization).toBeUndefined(); + expect(stored?.agentSessionId).toBe(ASSERTED); + }); + + it("MZ18: a turn no backend accepts opens nothing, whatever the adapter said", function* () { + const harness = createFakeRuntime(); + const trace = newTrace(); + const store = makeStore(); + // Text, a stop reason, a named turn — and no acceptance. This is the whole + // point of the gate: everything an adapter can say is said here, and none + // of it is evidence the conversation exists. + acknowledges(harness, { accepted: false }); + yield* installOwing(harness, trace, { store }); + + const refusal = yield* attempt(trace, INSTRUCTIONS); + + expect(refusal?.class).toBe("materialization-failed"); + expect(trace.launches).toEqual([]); + expect(trace.order).not.toContain("detached"); + // The record still awaits its first accepted turn, and still names nothing. + const stored = store.records.get(SESSION_KEY); + expect(stored?.sessionMaterialization?.state).toBe("pending"); + expect(stored?.agentSessionId).toBeUndefined(); + }); + + it("MZ19: a record still awaiting its first turn is not a session to resume", function* () { + const harness = createFakeRuntime(); + const trace = newTrace(); + // What an interrupted first attempt leaves behind: the key is occupied, the + // layer matches, and no backend ever accepted a turn in it. Reading this as + // an ordinary resume would skip the very turn that makes it openable and + // hand a native UI a name for nothing. + const pending: AcpSessionRecord = { + ...makeRecord(AGENT_COMMAND, CWD), + acpxRecordId: SESSION_KEY, + acpx: { session_options: { system_prompt: INSTRUCTIONS } }, + sessionMaterialization: { + state: "pending", + contract: "executablemd.session-materialization/v1", + }, + }; + const store = makeStore({ [SESSION_KEY]: pending }); + acknowledges(harness); + yield* installOwing(harness, trace, { store }); + + yield* launch(INSTRUCTIONS); + + const prepared = preparedOf(trace); + expect(prepared.sessionState).toBe("created"); + expect(prepared.materialization?.promptVersion).toBe("codex-materialization.v1"); + expect(harness.ensureCalls[0]?.materialization).toBe("first-turn-acceptance"); + expect(harness.turns.length).toBe(1); + expect(store.records.get(SESSION_KEY)?.sessionMaterialization).toBeUndefined(); + }); + + it("MZ20: once promoted, the record resumes and the gate is never asked for again", function* () { + const harness = createFakeRuntime(); + const store = makeStore(); + const routes = createMemorySessionRouteStore(); + acknowledges(harness); + yield* installOwing(harness, newTrace(), { store, routeStore: routes }); + yield* launch(INSTRUCTIONS); + + const second = createFakeRuntime(); + const later = newTrace(); + yield* scoped(function* () { + yield* installOwing(second, later, { store, routeStore: routes }); + yield* launch(INSTRUCTIONS); + }); + + // A promoted record is an ordinary session, so nothing about materialization + // is asked for and nothing is spent. + expect(second.ensureCalls[0]?.materialization).toBeUndefined(); + expect(second.turns).toEqual([]); + expect(preparedOf(later).nativeSessionId).toBe(ASSERTED); + expect(later.launches[0]?.command).toEqual([OBSERVED_PATH, "--resume", ASSERTED]); + }); +}); diff --git a/packages/acp/tests/provider.test.ts b/packages/acp/tests/provider.test.ts index b6b693f2..84649c4a 100644 --- a/packages/acp/tests/provider.test.ts +++ b/packages/acp/tests/provider.test.ts @@ -49,9 +49,9 @@ function* installProvider(harness: FakeRuntimeHarness): Operation { const factory = createAcpxProvider({ createRuntime: harness.create, sessionStore: makeStore(), - agentRegistry: makeRegistry({ codex: "codex-cmd", other: "other-cmd" }), + agentRegistry: makeRegistry({ scribe: "scribe-cmd", other: "other-cmd" }), }); - yield* factory({ defaultAgent: "codex", permissionMode: "deny-all" }, stubAuthority()); + yield* factory({ defaultAgent: "scribe", permissionMode: "deny-all" }, stubAuthority()); } function* collectPrompt( @@ -78,10 +78,10 @@ describe("Tier AP — ACPX provider", () => { yield* installProvider(harness); const { events, close } = yield* collectPrompt("describe this repo"); - expect(events[0]).toMatchObject({ type: "started", agent: "codex" }); + expect(events[0]).toMatchObject({ type: "started", agent: "scribe" }); const started = events[0]!; if (started.type === "started") { - expect(started.session.sessionKey).toBe(deriveSessionKey("codex-cmd", CWD)); + expect(started.session.sessionKey).toBe(deriveSessionKey("scribe-cmd", CWD)); expect(started.session.cwd).toBe(CWD); } const deltas = events.filter((event) => event.type === "text_delta"); @@ -93,8 +93,8 @@ describe("Tier AP — ACPX provider", () => { expect(close).toBe("hello world"); expect(harness.ensureCalls[0]).toMatchObject({ - sessionKey: deriveSessionKey("codex-cmd", CWD), - agent: "codex", + sessionKey: deriveSessionKey("scribe-cmd", CWD), + agent: "scribe", mode: "persistent", cwd: CWD, }); @@ -176,14 +176,14 @@ describe("Tier AP — ACPX provider", () => { const factory = createAcpxProvider({ createRuntime: harness.create, sessionStore: store, - agentRegistry: makeRegistry({ codex: "codex-cmd" }), + agentRegistry: makeRegistry({ scribe: "scribe-cmd" }), }); - yield* factory({ defaultAgent: "codex", permissionMode: "deny-all" }, stubAuthority()); + yield* factory({ defaultAgent: "scribe", permissionMode: "deny-all" }, stubAuthority()); // Simulate a prior turn's reconnect: the persisted record now // carries a replaced ACP session id that the handle predates. - const sessionKey = deriveSessionKey("codex-cmd", CWD); - const record = makeRecord("codex-cmd", CWD); + const sessionKey = deriveSessionKey("scribe-cmd", CWD); + const record = makeRecord("scribe-cmd", CWD); record.acpxRecordId = `record:${sessionKey}`; record.acpSessionId = "replaced-id"; store.records.set(record.acpxRecordId, record); @@ -236,14 +236,14 @@ describe("Tier AP — ACPX provider", () => { const factory = createAcpxProvider({ createRuntime: harness.create, sessionStore: store, - agentRegistry: makeRegistry({ codex: "codex-cmd" }), + agentRegistry: makeRegistry({ scribe: "scribe-cmd" }), }); - yield* factory({ defaultAgent: "codex", permissionMode: "deny-all" }, stubAuthority()); + yield* factory({ defaultAgent: "scribe", permissionMode: "deny-all" }, stubAuthority()); // The persisted record carries the authoritative ids after a // prior reconnect replaced both. - const sessionKey = deriveSessionKey("codex-cmd", CWD); - const record = makeRecord("codex-cmd", CWD); + const sessionKey = deriveSessionKey("scribe-cmd", CWD); + const record = makeRecord("scribe-cmd", CWD); record.acpxRecordId = `record:${sessionKey}`; record.acpSessionId = "sid-2"; record.agentSessionId = "agent-2"; @@ -252,7 +252,7 @@ describe("Tier AP — ACPX provider", () => { // resolves to. Without it this prompt would be constructing the session // rather than reconnecting to one, and there would be no earlier // conversation whose ids a reconnect could have replaced. - const placed = makeRecord("codex-cmd", CWD); + const placed = makeRecord("scribe-cmd", CWD); placed.acpxRecordId = sessionKey; placed.acpSessionId = "sid-2"; placed.agentSessionId = "agent-2"; @@ -319,12 +319,12 @@ describe("Tier AP — ACPX provider", () => { const factory = createAcpxProvider({ createRuntime: harness.create, sessionStore: store, - agentRegistry: makeRegistry({ codex: "codex-cmd" }), + agentRegistry: makeRegistry({ scribe: "scribe-cmd" }), }); - yield* factory({ defaultAgent: "codex", permissionMode: "deny-all" }, stubAuthority()); + yield* factory({ defaultAgent: "scribe", permissionMode: "deny-all" }, stubAuthority()); - const sessionKey = deriveSessionKey("codex-cmd", CWD); - const record = makeRecord("codex-cmd", CWD); + const sessionKey = deriveSessionKey("scribe-cmd", CWD); + const record = makeRecord("scribe-cmd", CWD); record.acpxRecordId = `record:${sessionKey}`; record.acpSessionId = "id-A"; record.agentSessionId = "agent-A"; @@ -398,13 +398,13 @@ describe("Tier AP — ACPX provider", () => { const factory = createAcpxProvider({ createRuntime: harness.create, sessionStore: store, - agentRegistry: makeRegistry({ codex: "codex-cmd" }), + agentRegistry: makeRegistry({ scribe: "scribe-cmd" }), }); - yield* factory({ defaultAgent: "codex", permissionMode: "deny-all" }, stubAuthority()); + yield* factory({ defaultAgent: "scribe", permissionMode: "deny-all" }, stubAuthority()); // Pre-seed the repo-root session so the walk from a subdir reuses it. - const rootKey = deriveSessionKey("codex-cmd", "/repo"); - const rootRecord = makeRecord("codex-cmd", "/repo"); + const rootKey = deriveSessionKey("scribe-cmd", "/repo"); + const rootRecord = makeRecord("scribe-cmd", "/repo"); rootRecord.acpxRecordId = `record:${rootKey}`; store.records.set(rootKey, rootRecord); @@ -448,10 +448,10 @@ describe("Tier AP — ACPX provider", () => { const factory = createAcpxProvider({ createRuntime: harness.create, sessionStore: makeStore(), - agentRegistry: makeRegistry({ codex: "codex-cmd" }), + agentRegistry: makeRegistry({ scribe: "scribe-cmd" }), withSessionRoute: (_context, op) => routeQueue.withSlot("route", op), }); - yield* factory({ defaultAgent: "codex", permissionMode: "deny-all" }, stubAuthority()); + yield* factory({ defaultAgent: "scribe", permissionMode: "deny-all" }, stubAuthority()); const a1 = yield* spawn(() => collectPrompt("a1")); yield* sleep(10); @@ -598,26 +598,26 @@ describe("Tier AP — ACPX provider", () => { harness.doctorReports.push({ ok: false, code: "ACP_BACKEND_UNAVAILABLE", - message: "codex not installed", - details: ["agent=codex"], + message: "scribe not installed", + details: ["agent=scribe"], }); yield* scoped(function* () { yield* installProvider(harness); let thrown: unknown; try { - yield* Agent.operations.agent("codex"); + yield* Agent.operations.agent("scribe"); } catch (error) { thrown = error; } expect(thrown).toBeInstanceOf(Error); if (thrown instanceof Error) { expect(thrown.message).toContain("ACP_BACKEND_UNAVAILABLE"); - expect(thrown.message).toContain("codex not installed"); + expect(thrown.message).toContain("scribe not installed"); } // The failed probe is not cached; the next probe succeeds and is. - expect(yield* Agent.operations.agent("codex")).toBe("codex"); - expect(yield* Agent.operations.agent("codex")).toBe("codex"); + expect(yield* Agent.operations.agent("scribe")).toBe("scribe"); + expect(yield* Agent.operations.agent("scribe")).toBe("scribe"); expect(harness.doctorCalls).toBe(2); }); }); @@ -629,11 +629,11 @@ describe("Tier AP — ACPX provider", () => { function* installState(harness: FakeRuntimeHarness): Operation { const state = yield* useAcpxProvider( - { defaultAgent: "codex", permissionMode: "deny-all" }, + { defaultAgent: "scribe", permissionMode: "deny-all" }, { createRuntime: harness.create, sessionStore: makeStore(), - agentRegistry: makeRegistry({ codex: "codex-cmd" }), + agentRegistry: makeRegistry({ scribe: "scribe-cmd" }), }, ); yield* Agent.around( @@ -712,11 +712,11 @@ interface Partition { function* usePartition(harness: FakeRuntimeHarness): Operation { const handle = yield* useAcpxProvider( - { defaultAgent: "codex", permissionMode: "deny-all" }, + { defaultAgent: "scribe", permissionMode: "deny-all" }, { createRuntime: harness.create, sessionStore: makeStore(), - agentRegistry: makeRegistry({ codex: "codex-cmd", other: "other-cmd" }), + agentRegistry: makeRegistry({ scribe: "scribe-cmd", other: "other-cmd" }), }, ); return { handle, absent: () => undefined }; @@ -766,7 +766,7 @@ function stubAuthority(): AuthorityLog { function fakeRequest(): AgentLaunchRequest { const request = { instructions: "You are the implementor.", - agent: "codex", + agent: "scribe", cwd: CWD, additionalDirectories: [], permissionMode: "deny-all", @@ -793,7 +793,7 @@ function* installPartitioned( return options.select ? options.select() : owned!.handle; }); const authority = stubAuthority(); - yield* factory({ defaultAgent: "codex", permissionMode: "deny-all" }, authority); + yield* factory({ defaultAgent: "scribe", permissionMode: "deny-all" }, authority); return { authority, selections: () => selections }; } @@ -833,13 +833,13 @@ describe("Tier SM — session placement and materialization", () => { const factory = createAcpxProvider({ createRuntime: harness.create, sessionStore: store, - agentRegistry: makeRegistry({ codex: "codex-cmd" }), + agentRegistry: makeRegistry({ scribe: "scribe-cmd" }), }); - yield* factory({ defaultAgent: "codex", permissionMode: "deny-all" }, stubAuthority()); + yield* factory({ defaultAgent: "scribe", permissionMode: "deny-all" }, stubAuthority()); const session = yield* Agent.operations.session(); - expect(session.sessionKey).toBe(deriveSessionKey("codex-cmd", CWD)); + expect(session.sessionKey).toBe(deriveSessionKey("scribe-cmd", CWD)); expect(session.cwd).toBe(CWD); // Placement, and nothing else: no session was ensured, no handle exists, // no record was written, no turn was started, and nothing is asserted @@ -1091,7 +1091,7 @@ describe("Tier PT — partitioned provider installation", () => { return grown; }; - yield* Agent.operations.agent("codex"); + yield* Agent.operations.agent("scribe"); grew.push(since()); yield* Agent.operations.session("one"); grew.push(since()); @@ -1296,7 +1296,7 @@ const HOST_DIR = "/runs/sessions/host"; /** One logical session's directory, as the host places it. */ const SESSION_DIR = "/runs/sessions/cwd/8f2a"; -const WORKFLOW_SESSION_KEY = "xmd:workflow:v1:run:acpx:codex-cmd:default"; +const WORKFLOW_SESSION_KEY = "xmd:workflow:v1:run:acpx:scribe-cmd:default"; const INSTRUCTIONS = "You have no native tool authority here."; @@ -1344,7 +1344,7 @@ function* installStrictProvider( const factory = createAcpxProvider({ createRuntime: harness.create, sessionStore: store, - agentRegistry: makeRegistry({ codex: "codex-cmd" }), + agentRegistry: makeRegistry({ scribe: "scribe-cmd" }), // deno-lint-ignore require-yield agentCwd: function* () { return HOST_DIR; @@ -1354,7 +1354,7 @@ function* installStrictProvider( permissions: "strict", sessions, }); - yield* factory({ defaultAgent: "codex", permissionMode: "deny-all" }, stubAuthority()); + yield* factory({ defaultAgent: "scribe", permissionMode: "deny-all" }, stubAuthority()); // An authored approve-all scope, installed the way `` installs // one. Under this profile it must reach no decision at all. yield* Agent.around({ @@ -1378,7 +1378,7 @@ function* installStrictProvider( * checkpoints one before running a prompt. */ function seedRoutedRecord(store: ReturnType, sessionKey: string, cwd: string) { - const record = makeRecord("codex-cmd", cwd); + const record = makeRecord("scribe-cmd", cwd); record.acpxRecordId = `record:${sessionKey}`; record.acpSessionId = ACP_SESSION_ID; store.records.set(record.acpxRecordId, record); @@ -1420,7 +1420,7 @@ describe("Tier WAP — strict workflow Agent profile", () => { expect(harness.ensureCalls).toHaveLength(1); expect(harness.ensureCalls[0]).toMatchObject({ sessionKey: WORKFLOW_SESSION_KEY, - agent: "codex", + agent: "scribe", mode: "persistent", cwd: SESSION_DIR, }); @@ -1430,7 +1430,7 @@ describe("Tier WAP — strict workflow Agent profile", () => { // The host placed the session; nothing walked the contextual directory. expect(log.places).toEqual([ - { agentName: "codex", agentCommand: "codex-cmd", session: undefined }, + { agentName: "scribe", agentCommand: "scribe-cmd", session: undefined }, ]); expect(log.established).toEqual([ { @@ -1527,9 +1527,9 @@ describe("Tier WAP — strict workflow Agent profile", () => { const factory = createAcpxProvider({ createRuntime: harness.create, sessionStore: store, - agentRegistry: makeRegistry({ codex: "codex-cmd" }), + agentRegistry: makeRegistry({ scribe: "scribe-cmd" }), }); - yield* factory({ defaultAgent: "codex", permissionMode: "deny-all" }, stubAuthority()); + yield* factory({ defaultAgent: "scribe", permissionMode: "deny-all" }, stubAuthority()); yield* Agent.around({ // deno-lint-ignore require-yield *requestPermission([request]) { @@ -1540,7 +1540,7 @@ describe("Tier WAP — strict workflow Agent profile", () => { : { outcome: "selected", optionId: allow.optionId }; }, }); - const sessionKey = deriveSessionKey("codex-cmd", CWD); + const sessionKey = deriveSessionKey("scribe-cmd", CWD); seedRoutedRecord(store, sessionKey, CWD); const prompt = yield* spawn(() => collectPrompt("ordinary run")); yield* sleep(20); @@ -1646,25 +1646,25 @@ describe("Tier APR — preparing an agent before it is probed", () => { return harness.create(options); }, sessionStore: makeStore(), - agentRegistry: makeRegistry({ codex: "codex-cmd" }), + agentRegistry: makeRegistry({ scribe: "scribe-cmd" }), *prepareAgent(agentName: string) { order.push(`prepare:${agentName}`); }, }); - yield* factory({ defaultAgent: "codex", permissionMode: "deny-all" }, stubAuthority()); + yield* factory({ defaultAgent: "scribe", permissionMode: "deny-all" }, stubAuthority()); // Nothing yet: installing a provider resolves no agent. expect(order).toEqual([]); - yield* Agent.operations.agent("codex"); + yield* Agent.operations.agent("scribe"); // Preparation first. The probe spawns the agent's command, so a host that // has to put that command on disk must have done so by now — otherwise the // probe reports the agent unavailable for a reason that names the wrong // cause, and no amount of later preparation is reached. - expect(order[0]).toBe("prepare:codex"); + expect(order[0]).toBe("prepare:scribe"); expect(order).toContain("probe"); - expect(order.indexOf("prepare:codex")).toBeLessThan(order.indexOf("probe")); + expect(order.indexOf("prepare:scribe")).toBeLessThan(order.indexOf("probe")); }); }); @@ -1679,9 +1679,9 @@ describe("Tier APC — Prompt checkpoint metadata", () => { const factory = createAcpxProvider({ createRuntime: harness.create, sessionStore: makeStore(), - agentRegistry: makeRegistry({ codex: "codex-cmd" }), + agentRegistry: makeRegistry({ scribe: "scribe-cmd" }), }); - yield* factory({ defaultAgent: "codex", permissionMode: "deny-all" }, authority); + yield* factory({ defaultAgent: "scribe", permissionMode: "deny-all" }, authority); const { events } = yield* collectPrompt("hello"); return { checkpoints: authority.checkpoints, events }; } diff --git a/packages/acp/tests/session-route.test.ts b/packages/acp/tests/session-route.test.ts index 5b3a15c5..5a9c445d 100644 --- a/packages/acp/tests/session-route.test.ts +++ b/packages/acp/tests/session-route.test.ts @@ -37,6 +37,7 @@ import type { AgentSessionRouteStore, AgentSessionRouteV1, AgentSessionRouteV2, + AgentSessionRouteV3, } from "../src/session-route.ts"; import type { ExecutableBuildBindingV1 } from "@executablemd/core"; import { cliBase } from "@executablemd/test-support/launch"; @@ -80,7 +81,7 @@ const BUILD: ExecutableBuildBindingV1 = { executableDigest: { algorithm: "sha256", value: "c".repeat(64) }, }; -/** The bound form, which exists only for `client-native`. */ +/** The bound client-native form, which is V2 and only V2. */ function boundClientNative(overrides: Partial = {}): AgentSessionRouteV2 { return { ...(clientNative() as Extract), @@ -90,6 +91,17 @@ function boundClientNative(overrides: Partial = {}): AgentS }; } +/** The bound ACP-first form, which is V3 and only V3. */ +function boundAcpFirst(overrides: Partial = {}): AgentSessionRouteV3 { + return { + ...acpFirst(), + schema: "session-route.v3", + route: "acp-first", + executableBinding: BUILD, + ...overrides, + }; +} + function* workspace(): Operation { const root = path.join(os.tmpdir(), `xmd-sr-${randomUUID()}`); yield* ensureDir(root); @@ -399,14 +411,17 @@ describe("Tier SR — the construction route", () => { }); /** - * Tier SV — the bound V2 client-native route + * Tier SV — the bound construction routes * (specs/native-agent-session-launch-spec.md §Construction route). * - * V2 adds one fact V1 never had: which build accepted the identity XMD chose. - * It exists only for `client-native`, because ACP-first construction gained - * nothing — and a V1 record is never read as a V2 one, in either direction. + * Both bound schemas add one fact V1 never had: which build the session's + * provider-native identity belongs to. V2 says it for `client-native`, where a + * build accepted the identity XMD chose; V3 says it for `acp-first`, where a + * build issued the identity XMD was handed. Each schema admits exactly the + * construction it was minted for, and a V1 record is never read as a bound one + * in either direction. */ -describe("Tier SV — the bound construction route", () => { +describe("Tier SV — the bound construction routes", () => { it("SV1: a bound record carries the binding and nothing else", function* () { const text = serializeAgentSessionRoute(boundClientNative()); expect(Object.keys(JSON.parse(text)).sort()).toEqual([ @@ -426,9 +441,9 @@ describe("Tier SV — the bound construction route", () => { expect(text).not.toContain("/"); }); - it("SV2: there is no bound acp-first form", function* () { - // A second schema for a shape that gained no fact would be a version number - // with nothing behind it. + it("SV2: each bound schema admits only its own construction", function* () { + // A record pairing one schema with the other's construction is state this + // build cannot account for, not a route with a spare member. expect(parseAgentSessionRoute({ ...acpFirst(), schema: "session-route.v2" })).toBe(undefined); expect( parseAgentSessionRoute({ @@ -437,6 +452,83 @@ describe("Tier SV — the bound construction route", () => { executableBinding: BUILD, }), ).toBe(undefined); + expect(parseAgentSessionRoute({ ...boundClientNative(), schema: "session-route.v3" })).toBe( + undefined, + ); + expect(parseAgentSessionRoute({ ...clientNative(), schema: "session-route.v3" })).toBe( + undefined, + ); + }); + + it("SV6: a bound acp-first record carries the binding and nothing else", function* () { + const parsed = parseAgentSessionRoute(JSON.parse(serializeAgentSessionRoute(boundAcpFirst()))); + expect(parsed).toEqual(boundAcpFirst()); + const text = serializeAgentSessionRoute(boundAcpFirst()); + expect(Object.keys(JSON.parse(text)).sort()).toEqual([ + "agent", + "executableBinding", + "provider", + "route", + "schema", + "sessionKey", + ]); + // Still nothing about the conversation: the provider named it, and no + // identity, instruction layer, process fact or path is recorded here. + expect(text).not.toContain("/"); + expect(text).not.toContain("nativeSessionId"); + }); + + it("SV7: a bound acp-first record is exact on the way in", function* () { + // Built as what the parser is actually handed — a record read back off + // disk — rather than as the type the parser is being asked to produce. + const good: Record = { ...boundAcpFirst() }; + const cases: [string, unknown][] = [ + ["no binding at all", (({ executableBinding: _b, ...rest }) => rest)(good)], + ["unknown binding schema", { ...good, executableBinding: { ...BUILD, schema: "v2" } }], + ["extra binding member", { ...good, executableBinding: { ...BUILD, path: "/bin/codex" } }], + [ + "short digest", + { + ...good, + executableBinding: { + ...BUILD, + executableDigest: { algorithm: "sha256", value: "c".repeat(63) }, + }, + }, + ], + ["binding is not a record", { ...good, executableBinding: "executable-build.v1" }], + ["a native identity beside it", { ...good, nativeSessionId: "11111111" }], + ["extra member beside it", { ...good, executablePath: "/usr/local/bin/codex" }], + ]; + for (const [name, value] of cases) { + expect([name, parseAgentSessionRoute(value)]).toEqual([name, undefined]); + } + }); + + it("SV8: a V1 acp-first record is never read as a bound one", function* () { + // A build observed today says which build is installed now, not which one + // issued this session's identity, so the unbound record stays unbound. + const parsed = parseAgentSessionRoute(acpFirst()); + expect(parsed?.schema).toBe("session-route.v1"); + expect((parsed as { executableBinding?: unknown }).executableBinding).toBe(undefined); + }); + + it("SV9: both stores publish a bound acp-first route create-once", function* () { + for (const { name, store } of yield* stores()) { + const winner = yield* store.publish(boundAcpFirst()); + expect([name, winner]).toEqual([name, boundAcpFirst()]); + const loser = yield* store.publish( + boundAcpFirst({ + executableBinding: { + schema: "executable-build.v1", + reportedVersion: "codex-cli 0.153.3", + executableDigest: { algorithm: "sha256", value: "e".repeat(64) }, + }, + }), + ); + expect([name, loser]).toEqual([name, boundAcpFirst()]); + expect([name, yield* store.read(KEY)]).toEqual([name, boundAcpFirst()]); + } }); it("SV3: a bound record without an exact binding refuses", function* () { @@ -488,7 +580,13 @@ describe("Tier SV — the bound construction route", () => { // Nothing here upgrades a route. A V1 record read and written again is // still V1, which is what keeps a build observed today from being written // into a session that never recorded one. - for (const route of [clientNative(), boundClientNative()] as AgentSessionRoute[]) { + const routes: AgentSessionRoute[] = [ + acpFirst(), + clientNative(), + boundClientNative(), + boundAcpFirst(), + ]; + for (const route of routes) { const round = parseAgentSessionRoute(JSON.parse(serializeAgentSessionRoute(route))); expect(round?.schema).toBe(route.schema); } diff --git a/packages/acp/tests/terminal-screen.test.ts b/packages/acp/tests/terminal-screen.test.ts new file mode 100644 index 00000000..d2b2b819 --- /dev/null +++ b/packages/acp/tests/terminal-screen.test.ts @@ -0,0 +1,706 @@ +/** + * Tier NA — native answer observation + * (specs/native-agent-session-launch-spec.md §Provider-returned adapters). + * + * The Codex native proof has to decide whether the agent answered, and the only + * thing it can read is a pseudo-terminal. A TUI draws by moving the cursor and + * repainting, so the bytes it emitted and the screen it is showing are two + * different things — which means a proof that searches the byte stream can find + * text that has since been erased, or text the program printed before it took + * the screen, while missing an answer the screen is showing right now. + * + * These cases drive fake TUI streams through the reconstruction the proof uses + * and check both halves: that a real answer is read however it was drawn, and + * that everything an answer is not is refused. No Codex process starts and no + * model turn is spent — the streams here are written by hand, so what the + * observer does with each shape is decided rather than sampled. + */ +import { describe, it } from "@executablemd/test-support/bdd"; +import { expect } from "@executablemd/test-support/expect"; +import { + observeAnswer, + screenShows, + terminalChannels, + TerminalReader, + terminalReader, + TerminalScreen, +} from "./fixtures/terminal-screen.ts"; +import type { AnswerQuestion } from "./fixtures/terminal-screen.ts"; + +/** The pty the proof opens, so these streams wrap where that one wraps. */ +const ROWS = 40; +const COLUMNS = 120; + +const ESC = String.fromCharCode(0x1b); +const csi = (body: string): string => `${ESC}[${body}`; +/** Cursor position, one-based as a terminal counts. */ +const at = (row: number, column: number): string => csi(`${row};${column}H`); +/** The TUI takes the screen, and gives the shell's back when it leaves. */ +const ALT_ON = csi("?1049h"); +const ALT_OFF = csi("?1049l"); +const CLEAR = csi("2J"); +/** Hold the drawing back, and put the finished frame on show. */ +const SYNC_ON = csi("?2026h"); +const SYNC_OFF = csi("?2026l"); + +/** Repaint the whole screen by addressing each row, as a TUI does. */ +function paint(rows: readonly string[]): string { + return rows.map((row, index) => `${at(index + 1, 1)}${csi("2K")}${row}`).join(""); +} + +/** A bordered pane row, padded to its right border as a TUI pads one. */ +function pane(text: string, width = 60): string { + return `│ ${text.padEnd(width)} │`; +} + +function border(width = 60, left = "╭", right = "╮"): string { + return `${left}${"─".repeat(width + 2)}${right}`; +} + +/** + * The sentence the native proof asks for. Chosen there because it is the first + * sentence of the instruction layer the launch installed, so it is text only a + * governed turn produces. + */ +const ANSWER = "The Implementor delivers an accepted plan as a focused, verified change."; + +/** A turn shaped like the proof's, which does not contain its own answer. */ +const TYPED = + "Do not use any tools. Reply with exactly two lines. First line: " + + "the first sentence of the body text under the 'Implementor' heading."; + +/** Codex's own furniture, named the same way the proof names it. */ +const CHROME: readonly string[] = ["Ask Codex to do anything", "esc to interrupt"]; + +function screen(): TerminalScreen { + return new TerminalScreen({ rows: ROWS, columns: COLUMNS }); +} + +function asked(over: Partial = {}): AnswerQuestion { + return { expected: ANSWER, typed: TYPED, chrome: CHROME, ...over }; +} + +describe("Tier NA — native answer observation", () => { + it("NA1: text printed before the TUI took the screen is not an answer", function* () { + const terminal = screen(); + terminal.write(`${ANSWER}\r\n`); + + // On the shell's own screen the words are genuinely there, which is why a + // proof reading retained bytes would have accepted them. + expect(observeAnswer(terminal.snapshot(), asked()).found).toBe(true); + + terminal.write(ALT_ON); + + const observed = observeAnswer(terminal.snapshot(), asked()); + expect(terminal.snapshot().alternate).toBe(true); + expect(observed).toEqual({ found: false, reason: "absent" }); + }); + + it("NA2: an answer the terminal wrapped mid-word is read as one sentence", function* () { + const terminal = screen(); + // Started 21 columns from the right margin, so the terminal itself breaks + // the word `delivers` across two rows with no space where it broke. + terminal.write(`${ALT_ON}${at(5, COLUMNS - 20)}${ANSWER}`); + + const rows = terminal.snapshot().rows; + expect(rows[4]?.endsWith("The Implementor deliv")).toBe(true); + expect(rows[5]).toBe("ers an accepted plan as a focused, verified change."); + expect(observeAnswer(terminal.snapshot(), asked())).toEqual({ + found: true, + reason: "answer", + }); + }); + + it("NA3: an answer a repaint moved is read from where it now is", function* () { + const terminal = screen(); + terminal.write(`${ALT_ON}${paint(["", "", ANSWER])}`); + expect(observeAnswer(terminal.snapshot(), asked()).found).toBe(true); + + terminal.write(`${CLEAR}${paint([...Array.from({ length: 19 }, () => ""), ANSWER])}`); + + expect(terminal.snapshot().rows[2]).toBe(""); + expect(terminal.snapshot().rows[19]).toBe(ANSWER); + expect(observeAnswer(terminal.snapshot(), asked()).found).toBe(true); + }); + + it("NA4: a repaint that replaces the answer is refused, though the bytes remain", function* () { + const terminal = screen(); + terminal.write(`${ALT_ON}${paint(["", "", ANSWER])}`); + expect(observeAnswer(terminal.snapshot(), asked()).found).toBe(true); + + terminal.write(paint(["", "", "Working on it."])); + + // The stream still carries every byte of the answer; the screen does not, + // and the screen is what an operator would be looking at. + expect(observeAnswer(terminal.snapshot(), asked())).toEqual({ + found: false, + reason: "absent", + }); + }); + + it("NA5: an answer wrapped inside a bordered pane is read across the border", function* () { + const terminal = screen(); + terminal.write( + `${ALT_ON}${paint([ + border(), + pane("The Implementor delivers an accepted plan as a"), + pane("focused, verified change."), + border(60, "╰", "╯"), + ])}`, + ); + + expect(terminal.snapshot().rows[1]?.startsWith("│ The Implementor")).toBe(true); + expect(observeAnswer(terminal.snapshot(), asked())).toEqual({ + found: true, + reason: "answer", + }); + }); + + it("NA6: cells an erase blanked do not close up into an answer", function* () { + const terminal = screen(); + terminal.write(`${ALT_ON}${at(5, 1)}${ANSWER}`); + expect(observeAnswer(terminal.snapshot(), asked()).found).toBe(true); + + // Twenty cells out of the middle of the sentence, which is what a redraw + // that has not finished repainting leaves behind. + terminal.write(`${at(5, 25)}${csi("20X")}`); + + expect(terminal.snapshot().rows[4]).toBe( + `The Implementor delivers${" ".repeat(21)}a focused, verified change.`, + ); + expect(observeAnswer(terminal.snapshot(), asked())).toEqual({ + found: false, + reason: "absent", + }); + }); + + it("NA7: a gap inside a row is a gap, not a join", function* () { + const terminal = screen(); + // Two columns that would read as the sentence if the blank cells between + // them closed up — which is what erasing part of a row, or laying two panes + // side by side, leaves on the screen. + terminal.write( + `${ALT_ON}${at(5, 1)}The Implementor delivers an accepted plan` + + `${at(5, 60)}as a focused, verified change.`, + ); + + expect(observeAnswer(terminal.snapshot(), asked())).toEqual({ + found: false, + reason: "absent", + }); + }); + + it("NA8: two panes on one row are two pieces of text", function* () { + const terminal = screen(); + // Borders with no padding either side, so nothing but the border itself + // says where one pane's text stops and the next one's starts. + terminal.write( + `${ALT_ON}${at(5, 1)}` + + "│The Implementor delivers an accepted plan│as a focused, verified change.│", + ); + + expect(observeAnswer(terminal.snapshot(), asked())).toEqual({ + found: false, + reason: "absent", + }); + }); + + it("NA9: the harness reading its own turn back is not an answer", function* () { + const terminal = screen(); + const quoting = `Reply with exactly this: ${ANSWER}`; + terminal.write(`${ALT_ON}${paint(["", quoting])}`); + + expect(observeAnswer(terminal.snapshot(), asked({ typed: quoting }))).toEqual({ + found: false, + reason: "only-typed", + }); + + // And the echo does not go on refusing once the agent has actually replied. + terminal.write(paint(["", quoting, "", ANSWER])); + expect(observeAnswer(terminal.snapshot(), asked({ typed: quoting }))).toEqual({ + found: true, + reason: "answer", + }); + }); + + it("NA10: an answer still being drawn is not an answer yet", function* () { + const terminal = screen(); + terminal.write(`${ALT_ON}${at(5, 1)}The Implementor delivers an accepted plan as a foc`); + + expect(observeAnswer(terminal.snapshot(), asked())).toEqual({ + found: false, + reason: "absent", + }); + + terminal.write("used, verified change."); + expect(observeAnswer(terminal.snapshot(), asked()).found).toBe(true); + }); + + it("NA11: text the TUI drew as its own furniture is not an answer", function* () { + const onOneRow = screen(); + onOneRow.write(`${ALT_ON}${at(38, 1)}Ask Codex to do anything · ${ANSWER}`); + expect(observeAnswer(onOneRow.snapshot(), asked())).toEqual({ + found: false, + reason: "absent", + }); + + const across = screen(); + across.write( + `${ALT_ON}${paint([ + "The Implementor delivers an accepted plan as a", + "Ask Codex to do anything", + "focused, verified change.", + ])}`, + ); + expect(observeAnswer(across.snapshot(), asked())).toEqual({ + found: false, + reason: "absent", + }); + }); + + it("NA12: an idle composer is the terminal's state, not the absence of an answer", function* () { + const terminal = screen(); + terminal.write( + `${ALT_ON}${paint([ + "› Do not use any tools.", + "", + ANSWER, + "", + border(), + pane("Ask Codex to do anything"), + border(60, "╰", "╯"), + ])}`, + ); + + const snapshot = terminal.snapshot(); + expect(screenShows(snapshot, "Ask Codex to do anything")).toBe(true); + expect(observeAnswer(snapshot, asked())).toEqual({ found: true, reason: "answer" }); + }); + + it("NA13: an answer that scrolled off the screen is gone with it", function* () { + const terminal = screen(); + terminal.write(`${ALT_ON}${at(ROWS, 1)}${ANSWER}`); + expect(observeAnswer(terminal.snapshot(), asked()).found).toBe(true); + + terminal.write("\r\n".repeat(ROWS)); + + expect(observeAnswer(terminal.snapshot(), asked())).toEqual({ + found: false, + reason: "absent", + }); + }); + + it("NA14: a control sequence split across two reads is still one sequence", function* () { + const terminal = screen(); + for (const chunk of [`${ESC}[?10`, "49h", `${ESC}[5`, `;1H${ANSWER}`]) { + terminal.write(chunk); + } + + const snapshot = terminal.snapshot(); + expect(snapshot.alternate).toBe(true); + expect(snapshot.rows[4]).toBe(ANSWER); + expect(snapshot.rows.some((row) => row.includes("49h") || row.includes(";1H"))).toBe(false); + expect(observeAnswer(snapshot, asked()).found).toBe(true); + }); + + it("NA15: leaving the alternate screen gives back what the shell had", function* () { + const terminal = screen(); + terminal.write("checking codex\r\n"); + terminal.write(`${ALT_ON}${paint(["", "", ANSWER])}`); + expect(observeAnswer(terminal.snapshot(), asked()).found).toBe(true); + + terminal.write(ALT_OFF); + + const snapshot = terminal.snapshot(); + expect(snapshot.alternate).toBe(false); + expect(snapshot.rows[0]).toBe("checking codex"); + expect(observeAnswer(snapshot, asked())).toEqual({ found: false, reason: "absent" }); + }); + + it("NA16: bytes arriving one at a time reconstruct the same screen", function* () { + const whole = screen(); + const stream = `${ALT_ON}${paint([ + border(), + pane(ANSWER.slice(0, 45)), + pane(ANSWER.slice(45).trim()), + ])}`; + whole.write(stream); + + const dribbled = screen(); + for (const char of stream) { + dribbled.write(char); + } + + expect(dribbled.snapshot()).toEqual(whole.snapshot()); + expect(observeAnswer(dribbled.snapshot(), asked()).found).toBe(true); + }); + + it("NA17: a pane border split down the middle of its bytes is still one border", function* () { + // What the proof actually hands over: a pty delivers bytes, and a pane + // border is three of them per glyph. A read that ends inside one would + // otherwise put a replacement character on the screen where the border + // goes, and the run boundaries are drawn from those borders. + const stream = `${ALT_ON}${paint([ + border(), + pane(ANSWER.slice(0, 45)), + pane(ANSWER.slice(45).trim()), + ])}`; + const bytes = new TextEncoder().encode(stream); + + const whole = screen(); + whole.write(bytes); + + const split = screen(); + for (let index = 0; index < bytes.length; index += 1) { + split.write(bytes.subarray(index, index + 1)); + } + + expect(split.snapshot()).toEqual(whole.snapshot()); + expect(split.snapshot().rows.join("")).not.toContain("�"); + expect(observeAnswer(split.snapshot(), asked()).found).toBe(true); + }); + + it("NA18: clearing the scrollback leaves the answer on the screen", function* () { + const drawn = (): TerminalScreen => { + const terminal = screen(); + terminal.write(`${ALT_ON}${paint(["", "", ANSWER])}`); + return terminal; + }; + + // `3J` is the scrollback, which is above the screen rather than on it, and + // an unimplemented parameter is not an instruction to blank anything. Both + // are here because either one falling through to a whole-screen erase would + // make this observer report the answer it is looking at as absent. + const scrollback = drawn(); + scrollback.write(csi("3J")); + expect(scrollback.snapshot().rows[2]).toBe(ANSWER); + expect(observeAnswer(scrollback.snapshot(), asked()).found).toBe(true); + + const unknown = drawn(); + unknown.write(csi("9J")); + expect(observeAnswer(unknown.snapshot(), asked()).found).toBe(true); + + // And the mode that does mean the visible screen still means it. + const visible = drawn(); + visible.write(csi("2J")); + expect(visible.snapshot().rows.join("")).toBe(""); + expect(observeAnswer(visible.snapshot(), asked()).found).toBe(false); + }); + + it("NA19: the watch latches on the read that finishes the answer", function* () { + const watch = new TerminalReader({ rows: ROWS, columns: COLUMNS }, true); + expect(watch.write(`${ALT_ON}${paint([pane("Ask Codex to do anything")])}`)).toBe(false); + expect(watch.ask(asked())).toBe(false); + + // Read by read, as the pty hands them over: the answer is not answered + // until the read that puts the last of it on the screen. + expect(watch.write(paint(["", "", "The Implementor delivers an accepted"]))).toBe(false); + expect(watch.write(paint(["", "", ANSWER]))).toBe(true); + expect(watch.found).toBe(true); + }); + + it("NA20: a redraw over the answer does not un-answer the turn", function* () { + const watch = new TerminalReader({ rows: ROWS, columns: COLUMNS }, true); + watch.write(ALT_ON); + watch.ask(asked()); + expect(watch.write(paint(["", "", ANSWER]))).toBe(true); + + watch.write(`${CLEAR}${paint(["", "", "", "", border(), pane("Ask Codex to do anything")])}`); + + // The screen has moved on, and the screen is right about what it is + // showing — but the question was whether the agent answered, and a TUI + // repainting over its own reply is not the agent taking it back. + expect(observeAnswer(watch.snapshot(), asked()).found).toBe(false); + expect(watch.found).toBe(true); + expect(watch.write("")).toBe(true); + }); + + it("NA21: an occurrence from before the turn does not latch", function* () { + const watch = new TerminalReader({ rows: ROWS, columns: COLUMNS }, true); + // The words are genuinely on the shell's screen here, which is exactly why + // a watch armed from the start of the process would have latched on them. + watch.write(`${ANSWER}\r\n`); + watch.write(`${ALT_ON}${paint([pane("Ask Codex to do anything")])}`); + + expect(watch.ask(asked())).toBe(false); + expect(watch.write(paint([pane("esc to interrupt")]))).toBe(false); + expect(watch.found).toBe(false); + }); + + it("NA22: the turn echoing back in the composer does not latch", function* () { + const quoting = `Reply with exactly this: ${ANSWER}`; + const watch = new TerminalReader({ rows: ROWS, columns: COLUMNS }, true); + watch.write(ALT_ON); + watch.ask(asked({ typed: quoting })); + + expect(watch.write(paint(["", `› ${quoting}`]))).toBe(false); + expect(watch.found).toBe(false); + + expect(watch.write(paint(["", `› ${quoting}`, "", ANSWER]))).toBe(true); + }); + + it("NA23: an answer still being drawn does not latch until it is whole", function* () { + const watch = new TerminalReader({ rows: ROWS, columns: COLUMNS }, true); + watch.write(`${ALT_ON}${at(5, 1)}`); + watch.ask(asked()); + + expect(watch.write("The Implementor delivers an accepted plan as a foc")).toBe(false); + expect(watch.write("used, verified change.")).toBe(true); + }); + + it("NA24: an answer erased within the read that drew it was never on the screen", function* () { + const watch = new TerminalReader({ rows: ROWS, columns: COLUMNS }, true); + watch.write(ALT_ON); + watch.ask(asked()); + + const chunk = `${at(5, 1)}${ANSWER}${at(5, 25)}${csi("20X")}`; + expect(chunk).toContain(ANSWER); + expect(watch.write(chunk)).toBe(false); + + // Every byte of the answer went through the watch, and no read boundary + // ever exposed it — which is the whole difference between reading the + // stream and reading the terminal. + expect(watch.found).toBe(false); + }); + + it("NA25: the TUI's own furniture does not latch", function* () { + const watch = new TerminalReader({ rows: ROWS, columns: COLUMNS }, true); + watch.write(ALT_ON); + watch.ask(asked()); + + for (const line of CHROME) { + expect(watch.write(paint(["", line]))).toBe(false); + } + expect(watch.found).toBe(false); + + expect(watch.write(paint(["", CHROME[0] ?? "", "", ANSWER]))).toBe(true); + }); + + it("NA26: the watch latches an answer whose glyphs were split across reads", function* () { + const watch = new TerminalReader({ rows: ROWS, columns: COLUMNS }, true); + const bytes = new TextEncoder().encode( + `${ALT_ON}${paint([ + border(), + pane(ANSWER.slice(0, 45)), + pane(ANSWER.slice(45).trim()), + border(60, "╰", "╯"), + ])}`, + ); + watch.ask(asked()); + + let latched = false; + for (let index = 0; index < bytes.length; index += 1) { + latched = watch.write(bytes.subarray(index, index + 1)); + } + + expect(latched).toBe(true); + expect(watch.snapshot().rows.join("")).not.toContain("�"); + }); + + it("NA27: a frame that erased the answer before showing it does not latch", function* () { + const watch = new TerminalReader({ rows: ROWS, columns: COLUMNS }, true); + watch.write(ALT_ON); + watch.ask(asked()); + + // What a repaint of a scrolling transcript looks like from inside: the + // sentence is laid down and taken away again while the terminal is holding + // its output back, so nobody watching the pty was ever shown it. + expect(watch.write(`${SYNC_ON}${paint(["", "", ANSWER])}`)).toBe(false); + expect(watch.write(paint(["", "", "Working on it."]))).toBe(false); + expect(watch.write(SYNC_OFF)).toBe(false); + expect(watch.found).toBe(false); + }); + + it("NA28: an answer the committed frame is showing latches at the commit", function* () { + const watch = new TerminalReader({ rows: ROWS, columns: COLUMNS }, true); + watch.write(ALT_ON); + watch.ask(asked()); + + expect(watch.write(`${SYNC_ON}${paint(["", "", ANSWER])}`)).toBe(false); + expect(watch.write(SYNC_OFF)).toBe(true); + expect(watch.found).toBe(true); + }); + + it("NA29: the commit decides, not wherever the read happened to stop", function* () { + // The same bytes cut three ways. A frame is finished by `?2026l` and not by + // an operating system choosing where one `data` event ends, so an observer + // that evaluated per read would answer differently for each of these. + const held = `${SYNC_ON}${paint(["", "", ANSWER])}`; + const replaced = paint(["", "", "Working on it."]); + const cuts: [string, readonly string[], boolean][] = [ + ["one read", [`${held}${replaced}${SYNC_OFF}`], false], + ["cut mid-frame", [held, `${replaced}${SYNC_OFF}`], false], + ["committed, then overdrawn in the next read", [`${held}${SYNC_OFF}`, replaced], true], + // The one that can only be got right where the frame ends: the answer was + // committed and then drawn over, and the read carrying both stops after. + ["committed and overdrawn inside one read", [`${held}${SYNC_OFF}${replaced}`], true], + ]; + + for (const [name, reads, latches] of cuts) { + const watch = new TerminalReader({ rows: ROWS, columns: COLUMNS }, true); + watch.write(ALT_ON); + watch.ask(asked()); + for (const read of reads) { + watch.write(read); + } + expect(`${name}: ${watch.found}`).toBe(`${name}: ${latches}`); + } + }); + + it("NA30: begin and end split across byte reads still bound the frame", function* () { + const watch = new TerminalReader({ rows: ROWS, columns: COLUMNS }, true); + watch.write(ALT_ON); + watch.ask(asked()); + + const bytes = new TextEncoder().encode( + `${SYNC_ON}${paint(["", "", ANSWER])}${paint(["", "", "Working on it."])}${SYNC_OFF}` + + `${SYNC_ON}${paint(["", "", ANSWER])}${SYNC_OFF}`, + ); + // One byte at a time, which splits `?2026h` and `?2026l` down the middle + // repeatedly. The first frame erased its answer and the second kept it. + const answeredAt: number[] = []; + for (let index = 0; index < bytes.length; index += 1) { + if (watch.write(bytes.subarray(index, index + 1))) { + answeredAt.push(index); + } + } + + expect(watch.found).toBe(true); + // Nothing latched until the second frame committed, which is the last byte. + expect(answeredAt[0]).toBe(bytes.length - 1); + }); + + it("NA31: bytes that never went through the terminal cannot answer", function* () { + const seen: string[] = []; + const watch = new TerminalReader({ rows: ROWS, columns: COLUMNS }, true); + const channels = terminalChannels((chunk) => { + seen.push(typeof chunk === "string" ? chunk : new TextDecoder().decode(chunk)); + }, watch); + channels.display(ALT_ON); + watch.ask(asked()); + + // `script` reports its own troubles beside the pty. Those bytes reached + // this process without ever being displayed, so however exactly they read, + // they are not something an operator could have been looking at. + const beside = `${paint(["", "", ANSWER])}\n${ANSWER}\n`; + const before = watch.snapshot(); + channels.diagnostic(beside); + + expect(channels.observing).toBe(true); + expect(watch.found).toBe(false); + expect(watch.snapshot()).toEqual(before); + // Still evidence about the run, which is the other half of the split. + expect(seen.join("")).toContain(ANSWER); + + // And the same bytes on the channel the terminal presented do answer. + expect(channels.display(paint(["", "", ANSWER]))).toBe(true); + }); + + it("NA32: every invocation reads a terminal, only the submitting one watches", function* () { + const size = { rows: ROWS, columns: COLUMNS }; + const submitted = { say: TYPED, expect: ANSWER }; + // The one invocation that submits: a journey's first, saying something and + // expecting an answer to it. + expect(terminalReader(size, { index: 0, ...submitted }).watching).toBe(true); + + // Preflight and both zero-native-turn invocations, which pass an empty plan. + expect(terminalReader(size, { index: 0 }).watching).toBe(false); + expect(terminalReader(size, { index: 1 }).watching).toBe(false); + // Re-entry is not the invocation that submits, so an expectation reaching it + // is a mistake and not a second thing to watch. + expect(terminalReader(size, { index: 1, ...submitted }).watching).toBe(false); + // Neither half is enough on its own: expecting without saying observes a + // turn nobody sent, and saying without expecting has nothing to look for. + expect(terminalReader(size, { index: 0, expect: ANSWER }).watching).toBe(false); + expect(terminalReader(size, { index: 0, say: TYPED }).watching).toBe(false); + expect(terminalReader(size, { index: 0, say: TYPED, expect: "" }).watching).toBe(false); + + const seen: string[] = []; + const reader = terminalReader(size, { index: 0 }); + const channels = terminalChannels( + (chunk) => seen.push(typeof chunk === "string" ? chunk : new TextDecoder().decode(chunk)), + reader, + ); + + expect(channels.observing).toBe(false); + expect(channels.display(`${ALT_ON}${paint(["", "", ANSWER])}`)).toBe(false); + channels.diagnostic(ANSWER); + // The stream is still kept whole, because it is this run's evidence. + expect(seen.join("")).toContain(ANSWER); + + // The screen is built all the same, because this invocation still has to + // decide what surface it is looking at. + expect(screenShows(reader.snapshot(), ANSWER)).toBe(true); + // And it cannot be asked for an answer: it submitted no turn, so a reply it + // reported would be attributed to one nobody spent. + expect(() => reader.ask(asked())).toThrow("submits no turn"); + expect(reader.found).toBe(false); + }); + + it("NA33: a surface only a held frame contains is not what the terminal showed", function* () { + const watch = new TerminalReader({ rows: ROWS, columns: COLUMNS }, true); + watch.write(ALT_ON); + watch.ask(asked()); + + // What the operator is looking at when a wait for an answer gives up, and + // what naming the terminal's state means: `still-working`. + watch.write(paint(["", pane("esc to interrupt")])); + const presented = watch.snapshot(); + expect(screenShows(presented, "esc to interrupt")).toBe(true); + + // Now a repaint begins. Inside it the pane is erased and a refusal is laid + // down — cells the terminal is holding, which nobody was shown. A reader of + // those would report `usage-limited` and send the next reader off to check + // a plan that was never at fault. + watch.write(`${SYNC_ON}${CLEAR}${paint(["", pane("You've hit your usage limit.")])}`); + expect(watch.snapshot()).toEqual(presented); + expect(screenShows(watch.snapshot(), "usage limit")).toBe(false); + + // Still the frame before, however many reads the repaint takes. + watch.write(paint(["", "", pane("Working on it.")])); + expect(watch.snapshot()).toEqual(presented); + expect(screenShows(watch.snapshot(), "esc to interrupt")).toBe(true); + + // And it advances at the commit, to exactly what the commit put on show. + watch.write(SYNC_OFF); + expect(screenShows(watch.snapshot(), "Working on it.")).toBe(true); + expect(screenShows(watch.snapshot(), "esc to interrupt")).toBe(false); + expect(screenShows(watch.snapshot(), "usage limit")).toBe(false); + // The answer was never on any of it, held or shown. + expect(watch.found).toBe(false); + }); + + it("NA34: a hold beginning mid-read presents the bytes before it, not after", function* () { + const watch = new TerminalReader({ rows: ROWS, columns: COLUMNS }, true); + watch.write(ALT_ON); + watch.ask(asked()); + + // One read that finishes drawing one surface and then starts withholding + // the next. What was presented is where the hold began, not where the + // operating system stopped the read. + watch.write( + `${paint(["", pane("esc to interrupt")])}` + + `${SYNC_ON}${CLEAR}${paint(["", pane("Ask Codex to do anything")])}`, + ); + expect(screenShows(watch.snapshot(), "esc to interrupt")).toBe(true); + expect(screenShows(watch.snapshot(), "Ask Codex to do anything")).toBe(false); + + // The commit, and the next hold, one byte at a time — which splits both + // sequences down the middle. The composer frame is presented as it commits, + // and the answer drawn after it is held back by the frame that follows. + const bytes = new TextEncoder().encode( + `${SYNC_OFF}${SYNC_ON}${CLEAR}${paint(["", "", ANSWER])}`, + ); + for (let index = 0; index < bytes.length; index += 1) { + watch.write(bytes.subarray(index, index + 1)); + } + + expect(screenShows(watch.snapshot(), "Ask Codex to do anything")).toBe(true); + expect(screenShows(watch.snapshot(), ANSWER)).toBe(false); + expect(watch.found).toBe(false); + + // Committing it shows both what it drew and that it answered. + expect(watch.write(SYNC_OFF)).toBe(true); + expect(screenShows(watch.snapshot(), ANSWER)).toBe(true); + }); +}); diff --git a/packages/acp/vendor/adapters/MANIFEST.json b/packages/acp/vendor/adapters/MANIFEST.json index 70f3589e..95aaa6af 100644 --- a/packages/acp/vendor/adapters/MANIFEST.json +++ b/packages/acp/vendor/adapters/MANIFEST.json @@ -8,14 +8,16 @@ "tarball": "codex/agentclientprotocol-codex-acp-1.6.2.tgz", "repository": "https://github.com/agentclientprotocol/codex-acp", "upstreamBase": "50f69e57ca761ccafd2ca29de7fb591068277516", - "patchedCommit": "fadc0a690e96c276629be8a34be980d35e821637", + "patchedCommit": "e1a15637c13e85cca05cd8ba398c5cef92dcaf33", + "patchedBranch": "https://github.com/taras/codex-acp/tree/feat/session-native-identity", "pullRequest": "https://github.com/agentclientprotocol/codex-acp/pull/438", "buildCommand": "npm run build && npm pack", "license": "Apache-2.0", "contract": "_meta.codex.turnId", "materializationContract": "session_info_update _meta[executablemd.session-materialization/v1]", - "byteLength": 208429, - "sha256": "448d007e00c47cf5f4d5167dc817d7621857f298778227cc1e4b0f490469e387", + "identityContract": "_meta.agentSessionId", + "byteLength": 208660, + "sha256": "3ee22bc6b1649d02fcef80b352516f395fe774e63b459193195a41c42930dd8b", "files": [ "package/LICENSE", "package/README.md", diff --git a/packages/acp/vendor/adapters/PROVENANCE.md b/packages/acp/vendor/adapters/PROVENANCE.md index 241167a3..b9342c3c 100644 --- a/packages/acp/vendor/adapters/PROVENANCE.md +++ b/packages/acp/vendor/adapters/PROVENANCE.md @@ -6,7 +6,7 @@ those instead of the adapter `npx` would resolve. | Provider | Package | Version | Contracts | | --- | --- | --- | --- | -| `codex` | `@agentclientprotocol/codex-acp` | 1.6.2 | `_meta.codex.turnId`, `executablemd.session-materialization/v1` | +| `codex` | `@agentclientprotocol/codex-acp` | 1.6.2 | `_meta.codex.turnId`, `executablemd.session-materialization/v1`, `_meta.agentSessionId` | | `claude` | `@agentclientprotocol/claude-agent-acp` | 0.70.0 | `_meta.claudeCode.assistantMessageUuid`, `executablemd.session-materialization/v1` | `MANIFEST.json` records, for each: the exact upstream base and patched commit, @@ -15,7 +15,7 @@ list. `generated/snapshots.ts` carries the same bytes as a module. ## Why this exists -Two facts XMD needs, neither of which a published adapter reports. +Three facts XMD needs, none of which a published adapter reports. ### Which turn a Prompt completed @@ -60,6 +60,31 @@ own, so a client not waiting for it reads nothing. `contract` above: which turn completed and whether a backend accepted one are different claims, and an adapter could carry either without the other. +### Which conversation the provider actually opened + +Handing a running session to the provider's own CLI needs the identity that CLI +addresses — for Codex, the App Server thread the adapter created or reopened. +Codex allocates it, so a client cannot know it without being told; Claude's +adapter is handed one, so nothing there needs reporting. + +Codex 1.6.2 returns that thread id only as the top-level ACP `sessionId`, which +is the ACP session's own name. A client cannot tell from it whether the provider +allocated the identity or the client did, and reading it as native identity would +mean asserting a thread the App Server may never have confirmed. The snapshot +therefore reports it explicitly on the response `_meta` of `session/new`, +`session/load` and `session/resume`, as `{"agentSessionId": ""}`, +taken from the thread the App Server answered with rather than the one requested. + +That change is not part of PR #438, which carries the turn identity. It is +reachable at +, recorded +as `patchedBranch` beside the commit it names. + +`identityContract` in `MANIFEST.json` records this third claim on its own, for +the same reason `materializationContract` is separate: an adapter could report a +turn identity, an acceptance, or a native session identity without the others, +and only `codex` declares this one. + These snapshots are what stands in until both land upstream. ## What is carried, and what is not diff --git a/packages/acp/vendor/adapters/codex/agentclientprotocol-codex-acp-1.6.2.tgz b/packages/acp/vendor/adapters/codex/agentclientprotocol-codex-acp-1.6.2.tgz index 13554acd..dac0139d 100644 Binary files a/packages/acp/vendor/adapters/codex/agentclientprotocol-codex-acp-1.6.2.tgz and b/packages/acp/vendor/adapters/codex/agentclientprotocol-codex-acp-1.6.2.tgz differ diff --git a/packages/acp/vendor/adapters/generated/snapshots.ts b/packages/acp/vendor/adapters/generated/snapshots.ts index dbf05e74..69c7f1f2 100644 --- a/packages/acp/vendor/adapters/generated/snapshots.ts +++ b/packages/acp/vendor/adapters/generated/snapshots.ts @@ -11,171 +11,171 @@ * all inline exactly these bytes. */ -/** `@agentclientprotocol/codex-acp@1.6.2`, sha256 448d007e00c47cf5f4d5167dc817d7621857f298778227cc1e4b0f490469e387. */ +/** `@agentclientprotocol/codex-acp@1.6.2`, sha256 3ee22bc6b1649d02fcef80b352516f395fe774e63b459193195a41c42930dd8b. */ const CODEX: string = [ - "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", @@ -190,1956 +190,1956 @@ const CODEX: string = [ "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", - "QFs7EtraiGjrhd3d4Lcs7CsGJiblrswnAt1an3rWrjpgbXUBa0CHI32YFMy2gutaCq0QWdEkQZRFwjjWRBpba2EMflgpUX6Z", - "9PtO+n2T/q2T/i2kn5HNfnKm9/pPNvGTTrKzJX7yfh7aIiYOwK47h3Mk9g1h7nlZWsFcA1TfWqD6vgmqT21Q+AFcx6EuN1WX", - "c41Vfcda1efMVX3fXtUPDFZ9x2LVj5is+ozNqh8arfqu1aofmK36jt2qHxiu+o7lqu+ZrvrEdtX3jVd9ar3q++arPrVf4QdV", - "1ZgEJzeGiCDTqfXUO9kHGU7pP6PhuHpz4iLRz3PqHHjHxSDDKS2l7qf/vU4XYQ2a6dWqaxYoneGW9llwmOOUf+4fQcIcvzw9", - "L/jpbllxBKG62SDDK13EIKEHFprKQ2JPMDYtOMowWU4NzmLBZjq1Xvoid5jjlH/lCZ5BhlP6NZUe3VSnHAw/QmU2y60RiD9M", - "llcjFGnYTKdWsPuHOaY81XH0qV27Hxi2+45lu99q2u5Hbdt9z7jdJ9btfmje7rv27X6rgbsftXD3PRN3n9i4+76Ru0+t3H3f", - "zN2ndm78QIk82M5Isi25XrpF1gaXYX2nJqcL7XN28b5nGO8Ty3ifMXL3PSt33zNz94mdu+8ZuvvE0t33TN19Yuvuh8buvmvt", - "7vPm7n5o7+7zBu9+aPHuhybvvmvz7keM3n3G6t13Tdp9a9Pu+0btPrVq9z2zdp/YtfuhYbvvWrb7rmm7b23bfde43bfW7b5r", - "3u5b+3Y/MHD3HQt33zdx96mNu88bufuhlbvvmbn7xM7dZwzdfc/S3Q9M3X3H1t2PGLv7jLW7H5i7+46923795eBNWEQkmlLM", - "wP1RU8N4n1jG+4xpvO/ZxvuscbwfWMf7oXm879rH+4yBvO9ZyPucibzv28j7gZG871jJ5ZerNaFpugwxpfetLb0fWFH7jhW1", - "HzGn9xl7ej80qPddi3o/MKn3HZt6P25U7/NW9T5nVu/7dvW+b1jvU8t63zOt94ltve8Z1/vEut53zet9a1/vewb2PrGw9zkT", - "e9+3sfd9I3ufWtn7oZm979rZ+56hvU8s7X3X1N63tva+a2zvW2t71OOSRCgwuSTtcl6ZT0ojEYmfkBJqZcBeM5G3IqgewBb8", - "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", - "ktmQJc08tZHgzk+U4IuGpe6PNCdzxXc5e87t8UnQzt1zTllIFPjadrYcNLFnjMM1tdG1yZo9bkJ1UVsQoZVqO1E04lllOhNh", - "26jVRYp2SE6yjCqT6E0A1cG4lfW2mP75mnL7wCzO8GqtfeC5Xu+MBdm10nkudNGG3HSqnLQxF6BgosGcqiqjL9DoVe7vdETF", - "Wr6duc+xqvbhKLWDs1bDyv1pkUdE2TJdy9y2tZPW/Faxe8NcO+aGKMryO02SeFgIlVpTFy7lYtp0XQwm94Ao1XYtJ7lsDSxf", - "ucypo449V7YuuMsg35Zr0mbRMnHjbrvriD7LCyAmBCfxiDSwIG3juqrdsm6o0l1oHHWpb2PFLXOSQU9n7O45Rkzp6BDMu2W3", - "LX5NJzolCtCt2jxNMBekptddVXB3Ho1yc7M+f5ZQFDXQOh+lp3WaAwBBaVE6AjUzttwKLidmqjStSbNZM+YnfVZLEuwTaQBZ", - "cjC2zAPB7bfCKNldW9qV093VMHts6ahns3ptZ/WUdR7CB+wrsb4xHSMUvAB1I2URSbnsl00pWGH5Sl6DPRm35TRX11KqE4yb", - "aM0npT/E/kIjkLBndGLlehYCehZdWTZG3g7XFJSl+q/SfUQW/7cMguuf51jcB5XsIreR55YGkKqiduoLzk1ktltLoqO1cSRe", - "c5GwCx7xwvC4aW/y506JWFlMqv8+noJZUx24CwdS96FAasKAMYwqybxV8zLiQgTx26BkTLJLZw7mggW7Hr4fqGpuxwGOazfq", - "Kp0//CkIlmfzMgl6doqmbcrUKrk87vNIoFZGteOMXtmWujXH2Uv48wcOnks6yBl5a/0Z+eQO9aemn+TWAUnnLCinFCqLy/Ph", - "8++k9DspvSEpJexsldyl2adJs/cYPaVGnz8oIKRlyehkIjodCWXSNGjcI0zjlKh1rn30oEzeTZOeuXk1+d7jlGwg/ZRPP5Ks", - "2nTBaYbRQdaMSxK9tBvrxMOox2CmT/baZMA9VN1gGQboYVU4sYEMiO7k5xxe2EJJdLTa5GfClOeAwlt+BKjALGBDqpBT+TE8", - "MXcRJU4iio1liS6KUtxPpfi0nbGsQxIYCYFTveik4V5sRHm0rNTOmSzc1c0px5dy4AAbTd/B7qNr8TXeU8oImr65TUiDYn8T", - "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", - "Es5ys3qfQ2e/We/n3JTeavfaTGMWjEv+NXOtzIQuc25kJ0MTX2Zo5Qq7C88rJib7zDwDM4/7Njt5+L7FdkO7eKYU+t6Gycj9", - "nK5NA5Pc/quZKdq8DQOT+zYdvJFMNQnlkmdqzMzJCguMyG5z4VEpk5UZzMxdahTM6nZnsZnVF8930hg6YMlc27xz2gKzMmmR", - "MyHfP+bdY9YjfN3KkKmXwQTbFUXbaLDb/CxArjKvyMw1JGa19B5YA71hbmrxclsilGlMYG4EiyyzHFS9IskhVLeVuU0JVL6O", - "iPHYWU5HZLGCjsiJZT2zNKXXPLWbn2Z0BrY5e205jNNHR8C47g3G0nM6JTmSAv96BY+0s+vW43dPUd1Sj+GzgyTjoe/O4fhy", - "r9eS/1gueL3OYOOyQYvFl3kvkMuln7WtCebP2jQ/T7/pZ+22O2Vqjm/6hD255QnP2dsu1srtsGLwQULAN8uWqSuxv13+mXu5", - "6jP3cqln7kXOPk/7zF2pEdeyizEi226T1oG3xe+J1ONqoSHYLFrOecD2lrVsyNwVt/Rz5qs9WnsJ0c0freV18yk7WOXVqdQD", - "thx9+/sD9p09YEtyklWTfMrw27qdeTBHXvG2cwSVbWtjlHm03nE5MFKykG0rcKo/V9/9aLNP1NOP7fYfp7/E/Nz8KboU1JYs", - "e5udv/yE3akCuxSsMwiWshnUUvtbMRIUg2m32cJzBnuJ32kXM1i+w/nOcvPM2HrRbt4To+J8WI/PcrmjcTDlvWE6c8bK15s8", - "TP/mZn0xM+vY2TfzdFt98TJvf4rTnMGyzQ7tb+yH7n7ORil0vCfPmzNn6ayrh3xv5jp0O0xKZT1XWzO4mrmybWff6uS6FL9h", - "jmf1mnkfpiKD5/J9KXdCZv5I+aVmoV30wKHr3d5r5Bcat0VY2xkJhl208BmxG0GsOSIldIrVphtdbbJ+APou4vN5s44lFzC5", - "Y+1X6Av1PfN+5yf3+8XGqzwv3eaYme2yaXn8hd6xq8xfUCzBmpoM+jiLyc/Z6gJp9NNu91VbnllcOpF9l2xPfM5+ypw5emn/", - "xBb4A+Py7bgDuMkRkffAvdie3QP3TMQwN3jUrixQqXIZnDhbJZ6wZzJBBc/WJ9WerZfKP1sfhdaz9fI0z9ZH4eDD5fb8kWAX", - "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", - "euIyfK3nLcPC5rxlS/vW37h3a3dlSF3G0W1IXaa82NgLeP7386n6WM1otnTtrf3J94w5zFIv01nLVv5ybXvXtgeji4LcJGXG", - "ooacZOStkpEssP9lb8qfhhREu5+HmvYp3dEbOwRr94uj+cCO5u/8SLDAa/4nADbI5vTMWu0id42UVHAW8F/25W5t/QvYEqO7", - "sif9SnWtnKcr0dGhXLQlga17Js3UPMh01/ZgBf5rd+cu7Wt3bQdLW+QqI32+hNNg//duaVsrsKNsBZ26h+9f7h26M6qfpkqf", - "RzFMwiGAeHZuP44Ed3HjrrKxUOM0Tzb67786GAxP5SSNaXmjADY6wC5hocMq98Mb+JvopfueUSkDQ+yX4jBEu2u7Qv+5PqUy", - "3RPXkedaovgnCwnh2rb8dRVkZHuCsiHRPTrhDcuwit1v/BD6NsOQ1/RD+mVM/TPlyuSF8ZBlrFDfgkG5lsEUquFE+c7f2Kyd", - "8Xq3gdZBU3waOc5QgHJ4wJzWsFTR1ZGtDezv2ADWZwDQ4jKn2GORDVqOf+JTRf/EoLx/4tZV/RPDWgnQ3368mFnR2117fkE2", - "Zy/gcTfTM3EXOVlF076I7Q02fT70eB/zWVZF1Q9RotqjbY5ut9scuJ11+/bjvOXr+6JFkenEthZsJNMxf/25ehe8a8TUnXXt", - "IjZmMz0NliyhZb0yVUn8DKsbn01GFzhudMNLutANyFhTJivTxBhzV2UU1LJVLXnvrjELFX2pZZda3OwYuEPX2sDQu9YNErad", - "nRgqv0JWTidSS8/fFLJX7RqJmvRFsJ+jQkCSdlXIuf3irTj8trh2u6VOqbVCCuvBymIrYN7dWmu2FIZnoLPB44QO5kDkBb4M", - "j7P0mRdXa7UnLV55USWJ0b5wKo6P6lAdcKva/iOr6yX5CboZ30lWB9io1jFbp7NxZKFD/doCET1vL5DZw194xjnpC3Go/D87", - "NiqGjtnEy5gI3bWRwkZDWWx0Rck0vU3C/OL8MgI5nBNML8og58ApWGpC9Fx8NtNEJclhM4KyYaiX7MtFZKl6B3s8aUPl5tOO", - "VAVxxWABECMsfb4wAtdQRo/K6LN965rV6G4az6dRGVFcR59sQcKxL0J4nE92pTJT1PD5ZANW2xv0o9CbSw15jaKcE8Rs7FpS", - "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", + "akyCkxtDRJDp1HrqneyDDKf0n9FwXL05cZHo5zl1DrzjYpDhlJZS99P/XqeLsAbN9GrVNQuUznBL+yw4zHHKP/ePIGGOX56e", + "F/x0t6w4glDdbJDhlS5ikNADC03lIbEnGJsWHGWYLKcGZ7FgM51aL32RO8xxyr/yBM8gwyn9mkqPbqpTDoYfoTKb5dYIxB8m", + "y6sRijRsplMr2P3DHFOe6jj61K7dDwzbfcey3W81bfejtu2+Z9zuE+t2PzRv9137dr/VwN2PWrj7nom7T2zcfd/I3adW7r5v", + "5u5TOzd+oEQebGck2ZZcL90ia4PLsL5Tk9OF9jm7eN8zjPeJZbzPGLn7npW775m5+8TO3fcM3X1i6e57pu4+sXX3Q2N337V2", + "93lzdz+0d/d5g3c/tHj3Q5N337V59yNG7z5j9e67Ju2+tWn3faN2n1q1+55Zu0/s2v3QsN13Ldt917Tdt7btvmvc7lvrdt81", + "b/etfbsfGLj7joW775u4+9TG3eeN3P3Qyt33zNx9YufuM4buvmfp7gem7r5j6+5HjN19xtrdD8zdfcfebb/+cvAmLCISTSlm", + "4P6oqWG8TyzjfcY03vds433WON4PrOP90Dzed+3jfcZA3vcs5H3ORN73beT9wEjed6zk8svVmtA0XYaY0vvWlt4PrKh9x4ra", + "j5jT+4w9vR8a1PuuRb0fmNT7jk29Hzeq93mrep8zq/d9u3rfN6z3qWW975nW+8S23veM631iXe+75vW+ta/3PQN7n1jY+5yJ", + "ve/b2Pu+kb1Prez90Mzed+3sfc/Q3ieW9r5rau9bW3vfNbb3rbU96nFJIhSYXJJ2Oa/MJ6WRiMRPSAm1MmCvmchbEVQPYAv+", + "WV7PtnAxWVd1AZ0QV4GJ8hWYOM4CE+MtMHHdBdQnySEKD5si8x2HAfUpc9zTsP7GPMZlQKbTc+jE+AxMXKcB9Wlz7rs592UO", + "Gv/hoE4BdFKdch64bjItSSUVmkbLuBuUm0rLeW4iTqosR5RH+GFSd53kXZVOZfKJdT+YUP8D/FCOKFTPrD5JjqMXpmltbiwy", + "LyqHT3gXhAn1QcAPmUplb/ml0onUPbFuCBPXD0F9khx3SCRNlWnxRJgErgjSYYcI1BPtZTDxXAgmxIdg4jkRTIgXwSSwyk8Y", + "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", + "O2Kg1O5ooFqlQrT0sofHuvPkj1h1vmq6JXip3faW3e4IzoXar7++3GYplysy7XKFp66p1DWZ2g/7SSwV58UPmXpKbf7dtHlM", + "KfCHpbRlUlv10SVYftL1rjDhv/T3eUoN/eutabsjmMFh3IvUuDfN9FhTvxOwyaV/21QhMFNJMyXx02opePn2NeuxXG8VGmVD", + "uCF0I8EeC+T14erTqo3FF4gK7qZd4eRnLXj5i8YTUWGtVAWFQsdxZ6D74MCuELC8FVn/CcPsNTaiZYbyy5tywAw27Gptrl2p", + "UR2FabSmR0VTsEMVWSvWructtmUDCxHaknasVg0pmL5h0YbT9h9p0j9Qh1he63KGVtikrfAzaE3OxD/fvn6laNKSngcJT5ug", + "YrUlMaNpXiqHozst0bCC/QOcLP/89zu1l5xn3yKyrU4RIv8gyPAQf0HeRBtgIeVIVem+xk0R0w8xWKnKjBZMMXsBE5PvvLVw", + "SzSpCCLfXETvNjh7sk1VAI8wJy0b6vo4ii8jlNCQak1KHwpALgzJVsvCwBtEAHiCbWb56Pe9zYX/2X9ESgIOoA03VCbO52He", + "OnE0Ccyuk2hNOCMxvc3w5wmr/XSdcRMrS+4+WV5jZzPvXJKCFS4lenDtDGcMZRa3ArfXFc7ISAxfndQRKKvQpI4PC+ws7/Rk", + "Pbi+takZe3cX+YhdtzBSLlrWcfBS4yvDxQfXRKvjk4+/KD0te3jwysfRh49KQr/DZt6mrpVHxccjW2RczLJkPB6zA3aTNUXg", + "SMq/bLh9yS/TKbG8SL95UytsXTKsmFoj0BoDlS/ps9yapWaAjpD1PBEODZPk4Cg+9RDnsPMHyPQU7TzujlIx88FGUPvb81og", + "Dom/1VxamuKdhFyny/uJrC+vKTbVpOI+fGTTI28NT7Jrs5aZHo6wy/LwLYd+ng26zG8ohgzSSFDnKtN9272ItJ/WxqKqmMqx", + "aaEXXsW9UY95rYZMmowW3B11497bYy6m/3mmK4ceAi6nvbDbrYTNPxI2/zgjbM4962nS5DJuznV9ZPVFdxnGQY7EIbN6zhLE", + "/WKMnXx4f1ujn3AgS6XNLBYe0LuNQkQbgShTKXVKL/igxXsAKmm13HPbc3mZ+jzbovy8mZJ3Ljqml/n1ZTGo6QmjYEbj2uHE", + "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", + "8PE4mZ7ROCmJ2z2ghSl7O9FDvYJqxGgvkqZG56SRCcVIUmvKykxGCdamHaWjnOCu6EyBdZx0o4BFpkWMn30fzVmXsxcaDBZL", + "WeBgkswvxwenCj6/An+s5LTNKcdKZksU7ZF5YqiecnLp6TlWGuhey9BSpncl5CwnnpfmVEb7mOhJXepRtCEDTP2GtHQxSZVp", + "J72C6kIZB5mbbFxLVcOKtdPyhHeULW00/jAk1DTlYGTnuzl4n1nX4NTr2JBqJ1kvnE5H7appdw7C+vcOW6cGpUeBDUx72raO", + "z7HESdzgeq1IXsrQqYTh0lph+rz7rnWMjZx8CSkfPqTcOBWSuR6m51q0zNfvmIh5/S1vjX3O2B6bgkKKKDvPD0ZbRM/lCskk", + "PfoRYQ3jNsHTLC0rY/ZaIV79QpFOIt0Ph+IDBsNf7DTtEUYfjoYa1+YdzonQfIQxDskYR4SOxppc7yb0yBVmPknTAbE4hCL9", + "QnJ8JXYyHyTVsQVqatGRMbabI9ePZETQqpg4LNPQz6LS5zPa5xiNlvifJqvnIEg2IHDvCPKTgv1JxXprGmWPwez7BPNcyeCy", + "tZ9WL4RUGhEjmrP28WHTrj8nbGZpLRSzmbhrKk/8s0KYYso2n7T+WS1FqsXT5dchJbXnwlHZTQAST9pm5XKkk2Iny0pIEEQ1", + "OgHnpGy8u3lcPnBMPOXLeQLkoajoPATQIqp4h3yfJyBOu83cZZDQEut01E3EA2d9Ypn1zJgaX2i0TdzmnDLZJDcbAS+Aap/5", + "E+jt59tHe6ZzrGdGNzbOX2uEzh8R3CamJS/E/vgzYYrCbypG4QcVovA3GIVPuroxd0VBKNWsrwb3h/WC+5NJF7A2HY5JPsvI", + "t27sWyc7Qj+ZtntYaQifs85klF1VD8WfT9vT7PLp2HpW6ccKlk+ZXjoZdfpakJujY3Le56iZgmSajjBfyLQ9mhZGqmVtTIY4", + "HU9bL/XWThhjC0XudIx7Y6Yd/Dyftnr6xZ20pH51p6muen8nvJt3W0oJ9USwNjvqOV/tdfr07mQ6ZlPd6mWcydUKpE7aWmza", + "ccIvkGgm/c7YoisSPvsXvbyTs5VaMJ6EzSibOgM7mWICrtmgW+msK1ksFcOCX4Juhw66TZm0nJyjMJ/02oxbxdOFO0+ngxYS", + "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", + "DagvABvdBuXeuwaukOtjq+VZy+nYXt24gd5zQ86srI43rL/lDphn446krD5DB3mpJ8e68GHspbwyNbwxSe+1/TLfcfWKDGML", + "C2NnId5sgL8Jb8hfwQ5xRRegDjoerIeGnQS0CxiFhWt2s6+9n5LJlS3475CVlwcq0+hOwZFjRofVzOhuq7wZ7a1VM7pdx4yO", + "HJj9MLFabxznKso0oe9Ai8wqa7afI2oSqxVM5rOx+GNZz7e+E6SPp+Nfdgb6czWexXHz3cZyUI99vzSeRt9t9N2PtLC6x3G5", + "2wX6LsXXFM9kG6LyXNln+BrkmuOuTPsJ1VfpfYPXDtqITrB0wHRdhVHmlj8LZjqrtGG7Hv9l2Jz3GmzaTUxdpcxnRo372c+w", + "buz1F/P5wObz9961s166147FJ+0M+dkHe3ETFdnPvhfdogpT1nzO6Umxn/PaPZT5nAtbXfs5adTfRq5D2nz7cT7G/551y3Sk", + "52E3i9Rvvnf9nb1JDA5pfTKFFxkry6C7tsFYgS4NZQSf4aXwCy72wPejo/I2OiBNAnJPEAvdG63iD7YNDPBoL9McpX3aqDQa", + "6weEzQ2fnLkuKtz4QVSCLG4D37kuposVtMZAW60d1zuq4hzAGZLAFKC/hk8ge/7vvzo8LJnT/wjbgxLuxtQKsF99JwIjNjJ4", + "BsCEhyF6jtfcNhxz9/7W4B2wgISwpLenm8DcpckxAOO9RUvd28dDkDFCICLH8VY+cCSG7a0dAe/0SvkIZJNnD7p3Q/ZqMY1O", + "jAPGAOvBWd/6u6WQgukjvp/c914Nd8H33iWaiaDvQoG8nRQh4zCNbzhI5g3egz6xrxshrZtU9iMkDXBRkwtTphchDUa2G8Fb", + "V3QjtCu4EdTruLqdem6Ea2K4gyLWt27skm6EdOksR0KQqoLs78ZfL50Cj0JevacTmHdeb30QEWjahs5n7lzwX1v+tbVa+6uV", + "E66dKNJ8DK+xlOZieG2oongaXgOZu9c3TmTwNvibAMlj6Rg8Dul3qtch3DqrKDbmVbeD+i7td0CpswTWDevJif0E5oOGxqK6", + "y+G18n5Pl8P+EfsI9Wf1WN/aDUFz/eKEOKwT4p/Xd0xBEOe3QOG4RV5Y6IK4cler0v6HzE4U70Nmk4dyPUiwgOkvXRWsuo6H", + "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", + "8vp2lwvbf697Gi6rT7imcfCvL3ZPQ/z+55r2cReEpuFz/+ee9kXvaWueaP/nonbni1rtU206AN1/n6va+pffihF+lsval72e", + "WYm54gyvvnL9n3PVCgXZ/5/etNJ3pjUXrTq2+Z+b1me6aUW6gI+8ao2LN/ngw7bQqb10ycmqntghSHNdbrL6XGTr0omtySK2", + "zrA/qhKkBqtPCLY+Y9YdkmOtS4hVn3NsXZ6x+uxi6zKKrUkjVpUmrib3Vm26raqcWKediA3lmfoxvBiY8Sc79/m96nJ6NUjF", + "1Sj3VpNsWw0SbK1NqaWJuSPFr2aEvFNSrUZJsNaaT8d1Egmt1iexapC3qnGaqlrD4Lg8tuZNTsTd2breZHcNIjabFaACaU/L", + "+WBzx2xh7yE16eFsIA7WRUlWFDO4Bp2dLaa7Ry8xUONoXpxd56MJhCaDo3R0DV792a0RjfMb0Hdcmq0M7AGHRX9wZU492Nsg", + "j25L1CWSHBI43YaysLY8gkeL4evFaFxalAjIGVRuitqhTc2Z/czpN3WfdBq3ZPRPRBASVB0e7KDbwLxtU3cm7DU5IhrUa1+X", + "b8QFUEhQbDpZvgE7PfbBh18yC6t848io1ODf6/Xgz9WWKKM9H6r0fjWzZybKl6588F/GuUe4wYB6FOsAEw0Aqg+z1i8uy64X", + "vW613RinXpv4iFoCOH7ekhWnk10KDgy8K2ast3s9WqD1Vq+AFBK2NqcgbFQ7jIGxii1w5ezB5BsQNj1rYvbGmMeiDVqri3zw", + "1g8QTLgulpciZIsV8qaT5xB+62nWxoAnylwqwzYPn1JgnN5iSsGofNSWZOQXD3tkwBoIRn4yK3P/sq2mx13wsu/AKvDCDOvt", + "VgSCk7cDlJJCfnSzUadn8LhuK1A0Ol9vZNjhcdTZfYDXQWf80WRZyGLN4CKEDbIu8hvZ3yKILVVz/XKAIsHhWEaxbztBr5mu", + "l7We9B61dHcrjSbPNi4CWTFcALqp/Wu1FSQD7hlxuwUx2Vpd5o7wBuwBhhwcQrq8rAIVIfAPWG/TyYGR5owk714pPu8y9Wmx", + "XQrlTO+1vC4mFD7J7uFmZf1cXPht2SeNdpGW7MbPVd0esJXOy/2kjX10GQBa4dlj6MXUyK1zOIT4WLks5RFyKc43jF8ryuB3", + "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", + "t2VH7ebnxfDienqqdvRe58fDV7sgdo/GpEUNGgL/qkqpH/mhCifBLkzGud4xTxVvnLL7qBVSn4CU2j493T08Vf2cHu0cHqmL", + "/ibzTZf+Bdg1Z6zzeQz0La/yQeUJHJEJgqPpLnk2gxQGcDTSX94JfI4f4wf3kkd13UkNJINYmsBRRCyC3ZAA2rpGkxrg0A9h", + "6Cgb6UV39uhOjxmJffjXw6Od1wd7e0eoOJdFN4pYBdrGkFKwPcluzra7735U30c35dn83TtKFvhk/Z3+uG96fffuw+P21+/e", + "2SkADM/saGbT3NYGLyHU1TQ413hL2BTdzc1+wS6QyH3uCLvJuIR/Wzocl6aH9ZqbW3OjDRGsB4Tb/janOH8a4tamKlxDIyiD", + "tumuyLqd8ADtsYuhDp56bG0Fw76yyeUMMj+U+xhpQl8RXSxlgow7WUPNUpe3l5bbi0sJWptNXJALcYD7oaqdrr0ZcSpnBA6/", + "h7hhwGvSB/1xR+eI3x+pCx7dsdNnt+OsLHUNZyzpg5MYDg7NgXs12YETeBFiCCTLMDDux98q7GBnZT12CoY7334DB22kj7KX", + "jfMtHi10wrpxWCdfPLpzdOFqT1fnUy/fGgwa6Rewi3/xRdqcf3FWuxvBfynTxt/8FBOvR7PhdH9UDKcv1DDU1nlRXLrRpISi", + "DwNwg0UOlWMao2kjfTd0T7TOT+/KL/+t057CnRHauLYI4h1BPi9d45nxNMHWk9Foqv55qv7f2PzjtUHyT+nxT+nJl+kvXxz/", + "9MXJl1/8cvzTv5182ewgd1FfQv+JIOv75rWDNdsobYJBqu6OY+pIqnd+Ok6/OPkF/vOoc9mCUDtayFzmziV30XW5ja47++i6", "v5EqUM8nEKnGTlgkaIbwIyGi8uHmNEo718NpJ93gCEl2tGIvoW1Qs0pDzq6tH4gFLih3envIWjAiPgnSTj7tAYlAGL1IrcsZ", "KB503R08+VVtIQFJvxjSKKvbY5tUYQ23m5a8RLZfnO792T54xXqx1umu9DuXFut+u4AMAdGrqGEjt9txaKEtGMldsLl63lC4", "nvvOVNcucYuA6/ToAakOol47zusAj75f0akiFl0+7JfgDqaEPQypK+p1QXSwv+edM+fu4jIgxMxrNqKSCFCCbgF84HvrxkGN", @@ -2161,15 +2161,15 @@ const CODEX: string = [ "7+oWR5zvf9cyf8Lz5oqrwFEg/84sg9+Fy0CNewuGTQHCGyXHCb9Lrmbq5DxQnAg7895sSoG46EgodRQ2kla8dfPdZ1s3I+xW", "HrcxrMCDH67U6VrJOTe09Xje2xNilTGSc+JkiVocmgnueU5g5OUWsbp4jsqMCEhXT1iImqDeUE5asuM69UbIquczWIxroCOx", "bOpNK9WB47dBf2ozcn0eutN+NgWtHvC/NnVNXwDoSQrWpRCzXpWdwp0SrU1FPbgoQEz09NGd7mieAiOT3/eDEDDdVxIM+lUi", - "fHXWs88NaC20PmsALlIYhD3dfvHMjCcNKyEODYPhvyVpl/XXZXd3eDFS/Ai+lM2z5lKn9g1do8LF//t7Lf5vV1/836643J1L", + "fHXWs88NaC20PmsALlIYhD3dfvHMjCcNKyEODYPhvydpl/XXZXd3eDFS/Ai+lM2z5lKn9g1do8LF//t7Lf5vV1/836643J1L", "6bdmuX+rn4hoQHzUkSqvZIPk14c7/cv8+6PX4BfCxsjwRbEu2VmrXdUYfLRzKCEBigPMY9Si4WVy9uoMMhSgi0gPI/YT5GcK", "9CsPdvIsn2bVHbTPoZh6ISDPY0Ce5x9qYPRVKYFQfP6Xv399kX/4+TpfH9+W364Pn+RfX5z/PftunGfj2/eT339YevDt0aDP", "cLfVPnade5jRR9n+cjS6VGdSjwpk02fRtgFxHACSNlT/eRyKRx0XiCUO1i5m1y4D6K8awmhySU3Vt7YpJAjPJtkHnwr4TXZ/", "Dh/azICy4bNYy4AETnNJAqz+PArDI4ALwhIAKx8euuMnCG+Ky6upOpQqoQy5AkF6Uajb6eijkpEEJP4oCXk9+rkYDLL2BRdR", "6z21n2WHfNEyzfGrRAC2vaxk5X6bignAD4XaQvuFOxD+KCF8oE9tXUSt092d9vdHR/upaIxan6Ham3c+jgejCYTqiC2LArha", "q+FPY3vN62zMrpyQt8FLOhXdnJq8c70dvh+OboZcSHFsdbKY/OMU3gNJilB72XyBiN849S8K7h7qJoe65NcZq6v7va+rA6WJ", - "LGJdHQi1212jjUsdFZ0CzCq4GrHCRbTByLTYMif9j7c7B39lFUuafA8+R9tvDw523hydQsKkd/bxR7z+mOcffv9xH4CCFyB6", - "ApJvQNxf54P+i6YKvECiFwwqfld+ebDz8vTwf5G9hrpZvDv8qhleFkKrDCsmRpigcbadDYcjOPqH/US/2/ABDu48BLqbPLqD", + "LGJdHQi1212jjUsdFZ0CzCq4GrHCRbTByLTYMif9z7c7B39lFUuafA8+R9tvDw523hydQsKkd/bxR7z+mOcffv9xH4CCFyB6", + "ApJvQNxf54P+i6YKvECiFwwqfld+ebDz8vTwf5K9hrpZvDv8qhleFkKrDCsmRpigcbadDYcjOPqH/US/2/ABDu48BLqbPLqD", "rDZtEkbAJo37nJ8FV7SC4tNLgw87rP5oussJo4q+unWV9HPvopG2UzH8q9vxVT6sqromq4IGc7f/7Pb5CARr24ESmdceg/8r", "+Z93AUqpxKccYtDqahE432PXICNLHGqhiZpSBI0uyWPw31W8HS8Ug1miFqGKFfVuA+7NMAOr6VUCSegbKQl9ZySh73g/wchD", "xc94fyWe+AZ1Zfy3Z/IqjXvUdfenX96Vv6w13x2CdU+D8g1+VE3ejse6ySI1w3qoZfiDvS09jdyW+HWwbzaHUG/hJ1Q0VcUl", @@ -2221,7 +2221,7 @@ const CODEX: string = [ "F7sOT3zZXWGC5PCFdu2UFhAQWzSuiRdRUnlKMv2u5y9DEDY3Mdej1+1lPt0dFnAC2D3O7V/xCl0K+1IYFKmPjtPdN7tHu1uv", "xD4hxfYIgECCFoPDYUXbqBGIeuHmFH33DjuobBjPr9Ybb1PutqmTW+a7SG4Zc5ftjSHcCRngGTl7e//0cOfgh52D0zdbr3dO", "f/x+92jncH9rGzbVzrvx3Y9X6kA6PYTDad65nAnFu1q5aop+zh24jSGaa4u4CPDB+AlVd6fu8qfWK4c1nW3Is0yB3+iDuKjf", - "2VRf/44nH6V50km3OphTXB0hY9wSOEclbW1aeZbxgZ5iaQ8OGjyG+E1eFTxuf9tej2QNw0/XGWoU+kVpg5uQihm+c1owi0ZQ", + "2VRf/4EnH6V50km3OphTXB0hY9wSOEclbW1aeZbxgZ5iaQ8OGjyG+E1eFTxuf9tej2QNw0/XGWoU+kVpg5uQihm+c1owi0ZQ", "VXeH0mVX+6KG4NTHg52t56932tdGvny1u73z5nBH/5T0Qv9R+E4IlxoVxb1MBdgXFDbD8TVErUjOZ8VAA8a/u8RA9KN9bdEg", "97euWump0x6/oqJo7eO338ALQrQsm1xHS0k5U9GUC6vaVjc0rTzsDZ5oBq/Hj0uEyD4tk7W162IIYSfW1kol9fRydS6ov0H4", "AWFobY2eo56q5msG3ho8YWHc9rW10WyKYhPOpuIHy45Yk7z/YngRxp8TM6JcLUpYJYqUnZrPhJMFuAK52FYjitrnJJjDa0tQ", @@ -2230,71 +2230,71 @@ const CODEX: string = [ "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", @@ -2322,592 +2322,596 @@ const CODEX: string = [ "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", - "N/viUz0Sy4tWOvNvIJvrUV6b/WDLmhL/6CgJaFT01oAvF+Ppd7EKq6FTMrfIWPssZKP1ST5vuHPLaQLQMEbx7WAnFgNiKsgc", - "4WDfTrHch4B0EJPCGCypLX6grZ5AdX5fkqPQh46aDmWPz4x7WRj03c+8b5xvTVggYQtq/3OHCtV2nRpL8avlJFNHsyx3EkSk", - "LQk3NCgMSCS+eulNUkwWuD8Orw7ovbbpIS1npx0vs7vMrxDdq+30tDglzgyIK9dGIlm5Xaf9RZVHN+w1LcLn7iS+shJbiBEY", - "NiKrKYjd8eJS8do3h5VeAmfOw1lu1SzulGAhbpP+tLopfXDzkvJCO1Vwz7bZrOLz550ECm/if/bTTljc78D/nCc7dn4xGOXf", - "1x4RaK7YKv8kWPc9OINR3p955+be+x+B4fZPXP5/R1QJs9TU059V/PzSEb4GMDkgX5QzNjRoeg5yqux1ng8/j8b0+XWgmOVD", - "I7lIFSeggMpNVQPjpCFi6k5oK0lPtu5KjJbCW8B+dqM8JV4u5DL4iGgxanJN7gHcGns25qKdDuAmN6AF3k29l9hlEssnZlUI", - "cXkS892ViFM8CjZ/byXDgdU056UYZpeLeTYpo1OgdXgYYZ2ML8rs8HmvITCMyBTuXqjbnIr/P5od4CMAywGutbLM9xOT8VRp", - "vDXL+pwGqJm3vEj4aHj/qyfgTZYVIL1OBmBUgviDHwWYjua39Lt5iqbmCogZi0Dhpj8ZjnKqyFBNNZqbfDcycqdZSySyzDs6", - "a7S1slXrBy4K5J4ZqzAYlYuhPF2VdBK996FmJUJ03PVPIe4MeBLnPJ9N+iMa+8UXn8yAlltbfy4XamqU+HSZ5xPavkMYeic7", - "HoE1M+6H/nW/mHQuWqHXFpnfcqjehK7l9+WY3Ccpzwc49fdHjd0VC9AfMnA5sZuODudbidIWzWUGXiHqmIFYlRG2xv8DLWry", - "apoPiv5odKe6y4sZo9GZl+MRuaG2wWekP7ljizWyec3KD2o3qrPrzBOmEc+vi8mpffRu2nvQuReuN5LWjQjtX5/q3qT3fFFz", - "xQyiRkIrai64SzVtVtmQFZU2OnG3Qc2LPogqTSGT2PG5zzb2u40rauAd9CeHQC5GowQo98ny0aqZMOztirlFrijEjK94ePZa", - "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", + "RKQtCTc0KAxIJL566U1STBa4Pw6vDui9tukhLWenHS+zu8yvEN2r7fS0OCXODIgr10YiWbldp/1FlUc37DUtwufuJL6yEluI", + "ERg2IqspiN3x4lLx2jeHlV4CZ87DWW7VLO6UYCFuk/60uil9cPOS8kI7VXDPttms4vPnnQQKb+J/9tNOWNzvwP+cJzt2fjEY", + "5T/WHhFortgq/yJY9z04g1Hen3nn5t77H4Hh9k9c/v9AVAmz1NTTn1X8/NIRvgYwOSBflDM2NGh6DnKq7HWeDz+PxvT5daCY", + "5UMjuUgVJ6CAyk1VA+OkIWLqTmgrSU+27kqMlsJbwH52ozwlXi7kMviIaDFqck3uAdwaezbmop0O4CY3oAXeTb2X2GUSyydm", + "VQhxeRLz3ZWIUzwKNn9vJcOB1TTnpRhml4t5NimjU6B1eBhhnYwvyuzwea8hMIzIFO5eqNuciv8/mh3gIwDLAa61ssz3E5Px", + "VGm8Ncv6nAaombe8SPhoeP+rJ+BNlhUgvU4GYFSC+IMfBZiO5rf0u3mKpuYKiBmLQOGmPxmOcqrIUE01mpt8NzJyp1lLJLLM", + "OzprtLWyVesHLgrknhmrMBiVi6E8XZV0Er33oWYlQnTc9U8h7gx4Euc8n036Ixr7xRefzICWW1t/LhdqapT4dJnnE9q+Qxh6", + "JzsegTUz7of+db+YdC5aodcWmd9yqN6EruX35ZjcJynPBzj190eN3RUL0B8ycDmxm44O51uJ0hbNZQZeIeqYgViVEbbG/wMt", + "avJqmg+K/mh0p7rLixmj0ZmX4xG5obbBZ6Q/uWOLNbJ5zcoPajeqs+vME6YRz6+Lyal99G7ae9C5F643ktaNCO1fn+repPd8", + "UXPFDKJGQitqLrhLNW1W2ZAVlTY6cbdBzYs+iCpNIZPY8bnPNva7jStq4B30J4dALkajBCj3yfLRqpkw7O2KuUWuKMSMr3h4", + "9lqAOcgojy5sDEN/nfzZupaz5ffvXsCP1l/vzKpnVm8ly+tQI7FxoY/8Ra6odqSVvDM+i20sjXawGWEW7e0ym0WYjZwoADmA", + "wcWJ8MCabZTrLZWVatYxxoHc3RdtuJ9EP1fwejq682cxnwzXmY5lKjLcMmkHrfcVTMBGu0pM9ma7Ur/6Pgw5EKc2euqcQ9qM", + "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", + "AK4SAA==", ].join(""); /** `@agentclientprotocol/claude-agent-acp@0.70.0`, sha256 4e26b7086e9943d7d6774472df5ea6cd29eaa21dcb810b2237eabdf401ad4981. */ @@ -5636,8 +5640,8 @@ export const EMBEDDED_ADAPTER_SNAPSHOTS: readonly EmbeddedAdapterSnapshot[] = Ob provider: "codex", package: "@agentclientprotocol/codex-acp", version: "1.6.2", - sha256: "448d007e00c47cf5f4d5167dc817d7621857f298778227cc1e4b0f490469e387", - byteLength: 208429, + sha256: "3ee22bc6b1649d02fcef80b352516f395fe774e63b459193195a41c42930dd8b", + byteLength: 208660, base64: CODEX, }), Object.freeze({ diff --git a/packages/core/mod.ts b/packages/core/mod.ts index b6cef3a9..8496ec67 100644 --- a/packages/core/mod.ts +++ b/packages/core/mod.ts @@ -334,6 +334,9 @@ export type { LaunchFailureClass, LaunchPhase, LaunchRecord, + MaterializationPlan, + MaterializationUsage, + MaterializedLaunchRecord, PreparedLaunchRecord, } from "./src/agent/launch.ts"; export { AgentLaunchProtocolError } from "./src/agent/launch-request.ts"; diff --git a/packages/core/src/agent/checkpoint.ts b/packages/core/src/agent/checkpoint.ts index 66c4110e..d587bd4f 100644 --- a/packages/core/src/agent/checkpoint.ts +++ b/packages/core/src/agent/checkpoint.ts @@ -101,6 +101,27 @@ function parseCheckpoint(value: unknown): AgentPromptCheckpoint { return Object.freeze({ provider, kind, value: token }); } +/** + * Read a checkpoint out of a value nobody has authenticated, or none. + * + * The total counterpart of the parser above, for a reader holding retained + * bytes rather than something a provider just handed over. A retained + * checkpoint that does not read back is not a checkpoint, and a caller that + * needed one says so itself — this reports absence and refuses nothing. + */ +export function readCheckpoint(value: unknown): AgentPromptCheckpoint | undefined { + if (typeof value !== "object" || value === null || Array.isArray(value)) { + return undefined; + } + const provider = nonEmpty(Reflect.get(value, "provider")); + const kind = nonEmpty(Reflect.get(value, "kind")); + const token = nonEmpty(Reflect.get(value, "value")); + if (provider === undefined || kind === undefined || token === undefined) { + return undefined; + } + return Object.freeze({ provider, kind, value: token }); +} + /** * Associate a checkpoint with the exact terminal event that carries it. * diff --git a/packages/core/src/agent/journal.ts b/packages/core/src/agent/journal.ts index 361f05aa..1a34e404 100644 --- a/packages/core/src/agent/journal.ts +++ b/packages/core/src/agent/journal.ts @@ -40,6 +40,8 @@ import type { Workflow, } from "@executablemd/durable-streams"; import type { Operation } from "effection"; +import { readCheckpoint } from "./checkpoint.ts"; +import type { AgentPromptCheckpoint } from "./checkpoint.ts"; import { AgentPromptError, parsePromptFailure } from "./errors.ts"; import type { SerializedPromptFailure } from "./errors.ts"; import { AgentInternal } from "./internal.ts"; @@ -67,6 +69,18 @@ export interface PromptRecord { * test). Missing in older records — parsed as absent, never inferred. */ raised?: boolean; + /** + * The provider's own name for this completed turn, when the retaining caller + * asked for it to be kept. + * + * Ordinarily a checkpoint is not journalled at all: it is associated with one + * terminal event and published through a host's own transaction, because what + * a host keeps beside a Prompt is that host's business. A launch is the one + * caller that has to keep it here — the turn it owes is retained so a replay + * never spends a second one, and the record of the turn is only evidence that + * it happened if it names which turn it was. + */ + checkpoint?: AgentPromptCheckpoint; } export function* persistPrompt( @@ -245,6 +259,13 @@ function serializePromptRecord(record: PromptRecord): Json { if (record.raised === true) { payload.raised = true; } + if (record.checkpoint !== undefined) { + payload.checkpoint = { + provider: record.checkpoint.provider, + kind: record.checkpoint.kind, + value: record.checkpoint.value, + }; + } return payload; } @@ -264,8 +285,18 @@ export function parsePromptRecord(value: unknown): PromptRecord | undefined { if (!isRecord(value)) { return undefined; } - const { sequence, agent, sessionKey, agentSessionId, status, stopReason, text, error, raised } = - value; + const { + sequence, + agent, + sessionKey, + agentSessionId, + status, + stopReason, + text, + error, + raised, + checkpoint, + } = value; if (typeof sequence !== "number" || typeof agent !== "string") { return undefined; } @@ -292,5 +323,14 @@ export function parsePromptRecord(value: unknown): PromptRecord | undefined { if (raised === true && record.status !== "completed") { record.raised = true; } + if (checkpoint !== undefined) { + // A checkpoint names a turn something can be continued from, so a record + // carrying one for a turn that did not complete contradicts itself. + const parsed = readCheckpoint(checkpoint); + if (!parsed || record.status !== "completed") { + return undefined; + } + record.checkpoint = parsed; + } return record; } diff --git a/packages/core/src/agent/launch-authority.ts b/packages/core/src/agent/launch-authority.ts index 14294d9c..b7a95922 100644 --- a/packages/core/src/agent/launch-authority.ts +++ b/packages/core/src/agent/launch-authority.ts @@ -10,9 +10,9 @@ * * What it owns is everything that decides whether a launch happened: which * request is live, whether this provider is the one installed for it, the order - * of `prepared -> detached -> exited`, whether each returned record describes - * the request that was routed, and the result the document settles on. A - * provider supplies the work; it never supplies the verdict. + * of `prepared -> materialized -> detached -> exited`, whether each returned + * record describes the request that was routed, and the result the document + * settles on. A provider supplies the work; it never supplies the verdict. */ import type { Operation } from "effection"; @@ -22,16 +22,35 @@ import { AgentLaunchProtocolError } from "./launch-request.ts"; import type { AgentLaunchRequest, IssuedLaunch } from "./launch-request.ts"; import { readPlacement } from "./session-request.ts"; import type { AgentSessionRequest } from "./session-request.ts"; -import type { DetachedLaunchRecord, ExitedLaunchRecord, PreparedLaunchRecord } from "./launch.ts"; +import type { + DetachedLaunchRecord, + ExitedLaunchRecord, + MaterializationPlan, + MaterializedLaunchRecord, + PreparedLaunchRecord, +} from "./launch.ts"; /** * The live work one provider offers for a launch. * * Each runs at most once, and only when its phase is absent from the journal. * A replay of a completed phase never reaches these at all. + * + * `materialize` is offered only by a provider whose freshly created session is + * not yet openable, and is reached only for a preparation that planned the turn. + * A preparation carrying a plan the provider cannot perform is a protocol + * violation rather than a launch that quietly skips what it planned to spend. + * + * `detach` and `exit` receive the preparation carrying the identity the launch + * is handing over, which for a launch that owed a turn is the one that turn + * asserted rather than the empty one the preparation was retained with. */ export interface AgentLaunchPhases { prepare(): Operation; + materialize?( + prepared: PreparedLaunchRecord, + plan: MaterializationPlan, + ): Operation; detach(prepared: PreparedLaunchRecord): Operation; exit(prepared: PreparedLaunchRecord): Operation; } @@ -86,6 +105,11 @@ export interface AgentProviderAuthority { /** How one launch retains its phases, supplied by the invocation that issued it. */ export interface LaunchRetention { prepared(live: () => Operation): Operation; + materialized( + prepared: PreparedLaunchRecord, + plan: MaterializationPlan, + live: () => Operation, + ): Operation; detached(live: () => Operation): Operation; exited(live: () => Operation): Operation; } @@ -98,6 +122,8 @@ export interface LiveLaunch { settled?: SessionLaunchResult; /** The retained preparation, so a refusal is reportable to the caller. */ preparation?: PreparedLaunchRecord; + /** The retained materialization, for a launch that owed a turn. */ + materialization?: MaterializedLaunchRecord; /** The retained detach, so a handoff that stopped there says why. */ detachment?: DetachedLaunchRecord; /** The retained exit, so how the native UI ended is the caller's answer. */ @@ -144,14 +170,6 @@ function crossCheck(request: AgentLaunchRequest, record: PreparedLaunchRecord): return "session"; } } - // A provider that returns its own identity owns its own session lifetime and - // binds no build, so a binding beside one describes a check nothing performed. - // The parser refuses the same pairing on the way back in; this is the live - // half, before anything durable exists. The other direction stays open: the - // client-allocated path was released unbound, and legacy history is readable. - if (record.identityProvenance === "provider-returned" && record.executableBinding !== undefined) { - return "identity provenance"; - } return undefined; } @@ -206,19 +224,64 @@ export function createLaunchAuthority( `the provider prepared a session whose ${mismatch} is not what this launch asked for`, ); } - if (prepared.nativeSessionId.length === 0) { + const plan = prepared.materialization; + // A launch that owes a turn has nothing to name yet, and one that owes + // none has everything to name. Either preparation asserting the other's + // identity would mean the phase order stopped describing this launch. + if (plan === undefined && prepared.nativeSessionId.length === 0) { throw new AgentLaunchProtocolError( "the provider prepared a session but asserted no provider-native identity", ); } + if (plan !== undefined && prepared.nativeSessionId.length > 0) { + throw new AgentLaunchProtocolError( + "the provider prepared a provider-native identity for a session no backend has " + + "accepted a turn in yet", + ); + } + + // What the handoff is given: the preparation, carrying whichever identity + // this launch is entitled to assert by the time it reaches one. + let handed = prepared; + if (plan) { + const materialize = phases.materialize; + if (!materialize) { + throw new AgentLaunchProtocolError( + "this launch planned a materialization turn and its provider offers no way to spend one", + ); + } + const materialized = yield* launch.retention.materialized(prepared, plan, () => + materialize(prepared, plan), + ); + launch.materialization = materialized; + if ( + materialized.promptVersion !== plan.promptVersion || + materialized.requestId !== plan.requestId + ) { + throw new AgentLaunchProtocolError( + "the provider retained a materialization turn other than the one this launch planned", + ); + } + if (materialized.failure) { + return; + } + const asserted = materialized.nativeSessionId; + if (asserted === undefined || asserted.length === 0) { + throw new AgentLaunchProtocolError( + "the materialization turn completed without asserting the provider-native identity " + + "it made openable", + ); + } + handed = { ...prepared, nativeSessionId: asserted }; + } - const detached = yield* launch.retention.detached(() => phases.detach(prepared)); + const detached = yield* launch.retention.detached(() => phases.detach(handed)); launch.detachment = detached; if (detached.failure) { return; } - const exited = yield* launch.retention.exited(() => phases.exit(prepared)); + const exited = yield* launch.retention.exited(() => phases.exit(handed)); launch.exit = exited; if (exited.failure) { return; @@ -231,10 +294,10 @@ export function createLaunchAuthority( } launch.settled = { - agent: prepared.agent, - session: { sessionKey: prepared.sessionKey, cwd: prepared.cwd }, - nativeSessionId: prepared.nativeSessionId, - launcher: prepared.launcher, + agent: handed.agent, + session: { sessionKey: handed.sessionKey, cwd: handed.cwd }, + nativeSessionId: handed.nativeSessionId, + launcher: handed.launcher, }; }, diff --git a/packages/core/src/agent/launch-journal.ts b/packages/core/src/agent/launch-journal.ts index d268b2b6..a8789588 100644 --- a/packages/core/src/agent/launch-journal.ts +++ b/packages/core/src/agent/launch-journal.ts @@ -10,9 +10,16 @@ * provider session it already prepared, and a record written only when the * whole launch settles would describe nothing at all. * - * A launch is not a prompt, so nothing here reuses `agent_prompt`. Their + * A launch phase is not a prompt, so no phase here reuses `agent_prompt`. Their * inputs, phases and process semantics differ, and sharing one type would make * a replayed prompt and a replayed launch indistinguishable in a journal. + * + * The one exception is the materialization turn, and it is not an exception to + * that reasoning: it is a model turn, sent to an agent session, and it is + * retained as an ordinary `agent_prompt` because that is what it is. What must + * never be re-run is the sending, and `agent_prompt` is the durable operation + * that already guarantees that — which is the whole reason the turn is retained + * as a prompt first and as the `materialized` phase second. */ import { createDurableOperation } from "@executablemd/durable-streams"; @@ -26,8 +33,15 @@ import type { InstructionReconciliation, LaunchFailure, LaunchFailureClass, + MaterializationPlan, + MaterializationUsage, + MaterializedLaunchRecord, PreparedLaunchRecord, } from "./launch.ts"; +import { AgentInternal } from "./internal.ts"; +import { readCheckpoint } from "./checkpoint.ts"; +import { persistPrompt } from "./journal.ts"; +import type { PromptRecord } from "./journal.ts"; import { sourceDescription } from "../source-position.ts"; import type { SourcePosition } from "../types.ts"; import type { PermissionMode } from "./agent-api.ts"; @@ -70,6 +84,7 @@ const FAILURE_CLASSES: readonly LaunchFailureClass[] = [ "session-busy", "session-recovery-required", "executable-binding-refused", + "materialization-failed", ]; function isRecord(value: unknown): value is Record { @@ -188,6 +203,36 @@ function serializeBinding(binding: ExecutableBuildBindingV1): Json { }; } +const PLAN_MEMBERS = ["promptVersion", "requestId", "prompt"]; + +/** + * Read a retained materialization plan strictly. + * + * Exact members, like a build binding and for the same reason: the plan is what + * a resumed launch checks the retained turn against, and a member this build + * ignores is one the writer thought identified the turn. + */ +function materializationPlan(value: unknown): MaterializationPlan | undefined { + if (!isRecord(value) || !exactMembers(value, PLAN_MEMBERS)) { + return undefined; + } + const { promptVersion, requestId, prompt } = value; + if (typeof promptVersion !== "string" || promptVersion.length === 0) { + return undefined; + } + if (typeof requestId !== "string" || requestId.length === 0) { + return undefined; + } + if (typeof prompt !== "string" || prompt.length === 0) { + return undefined; + } + return { promptVersion, requestId, prompt }; +} + +function serializePlan(plan: MaterializationPlan): Json { + return { promptVersion: plan.promptVersion, requestId: plan.requestId, prompt: plan.prompt }; +} + function permissionMode(value: unknown): PermissionMode | undefined { if (value === "approve-all" || value === "approve-reads" || value === "deny-all") { return value; @@ -216,6 +261,9 @@ function serializePrepared(record: PreparedLaunchRecord): Json { if (record.executableBinding !== undefined) { payload.executableBinding = serializeBinding(record.executableBinding); } + if (record.materialization !== undefined) { + payload.materialization = serializePlan(record.materialization); + } if (record.requestedModel !== undefined) { payload.requestedModel = record.requestedModel; } @@ -280,22 +328,31 @@ export function parsePrepared(value: unknown): PreparedLaunchRecord | undefined if (!directories || !mode || !reconciled || !provenanceValue) { return undefined; } - // A binding says which build accepted a client-allocated identity, so a - // record that chose no identity cannot have one. Absence is not refused: the - // client-allocated path was released before any build was observed, and that - // history stays readable as the legacy, native-only session it is. Whether a - // legacy record may still do live work is the provider's decision, not this - // parser's — core observes no executables. + // A binding says which build a provider-native identity belongs to, and both + // provenances have one to say it about: a build accepted the identity XMD + // chose, or it issued the identity XMD was handed. So a binding is valid + // beside either, and which agents require one is the provider's decision + // rather than this parser's — core observes no executables and knows no + // adapters. Absence is not refused: both paths were released before any build + // was observed, and that history stays readable as the legacy, native-only + // sessions it describes. let binding: ExecutableBuildBindingV1 | undefined; if (value.executableBinding !== undefined) { - if (provenanceValue !== "client-allocated") { - return undefined; - } binding = executableBinding(value.executableBinding); if (!binding) { return undefined; } } + // Absence is what says no turn is owed, so a plan that does not read back is + // refused rather than dropped: reading it as absence would let a launch whose + // record is damaged proceed as one that never needed a turn. + let plan: MaterializationPlan | undefined; + if (value.materialization !== undefined) { + plan = materializationPlan(value.materialization); + if (!plan) { + return undefined; + } + } const record: PreparedLaunchRecord = { phase: "prepared", agent, @@ -316,6 +373,9 @@ export function parsePrepared(value: unknown): PreparedLaunchRecord | undefined if (binding !== undefined) { record.executableBinding = binding; } + if (plan !== undefined) { + record.materialization = plan; + } if (typeof requestedModel === "string") { record.requestedModel = requestedModel; } @@ -332,6 +392,162 @@ export function parsePrepared(value: unknown): PreparedLaunchRecord | undefined return record; } +/** Every member of a usage report that is a figure rather than a currency. */ +type UsageCount = Exclude; + +const USAGE_COUNTS: readonly UsageCount[] = [ + "inputTokens", + "outputTokens", + "cachedReadTokens", + "cachedWriteTokens", + "thoughtTokens", + "totalTokens", + "costAmount", +]; + +/** A figure that counts or measures, and so is finite and never negative. */ +function nonNegative(value: unknown): number | undefined { + return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : undefined; +} + +/** + * Read what the provider reported the turn cost. + * + * A member this build does not know refuses the record rather than being + * dropped, because a dropped member is displayed as `provider did not report` — + * which would state, about a figure the provider did report, the one thing this + * record must never say. + */ +function parseUsage(value: unknown): MaterializationUsage | undefined { + if (!isRecord(value)) { + return undefined; + } + const usage: { -readonly [K in keyof MaterializationUsage]: MaterializationUsage[K] } = {}; + for (const [member, entry] of Object.entries(value)) { + if (member === "costCurrency") { + if (typeof entry !== "string" || entry.length === 0) { + return undefined; + } + usage.costCurrency = entry; + continue; + } + const known = USAGE_COUNTS.find((candidate) => candidate === member); + const count = nonNegative(entry); + if (known === undefined || count === undefined) { + return undefined; + } + usage[known] = count; + } + return usage; +} + +function serializeUsage(usage: MaterializationUsage): Json { + const payload: Record = {}; + for (const member of USAGE_COUNTS) { + const entry = usage[member]; + if (entry !== undefined) { + payload[member] = entry; + } + } + if (usage.costCurrency !== undefined) { + payload.costCurrency = usage.costCurrency; + } + return payload; +} + +function serializeMaterialized(record: MaterializedLaunchRecord): Json { + const payload: Record = { + phase: record.phase, + promptVersion: record.promptVersion, + requestId: record.requestId, + response: record.response, + usage: serializeUsage(record.usage), + }; + if (record.turn !== undefined) { + payload.turn = { + provider: record.turn.provider, + kind: record.turn.kind, + value: record.turn.value, + }; + } + if (record.nativeSessionId !== undefined) { + payload.nativeSessionId = record.nativeSessionId; + } + if (record.durationMs !== undefined) { + payload.durationMs = record.durationMs; + } + if (record.stopReason !== undefined) { + payload.stopReason = record.stopReason; + } + if (record.failure !== undefined) { + payload.failure = serializeFailure(record.failure); + } + return payload; +} + +export function parseMaterialized(value: unknown): MaterializedLaunchRecord | undefined { + if (!isRecord(value) || value.phase !== "materialized") { + return undefined; + } + const { promptVersion, requestId, response, nativeSessionId, durationMs, stopReason, failure } = + value; + // The plan these name is what a replay looks the turn up by, so a record that + // identifies it as nothing identifies no turn at all. + if (typeof promptVersion !== "string" || promptVersion.length === 0) { + return undefined; + } + if (typeof requestId !== "string" || requestId.length === 0) { + return undefined; + } + if (typeof response !== "string") { + return undefined; + } + const usage = parseUsage(value.usage); + if (!usage) { + return undefined; + } + const record: MaterializedLaunchRecord = { + phase: "materialized", + promptVersion, + requestId, + usage, + response, + }; + if (nativeSessionId !== undefined) { + // An empty one is the absence of an identity written down, and a launch + // reading it back would hand a native UI a name for nothing. + if (typeof nativeSessionId !== "string" || nativeSessionId.length === 0) { + return undefined; + } + record.nativeSessionId = nativeSessionId; + } + if (value.turn !== undefined) { + const turn = readCheckpoint(value.turn); + if (!turn) { + return undefined; + } + record.turn = turn; + } + if (durationMs !== undefined) { + const elapsed = nonNegative(durationMs); + if (elapsed === undefined) { + return undefined; + } + record.durationMs = elapsed; + } + if (typeof stopReason === "string") { + record.stopReason = stopReason; + } + if (failure !== undefined) { + const parsed = parseFailure(failure); + if (!parsed) { + return undefined; + } + record.failure = parsed; + } + return record; +} + function parseDetached(value: unknown): DetachedLaunchRecord | undefined { if (!isRecord(value) || value.phase !== "detached") { return undefined; @@ -417,6 +633,166 @@ export function persistPreparation( return persistPhase(identity, "prepared", description, live, serializePrepared, parsePrepared); } +/** The materialization turn as the durable prompt it is. */ +function promptOfMaterialization( + prepared: PreparedLaunchRecord, + sequence: number, + record: MaterializedLaunchRecord, +): PromptRecord { + const prompt: PromptRecord = { + sequence, + agent: prepared.agent, + sessionKey: prepared.sessionKey, + // The identity the turn made real, because that is the conversation it was + // sent to. A launch that owes a turn prepares none, so a turn that failed + // reports the empty one it was still standing on. + agentSessionId: record.nativeSessionId ?? prepared.nativeSessionId, + status: record.failure ? "failed" : "completed", + text: record.response, + }; + if (record.stopReason !== undefined) { + prompt.stopReason = record.stopReason; + } + if (record.failure !== undefined) { + prompt.error = { message: record.failure.message }; + } + if (record.turn !== undefined && prompt.status === "completed") { + prompt.checkpoint = record.turn; + } + return prompt; +} + +/** + * The materialized phase rebuilt from the durable prompt alone. + * + * Reached when a run stopped between appending the prompt and appending the + * phase. The turn was spent, and the only thing that could say otherwise is a + * second one — so this reconstructs rather than re-runs, from the prompt's own + * outcome, the checkpoint the provider named it with, and the session it was + * sent to. What the reconstruction cannot recover is what the turn cost: those + * figures were observed once and lost, and an unreported figure is reported as + * unreported. + */ +function materializedFromPrompt( + plan: MaterializationPlan, + prompt: PromptRecord, +): MaterializedLaunchRecord { + const record: MaterializedLaunchRecord = { + phase: "materialized", + promptVersion: plan.promptVersion, + requestId: plan.requestId, + usage: {}, + response: prompt.text, + }; + if (prompt.stopReason !== undefined) { + record.stopReason = prompt.stopReason; + } + if ( + prompt.status === "completed" && + prompt.checkpoint !== undefined && + prompt.agentSessionId !== undefined && + prompt.agentSessionId.length > 0 + ) { + record.turn = prompt.checkpoint; + // The conversation the turn was sent to, which for a launch that owed one + // is the only place the identity was ever written down before this phase. + record.nativeSessionId = prompt.agentSessionId; + return record; + } + record.failure = { + class: "materialization-failed", + message: + prompt.error?.message ?? + `the materialization turn ${prompt.status} without naming both the turn it was and the ` + + `session it made openable`, + }; + return record; +} + +/** + * What a launch retains when it cannot tell whether the turn was already spent. + * + * The preparation is retained immediately before the turn is sent, so a run that + * replays `prepared` and then finds no outcome for the turn is looking at a run + * that reached the sending point and never recorded what happened there. Nothing + * reachable from here separates a turn that was never sent from one the backend + * accepted and the interrupted run never saw — and sending now, if it is the + * second, spends a turn in someone's conversation to learn that. + * + * So the launch stops. This is retained rather than raised bare, so every later + * replay says the same thing without reconsidering it. + */ +function unrecoverable(plan: MaterializationPlan): MaterializedLaunchRecord { + return { + phase: "materialized", + promptVersion: plan.promptVersion, + requestId: plan.requestId, + usage: {}, + response: "", + failure: { + class: "session-recovery-required", + message: + `this launch prepared a session and then stopped without recording what the turn ` + + `that would make it openable did, so whether that turn was spent is not knowable ` + + `here — resolve the session by hand rather than letting a resume send a second one`, + }, + }; +} + +/** + * Retain the one turn a launch may owe, as a prompt and then as a phase. + * + * Two durable operations, in this order, because they answer different + * questions: the prompt says the turn was spent, and the phase says the launch + * may go on. A run that stopped between them replays the first and rebuilds the + * second, which is the whole reason the prompt is appended first. + * + * `preparedThisRun` says whether this run is the one that prepared the session, + * rather than a resume reading a preparation an earlier run retained. It decides + * the one thing a resume must not decide for itself: reaching the live path of a + * turn whose preparation replayed means an earlier run already stood where this + * one is standing, so this run refuses instead of sending. + * + * The prompt is issued either way, including when it is refused. Skipping it + * would leave two runs disagreeing about which durable operation comes after + * `prepared`, and a journal read against the wrong one diverges. + * + * The sequence is allocated outside the live work, so a replay that spends no + * turn still numbers this run's prompts the way the first attempt did. + */ +export function* persistMaterialization( + identity: LaunchIdentity, + prepared: PreparedLaunchRecord, + plan: MaterializationPlan, + live: () => Operation, + preparedThisRun: boolean, +): Operation { + const sequence = yield* AgentInternal.operations.nextPromptSequence(); + let spent: MaterializedLaunchRecord | undefined; + const promptIdentity: { name: string; input: string; position?: Readonly } = { + name: `${identity.name}/materialization`, + input: plan.prompt, + }; + if (identity.position) { + promptIdentity.position = identity.position; + } + const prompt = yield* persistPrompt(promptIdentity, function* () { + spent = preparedThisRun ? yield* live() : unrecoverable(plan); + return promptOfMaterialization(prepared, sequence, spent); + }); + return yield* persistPhase( + identity, + "materialized", + { input: plan.prompt, promptVersion: plan.promptVersion, requestId: plan.requestId }, + // deno-lint-ignore require-yield + function* () { + return spent ?? materializedFromPrompt(plan, prompt); + }, + serializeMaterialized, + parseMaterialized, + ); +} + export function persistDetach( identity: LaunchIdentity, live: () => Operation, diff --git a/packages/core/src/agent/launch-owner.ts b/packages/core/src/agent/launch-owner.ts index 7c7e8528..4a9620f8 100644 --- a/packages/core/src/agent/launch-owner.ts +++ b/packages/core/src/agent/launch-owner.ts @@ -37,7 +37,12 @@ import type { import { AgentLaunchProtocolError, issueLaunch } from "./launch-request.ts"; import type { AgentLaunchRequest } from "./launch-request.ts"; import type { LiveLaunch } from "./launch-authority.ts"; -import { persistDetach, persistExit, persistPreparation } from "./launch-journal.ts"; +import { + persistDetach, + persistExit, + persistMaterialization, + persistPreparation, +} from "./launch-journal.ts"; import type { LaunchIdentity } from "./launch-journal.ts"; import { getExpansion } from "../expansion.ts"; @@ -120,6 +125,7 @@ function parseFailureClass(value: string): AgentLaunchError["failureClass"] { case "session-busy": case "session-recovery-required": case "executable-binding-refused": + case "materialization-failed": return value; default: return "unsupported-capability"; @@ -193,6 +199,10 @@ export function launchSession( generation, ); + // Whether this run is the one that prepared the session, rather than a + // resume reading a preparation an earlier run retained. Only the launch that + // did the preparing may send the turn that follows it. + let preparedThisRun = false; const launch: LiveLaunch = { issued, retention: { @@ -207,8 +217,13 @@ export function launchSession( additionalDirectories: site.additionalDirectories, permissionMode: site.permissionMode, }, - live, + function* () { + preparedThisRun = true; + return yield* live(); + }, ), + materialized: (prepared, plan, live) => + persistMaterialization(site.identity, prepared, plan, live, preparedThisRun), detached: (live) => persistDetach(site.identity, live), exited: (live) => persistExit(site.identity, live), }, @@ -256,6 +271,9 @@ export function launchSession( if (launch.preparation?.failure) { raiseRetained("prepared", launch.preparation.failure); } + if (launch.materialization?.failure) { + raiseRetained("materialized", launch.materialization.failure); + } if (launch.detachment?.failure) { raiseRetained("detached", launch.detachment.failure); } diff --git a/packages/core/src/agent/launch.ts b/packages/core/src/agent/launch.ts index 0ae7d79e..22e8b2b4 100644 --- a/packages/core/src/agent/launch.ts +++ b/packages/core/src/agent/launch.ts @@ -2,12 +2,17 @@ * The native session launch seam (specs/native-agent-session-launch-spec.md). * * A launch is one deterministic preparation followed by an ownership handoff, - * and it moves through four phases: + * and it moves through these phases: * * ```text - * prepared -> detached -> launched -> exited + * prepared -> materialization prompt -> materialized -> detached -> launched -> exited * ``` * + * `materialization prompt` and `materialized` are present only for a provider + * whose freshly created conversation is not yet one its native UI can open. The + * providers that need no such turn go straight from `prepared` to `detached`, + * and a launch on them still costs zero model turns. + * * Each phase a provider completes is retained by the invocation that issued * the launch, through the authority core delivers to the selected provider. * The provider hands each phase's work over rather than performing it and @@ -27,8 +32,9 @@ */ import type { PermissionMode } from "./agent-api.ts"; +import type { AgentPromptCheckpoint } from "./checkpoint.ts"; -export type LaunchPhase = "prepared" | "detached" | "launched" | "exited"; +export type LaunchPhase = "prepared" | "materialized" | "detached" | "launched" | "exited"; /** * What a launch did about the instruction layer, so the choice is observable @@ -62,7 +68,8 @@ export type LaunchFailureClass = | "native-exit" | "session-busy" | "session-recovery-required" - | "executable-binding-refused"; + | "executable-binding-refused" + | "materialization-failed"; /** * `session-busy` is contention, not breakage: another XMD owner holds the @@ -77,6 +84,12 @@ export type LaunchFailureClass = * executable-file validation, version parsing, digesting, schema recognition, * equality, and a session established before any build was recorded all end * here. + * + * `materialization-failed` is the one turn a launch may owe: the conversation + * ACP created is not yet one the native UI can open, the exchange that would + * make it openable did not complete, and the launch stops with ACP ownership + * still where it was rather than handing over a session the UI would refuse by + * name. */ export interface LaunchFailure { class: LaunchFailureClass; @@ -137,6 +150,91 @@ export function sameExecutableBuild( ); } +/** + * The one model turn a launch may owe, named before it is spent. + * + * Some providers persist a conversation only once something has been said in + * it, so the session ACP just created is not yet one the native UI can open. + * Exactly one XMD-owned turn closes that gap, and it is planned in the + * preparation rather than decided later: the version says which exact prompt + * will be sent, and the request id is fixed here so a replay that finds the + * turn already retained is looking for the same turn rather than a new one. + * + * Present only for a provider that needs it, and only for a conversation this + * launch created. Nothing else acquires a turn by being launched. + */ +export interface MaterializationPlan { + /** Which exact prompt this is — `codex-materialization.v1`. */ + readonly promptVersion: string; + /** The request id the turn runs under, immutable once `prepared` is kept. */ + readonly requestId: string; + /** + * The exact text that will be sent, retained before it is sent. + * + * A version names a prompt; this is the prompt. Keeping the bytes with the + * plan is what lets a reader of the journal see what an XMD-owned turn said + * in someone's conversation without holding the build that composed it. + */ + readonly prompt: string; +} + +/** + * What the provider reported about what the materialization turn cost. + * + * Every field is optional and a missing one means the provider reported + * nothing, which is displayed and retained as exactly that. Nothing here reads + * absence as zero: a turn whose token count was never reported is not a free + * turn, and saying so would be inventing an observation. + */ +export interface MaterializationUsage { + readonly inputTokens?: number; + readonly outputTokens?: number; + readonly cachedReadTokens?: number; + readonly cachedWriteTokens?: number; + readonly thoughtTokens?: number; + readonly totalTokens?: number; + readonly costAmount?: number; + readonly costCurrency?: string; +} + +/** + * The turn that made a fresh conversation openable, and what it cost. + * + * Retained as its own phase because it sits between two facts that must not be + * confused: the session exists (`prepared`) and ACP has let go of it + * (`detached`). A launch interrupted after the turn must never spend a second + * one, and the only thing that can say the first was spent is a record of it. + * + * `turn` is the provider's own name for the completed turn, carried across + * unchanged. It is the evidence the exchange reached the backend rather than + * merely being written to a socket, and it is the same checkpoint the durable + * prompt retained — which is what lets this record be rebuilt from that prompt + * when a run stopped between the two. + */ +export interface MaterializedLaunchRecord { + phase: "materialized"; + promptVersion: string; + requestId: string; + /** + * The provider-native identity this turn made real. Absent on a failure. + * + * A conversation a backend has not accepted a turn in is not one a native UI + * can open, so the identity of one is asserted here rather than in the + * preparation: the launch that plans a turn prepares no identity at all, and + * this is where the one it produced becomes the thing that gets handed over. + */ + nativeSessionId?: string; + /** The provider's identity for the completed turn. Absent on a failure. */ + turn?: AgentPromptCheckpoint; + /** How long the turn took, in milliseconds. Absent when no turn was run. */ + durationMs?: number; + usage: MaterializationUsage; + /** The assistant's full response text, retained and displayed unabridged. */ + response: string; + stopReason?: string; + failure?: LaunchFailure; +} + /** * What one provider retained about the session it prepared. * @@ -144,6 +242,12 @@ export function sameExecutableBuild( * record id, and a provider-native session id are three different identities, * and only the third one crosses the handoff. * + * It is empty exactly when `materialization` names a turn this launch still + * owes. Until that turn is accepted there is no conversation for an identity to + * name — the provider holds occupancy, not a session — so the preparation says + * so rather than asserting a name nothing would resume, and the accepted turn + * asserts the identity instead. + * * `instructions` is the prepared text itself, and it is retained beside its * digest — the execution's secret gate runs before this record persists, so * prepared text carrying a credential-shaped value never reaches the journal @@ -165,15 +269,25 @@ export interface PreparedLaunchRecord { */ identityProvenance: IdentityProvenance; /** - * Which build accepted the client-allocated identity, present exactly when - * this provider binds one. A provider that returns its own identity owns its - * own session lifetime and binds nothing, so it carries none. + * Which build the provider-native identity belongs to, present exactly when + * the adapter behind it binds one. Independent of who chose the identity: a + * build accepted the name XMD allocated, or issued the name XMD was handed, + * and neither name resolves to one conversation without it. * - * Optional because the client-allocated path was released before any build - * was observed. A record without it is legacy history: readable, resumable by - * the native-only contract that wrote it, and never an attachable session. + * Optional because both paths were released before any build was observed. A + * record without it is legacy history: readable, resumable by the native-only + * contract that wrote it, and never an attachable session. */ executableBinding?: ExecutableBuildBindingV1; + /** + * The one turn this launch owes before the native UI can open, when it owes + * one. Absent means no turn is owed and none may be taken. + * + * Retained with the preparation so the plan is fixed before anything is + * spent: a replay reads which prompt and which request id the first attempt + * committed to, rather than choosing them again. + */ + materialization?: MaterializationPlan; instructionsDigest: string; instructions: string; cwd: string; @@ -199,7 +313,11 @@ export interface ExitedLaunchRecord { failure?: LaunchFailure; } -export type LaunchRecord = PreparedLaunchRecord | DetachedLaunchRecord | ExitedLaunchRecord; +export type LaunchRecord = + | PreparedLaunchRecord + | MaterializedLaunchRecord + | DetachedLaunchRecord + | ExitedLaunchRecord; /** * A launch that stopped at a phase, carrying the phase it reached and the diff --git a/packages/core/src/expand.ts b/packages/core/src/expand.ts index d52313a6..9faa9034 100644 --- a/packages/core/src/expand.ts +++ b/packages/core/src/expand.ts @@ -2252,8 +2252,11 @@ function paneWork(pane: TerminalPane, title: string, site: GridSite): PaneWork { // by being here: it reserves and flushes this pane instead of competing // for the run's one foreground lease, and the child it starts is what // makes this pane ready. - yield* usePaneNativeLauncher(claim, flushPane, (request, spawned) => - composite.launch(pane.ordinal, request, spawned), + yield* usePaneNativeLauncher( + claim, + flushPane, + (request, spawned) => composite.launch(pane.ordinal, request, spawned), + (text) => composite.display(pane.ordinal, `${text}\n`), ); const siteEnv = yield* env; // Starts from what the grid site can see and keeps its own writes: a diff --git a/packages/core/src/terminal/pane-launcher.ts b/packages/core/src/terminal/pane-launcher.ts index bce408d0..a8ce3236 100644 --- a/packages/core/src/terminal/pane-launcher.ts +++ b/packages/core/src/terminal/pane-launcher.ts @@ -50,6 +50,7 @@ export function* usePaneNativeLauncher( claim: TerminalPaneClaim, flush: () => Operation, runInPane: RunInPane, + notify: (text: string) => Operation, ): Operation { yield* NativeLauncher.around({ /** @@ -74,6 +75,11 @@ export function* usePaneNativeLauncher( *flush() { yield* flush(); }, + // Into this pane's own text, for the same reason `flush` is: what a launch + // says is addressed to whoever is watching this pane. + *notify([text]) { + yield* notify(text); + }, *launch([request, spawned]) { // The end of the chain, and deliberately so. Middleware written nearer // the authored launch composes in front of this and may observe, wrap, diff --git a/packages/core/tests/agent-session-launch.test.ts b/packages/core/tests/agent-session-launch.test.ts index 9905a2b4..b28ec0d2 100644 --- a/packages/core/tests/agent-session-launch.test.ts +++ b/packages/core/tests/agent-session-launch.test.ts @@ -26,10 +26,12 @@ import type { ExecutableBuildBindingV1, ExitedLaunchRecord, IdentityProvenance, + MaterializationPlan, + MaterializedLaunchRecord, PreparedLaunchRecord, } from "../src/agent/launch.ts"; import { sameExecutableBuild } from "../src/agent/launch.ts"; -import { parsePrepared } from "../src/agent/launch-journal.ts"; +import { parseMaterialized, parsePrepared } from "../src/agent/launch-journal.ts"; import type { AgentLaunchRequest } from "../src/agent/launch-request.ts"; import { installAgentComponents } from "../src/agent/components.ts"; import type { AgentProviderFactory } from "../src/agent/provider-api.ts"; @@ -38,6 +40,7 @@ import { installControlledLauncher, NATIVE_LAUNCHER_UNAVAILABLE, nativeLaunch, + notifyTerminal, prepareControlledComposite, reserveTerminal, TerminalGrids, @@ -75,6 +78,18 @@ interface LaunchStub { identityProvenance?: IdentityProvenance; /** The build the prepared record says accepted that identity. */ executableBinding?: ExecutableBuildBindingV1; + /** The turn a freshly prepared session owes before a native UI can open it. */ + materialization?: MaterializationPlan; + /** The request id of every turn this provider *actually* spent, in order. */ + turns: string[]; + /** Refuse the turn rather than completing it. */ + turnRefused?: boolean; + /** Plan a turn and then offer the authority no way to spend one. */ + withholdMaterialize?: boolean; + /** Complete the turn without asserting the session it made openable. */ + withholdMaterializedIdentity?: boolean; + /** Assert an identity in a preparation that also plans a turn. */ + assertIdentityBeforeTurn?: boolean; } function digest(text: string): string { @@ -89,6 +104,7 @@ function createLaunchStub(overrides: Partial = {}): LaunchStub { exits: 0, factoryActivations: 0, nativeSessionId: "native-abc", + turns: [], ...overrides, // The authority is the second argument because it is delivered, never // published: this stub is only able to author a phase because core installed @@ -130,7 +146,13 @@ function createLaunchStub(overrides: Partial = {}): LaunchStub { agent, sessionKey, provider: "stub", - nativeSessionId: stub.nativeSessionId, + // A launch that owes a turn has no conversation to name yet: + // the turn asserts the identity, and the preparation says so + // by asserting none. + nativeSessionId: + stub.materialization === undefined || stub.assertIdentityBeforeTurn + ? stub.nativeSessionId + : "", sessionState: "created", instructionChannel: "stub.systemPrompt", instructionReconciliation: "installed", @@ -145,8 +167,59 @@ function createLaunchStub(overrides: Partial = {}): LaunchStub { if (stub.executableBinding !== undefined) { prepared.executableBinding = stub.executableBinding; } + if (stub.materialization !== undefined) { + prepared.materialization = stub.materialization; + } return prepared; }, + // Offered only when this stub can spend a turn, exactly as a + // provider whose sessions are openable on creation offers none. + ...(stub.materialization === undefined || stub.withholdMaterialize + ? {} + : { + *materialize(accepted, plan): Operation { + stub.turns.push(plan.requestId); + // A real provider says this before it spends the turn, and + // says it to whoever holds the terminal this launch + // reserved. Modelled here so the destination is provable. + yield* notifyTerminal( + `stub: spending one model turn in "${accepted.sessionKey}"`, + ); + const base: Pick< + MaterializedLaunchRecord, + "phase" | "promptVersion" | "requestId" | "durationMs" + > = { + phase: "materialized", + promptVersion: plan.promptVersion, + requestId: plan.requestId, + durationMs: 7, + }; + if (stub.turnRefused) { + return { + ...base, + usage: {}, + response: "", + failure: { + class: "materialization-failed", + message: "the stub provider refused the turn", + }, + }; + } + return { + ...base, + // What the turn made openable. Withholding it is a + // provider claiming a completed turn produced no + // conversation, which is not a launch to hand over. + ...(stub.withholdMaterializedIdentity + ? {} + : { nativeSessionId: stub.nativeSessionId }), + turn: { provider: "stub", kind: "stub-turn-id", value: "turn-0001" }, + usage: { inputTokens: 11, totalTokens: 13 }, + response: "Acknowledged.", + stopReason: "end_turn", + }; + }, + }), // deno-lint-ignore require-yield *detach() { stub.detaches++; @@ -190,6 +263,8 @@ interface LauncherLog { reserved: number; flushed: number; requests: NativeLaunchRequest[]; + /** What a launch told this terminal's reader, in order. */ + notices: string[]; /** Every launcher event in order, so `flush` before `launch` is provable. */ order: string[]; } @@ -247,11 +322,13 @@ interface Run { events: DurableEvent[]; /** Everything the controlled composite did, in order. */ composite: string[]; + /** What each pane showed its own reader, by ordinal. */ + shown: Map; } function* runDoc(doc: string, options: RunOptions = {}): Operation { const stub = options.stub ?? createLaunchStub(); - const launcher: LauncherLog = { reserved: 0, flushed: 0, requests: [], order: [] }; + const launcher: LauncherLog = { reserved: 0, flushed: 0, requests: [], notices: [], order: [] }; const stream = options.stream ?? new InMemoryStream(); const owned = options.dir === undefined; const dir = options.dir ?? path.join(os.tmpdir(), `xmd-sl-${randomUUID()}`); @@ -287,6 +364,10 @@ function* runDoc(doc: string, options: RunOptions = {}): Operation { launcher.flushed++; launcher.order.push("flush"); }, + onNotify: (text) => { + launcher.notices.push(text); + launcher.order.push("notify"); + }, record: (request) => { launcher.requests.push(request); launcher.order.push("launch"); @@ -399,6 +480,7 @@ function* runDoc(doc: string, options: RunOptions = {}): Operation { launcher, events: yield* stream.readAll(), composite: providerLog.events, + shown: providerLog.shown, }; }); } @@ -412,7 +494,7 @@ function* runInterrupted( ): Operation { const arrived = withResolvers(); const hold = withResolvers(); - const launcher: LauncherLog = { reserved: 0, flushed: 0, requests: [], order: [] }; + const launcher: LauncherLog = { reserved: 0, flushed: 0, requests: [], notices: [], order: [] }; yield* ensureDir(dir); yield* scoped(function* () { const docPath = path.join(dir, "doc.md"); @@ -495,7 +577,7 @@ const LAUNCH = "\nYou are the implementor.\n\n" describe("Tier SL — native session launch", () => { it("SL1: without a provider the launch fails, and nothing is reserved or spawned", function* () { - const launcher: LauncherLog = { reserved: 0, flushed: 0, requests: [], order: [] }; + const launcher: LauncherLog = { reserved: 0, flushed: 0, requests: [], notices: [], order: [] }; const dir = path.join(os.tmpdir(), `xmd-sl-${randomUUID()}`); yield* ensureDir(dir); const result = yield* scoped(function* () { @@ -1033,6 +1115,7 @@ describe("Tier SP — a launch inside a terminal pane", () => { yield* childMayExit.operation; return { exitCode: 0 }; }, + function* () {}, ); const first = yield* spawn(function* () { @@ -1068,6 +1151,28 @@ describe("Tier SP — a launch inside a terminal pane", () => { // The child that started is what made the pane ready, and it did. expect(claims.readiness[0]?.acknowledged).toBe(true); }); + + it("SP6: a launch that owes a turn tells its own pane's reader, not the run's", function* () { + const run = yield* runDoc(PANES, { + grid: true, + stub: createLaunchStub({ materialization: OWED }), + }); + + expect(run.result.ok ? "" : run.result.error.message).toBe(""); + // Both panes spent their one turn, and each said so where the person who + // can see that pane is looking. + expect(run.stub.turns).toEqual([OWED.requestId, OWED.requestId]); + expect(run.shown.get(0)).toContain(`spending one model turn in "stub:left"`); + expect(run.shown.get(1)).toContain(`spending one model turn in "stub:right"`); + // Neither pane's notice reached the other's reader, which is the half a + // launcher that merely printed somewhere would still pass. + expect(run.shown.get(0)).not.toContain("stub:right"); + expect(run.shown.get(1)).not.toContain("stub:left"); + // And none of it reached the host: the root launcher is the one the grid + // holds, and a pane launch never delegates to it. + expect(run.launcher.notices).toEqual([]); + expect(run.output).not.toContain("spending one model turn"); + }); }); /** @@ -1376,16 +1481,28 @@ describe("Tier PV — identity provenance", () => { } }); - it("PV4: a provider-returned record carries no build binding", function* () { - // A provider that names its own session owns its own session lifetime and - // binds no build, so a binding beside one describes a check nothing - // performed. - expect( - parsePrepared(record({ identityProvenance: "provider-returned", executableBinding: BOUND })), - ).toBe(undefined); - // Absent provenance reads as provider-returned, so the same pairing refuses - // through the compatibility inference too. - expect(parsePrepared(record({ executableBinding: BOUND }))).toBe(undefined); + it("PV4: a build binding is valid beside either provenance", function* () { + // Who chose the identity and which build it belongs to are separate facts: + // a build accepted the name XMD allocated, or issued the name XMD was + // handed, and neither name resolves to one conversation without it. Which + // agents require one is the provider's decision — core observes no + // executables and knows no adapters — so refusing a pairing here would be + // this parser deciding it. + for (const provenance of ["provider-returned", "client-allocated"]) { + const parsed = parsePrepared( + record({ identityProvenance: provenance, executableBinding: BOUND }), + ); + expect([provenance, parsed?.identityProvenance, parsed?.executableBinding]).toEqual([ + provenance, + provenance, + BOUND, + ]); + } + // Absent provenance reads as provider-returned, and carries its binding + // through that same compatibility inference. + const inferred = parsePrepared(record({ executableBinding: BOUND })); + expect(inferred?.identityProvenance).toBe("provider-returned"); + expect(inferred?.executableBinding).toEqual(BOUND); }); it("PV5: the settled failure classes round-trip", function* () { @@ -1407,8 +1524,8 @@ describe("Tier PV — identity provenance", () => { * Tier EB — the executable build binding, read and compared strictly * (specs/native-agent-session-launch-spec.md §Provider-native identity). * - * A client-allocated identity means one thing only while the build that - * accepted it can be recognized later, so the binding is exact on the way in + * A provider-native identity means one thing only while the build that issued + * or accepted it can be recognized later, so the binding is exact on the way in * and exact on the way out. Core observes no executables: it reads what was * retained and says whether two of them name the same build. */ @@ -1496,4 +1613,390 @@ describe("Tier EB — executable build binding", () => { it("EB6: completed replay stays provider-cold for a legacy unbound preparation", function* () { yield* replayIsCold({ identityProvenance: "client-allocated" }); }); + + it("EB7: a bound provider-returned preparation round-trips unchanged", function* () { + const parsed = parsePrepared( + prepared({ identityProvenance: "provider-returned", executableBinding: BOUND }), + ); + expect(parsed?.identityProvenance).toBe("provider-returned"); + expect(parsed?.executableBinding).toEqual(BOUND); + }); + + it("EB8: completed replay stays cold for a bound provider-returned preparation", function* () { + // The one property a legacy record and a bound one share. Whichever side + // named the session, a launch the journal already completed asks nothing: + // no build is observed, no route is read, and no child is started. + yield* replayIsCold({ identityProvenance: "provider-returned", executableBinding: BINDING }); + }); +}); + +/** One durable yield, as the journal holds it. */ +interface Retained { + type: string; + name: string; + /** The description's `input`, which is what the effect was asked to do. */ + input: Json | undefined; + value: Json | undefined; +} + +function retained(events: DurableEvent[]): Retained[] { + return events.flatMap((event) => + event.type === "yield" && event.result.status === "ok" + ? [ + { + type: event.description.type, + name: event.description.name, + input: event.description.input, + value: event.result.value, + }, + ] + : [], + ); +} + +function one(events: DurableEvent[], suffix: string): Record { + const found = retained(events).filter((entry) => entry.name.endsWith(suffix)); + if (found.length !== 1) { + throw new Error(`expected exactly one retained "${suffix}", found ${found.length}`); + } + const value = found[0]?.value; + if (typeof value !== "object" || value === null || Array.isArray(value)) { + throw new Error(`retained "${suffix}" is not a record`); + } + return value; +} + +/** One member of a retained record that is itself a record. */ +function nested(record: Record, member: string): Record { + const value = record[member]; + if (typeof value !== "object" || value === null || Array.isArray(value)) { + throw new Error(`retained member "${member}" is not a record`); + } + return value; +} + +/** + * The journal as it would stand had the run stopped right after `suffix`. + * + * A stop between two adjacent appends is exactly what these boundaries are + * about, and holding the native child cannot produce it: every append the turn + * makes happens before anything is spawned. So the journal is cut where the + * interruption would have cut it. + */ +function* cutAfter(stream: InMemoryStream, suffix: string): Operation { + const events = yield* stream.readAll(); + const index = events.findIndex( + (event) => event.type === "yield" && event.description.name.endsWith(suffix), + ); + if (index < 0) { + throw new Error(`no durable yield ending in "${suffix}" to cut after`); + } + return new InMemoryStream(events.slice(0, index + 1)); +} + +/** + * The turn a stub session owes. Fixed rather than minted, so a case can name the + * request id the retained plan committed to. + */ +const OWED: MaterializationPlan = { + promptVersion: "stub-materialization.v1", + requestId: "req-0001", + prompt: "Reply with a brief acknowledgement only.", +}; + +describe("Tier MR — retaining and replaying the materialization turn", () => { + function owing(overrides: Partial = {}): LaunchStub { + return createLaunchStub({ materialization: OWED, ...overrides }); + } + + it("MR1: the owed turn is spent once and retained as both a prompt and a phase", function* () { + const stub = owing(); + const run = yield* runDoc(LAUNCH, { stub }); + expect(run.result.ok ? "" : run.result.error.message).toBe(""); + expect(stub.turns).toEqual([OWED.requestId]); + expect(retainedPhases(run.events)).toEqual(["prepared", "materialized", "detached", "exited"]); + + // The plan is retained with the preparation, before anything is spent. + expect(one(run.events, "/prepared").materialization).toEqual({ + promptVersion: OWED.promptVersion, + requestId: OWED.requestId, + prompt: OWED.prompt, + }); + // The prompt says the turn was spent, and says which turn it was. + const prompt = retained(run.events).find((entry) => entry.name.endsWith("/materialization")); + expect(prompt?.type).toBe("agent_prompt"); + expect(prompt?.input).toBe(OWED.prompt); + expect(one(run.events, "/materialization").status).toBe("completed"); + expect(one(run.events, "/materialization").checkpoint).toEqual({ + provider: "stub", + kind: "stub-turn-id", + value: "turn-0001", + }); + // The phase says the launch may go on, and what the turn cost. + expect(one(run.events, "/materialized").usage).toEqual({ inputTokens: 11, totalTokens: 13 }); + expect(one(run.events, "/materialized").response).toBe("Acknowledged."); + // Only then is the session handed over. + expect(run.launcher.requests.length).toBe(1); + // Spending someone's turn is not silent, and at the root the terminal that + // hears about it is the run's own — reserved before the turn, so the reader + // is told inside the lease the launch already holds. + expect(run.launcher.notices).toEqual([`stub: spending one model turn in "stub:default"`]); + expect(run.launcher.order).toEqual(["reserve", "flush", "notify", "launch"]); + }); + + it("MR2: a completed launch replays without spending a second turn", function* () { + const stream = new InMemoryStream(); + const stub = owing(); + const first = yield* runDoc(LAUNCH, { stream, stub }); + expect(first.result.ok ? "" : first.result.error.message).toBe(""); + expect(stub.turns.length).toBe(1); + + const second = yield* runDoc(LAUNCH, { stream, stub }); + expect(second.result.ok).toBe(true); + expect(second.output).toBe(first.output); + expect(stub.turns.length).toBe(1); + expect(stub.factoryActivations).toBe(1); + expect(second.launcher.requests.length).toBe(0); + }); + + it("MR3: a retained prompt with no phase rebuilds the phase and spends nothing", function* () { + const stub = owing(); + const dir = path.join(os.tmpdir(), `xmd-mr-${randomUUID()}`); + yield* ensure(() => rm(dir, { recursive: true, force: true })); + const stream = new InMemoryStream(); + const first = yield* runDoc(LAUNCH, { stream, stub, dir }); + expect(first.result.ok ? "" : first.result.error.message).toBe(""); + + // Stopped between the two appends the turn makes. + const cut = yield* cutAfter(stream, "/materialization"); + const resumed = yield* runDoc(LAUNCH, { stream: cut, stub, dir }); + expect(resumed.result.ok ? "" : resumed.result.error.message).toBe(""); + // The turn was spent once, by the run that spent it. + expect(stub.turns).toEqual([OWED.requestId]); + expect(stub.preparations.length).toBe(1); + + // Rebuilt from the prompt alone: the provider's name for the turn survives, + // and what the turn cost does not — it was observed once and is reported as + // unreported rather than as nothing. + const rebuilt = one(resumed.events, "/materialized"); + expect(rebuilt.turn).toEqual({ + provider: "stub", + kind: "stub-turn-id", + value: "turn-0001", + }); + expect(rebuilt.response).toBe("Acknowledged."); + expect(rebuilt.usage).toEqual({}); + expect(rebuilt.failure).toBe(undefined); + // And the launch goes on to hand the retained identity over. + expect(resumed.launcher.requests[0]?.command).toEqual(["stub-ui", "--resume", "native-abc"]); + }); + + it("MR4: a preparation with no prompt outcome refuses rather than sending again", function* () { + const stub = owing(); + const dir = path.join(os.tmpdir(), `xmd-mr-${randomUUID()}`); + yield* ensure(() => rm(dir, { recursive: true, force: true })); + const stream = new InMemoryStream(); + const first = yield* runDoc(LAUNCH, { stream, stub, dir }); + expect(first.result.ok ? "" : first.result.error.message).toBe(""); + + // Stopped after the session was prepared and before anything said what its + // turn did — the one state that cannot be told from a turn already charged. + const cut = yield* cutAfter(stream, "/prepared"); + const resumed = yield* runDoc(LAUNCH, { stream: cut, stub, dir }); + + expect(resumed.result.ok).toBe(false); + expect(resumed.result.ok ? "" : resumed.result.error.message).toContain("not knowable"); + // No second turn, and no native UI over a session nothing can vouch for. + expect(stub.turns).toEqual([OWED.requestId]); + expect(resumed.launcher.requests.length).toBe(0); + const refusal = nested(one(resumed.events, "/materialized"), "failure"); + expect(refusal.class).toBe("session-recovery-required"); + expect(refusal.message).toContain("not knowable"); + expect(retainedPhases(resumed.events)).toEqual(["prepared", "materialized"]); + }); + + it("MR5: a retained refusal replays as itself and never opens a native UI", function* () { + const stream = new InMemoryStream(); + const stub = owing({ turnRefused: true }); + const first = yield* runDoc(LAUNCH, { stream, stub }); + expect(first.result.ok).toBe(false); + expect(first.result.ok ? "" : first.result.error.message).toContain("refused the turn"); + expect(first.stub.detaches).toBe(0); + expect(first.launcher.requests.length).toBe(0); + + const second = yield* runDoc(LAUNCH, { stream, stub }); + expect(second.result.ok).toBe(false); + expect(second.result.ok ? "" : second.result.error.message).toContain("refused the turn"); + // Replayed, not retried, and still not handed over. + expect(stub.turns.length).toBe(1); + expect(stub.detaches).toBe(0); + expect(second.launcher.requests.length).toBe(0); + }); + + it("MR6: a session that is openable already owes nothing and is charged nothing", function* () { + const stub = createLaunchStub(); + const run = yield* runDoc(LAUNCH, { stub }); + expect(run.result.ok ? "" : run.result.error.message).toBe(""); + expect(stub.turns).toEqual([]); + expect(one(run.events, "/prepared").materialization).toBe(undefined); + expect(retainedPhases(run.events)).toEqual(["prepared", "detached", "exited"]); + expect(retained(run.events).some((entry) => entry.type === "agent_prompt")).toBe(false); + }); + + it("MR7: a planned turn the provider cannot spend stops the launch", function* () { + const stub = owing({ withholdMaterialize: true }); + const run = yield* runDoc(LAUNCH, { stub }); + expect(run.result.ok).toBe(false); + expect(run.result.ok ? "" : run.result.error.message).toContain("offers no way to spend one"); + expect(stub.turns).toEqual([]); + expect(stub.detaches).toBe(0); + expect(run.launcher.requests.length).toBe(0); + }); + + it("MR8: a preparation cannot name a session its own planned turn would create", function* () { + const stub = owing({ assertIdentityBeforeTurn: true }); + const run = yield* runDoc(LAUNCH, { stub }); + expect(run.result.ok).toBe(false); + expect(run.result.ok ? "" : run.result.error.message).toContain( + "no backend has accepted a turn in yet", + ); + // Refused before the turn, so a provider that names a conversation it has + // not had never gets to spend one either. + expect(stub.turns).toEqual([]); + expect(stub.detaches).toBe(0); + expect(run.launcher.requests.length).toBe(0); + }); + + it("MR9: a completed turn that names no session stops before the handoff", function* () { + const stub = owing({ withholdMaterializedIdentity: true }); + const run = yield* runDoc(LAUNCH, { stub }); + expect(run.result.ok).toBe(false); + expect(run.result.ok ? "" : run.result.error.message).toContain( + "without asserting the provider-native identity", + ); + // The turn was spent and is retained as spent — what is missing is the + // session, and there is nothing for a native UI to be handed. + expect(stub.turns).toEqual([OWED.requestId]); + expect(retainedPhases(run.events)).toEqual(["prepared", "materialized"]); + expect(stub.detaches).toBe(0); + expect(run.launcher.requests.length).toBe(0); + }); + + it("MR10: the identity handed over is the one the accepted turn asserted", function* () { + const stub = owing({ nativeSessionId: "native-from-turn" }); + const run = yield* runDoc(LAUNCH, { stub }); + expect(run.result.ok ? "" : run.result.error.message).toBe(""); + // The preparation asserted none, the turn asserted this one, and this one + // is what the native UI was told to resume. + expect(one(run.events, "/prepared").nativeSessionId).toBe(""); + expect(one(run.events, "/materialized").nativeSessionId).toBe("native-from-turn"); + expect(run.launcher.requests[0]?.command).toEqual(["stub-ui", "--resume", "native-from-turn"]); + }); +}); + +/** + * Tier MJ — the materialization phase read strictly. + * + * This is the one phase whose record decides whether a model turn was already + * paid for. A malformed one read past would either charge a second turn or hand + * a native UI a session nothing named, so every member is parsed rather than + * trusted and anything unrecognized refuses the whole record. + */ +describe("Tier MJ — reading the materialization phase back", () => { + function materialized(overrides: Record = {}): Record { + return { + phase: "materialized", + promptVersion: "codex-materialization.v1", + requestId: "11111111-2222-3333-4444-555555555555", + nativeSessionId: "01998f2e-0000-7000-8000-000000000000", + turn: { provider: "acpx", kind: "codex-thread-id", value: "turn-1" }, + durationMs: 812, + usage: { inputTokens: 11, totalTokens: 13, costAmount: 0, costCurrency: "USD" }, + response: "Acknowledged.", + stopReason: "end_turn", + ...overrides, + }; + } + + it("MJ1: a complete record round-trips every member unchanged", function* () { + const parsed = parseMaterialized(materialized()); + expect(parsed?.promptVersion).toBe("codex-materialization.v1"); + expect(parsed?.requestId).toBe("11111111-2222-3333-4444-555555555555"); + expect(parsed?.nativeSessionId).toBe("01998f2e-0000-7000-8000-000000000000"); + expect(parsed?.turn).toEqual({ provider: "acpx", kind: "codex-thread-id", value: "turn-1" }); + expect(parsed?.durationMs).toBe(812); + expect(parsed?.usage).toEqual({ + inputTokens: 11, + totalTokens: 13, + costAmount: 0, + costCurrency: "USD", + }); + expect(parsed?.response).toBe("Acknowledged."); + expect(parsed?.stopReason).toBe("end_turn"); + }); + + it("MJ2: a record that identifies its plan as nothing identifies no turn", function* () { + for (const value of ["", 1, null, {}]) { + expect(parseMaterialized(materialized({ promptVersion: value }))).toBe(undefined); + expect(parseMaterialized(materialized({ requestId: value }))).toBe(undefined); + } + }); + + it("MJ3: an identity that names nothing is refused rather than handed over", function* () { + for (const value of ["", 1, null, []]) { + expect(parseMaterialized(materialized({ nativeSessionId: value }))).toBe(undefined); + } + // Absent is a different claim from empty: a turn that failed made nothing + // openable, and says so by naming nothing at all. + const absent = materialized(); + delete absent.nativeSessionId; + expect(parseMaterialized(absent)?.nativeSessionId).toBe(undefined); + }); + + it("MJ4: a duration that is not an elapsed time is refused", function* () { + for (const value of [-1, "812", null, Number.NaN, Number.POSITIVE_INFINITY]) { + expect(parseMaterialized(materialized({ durationMs: value }))).toBe(undefined); + } + expect(parseMaterialized(materialized({ durationMs: 0 }))?.durationMs).toBe(0); + }); + + it("MJ5: a usage report is refused whole rather than read part-way", function* () { + // A member no build of this reader knows is a report it cannot claim to + // have understood, so absence never stands in for an unrecognized figure. + expect(parseMaterialized(materialized({ usage: { reasoningTokens: 4 } }))).toBe(undefined); + for (const value of [-1, "11", null, Number.NaN, Number.POSITIVE_INFINITY]) { + expect(parseMaterialized(materialized({ usage: { inputTokens: value } }))).toBe(undefined); + } + for (const value of ["", 3, null]) { + expect(parseMaterialized(materialized({ usage: { costCurrency: value } }))).toBe(undefined); + } + for (const value of ["", 3, null, []]) { + expect(parseMaterialized(materialized({ usage: value }))).toBe(undefined); + } + // Reported nothing is a report, and it is retained as exactly that. + expect(parseMaterialized(materialized({ usage: {} }))?.usage).toEqual({}); + }); + + it("MJ6: a turn or a failure the reader cannot name refuses the record", function* () { + const turns: Json[] = [{ provider: "acpx", kind: "codex-thread-id" }, { provider: "" }, 1, []]; + for (const value of turns) { + expect(parseMaterialized(materialized({ turn: value }))).toBe(undefined); + } + const failures: Json[] = [{ class: "invented", message: "x" }, { class: "native-exit" }, 1]; + for (const value of failures) { + expect(parseMaterialized(materialized({ failure: value }))).toBe(undefined); + } + const failed = parseMaterialized( + materialized({ failure: { class: "materialization-failed", message: "no" } }), + ); + expect(failed?.failure).toEqual({ class: "materialization-failed", message: "no" }); + }); + + it("MJ7: a record of another phase is not a materialization", function* () { + expect(parseMaterialized(materialized({ phase: "detached" }))).toBe(undefined); + expect(parseMaterialized(materialized({ response: 1 }))).toBe(undefined); + for (const value of [undefined, null, "materialized", []]) { + expect(parseMaterialized(value)).toBe(undefined); + } + }); }); diff --git a/packages/runtime/launcher.ts b/packages/runtime/launcher.ts index f719ba94..72b8037e 100644 --- a/packages/runtime/launcher.ts +++ b/packages/runtime/launcher.ts @@ -77,6 +77,21 @@ export interface NativeLauncherHandler { * travels here instead of in `NativeLaunchRequest`. */ launch(request: NativeLaunchRequest, spawned: () => void): Operation; + /** + * Show the person one line about the launch itself, on the terminal this + * launch reserved. + * + * Not document output. What a launch has to say — that a turn is about to be + * spent in their name, what it answered, what it cost — is addressed to + * whoever is sitting there, and it belongs on the screen the native UI is + * about to open on rather than in the document's captured text, where a + * `` would keep it and a replay would print it again. + * + * It goes through the launcher for the same reason `flush` does: this is the + * only thing that knows which terminal a given launch owns, so a pane's + * launch writes into that pane and the root's writes to the root. + */ + notify(text: string): Operation; } export const NATIVE_LAUNCHER_UNAVAILABLE = @@ -105,6 +120,10 @@ export const NativeLauncher: Api = createApi void): Operation { throw new NativeLauncherUnavailableError(); }, + // deno-lint-ignore require-yield + *notify(_text: string): Operation { + throw new NativeLauncherUnavailableError(); + }, }, ); @@ -118,6 +137,11 @@ export function flushOutput(): Operation { return NativeLauncher.operations.flush(); } +/** Say one thing to whoever is at the terminal this launch reserved. */ +export function notifyTerminal(text: string): Operation { + return NativeLauncher.operations.notify(text); +} + /** * Run one native UI as a foreground child and report how it ended. * @@ -202,6 +226,12 @@ export function* installForegroundLauncher( *launch([request, spawned]) { return yield* runForeground(request, spawned); }, + *notify([text]) { + // Written and drained, not queued: the next thing to reach this + // terminal may be a child drawing over it. + process.stdout.write(`${text}\n`); + yield* drainStream(process.stdout); + }, }, { at: "min" }, ); @@ -435,6 +465,8 @@ export interface ControlledLauncherOptions { start?: (request: NativeLaunchRequest, spawned: () => void) => Operation; onReserve?: () => void; onFlush?: () => void; + /** Each line the launch addressed to the terminal, in the order it said them. */ + onNotify?: (text: string) => void; } export function* installControlledLauncher( @@ -464,6 +496,10 @@ export function* installControlledLauncher( *flush() { options.onFlush?.(); }, + // deno-lint-ignore require-yield + *notify([text]) { + options.onNotify?.(text); + }, *launch([request, spawned]) { options.record?.(request); if (options.start) { diff --git a/packages/runtime/mod.ts b/packages/runtime/mod.ts index 06182ead..3165d8a6 100644 --- a/packages/runtime/mod.ts +++ b/packages/runtime/mod.ts @@ -18,7 +18,7 @@ * (`cwd`, `env`, `platform`, `command`, `compile`) * - `API.Service` — scoped attached service startup (`startService`) * - `NativeLauncher` — handing one native agent UI the foreground terminal - * (`reserveTerminal`, `flushOutput`, `nativeLaunch`) + * (`reserveTerminal`, `flushOutput`, `notifyTerminal`, `nativeLaunch`) * - `Config` — shared execution config (`timeout`, `timeoutExec`, `timeoutFetch`, * `verbose`) * @@ -138,6 +138,7 @@ export { NativeLauncherUnavailableError, nativeLaunch, NO_TERMINAL, + notifyTerminal, reserveTerminal, } from "./launcher.ts"; export type { diff --git a/scripts/tests/adapter-vendor.test.ts b/scripts/tests/adapter-vendor.test.ts index 0514c662..49946cbe 100644 --- a/scripts/tests/adapter-vendor.test.ts +++ b/scripts/tests/adapter-vendor.test.ts @@ -29,7 +29,7 @@ const VENDOR = "packages/acp/vendor/adapters"; const REVIEWED = { codex: { upstreamBase: "50f69e57ca761ccafd2ca29de7fb591068277516", - patchedCommit: "fadc0a690e96c276629be8a34be980d35e821637", + patchedCommit: "e1a15637c13e85cca05cd8ba398c5cef92dcaf33", }, claude: { upstreamBase: "8710ce1cbccf562cb04b4bcc30e053e960aee05f", @@ -83,6 +83,7 @@ interface ManifestSnapshot { buildCommand: string; contract: string; materializationContract: string; + identityContract?: string; } function* manifest(): Operation { @@ -194,5 +195,20 @@ describe("Tier AD — embedded ACP adapter snapshots", () => { // an adapter can carry either without the other. expect(snapshot.materializationContract).toContain("executablemd.session-materialization/v1"); } + + // A third claim, declared only where the provider allocates the identity. + // Codex names its own App Server thread and a client cannot know it + // otherwise; Claude is handed the identity it uses, so a snapshot declaring + // one there would be claiming the adapter reports something it never does. + expect( + Object.fromEntries( + declared.map((snapshot) => [snapshot.provider, snapshot.identityContract]), + ), + ).toEqual({ codex: "_meta.agentSessionId", claude: undefined }); + for (const snapshot of declared) { + if (snapshot.identityContract !== undefined) { + expect(snapshot.identityContract).toMatch(/^_meta\./); + } + } }); }); diff --git a/specs/acp-client-spec.md b/specs/acp-client-spec.md index ee337d35..80941504 100644 --- a/specs/acp-client-spec.md +++ b/specs/acp-client-spec.md @@ -59,16 +59,19 @@ routes an opaque request and cannot manufacture that result. its `SessionLaunchResult`; the route is where public middleware sees the ask, and authority to perform it reaches the installed provider directly rather than travelling on this chain - (specs/native-agent-session-launch-spec.md). A launch performs no model turn, - and a provider that answers `prompt()` does not thereby answer it: native - session launch is its own capability, installed on its own. -- Built-in **`claude` is advertised**, for two separate capabilities: native - launch, and attaching ACP to a session a native process constructed. Its - sessions are named by XMD and created by the native process + (specs/native-agent-session-launch-spec.md). A launch performs no model turn + except the one materialization turn an adapter may require to make a freshly + created conversation resumable at all, and a provider that answers `prompt()` + does not thereby answer it: native session launch is its own capability, + installed on its own. +- Built-in **`claude` and `codex` are advertised** for native launch, and + `claude` additionally for attaching ACP to a session a native process + constructed. Claude's sessions are named by XMD and created by the native + process; Codex names its own and reports it back (specs/native-agent-session-launch-spec.md). So the ownership, - construction-route and executable-observation requirements below apply to it + construction-route and executable-observation requirements below apply to them on every host, and only the hosts that assemble all three — Deno and the - compiled binary — can serve it. `codex` remains unadvertised for both. + compiled binary — can serve them. - Every operation that can act on an **advertised** session — `session()`, a subscribed `prompt()` stream, a launch, and an incomplete launch replay — takes exclusive ownership of it first, through the session coordinator its @@ -82,9 +85,12 @@ routes an opaque request and cannot manufacture that result. host, Codex included. - The host also passes in a **construction-route store** and an **executable observer**, directly and from the same trusted root as the coordinator. Both - are required only for an advertised agent whose adapter names its own - sessions: a provider that returns the identity constructs nothing a route - governs and binds no build, and keeps its behavior unchanged on a host that + are required only for an advertised agent whose adapter binds a build. Which + side chose the identity does not decide that: whoever named the session, the + name resolves to one conversation only beside the build that issued or + accepted it, so an adapter that pins a build needs a route to say how the + session was constructed and an observer to say which build that was. An + adapter that binds nothing keeps its behavior unchanged on a host that has neither. A host missing either refuses that agent before any provider effect, on the same terms as a missing coordinator. The observer is not a contextual Api for the same reason the coordinator is not: executable @@ -96,9 +102,13 @@ routes an opaque request and cannot manufacture that result. launch by an adapter that names its own sessions publishes `client-native` under an identity that adapter allocated, unless existing durable ACPX state or an existing route says the session was constructed through ACP — in which - case it publishes or adopts `acp-first` and retains `identity-unavailable`. - Publication is create-once, so the loser of either order adopts the winner, - and no route converts. + case it publishes or adopts `acp-first` and retains `identity-unavailable`. A + launch by an adapter that binds a build and lets the provider name the session + publishes or adopts the **bound** `acp-first` form, carrying the build it just + observed, before ACP creates anything; an existing unbound `acp-first` record + refuses rather than gaining the current executable. Publication is + create-once, so the loser of either order adopts the winner, and no route + converts. - A `session()` or subscribed `prompt()` meeting a **bound** `client-native` route **attaches** to it. Under the same ownership it reobserves the build and compares the binding exactly, requires any retained ACP arrangement to assert diff --git a/specs/native-agent-session-launch-spec.md b/specs/native-agent-session-launch-spec.md index 2de01c5e..66f848ae 100644 --- a/specs/native-agent-session-launch-spec.md +++ b/specs/native-agent-session-launch-spec.md @@ -164,8 +164,11 @@ raw environment, or executable argument vector. `launchAgentSession()` is distinct from `prompt()`: - `prompt()` performs one model turn through ACP and returns the agent response; -- `launchAgentSession()` performs no model turn, transfers the session to a - native UI, and returns only after that UI exits. +- `launchAgentSession()` returns no agent response at all. It transfers the + session to a native UI and returns only after that UI exits. It performs no + model turn of its own except the one materialization turn described below, + which an adapter may require to make a freshly created conversation resumable + and which is never the launch's return value. The base `Agent.launch(request)` routing handler fails. A provider must install the route explicitly; availability of `agent()`, `session()`, and `prompt()` @@ -224,7 +227,9 @@ An empty cached transcript is not proof that a retained or previously handed-off session has no conversation. Native UI turns are provider-owned and need not be mirrored into ACPX or XMD state. Relaunch therefore never silently keeps a stale layer, discards unobserved native history, substitutes a new provider session -for retained continuity, or performs a bootstrap turn. +for retained continuity, or performs a bootstrap turn. A materialization turn is +not a bootstrap turn: it runs only for a conversation this launch just created, +carries no authored content, and never runs against a retained one. The prepared text and filesystem authority are different capabilities: @@ -291,10 +296,13 @@ provenance, because the two constructions make different claims. A **provider-returned** adapter proves all seven of the following: -1. session creation materializes durable state the native UI can resume; +1. by the time the launch hands over, durable state the native UI can resume + exists — either because creation alone materialized it, or because the + adapter's declared materialization turn did; 2. its returned native ID names that exact state; -3. prepared instructions are effective on the first native user turn without a - bootstrap model turn; +3. prepared instructions are effective on the first native *user* turn without a + bootstrap model turn in front of them, and a materialization turn that + preceded that user turn neither supplied nor consumed them; 4. cwd and permissions survive the handoff without being widened; 5. the ACP owner can release the session before native attachment; 6. the native process can exit without deleting the resumable session; and @@ -426,9 +434,28 @@ the failure this contract asks for rather than a hopeful spawn. `claude` is advertised. Its client-allocated claims were proven through the production CLI against **Claude Code 2.1.241 on macOS arm64**, which is the -compatibility point the advertisement stands on. `codex` is unadvertised: its -command shape and adapter contract tests exist, and nothing has run its -provider-returned claims against an installed Codex. +compatibility point the advertisement stands on. + +`codex` is advertised for native launch, gated by the complete provider-returned +proof through the production CLI against **`codex-cli 0.153.2` on macOS arm64**, +with the vendored `@agentclientprotocol/codex-acp` 1.6.2 snapshot that asserts +the App Server thread on the response `_meta` — that whole tuple is the +compatibility point the advertisement stands on, and a launch outside it refuses +before an identity exists. Complete means through to history: the gate closes +only when XMD rejoins that same conversation over ACP afterwards and reads the +native turn back out of it, because a conversation that cannot be rejoined is +not the one this contract says was handed over. + +Reaching it costs one model turn, and only Codex owes it. The App Server writes +a thread's rollout at that thread's first turn and `codex resume ` reads +rollouts, so a conversation ACP created and nothing has spoken in is refused by +name. `codex-materialization.v1` is the single XMD-owned turn that closes that +gap for a freshly created conversation, and it is not the author-supplied +bootstrap of #514: its bytes are fixed by the adapter, it carries no authored +content, path, identity or environment, it refuses on any tool call, and an +already-resumable conversation receives none. Reading the ACP session id as the +native identity remains exactly the substitution the provider-returned route +exists to refuse. ## Runtime sequence @@ -867,24 +894,48 @@ interface AgentSessionRouteV2 { } ``` -There is no V2 `acp-first`: ACP-first construction gained no fact, and a second -schema for it would be a version number with nothing behind it. New -client-native construction publishes V2 and observes the build before it -allocates an identity. Serialization preserves the schema it was given, so -nothing here upgrades a route. +ACP-first construction bound to a build is V3, and only V3: -Every member of both schemas is exact. A path, adapter command, environment, +```ts +interface AgentSessionRouteV3 { + schema: "session-route.v3"; + route: "acp-first"; + provider: string; + agent: string; + sessionKey: string; + executableBinding: ExecutableBuildBindingV1; +} +``` + +It carries the binding and nothing more. The other members of V2 describe an +identity XMD chose and a layer it wrote a file for, and neither is a fact about +a session the provider named — so an ACP-first route says how the session was +constructed and which build constructed it, exactly as it always did, with the +one fact that was missing. + +Each bound schema admits only its own construction: a V2 record is +`client-native` and a V3 record is `acp-first`, and the two pairings do not +cross. New client-native construction publishes V2 and observes the build before +it allocates an identity; new bound ACP-first construction publishes V3 and +observes the build before it creates a session. Serialization preserves the +schema it was given, so nothing here upgrades a route. + +Every member of all three schemas is exact. A path, adapter command, environment, argv, instruction text, credential, transcript, process fact or temporary path is not a member, and a record carrying one is refused rather than read partially. A binding beside a V1 record is such a member, which is what keeps a -V1 record from being read as a V2 one. So are missing, malformed, +V1 record from being read as a bound one. So are missing, malformed, unknown-schema, moved and natural-key-mismatched records. Only a file that is not there means the session has not been constructed yet. -A V1 `client-native` route is legacy-unbound. It remains valid for native resume -under the contract that created it, authorizes no ACP attachment, and is never -overwritten, supplemented or upgraded. A user who needs attachment creates a -differently named logical session under the bound contract. +A V1 route of either kind is legacy-unbound. A V1 `client-native` route remains +valid for native resume under the contract that created it, authorizes no ACP +attachment, and is never overwritten, supplemented or upgraded. A V1 `acp-first` +route is the same story from the other side: it says the session was constructed +before XMD recorded which build issued its identity, so an agent whose adapter +binds a build refuses it rather than writing the current executable into it. A +user who needs either bound behavior creates a differently named logical session +under the bound contract. The route shares the coordinator's namespace, natural key and digest, so one session names one lease, one ownership record and one route. The route directory @@ -1365,14 +1416,23 @@ model. The following capabilities remain outside V1 and fail closed rather than degrading: -- **Only `claude` is advertised**, and separately for each capability. It is - client-allocated, and its proofs ran the applicable claims under - *Provider-native identity* against Claude Code 2.1.241 on macOS arm64. `codex` - has a command shape and contract tests and is not launch-capable, because - nothing has proven its provider-returned claims against an installed Codex. A - launch naming an unadvertised agent is refused with `unsupported-capability` - before anything of the session moves, and so is an attachment naming an agent - advertised only for native launch. +- **Only `claude` and `codex` are advertised**, and separately for each + capability. `claude` is client-allocated and is advertised for both native + launch and client-native attachment; its proofs ran the applicable claims + under *Provider-native identity* against Claude Code 2.1.241 on macOS arm64. + `codex` is provider-returned and is advertised for native launch only, on the + frozen tuple named under *Provider-native identity*. Handing the session to a + native UI does not on its own satisfy that advertisement: the native-launch + gate for `codex` is the complete provider-returned proof, which requires that + XMD rejoins the same conversation through ACP afterwards and reads the native + turn back out of its history, so continuity is part of the claim being made + and not a separate one. Its absence + from client-native attachment says something else entirely: that capability is + joining a conversation a native client allocated, and `codex` never has one, + because its route is ACP-first and the identity is the adapter's own answer to + XMD. A launch naming an unadvertised agent is refused + with `unsupported-capability` before anything of the session moves, and so is + an attachment naming an agent advertised only for native launch. - **`Agent.AddDir` is unbuilt**, so a launch declares no additional roots. The retained request says so explicitly — an empty ordered list — rather than omitting the fact, and no adapter maps a root it was never given. The ACP @@ -1406,7 +1466,9 @@ contract. Implementation review checks these frozen invariants: 1. Only explicitly rendered `Session.Launch` content crosses as instructions. -2. Launch performs no model turn. +2. Launch performs no model turn beyond an adapter's declared materialization + turn, which runs at most once, only for a conversation the launch just + created, and only with that adapter's fixed prompt. 3. Provider-native identity is asserted, never inferred. 4. ACP and the native UI never concurrently own one session. 5. XMD remains the supervising parent and the document stays suspended.