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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions .agents/plans/stations-providers/PLAN.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ Use the dedicated foundation worktree and preserve other worktree owners. One br
| [DIS-82](https://linear.app/outfitter/issue/DIS-82) | Minimum shared observation/receipt seam on Codex | DIS-80 |
| [DIS-83](https://linear.app/outfitter/issue/DIS-83) | Independent provider startup/recovery | DIS-80, DIS-82 |
| [DIS-84](https://linear.app/outfitter/issue/DIS-84) | Native Hermes transport proof on the authorized default profile | Can start independently; findings inform the shared design |
| [DIS-85](https://linear.app/outfitter/issue/DIS-85) | Hermes adapter and two coherent local turns | DIS-70, DIS-79, DIS-80, DIS-81, DIS-82, DIS-84 |
| [DIS-94](https://linear.app/outfitter/issue/DIS-94) | Request-correlated native Hermes gateway execution contract | DIS-84 |
| [DIS-85](https://linear.app/outfitter/issue/DIS-85) | Hermes adapter and two coherent local turns | DIS-70, DIS-79, DIS-80, DIS-81, DIS-82, DIS-84, DIS-94 |
| [DIS-86](https://linear.app/outfitter/issue/DIS-86) | Hermes ambiguity/replay/attention recovery | DIS-85 |
| [DIS-87](https://linear.app/outfitter/issue/DIS-87) | Desktop A → Dispatch B → Desktop C coexistence | DIS-86 |
| [DIS-88](https://linear.app/outfitter/issue/DIS-88) | Hermes diagnostics, docs, skills and package proof | DIS-86; attached/Hermes-only claims also require DIS-87/DIS-83 |
Expand Down Expand Up @@ -61,7 +62,7 @@ Implement and review the binding migration before enabling provider routing. Ext

In parallel with shared code, inspect the installed Hermes contract and use the authorized local default profile for synthetic live checks. Record version, profile, durable/runtime session identities, native run IDs where they exist, replay scope and canonical history evidence. The initial adapter owns dedicated sessions. Desktop/API warm alternation failed the native prerequisite check and remains unsupported; any future coexistence test must establish both idle state and coherent native context. An acceptance response or a closed event stream alone never proves execution.

The native stdio proof passed two coherent turns, per-session terminal cwd and one clean gateway restart. It has no native keyed admission or durable request-indexed turn ID. Unknown outcomes never retransmit. Automatic ordinary resume remains disabled across generation changes until Hermes provides a supported non-executing recovery guarantee; lazy watch is an exact-segment diagnostic path, not an execution resume. Record that upstream limit in DIS-86 without blocking same-generation creation and continuation that satisfy the shared gates.
The native stdio proof passed two coherent turns, per-session terminal cwd and one clean gateway restart. It has no native keyed admission or durable request-indexed turn ID. A source-pinned audit found that idle check/claim can race single-start heartbeat or bot turns, so sequence, streaming acknowledgment and `running:false` cannot correlate an arbitrary terminal to the submitted request. [DIS-94](https://linear.app/outfitter/issue/DIS-94) is actively preparing the additive `prompt_turn_correlation_v1` contract: atomic admission with an owner token plus a turn id echoed through start, terminal, error and retained evidence. Until that isolated upstream work is verified and adopted, stock Hermes is unavailable for durable send receipts; the two-turn probe remains continuity/cwd evidence only. Unknown outcomes never retransmit. Automatic ordinary resume remains disabled across generation changes until Hermes provides a supported non-executing recovery guarantee; lazy watch is an exact-segment diagnostic path, not an execution resume.
Comment thread
galligan marked this conversation as resolved.

After two coherent Dispatch turns, exercise replay/conflict, lost acknowledgment, unavailable runtime and attention boundaries, using isolated services for destructive fault simulations. Verify Desktop continuity and operator diagnostics, then run a fresh full-stack review. Continue through correctable findings; stop only at a concrete capability or authority boundary and preserve a precise pickup record.

Expand All @@ -73,7 +74,7 @@ Before marking DIS-85 ready to start, the coordinator records:

1. Exact reviewed foundation base commit/PRs and whether the agent consumes merged main or an explicitly approved stack base.
2. DIS-70 and DIS-79–82 verification, migration version/coverage and no unresolved correctness/review blockers.
3. DIS-84's actual runtime/profile/API proof and unsupported cases.
3. DIS-84's actual runtime/profile/API proof and unsupported cases, plus verified adoption of DIS-94's request-correlation contract.
4. Known Codex startup dependency and provider capability limits.
5. Worktree/branch ownership and the next concrete implementation step.

Expand Down
5 changes: 5 additions & 0 deletions .agents/plans/stations-providers/RETRO.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,8 @@ The native HTTP Runs probe passed keyed replay/conflict, two-turn continuity, ca
- The initial adapter must preserve unknown outcomes without retransmission and quarantine stored sessions after an owner generation change until supported safe resume exists. This concrete upstream limit does not prevent the correctly bounded same-generation implementation after DIS-80/81/82 pass.

No merge, release, installed Dispatch registry migration, runtime replacement or service deployment occurred. The owned native processes were temporary proof clients using the existing default profile; existing Desktop and API services remained running.

### Native request-correlation prerequisite

- A subsequent source-pinned audit of Hermes `939e45c91d751fadd94dcd1b873ac3cb44846213` found an idle-check/claim race with unsolicited single-start heartbeat and bot turns. Sequence fencing, a streaming acknowledgment and `running:false` do not prove which prompt produced an arbitrary terminal event.
- DIS-94 is actively preparing an isolated upstream additive `prompt_turn_correlation_v1` contract: atomic admission with an owner token and a native turn id echoed in start, terminal, error and retained evidence. It is not installed or verified. Until it is adopted, Dispatch must refuse durable Hermes send receipts rather than infer success. The existing two-turn/cwd probe remains valid native continuity evidence; generation quarantine and unknown-outcome handling remain separate limits.
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ Keep one daemon per station. Provider process ownership, client connection owner

The [native Hermes investigation](../research/hermes-native-provider-contract.md) selects owned stdio because it supports per-session cwd. Plain text and dedicated Dispatch-owned sessions are the initial contract. Native acknowledgments lack durable keyed admission; local reservations prevent automatic duplicate submission and preserve unknown outcomes. Ordinary cold resume can auto-continue a stale crash marker even after prior terminal evidence, so automatic continuation across a gateway generation change requires a supported suppression guarantee. Until then, quarantine old sessions while permitting new independent work after fencing the old child. Desktop attachment and unrestricted autonomous-turn attribution retain separate proof gates. The [HTTP Runs alternative](../research/hermes-http-runs-contract.md) does not provide a fallback.

The source-pinned stdio audit adds a prerequisite to any durable Hermes receipt claim: on stock `939e45c91d751fadd94dcd1b873ac3cb44846213`, idle check and turn claim can race an unsolicited heartbeat or bot turn, while public terminal events carry no request/turn identity. Sequence fencing, a streaming acknowledgment and `running:false` cannot repair that ambiguity. [DIS-94](https://linear.app/outfitter/issue/DIS-94) is actively preparing an additive `prompt_turn_correlation_v1` contract with atomic admission, an owner token, and a native turn id echoed through start, terminal, error and retained evidence. Until its isolated upstream implementation is verified and adopted, Dispatch refuses durable Hermes execution rather than guessing a receipt result; generation quarantine remains an independent boundary.

### Stable thread identity, scoped native identity

| Identity | Meaning |
Expand Down
7 changes: 7 additions & 0 deletions docs/research/hermes-native-provider-contract.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@ Allow one unresolved Dispatch submission per Hermes thread. `prompt.submit` take

Events arrive as JSON-RPC `event` notifications with type, runtime session ID and payload. `message.complete` carries native status/text; settled `session.info` separately reports whether the foreground session is running. Tool completion carries native tool correlation and result. Map these to the pending local request only when the exact binding/runtime/generation, exclusive-owner scope and evidence uniquely establish correlation. One pending client request alone is insufficient if Hermes starts goals, loops, delegation/process notifications or other unsolicited turns. Track unsolicited activity separately, keep those modes outside the initial advertised contract, and retain uncertainty whenever the native event cannot be attributed. Persist the received evidence and canonical row correlation. A terminal answer, readiness for the next input and completion of detached background work remain separate facts.

### Request-correlation prerequisite

The source-pinned `939e45c91d751fadd94dcd1b873ac3cb44846213` gateway cannot positively establish that an arbitrary `message.complete` belongs to an accepted `prompt.submit`. Its idle check and in-process claim are separate: a notification poller can claim an idle session before direct submission acquires its lock, and the direct path then sets the shared running flag without rechecking it. Heartbeat and bot-mailbox turns can each produce the same single `message.start` → `message.complete` shape as an ordinary prompt. A pre-submit sequence watermark, `status:streaming`, one pending receipt, replay order, or a later `running:false` are therefore insufficient ownership proof.

Dispatch must fail closed for durable Hermes send receipts on that stock contract. The additive upstream contract is the capability `prompt_turn_correlation_v1`: atomically allocate an opaque `turn_id` while claiming an idle session; keep a per-turn owner token so only that owner can release the claim; return the id from accepted submit; and echo it in start, terminal completion, terminal error, active/settled info, and retained or replayed evidence. Dispatch may resolve only an exact matching id in the current gateway generation; missing, mismatched, truncated, or restart-era evidence remains unknown. [DIS-94](https://linear.app/outfitter/issue/DIS-94) is actively implementing and testing this in an isolated upstream worktree. It is not a verified capability or an installed-runtime change. The synthetic two-turn/cwd probe remains positive evidence of native continuity, not production request-correlation proof.
Comment thread
galligan marked this conversation as resolved.

Hermes has no native idempotency key or durable request-indexed turn record on this transport. A local key prevents Dispatch from issuing the same request again; it does not prove native admission. After a write failure, timeout, lost acknowledgment or process death, preserve unknown outcome and block later work. Never resend the prompt, replace the session, switch transport or perform ordinary auto-continuing resume to repair uncertainty.

A known native error before admission can reject the request. An accepted response proves only native admission progress. Historical text equality alone cannot prove that a particular local request ran. Reconcile only with unique, positive correlation; absent, duplicated, partial or compressed history remains uncertain. Local exact-key receipt replay stays durable even when native evidence cannot recover the result.
Expand Down Expand Up @@ -97,6 +103,7 @@ Paths refer to the inspected Hermes source revision:
- `tui_gateway/entry.py:241–285`: startup, ready notification and JSONL dispatch.
- `tui_gateway/methods_session.py:325–395,689–853,1673–1711,1893–1897`: creation identities, lazy/ordinary resume, status/history and close.
- `tui_gateway/methods_prompt.py:540–653`: admission, exclusive submit and immediate response.
- `tui_gateway/session_notifications.py:127–132,180–210,492–541`: notification claim plus the single-start heartbeat and bot-mailbox paths.
- `tui_gateway/prompt_turn.py:622–672,784–878`: native terminal status, markers and settled observations.
- `tui_gateway/server.py:2047–2094`: session info identity/cwd/running provenance.
- `tui_gateway/session_auto_continue.py:21–114`: crash-marker automatic continuation.
Expand Down