From 2ccc5f9b62057bf70e1ac0b4867d9217b5271422 Mon Sep 17 00:00:00 2001 From: Lu Nelson Date: Thu, 3 Sep 2026 14:48:15 +0200 Subject: [PATCH 01/13] Cut Mission 6 resumable fixture authority --- libs/@hashintel/brunch-agent/MISSION.md | 226 +++++++++--------- libs/@hashintel/brunch-agent/MISSION.next.md | 25 +- ...6-resumable-workpiece-petrinaut-fixture.md | 164 ------------- .../mission-drafts/7-capture-backed-review.md | 4 +- .../mission-drafts/9-traceable-projection.md | 2 +- 5 files changed, 121 insertions(+), 300 deletions(-) delete mode 100644 libs/@hashintel/brunch-agent/docs/mission-drafts/6-resumable-workpiece-petrinaut-fixture.md diff --git a/libs/@hashintel/brunch-agent/MISSION.md b/libs/@hashintel/brunch-agent/MISSION.md index 2d09a6215ad..30ee78c456d 100644 --- a/libs/@hashintel/brunch-agent/MISSION.md +++ b/libs/@hashintel/brunch-agent/MISSION.md @@ -1,163 +1,153 @@ -# Mission 5 — one Flue conversation route for Voice and the typed panel +# Mission 6 — resume one prepared workpiece and Petrinaut document ## Status -**Live as of 2026-09-03** for [FE-1574](https://linear.app/hash/issue/FE-1574/let-voice-speak-through-canonical-brunch-conversations) on `ln/fe-1574-direct-voice-flue`, stacked directly on the closed Mission 4 branch. This is the sole execution authority for the branch. The builder implementation now routes typed panel and finalized Voice turns through one browser `FlueClient` at `/agents/chat/:instanceId`, projects canonical replies into Petrinaut and TTS, uses durable Flue abort for explicit Stop, and rehydrates canonical conversation state through SDK observation. The former Brunch `/api/chat` handler and projector are deleted. Mission acceptance remains open until the required human demo and proof-leaf-8 bundle exist. +**Live on `ln/fe-1575-resumable-workpiece-petrinaut` from 2026-09-03.** [FE-1575](https://linear.app/hash/issue/FE-1575/resume-one-brunch-workpiece-and-petrinaut-document-across-tabs) is in progress. This authority cut is committed separately before product or evaluation implementation begins. It was recut on restack the same day to carry the product-manager litmus adopted in [`MISSION.next.md`](MISSION.next.md#current-authority-and-accepted-spine) after the first cut: completion is the readiness gate below, not the first green two-tab pass. -The accepted departure base remains Mission 4's package-composed `ChatAgent`: `useBrunchAgent()` mounts core's independent `elicitation` capability and `useSdcpnPlugin()` mounts the SDCPN job contribution. `@hashintel/brunch-agent-transport-aisdk` is now the browser adapter over public `@flue/sdk`, not a server handler. The current external Voice evidence remains PR [#9496](https://github.com/hashintel/hash/pull/9496) at `c7fe8a2e68e8fdc37018b21ec2e9daf4e9ef7c82`, PR [#9507](https://github.com/hashintel/hash/pull/9507) at `252b9dbb0c77fae8cee45a506f09cac3e20c381c`, and PR [#9512](https://github.com/hashintel/hash/pull/9512) at `d13535d1077b3a78d6a1411031b7d0a0a78e3144`. They are read-only source evidence, not branches to rewrite or wholesale architecture to restore. +## Imperative -Cold-start reads are [`docs/evidence/implementations/mission-4-voice-integration-handoff.md`](docs/evidence/implementations/mission-4-voice-integration-handoff.md), [`packages/transport-aisdk/src/index.ts`](packages/transport-aisdk/src/index.ts), [`packages/transport-aisdk/src/ui-stream.ts`](packages/transport-aisdk/src/ui-stream.ts), [`packages/transport-aisdk/src/transcript.ts`](packages/transport-aisdk/src/transcript.ts), [`apps/brunch-agent/src/app.ts`](../../../apps/brunch-agent/src/app.ts), [`apps/brunch-agent/src/http/ownership.ts`](../../../apps/brunch-agent/src/http/ownership.ts), [`apps/brunch-agent/test/petrinaut-chat.integration.ts`](../../../apps/brunch-agent/test/petrinaut-chat.integration.ts), [`apps/brunch-agent/test/architecture/boundaries.integration.ts`](../../../apps/brunch-agent/test/architecture/boundaries.integration.ts), [`apps/petrinaut-website/src/main/app/local-storage-demo/`](../../../apps/petrinaut-website/src/main/app/local-storage-demo/), [`apps/petrinaut-website/src/main/app/voice-interview/`](../../../apps/petrinaut-website/src/main/app/voice-interview/), and the installed Flue 2.0.3 documentation at `node_modules/@flue/sdk/docs/sdk/flue-client.md`, `node_modules/@flue/sdk/docs/reference/streaming-protocol.md`, and `node_modules/@flue/sdk/docs/guide/react.md`. +Determine whether one canonical Brunch conversation can maintain a useful Markdown workpiece and drive a meaningful change to a real Petrinaut document through the browser without reviving a comprehensive typed domain IR. -## Imperative +Mission 3 separately showed a recoverable Markdown workpiece and hermetic canonical Petrinaut callbacks, but its paid model could not carry a nested construction schema and no product path joined the two results. Mission 4 accepted the independent core `elicitation` capability and SDCPN job-skill composition but produced no full-run candidate. This mission must retire the join and resume uncertainty honestly with one deliberately prepared fixture rather than treating either historical result as an integrated product. + +### Visible product advance -Make the mounted Flue conversation route the only product door into a Brunch conversation, and make Voice a faithful audio projection of that one canonical conversation. One finalized spoken answer and one typed panel message must both enter the owning Flue conversation through `@flue/sdk` against `/agents/chat/:instanceId`, and the corresponding canonical Brunch response must reach visible text and TTS without another model rewriting the text. Do this now because Mission 4 established the canonical agent composition while two transports still exist to the same conversation: the Voice preview's AI SDK composer path and the server-side `/api/chat` adapter, which admits through a different code path than the SDK does. Routing Voice onto Flue while keeping `/api/chat` for typed text would harden the split into two routes, two ownership rules, and two protocols; the least mechanism is one route, with the AI SDK reduced to the panel's rendering contract behind a host-supplied browser `ChatTransport`. +**Release note:** Brunch edits the Petrinaut net you are looking at from the conversation, and your work survives closing the tab. -### Product-manager litmus +**Demo script (no engineer present):** with the local Brunch/Petrinaut development stack running, open the stable demo fixture selector for the labelled prepared crew-reservation case. Its canonical Brunch conversation, current Markdown workpiece, and non-empty Petrinaut net come back together. Tell Brunch the one new realistic fact the fixture is prepared for: final inspection uses the single dispatch crew, and sign-off releases it. Watch the workpiece update and a new arc appear in the live net from `Dispatch crew available` to `Start final inspection`. Save. Open the same fixture in a second tab and continue the conversation from the saved state. The fixture announces out loud that it is test-authored and prepared, and what it does not claim. -Adopted on restack onto the parent spine's 2026-09-03 litmus reframing. A product manager who did not watch the work must be able to notice the advance; the single-route consolidation, the browser `ChatTransport`, the deleted `/api/chat` door, and the repurposed transport package are internal sequencing and must not be presented as the advance. +**Previously impossible:** Brunch only produced off-canvas net JSON for manual load; nothing it did touched the live document or survived a reload. -**Release note:** in the Petrinaut Brunch panel you can type or speak to Brunch in one conversation; what you hear is exactly what Brunch wrote; **Stop** really stops Brunch rather than just hiding its answer; and reopening the panel shows the same conversation you left, without re-sending or replaying anything. +**Deployment posture:** the demo runs against the locally run Petrinaut website and Brunch agent (`yarn dev:brunch`). Mission 8 stopped before remote deployment, so no product-manager-noticeable claim here depends on remote infrastructure; remote durability stays with Mission 8. -**Demo script (no engineer present), on the deployment posture available at cut time — the local `yarn dev:brunch` pair with the Brunch preview selected:** open the panel and type one message; read the reply. Start Voice mode and speak one answer; see exactly one new user message appear, then see Brunch's reply appear as text and hear the same words read aloud. Speak over it once; playback stops and the text stays. Ask a second question and press **Stop** while Brunch is still working; the conversation shows that turn as stopped, not as an answer. Close the panel and reopen the same conversation: the typed turn, the spoken turn, and the stopped turn are all there exactly as you saw them, nothing replays, and nothing is sent again. +**Completion:** the mission is done when a product manager can run that demo script end to end for this fixture and every readiness-gate obligation in [Proof](#proof) is closed. The first green pass through the two-tab path is an internal milestone inside the mission, not its completion. -**Previously impossible:** Stop only cancelled the browser request while Brunch kept working, so reopening the panel showed a full answer you had stopped; typed and spoken turns entered Brunch through different doors, so a spoken turn could be held or ordered differently from a typed one. +## Throughline -**Completion:** the mission is complete at the contract stratum below — when a product manager can run this demo script end to end and proof leaf 8's witness bundle records it — not when the first typed or spoken turn crosses the route. The first green typed-panel tracer and the first green Voice tracer are internal milestones. +### Observed departure point and first unproved boundary -### Recut rationale +The production browser already has most local pieces: -Inspected at the real boundary on 2026-09-03 (`node_modules/@flue/sdk/docs/reference/streaming-protocol.md`, `packages/transport-aisdk/src/index.ts`, `packages/transport-aisdk/src/ui-stream.ts`, `apps/petrinaut-website/src/main/app/local-storage-demo/brunch-panel-transport.ts`, `node_modules/ai/dist/index.d.ts` `ChatTransport`): +- `apps/petrinaut-website`'s local-storage demo owns an editable `PetrinautDocHandle`, writes handle changes to `petrinaut-sdcpn`, maps each net to a persistent Brunch conversation id, and hydrates panel messages from the Brunch history door; +- Petrinaut's stock AI panel already validates and executes canonical read, mutation, and command tools against the active browser document and returns the original tool-call id; +- `apps/brunch-agent` already maps the principal plus conversation id to one Flue conversation, exposes `GET /api/chat?id=…` history, resumes client-tool results as correlated Flue signals, and projects the resulting stream back to the panel; and +- the SDCPN skill already emits a full recoverable `runbook-ir` block and requires construction to consume that workpiece rather than transcript archaeology. -- Flue's SSE does not remove the need for translation while the panel speaks `useChat`: Flue admits one `DeliveredMessage` with a 202 and streams `ConversationStreamChunk` batches on a separate, never-ending offset-resumed read; the AI SDK posts the whole `messages` array and expects one finite `UIMessageChunk` stream per turn. Request shape, vocabulary, and lifecycle all differ, and `@flue/*` ships no AI SDK adapter. -- At the recut, the adapter was one translation cut across two homes by the transport topology gate: AI SDK request framing, CORS, and principal parsing in `transport-aisdk` (then Flue-free), and the load-bearing `ConversationStreamChunk → UIMessageChunk` projection plus snapshot → UI messages in `apps/brunch-agent/src/conversation/`. -- A Hono-level relocation would have re-expressed the same admit → follow → project → terminate join as a server handler; it would have removed nothing and kept two routes. It was rejected. -- AI SDK `ChatTransport` is a client-side interface, and Petrinaut already accepts and wraps host-supplied transports. The landed browser transport over the same `createFlueClient()` that Voice uses owns the projector, removes `/api/chat` and its handler, and makes typed and spoken turns share one admission path, one ownership guard, and one protocol. +The first unproved boundary is ordinary Brunch conversation → mounted canonical document read / least mutation → browser execution → correlated continuation. Today ordinary SDCPN conversations mount only the Petrinaut documentation reader as a browser tool; the validated construction subset is headless-only, and no stable fixture selector or coherent cross-tab witness joins the conversation, workpiece, and document lifecycles. -## Throughline +### Accepted fixture and boundary crossings + +Prepare the existing final-inspection / dispatch-crew case as an explicitly test-authored fixture. Its starting workpiece and non-empty net preserve this narrow account: one crew is reserved during final inspection, sign-off releases it, the batch then becomes dispatch-ready, and timing plus failure/recovery remain unresolved. Its prepared material must identify its authorship and must not be presented as a Mission 4 candidate or model-produced evidence. -The real boundary is the local Petrinaut surface driven by `yarn dev:brunch` — both its typed panel and its Voice control — through one same-origin-proxied Flue route into the mounted production `ChatAgent`, back to visible Petrinaut text and, for Voice, audible playback: +Prepare the net with `Batch ready`, `Under final inspection`, `Ready for dispatch`, and `Dispatch crew available` places plus `Start final inspection` and `Sign-off` transitions. Preserve the batch-flow arcs and the return of the crew from sign-off, but deliberately omit the standard input arc that reserves the sole crew when final inspection starts. Use one realistic confirming answer: final inspection consumes the sole available dispatch crew, sign-off returns it, and timing plus recovery remain unknown. The least candidate mutation is one canonical weight-1 standard input arc from `Dispatch crew available` to `Start final inspection`. The exact before/after edge makes the semantic oracle discriminating while avoiding Mission 3's deeply nested schema failure. If that shallow mutation still cannot cross Flue faithfully, stop with the carrier blocker rather than weakening the claim. ```text - Petrinaut typed panel (`useChat`) Petrinaut microphone - → host-supplied browser `ChatTransport` → OpenAI Realtime provisional STT + turn detection - (`sendMessages` → one user text or → one validated finalized `continue_interview` answer - one client-tool-result signal) - └──────────────┬────────────────────────────┘ -→ one browser `createFlueClient()` per selected principal + logical conversation id -→ one supported `send()` admission at the same-origin proxied `/agents/chat/:instanceId` route - (Voice may enter via the panel's transport — preferred, one visible store — or call `send()` directly; see fog-line) -→ `agentOwnershipGuard` (the only ownership check) → `createAgentRouter(ChatAgent)` -→ current `ChatAgent` with `useBrunchAgent()` + `useSdcpnPlugin()` -→ SDK reads: `wait(admission, { onEvent })` for the panel's finite per-turn stream, - `observe({ live: "sse" })` for canonical state and reopen -→ response parts correlated by server-issued `submissionId` -→ panel: existing `ConversationStreamChunk → UIMessageChunk` projector, terminated on `submission-settled` -→ Voice: canonical completed Brunch text displayed and passed unchanged as TTS input -→ local playback/observation cancellation or explicit conversation-wide `abort()` -→ observation rehydration after reopening the same logical conversation +stable prepared-fixture selector +→ resolve distinct fixture, Petrinaut document, and Flue conversation identities +→ open the prepared non-empty browser document and hydrate canonical Flue history +→ recover the latest Markdown workpiece revision by source message id plus content hash +→ submit the realistic crew-reservation confirmation through the production panel door +→ Brunch emits an inspectable full workpiece revision without erasing prior meaning or the remaining unknown +→ SDCPN construction reads that current workpiece and the live browser document +→ Brunch requests the least canonical meaningful mutation +→ Petrinaut validates and executes it against the bound document +→ the original tool-call id and result resume the same Flue conversation +→ inspect the canonical non-empty document and record a settled fixture witness only after conversation/workpiece/document state is observable +→ a second tab opens the same fixture selector, resolves the same identities and settled hashes, and can continue ``` -The `/api/chat` route, `createPetrinautChatHandler`, the in-process `init().dispatch()/read()` admission path, the `GET ?id=` history door, and the `/api/chat` Vite proxy are removed from the Brunch app; the local launcher proxies `/agents/chat/*` instead. `@hashintel/brunch-agent-transport-aisdk` is repurposed as the browser-side adapter: it exports the projector, the snapshot → UI-message projection, the header names, and a `ChatTransport` factory over a caller-supplied `FlueClient`, and depends on `ai` and the public `@flue/sdk` client only. The Petrinaut panel itself stays on `useChat`; it is not rewritten onto `@flue/react`. +The fixture witness is a small local viability manifest, not a new event log, independent workpiece store, or distributed transaction. It records distinct ids, prepared inputs, latest settled workpiece source/hash, document hash or local revision token, and limitations. A failed history load, workpiece recovery, rejected/no-op mutation, or missing result correlation must not advance that witness; the partial state remains visible for diagnosis. The existing automatic localStorage mirror is the only document-save mechanism unless a real failure proves it insufficient. -`conversationId` is the stable logical reference selected by the Petrinaut host. The current principal plus that id mechanically derives the Flue instance path and ownership headers. `submissionId` correlates one admitted answer and its settlement. Flue offsets remain opaque. `uid` identifies one current incarnation and may guard a known continuation, but it must not replace the logical conversation id or be presented as durable user identity. +### Expected touched paths -For maintained Voice state beyond what the panel already holds, use the SDK's materialized `observe()` surface, or `useFlueAgent()` over the same memoized client if the React seam earns it. Use `readSubmissionReply()`, `read()`, or `wait({ onEvent })` only for submission-scoped extraction, not as a parallel transcript reducer; the panel transport's per-submission projection into `useChat`'s own store is that submission-scoped use, not a second transcript. Do not parse SSE, calculate offsets, retry stream chunks, or hand-pick the latest message. The tracer may stream canonical text visibly through the observation, but TTS begins only from completed speakable segments and may remain settlement-gated; token-by-token speech is not part of this claim. +This manifest is provisional and may shrink or move when the first real probe exposes the deeper existing boundary: -The first tracer is text-turn-only at the Brunch boundary. It does not require the temporary `brunch_ask` client-tool shim: a finalized spoken answer is a direct Flue user message, and canonical plain assistant text is sufficient to prove the transport. If the real tracer cannot preserve answer correlation without structured questions, stop and present that observed strain before mounting the suspended capability. +```text +libs/@hashintel/brunch-agent/ +├── MISSION.md ~ live authority and eventual close evidence +├── MISSION.next.md ~ future joins and carried flags only +├── packages/plugin-sdcpn/ ~ mount only the read/mutation capability earned by this tracer +└── docs/evidence/ + prepared fixture manifest and browser witness +apps/brunch-agent/ +├── src/agents/chat-agent/ and src/conversation/ ? only if normal client-tool mounting/correlation requires it +└── test/ + real Flue/client-tool fixture integration +apps/petrinaut-website/ +└── src/main/app/local-storage-demo/ ~ fixture selection, prepared seed, settled witness, and cross-tab resume +libs/@hashintel/petrinaut-core/ or libs/@hashintel/petrinaut/ ? only for an observed canonical contract or browser-host defect +``` -### Contract stratum and readiness gate +## Proof -Close the **one-route conversation transport stratum**: one typed turn and one finalized Voice turn each admitted once through `@flue/sdk` at the mounted route, canonical output, client-tool follow-up as a signal, local playback cancellation, durable abort, visible failure, and same-conversation reopen — with no second server-side door remaining. +The visible advance is the demo script in the imperative, run by a product manager against the named local posture. The evidence that backs the claim is one stable local demo URL or fixture selector plus its labelled prepared manifest, exact before/after Flue snapshots, recovered Markdown workpiece revisions, canonical Petrinaut document states, and two-tab witness; those are oracles for the builder and adjudicator, not the advance itself. Together they establish single-fixture browser-backed viability. They do **not** establish automatic full-net projection, capture-backed or selected-pair provenance, behavioral execution, broad scenario coverage, remote replacement durability, concurrent editing, Mission 3/4 quality superiority, or a promoted reusable product seed. -Order the tracers so the cheaper one proves the route first: the typed panel over the browser transport (it reuses the existing projector and has an existing integration scenario to re-express), then Voice. After each end-to-end turn works, enumerate the lateral obligations it exposes and close those required to make the visible claim true: duplicate finalization, ambiguous admission, submission/reply correlation, client-tool resume correlation, reconnect and replay, local cancellation versus durable abort races, fatal ownership errors, and canonical text/TTS-input correspondence. Carry broader speech ergonomics, multi-turn barge-in tuning, structured questions, and remote identity and exposure only to the named deferred owners below. +### Internal milestone: first green throughline -## Proof +The first internal milestone is one pass through the throughline for the prepared fixture: a cold reader can reconstruct the spine and distinguish supplied evidence, inference, and the explicit unknown in the workpiece; one realistic turn produces an inspectable workpiece revision without erasing the unknown; Brunch reads the live document and applies the one supported arc through the real browser client-tool boundary; the canonical net is non-empty and visibly corresponds to the confirmed meaning; and a second tab observes the same settled conversation, workpiece, and document revision and continues without duplicate submission or identity drift. Reaching this milestone authorizes the readiness work below; it does not close the mission. -This proof establishes that one real local typed turn and one real local Voice turn each cross the supported Flue conversation protocol at the single mounted route into the current canonical Brunch agent, that the typed turn returns as one finite AI SDK stream and the Voice turn as one visible and spoken canonical response, both with bounded cancellation and recovery semantics, and that no server-side AI SDK door remains. It does **not** establish trusted production authentication, remote deployment, broad Voice UX, structured-question transport, Petrinaut client-tool mutation, workpiece viability, or that the `useChat` panel itself is removable. +### Readiness gate: completion bar -1. **Typed panel over the browser Flue transport.** A typed panel submission calls `send()` exactly once with one `kind: "user"` message; a completed client-tool follow-up calls `send()` exactly once with one `kind: "signal"` `client-tool-result` message and resumes the same assistant message id; the returned `UIMessageChunk` stream carries the same start/step/part/finish sequence the former `/api/chat` integration asserted, and terminates on that submission's `submission-settled`. Reopen hydration comes from `observe({ live: "sse" })` through `snapshotToUiMessages`. Oracle: the current `apps/brunch-agent/test/petrinaut-chat.integration.ts` scenario re-expressed through the browser transport against the in-process `app.fetch` of the real `app.ts` (Flue route, ownership guard, faux provider), preserving its text, reasoning, server-tool, and client-tool-resume assertions; the relocated projector and transcript unit tests; and the outer witness typing one message in the real panel with the network ledger showing only `/agents/chat/:instanceId` traffic. -2. **Direct finalized admission.** A completed Realtime `continue_interview` call invokes Flue `send()` exactly once with one `kind: "user"` message; provisional transcript events, duplicated provider terminal events, stale epochs, and repeated tool-call delivery never enter history. The admitted server `submissionId` becomes the turn correlation key. A lost or ambiguous admission is surfaced and never blindly resent. Oracle: named cases in `apps/petrinaut-website/src/main/app/voice-interview/realtime-brunch-bridge.test.ts`, including `admits one finalized Realtime answer through Flue once`, plus canonical snapshot inspection showing exactly one matching visible user message. -3. **No server-side AI SDK door.** The Brunch app no longer mounts `/api/chat`; `createPetrinautChatHandler`, `PETRINAUT_CHAT_ROUTE`, the in-process `init()` admission path, and the `/api/chat` proxy are deleted; the repurposed transport package contains no `Request`/`Response` handler. The real Voice turn reaches the mounted route through `@flue/sdk` — either through the panel's Flue transport or by a direct `send()` — and makes no submission over any non-Flue protocol. Oracle: `apps/brunch-agent/test/build-artifact.test.ts` asserting the built server answers `/api/chat` with Hono's 404 and still serves the Flue route; the retained browser network ledger from the outer witness; and a focused integration case in `apps/petrinaut-website/src/main/app/voice-interview/voice-preview.integration.test.ts` named `admits a Voice turn only through the Flue route`. -4. **Canonical visible and TTS output.** The materialized response selected for the admitted `submissionId` is the source for visible text and TTS input. Completed visible assistant text is preserved in part order; reasoning and non-speech parts are not promoted to spoken text. The exact string array sent for canonical speech equals the selected Brunch text, and no response-preparation or simplification generation call occurs. Oracle: `apps/petrinaut-website/src/main/app/voice-interview/canonical-speech.test.ts`, `openai-realtime-session.test.ts`, and the outer artifact comparison of canonical snapshot text to the recorded TTS request payload; the human witness confirms that playback begins but does not claim synthesized audio is a verbatim recording. -5. **Cancellation and abort stay distinct.** Barge-in, pause, or panel closure stops local playback/observation according to the existing Voice contract without rewriting or deleting canonical history. An explicit durable Stop action uses Flue's conversation-wide `abort()` when work is unsettled, and history/observation exposes an `aborted` settlement; an abort that loses the race to completion remains completed. Oracle: named local-versus-durable cancellation cases in `voice-turn-controller.test.ts` and `voice-preview.integration.test.ts`, plus the retained Voice event ledger and Flue settlement. -6. **Reopen resumes without replay.** Reopening the same selected conversation rehydrates its canonical messages and settlements from Flue, does not submit another user message, and does not automatically replay settled audio. An absent conversation, fatal 401/403, reconnecting stream, and settled conversation are visibly distinguishable. Oracle: a named `rehydrates the settled Voice turn without resubmission or playback` case over the SDK observation in `realtime-brunch-bridge.test.ts`, followed by the outer witness reopening the panel and comparing the second view with the same snapshot. -7. **Architecture and boundary integrity.** The built app still mounts `useBrunchAgent()` plus `useSdcpnPlugin()`, excludes the obsolete app-local stub agent, derives ownership from principal plus logical conversation id in exactly one guard, and reaches Flue locally through a same-origin protocol-preserving proxy rather than a newly public route. The transport package's runtime dependencies are exactly `ai` and `@flue/sdk`; it imports no `@flue/runtime`, core, plugin, or binding module. Oracle: `apps/brunch-agent/test/build-artifact.test.ts`, `apps/brunch-agent/test/agent-ownership.test.ts`, the transport case in `apps/brunch-agent/test/architecture/boundaries.integration.ts` (`transports consume their wire encoder and the public Flue client only — never core, a binding, or the runtime`), SDCPN packaging tests, and browser inspection of the claimed local route and headers. -8. **Real Voice witness and retained proof bundle.** With `yarn dev:brunch`, a human speaks one answer, sees exactly one matching user message, sees and hears the canonical Brunch response begin, interrupts playback once, exercises Stop on one unsettled turn, and reopens the original settled turn. Retain under `docs/evidence/implementations/mission-5-direct-voice-flue/` the witness record, sanitized Voice event ledger, network route summary, canonical Flue snapshot, settlement outcomes, source/build commit, and hashes. Oracle: human adjudication against that bundle; mocked browser or server-only evidence cannot satisfy this leaf. -9. **Focused repository verification and truthful docs.** Brunch app, website, core/plugin, transport, and Petrinaut checks pass; end-user and operator prose describes the single route that actually shipped and preserves the distinction between canonical text and generated audio; no surviving prose or comment names `/api/chat` as a Brunch door. Oracle: `yarn exec turbo run lint:tsc lint:eslint test:unit build --filter @apps/brunch-agent --filter @apps/petrinaut-website --filter @hashintel/petrinaut --filter @hashintel/brunch-agent --filter @hashintel/brunch-agent-plugin-sdcpn --filter @hashintel/brunch-agent-transport-aisdk`, `yarn workspace @local/petrinaut-arch-docs lint:arch-docs` if a Petrinaut architectural boundary changes, `rg -n "api/chat" apps/brunch-agent libs/@hashintel/brunch-agent/packages apps/petrinaut-website/src/main/app/local-storage-demo` returning only the stock Petrinaut route and frozen Mission 4 evidence, inspection of `apps/petrinaut-website/README.md` and `libs/@hashintel/petrinaut/docs/ai-assistant.md`, and a patch changeset if the published Petrinaut package changes. +The mission completes only when the demo script works for this fixture and these obligations are closed: stale fixture/workpiece/document revision refusal, duplicate tool delivery, read/write failure visibility, unsupported meaning, no-op mutation honesty, partial-save behavior, second-tab rehydration, separate identity integrity, and one negative mutation case. Do not close every consequential-element provenance link, remote task replacement, broad scenario coverage, or repeated automatic projection here; those become Mission 7 or Mission 9 obligations only after this tracer exposes a finite peer set and load-bearing seams. -## Constraints +Every final leaf has a discriminating oracle: -- Preserve Mission 4's current core/plugin/app composition and authored skill packaging. Voice reconciliation must never restore the deleted app-local `ChatAgent`, concise stub prompt, YAML plugin machinery, or a second model-facing agent. -- Flue history is the sole canonical conversation record. Voice owns media capture, provisional display, turn finalization, TTS, playback, and local interaction state; it owns no durable transcript and may not splice into stock-assistant history. -- Use `@flue/sdk`/`@flue/react` directly for shell-facing conversation transport. No adapter may re-specify Flue offsets, retries, materialization, settlement, or recovery. The browser `ChatTransport` is a projection over the public `FlueClient` (`send()`, `wait()`/`observe()`, `history()`), never a second HTTP client; it reads chunks only through the SDK's `onEvent`/observation surfaces. -- One product route. `/agents/chat/:instanceId` behind `agentOwnershipGuard` is the sole door for typed, Voice, diagnostic, and evaluation traffic; no route, handler, or package may accept a conversation turn over another protocol. The stock Petrinaut `/api/chat` (the website's own OpenAI function) is untouched and must not be borrowed. -- The Petrinaut panel remains on `useChat`; the AI SDK is its rendering contract, supplied a transport by the host. Do not rewrite the panel onto `@flue/react`, and do not add a second transcript store beside `useChat`'s messages for the typed panel. -- Submit only the validated finalized answer. Provisional transcription and audio remain ephemeral. One Voice finalization causes at most one `send()` call; because Flue 2.0.3 does not accept a caller idempotency key on `send()`, ambiguous admission must remain visible and must not trigger an automatic retry. -- Brunch owns canonical response content. TTS may synthesize audio from exact selected text, but no second model may summarize, shorten, paraphrase, or select replacement wording for the tracer. -- Local playback cancellation, local observation cancellation, HTTP request cancellation, and Flue's conversation-wide durable abort are distinct operations and must remain distinguishable in code, UI state, evidence, and tests. -- The current browser-minted local principal is an ownership discriminator, not trusted authentication. The outer proof is local and same-origin; it must not expose `/agents/chat/:id` publicly or claim production identity, authorization, CORS, deployment, or recovery. -- `@hashintel/brunch-agent-transport-aisdk` survives only as the browser-side adapter and the home of the projector, snapshot projection, and header names. Its runtime dependencies are `ai` and `@flue/sdk`; it never imports `@flue/runtime`, core, a plugin, or a binding, and client-tool names reach it as caller-supplied options. The boundary test's transport gate is amended to say exactly that — this is the one accepted topology-gate change of the recut. -- Do not mount the suspended `brunch_ask` capability merely to preserve the divergent preview stack. Re-entry requires observed plain-turn correlation strain and an owner decision consistent with the structured-question planning contract. -- External Voice branches and their issues/PRs remain read-only evidence. Port only behavior that serves this mission, preserve relevant provenance in commits, and do not rewrite, close, or represent those records as accepted wholesale. -- Record admission, first canonical text, first TTS request/audio, and settlement latency without transcript, prompt, tool, SDP, audio, credential, or response-body content in ordinary telemetry. -- No implementation begins until this authority cut is committed separately. Material changes to this contract require owner review and another focused authority commit before dependent implementation. +1. **The prepared fixture is honest and sufficient for this narrow test.** The committed fixture manifest and a cold-reader adjudication identify its test-authored source, process spine, constrained crew, release policy, quantity context, explicit unknown, prepared net meaning, and non-claims. The reader must do this without transcript archaeology. +2. **One evidence turn maintains the Markdown workpiece.** A production-agent fixture integration retains the exact Flue snapshot and mechanically recovers the latest `runbook-ir` block with source message id and SHA-256. Before/after adjudication must find the supplied contextual quantity, retained crew/release meaning, retained unsupported context, and no invented fact or hardened unknown. +3. **The real browser executes a correlated Petrinaut read and write.** Focused plugin/transport tests prove that `getLatestNetDefinition` and the selected `addArc` schema come mechanically from Petrinaut's canonical contracts, fixture mode advertises only the selected operations, duplicate result delivery does not apply the mutation twice, rejected input remains visible, and a mutation that would change nothing is reported as a no-op rather than as a change. The browser witness must retain tool name, call id, parsed input, execution output, resumed signal, and resulting canonical definition; a headless callback alone does not pass. +4. **The document change is meaningful rather than merely accepted.** A structural comparison proves there was no standard input arc from `Dispatch crew available` to `Start final inspection` before the turn and exactly one weight-1 arc afterward, while `Sign-off` still returns the crew and the prepared net remains non-empty. The changed workpiece retains the reservation/release meaning and unresolved timing/recovery. Parser/schema acceptance or a disconnected convenience element fails. +5. **The settled witness cannot bless partial state.** A focused failure test injects history/workpiece-recovery failure, rejected `addArc`, or missing/duplicate result correlation and shows that the prior settled manifest remains selected while the failure and any partial state are inspectable. Do not invent a localStorage failure interface solely to satisfy this leaf. +6. **A second tab resumes the same fixture.** With `yarn dev:brunch` running, the recorded browser protocol opens the stable selector in Tab A, performs and settles the turn, then opens it in Tab B. The witness compares fixture id, document id and canonical definition hash, Flue conversation id and history, latest workpiece source/hash, and absence of duplicate submission before one read or continuation succeeds in Tab B. Tab B opened against a stale or mismatched revision must refuse visibly rather than silently select older artifacts. +7. **The cut has not smuggled in the later architecture.** Public-schema and dependency inspection finds only fixture identity/revision links, Markdown recovery metadata, and canonical Petrinaut payloads—no closed process ontology, typed capture-to-workpiece reducer, graph database, second conversation log, or general projection engine. -### Expected touched paths +Verification proceeds inside-out but closure requires the outer boundary: -```text -~ libs/@hashintel/brunch-agent/packages/transport-aisdk/src/ delete the HTTP handler; add ChatTransport factory over FlueClient; receive ui-stream + snapshotToUiMessages + headers -~ libs/@hashintel/brunch-agent/packages/transport-aisdk/package.json deps become ai + @flue/sdk; drop valibot if unused -~ libs/@hashintel/brunch-agent/packages/transport-aisdk/test/ replace chat-handler/golden with transport + projector + snapshot tests -~ apps/brunch-agent/test/architecture/boundaries.integration.ts amend the transport gate -- apps/brunch-agent/src/http/petrinaut-chat.ts server-side door removed -- apps/brunch-agent/src/conversation/ui-stream.ts moves into the transport package -~ apps/brunch-agent/src/conversation/transcript.ts snapshotToUiMessages moves out; formatFlueTranscript stays for the CLI -~ apps/brunch-agent/src/http/routes.ts, local-origins.ts drop PETRINAUT_CHAT_ROUTE and the /api/chat proxy; proxy /agents/chat/* -~ apps/brunch-agent/src/app.ts remove the /api/chat mount and app-transport closure -~ apps/brunch-agent/package.json drop the `ai` devDependency if nothing else uses it -- apps/brunch-agent/test/petrinaut-chat.test.ts, petrinaut-chat.integration.ts, petrinaut-chat-result.ts, flue-ui-stream.test.ts re-expressed against the browser transport / relocated -~ apps/brunch-agent/test/build-artifact.test.ts, local-dev-origins.test.ts single-route assertions -~ apps/brunch-agent/petrinaut-local.vite.config.ts same-origin Flue-route proxy for the local real surface -~ apps/petrinaut-website/src/main/app/local-storage-demo/ createFlueClient composition, browser transport, delete use-flue-chat-history -~ apps/petrinaut-website/src/main/app/voice-interview/ direct Flue admission, materialized response, cancellation, reopen -~ apps/petrinaut-website/package.json add @flue/sdk -~ yarn.lock workspace dependency update -? apps/brunch-agent/src/http/ownership.ts, src/conversation/identity*.ts only if the identity-contract home (fog-line) moves -? libs/@hashintel/petrinaut/src/ui/ smallest public panel seam only if host composition cannot remain local -~ apps/petrinaut-website/README.md operator-facing route and preview behavior -~ libs/@hashintel/petrinaut/docs/ai-assistant.md user-visible Voice behavior -~ libs/@hashintel/brunch-agent/MISSION.next.md reconcile the production-door, restricted-ingress, and adapter-removal statements -+ libs/@hashintel/brunch-agent/docs/evidence/implementations/mission-5-direct-voice-flue/ retained proof bundle -? .changeset/ one patch changeset only if the published Petrinaut package changes -``` +- **Inner:** fixture parsing and prepared-label checks; identity separation; workpiece recovery/hash; canonical `addArc` schema and exact before/after edge assertion; idempotent client-tool result handling; settled-witness refusal. +- **Middle:** the built production `ChatAgent` and `/api/chat` path hydrate the prepared Flue conversation, accept the evidence turn, recover the revised workpiece, and carry actual browser-tool calls/results. Run the focused workspaces through root Turbo (`test:unit`, `lint:tsc`, `lint:eslint`, and `build` where changed). +- **Outer:** the two-tab `yarn dev:brunch` witness above, with retained before/after artifacts. +- **Semantic:** a cold human accepts fixture/workpiece honesty and the workpiece-to-document correspondence. The oracle may falsify those claims; it may not rewrite the interaction or architecture policy. +- **Product:** a product manager who did not watch the work runs the demo script from the imperative without an engineer and notices the advance. This is the last check before close, after the readiness gate; it is not a substitute for the oracles above. -## Fog-line +## Constraints -- How a finalized Voice answer enters Flue. Two shapes are admissible: **(B, preferred)** Voice submits through the panel's own Flue `ChatTransport` (`useChat.sendMessage` → `send()`), so the panel's `useChat` messages remain the single visible store and Voice's `observe()` shrinks to selecting completed canonical text for TTS — or reads the panel's completed assistant message and drops `observe()` entirely; **(A)** Voice calls `send()` directly and keeps its own `observe()` state, with the panel rehydrating. Start with B; fall back to A only if the existing hold-while-streaming, epoch, or TTS-correlation semantics demonstrably strain under the panel's transport, and record the observed strain. Either way, one finalization is one `send()`, and if the chosen shape would create two mutable transcript stores or a second custom reducer, stop and reorient at the panel boundary. -- The smallest honest home for the browser-safe principal + logical-conversation-id → Flue-instance-id contract and the two ownership header names. `apps/brunch-agent/src/conversation/identity-web.ts` proves the algorithm; the website must not gain an app-to-app source import, and core must not own HTTP header names. The leading candidate is the repurposed transport package, which already exports the principal header; a website-local copy pinned by an equality test against the app is the fallback. Do not create a new package to hold two strings and a hash. -- Whether `wait(admission, { onEvent })` alone gives the browser transport a clean finite per-turn stream, or whether the panel needs `observe()` for reconnect during a turn. `wait()` rejects on failed/aborted settlement and on `terminal_event_missing`; the transport must map those to `error`/`abort` chunks rather than throwing past `useChat`. The first real disconnect mid-turn decides; do not pre-build reconnect machinery. -- Whether `reconnectToStream` should return `null` (observation-only rehydration, the current behavior) or resume an unsettled submission after reload. Start with `null` plus SDK observation; re-enter only if the witness observes a lost in-flight turn. -- The exact subset of PRs #9496, #9507, and #9512 to port after semantic comparison with the current branch. Their useful Voice state-machine behavior is evidence; their app-local agent topology, temporary ask shim, and generative preparation are not presumed requirements. -- The bounded speech-selection policy if the exercised Brunch response contains multiple completed text blocks or an interactive part. Begin with canonical completed visible text in order; if this produces duplicate, misleading, or unspeakable output, retain the mismatch and seek a Brunch-owned deterministic presentation rule rather than another generator. -- Whether the existing Stop affordance can express both local Voice interruption and explicit conversation-wide durable abort without misleading the user. The first real race decides the smallest UI distinction. -- Whether a same-origin local proxy can carry every SDK history/SSE/send/abort route unchanged. A crisp protocol or middleware blocker permits the thinnest route correction; it does not permit rebuilding the AI SDK adapter under another name. +- Keep fixture id, Flue conversation id, latest workpiece source/revision, and Petrinaut document id/revision distinct and explicitly linked. One id must not impersonate all lifecycles. +- Flue history remains the canonical conversation log. Browser message caches and fixture artifacts are projections or evidence, never a second authority. +- Markdown remains the semantic workpiece. Recover its full latest version; do not introduce a comprehensive typed domain IR to make fixture lookup convenient. +- Projection consumes the current workpiece. The transcript may establish provenance and help recover that artifact but may not become the primary construction IR. +- Petrinaut owns canonical schemas, browser validation, mutations, and document state. Brunch imports or mechanically derives those contracts and does not hand-copy their field shapes. +- Client tools execute against the active bound browser document and return the original tool-call id. Stale, duplicate, cross-document, malformed, failed, and no-op outcomes fail visibly. +- Publish a new settled fixture witness only after the claimed Flue snapshot, workpiece revision, and document state can all be inspected. The witness does not make the browser and Flue stores transactional. Do not invent explicit save or cross-store transaction machinery without an observed recovery failure requiring it. +- Preserve the accepted Mission 4 `useBrunchAgent()` plus `useSdcpnPlugin()` architecture. The app composes; the plugin owns SDCPN operation semantics; the transport carries results; the UI executes them. +- Keep construction tools unavailable to unrelated ordinary conversations unless the real path proves the smallest safe selection can be scoped to this fixture/mode. Stock-assistant behavior must remain unchanged when Brunch is absent or unselected. +- The fixture is local and deliberately prepared. Make no remote durability, capture provenance, automatic projection, behavioral execution, or concurrent collaboration claim. +- No HASH Graph, Temporal, Redis, new database, observer, workflow engine, second agent, second event log, or closed workpiece schema. +- Update the affected Petrinaut user guide in the same change if the selector, save/resume behavior, or panel behavior becomes user-facing; add one Petrinaut changeset only if a published Petrinaut package changes. -## Stop or reorient +## Fog-line -Stop and surface the evidence if the implementation creates a second conversation authority, keeps or re-adds any server-side route that accepts a conversation turn over a non-Flue protocol, submits provisional STT, automatically retries an ambiguous admission, rewrites canonical text through another model, hand-rolls stream recovery, computes offsets, restores the old stub agent, or activates `brunch_ask` without observed need and owner approval. +- Whether the selected shallow `addArc` schema survives the provider-visible Flue carrier and results in exactly one browser mutation without reopening the broader nested-schema problem. +- The least safe way to expose canonical `getLatestNetDefinition` plus `addArc` in a fixture conversation while retaining the headless-only guard for broader construction. +- How to prepare canonical Flue history reproducibly without pretending test-authored assistant content was model-produced; the preparation route and authorship must survive in the manifest. +- Whether the latest `runbook-ir` message id and hash are sufficient workpiece revision identity or the two-tab consumer exposes a need for a separate persisted workpiece artifact. +- Whether Mantine/localStorage synchronization plus the active `PetrinautDocHandle` is sufficient for the same-browser two-tab witness, and which document hash/revision signal best distinguishes settled from stale state. +- Whether the known provider-visible nested-schema failure is absent for the selected flat mutation. Do not generalize one success to nested construction classes. +- Which of history recovery, invalid `addArc`, or duplicate result delivery is the cheapest discriminating failure for the settled-witness rule after the first real path reveals the ordering. -Stop if the browser transport cannot preserve the current client-tool resume semantics (completed client-tool parts on the referenced assistant message → one signal send → continuation of the same assistant message id) without a server-side helper; that is evidence the resume contract needs redesign, not permission to reintroduce `/api/chat`. +Resolve these at the named production/browser boundaries. Clarifying prose alone does not clear them. If a choice changes the accepted interaction policy, architectural ownership, or proof claim, return it to the owner and amend this authority before implementation continues. + +## Stop or reorient -Stop at the boundary if direct Flue state cannot reach the existing visible panel without duplicated mutable history; decide the UI ownership seam before adding synchronization machinery. Stop if local cancellation accidentally aborts durable work, explicit Stop only cancels a browser request while the provider keeps spending, a stale response is spoken after conversation/epoch change, or reopen resubmits or replays a settled turn. +Stop and surface evidence if: -Stop rather than widen if the real route requires public unauthenticated exposure, production identity work, remote deployment, Petrinaut mutation tools, workpiece/projection state, or a whole assistant rewrite. Those are not hidden prerequisites to this transport tracer. +- fixture preparation requires pretending a Mission 4 candidate exists or hides test-authored/model-authored boundaries; +- the path conflates fixture, conversation, workpiece, and document identities or creates a second canonical conversation history; +- the agent rereads transcript prose as its primary projection input because the current Markdown workpiece cannot carry the needed meaning; +- parser/schema acceptance, document non-emptiness, or a disconnected convenience element is offered as semantic correspondence; +- client-tool results lose their original call id, can target the wrong document, or duplicate execution on retry/reload; +- a partial or failed write advances the settled witness, or second-tab reopening silently selects stale/mismatched artifacts; +- exposing one browser mutation requires mounting an unrestricted construction surface for every ordinary conversation; +- the selected provider/Flue schema cannot faithfully carry the least meaningful mutation—record the crisp blocker rather than hand-copying Petrinaut schemas or widening into Mission 9; +- the tracer needs a closed ontology, typed claim ledger, general projection engine, distributed transaction, or new durable service before a concrete failure demonstrates that need; or +- work widens into capture-backed why/provenance, automatic projection breadth, remote deployment durability, concurrent collaboration, or broad scenario readiness. ## Deferred -- **`useChat` panel removal:** with the server-side door gone, the AI SDK survives only as the Petrinaut panel's rendering contract behind a host-supplied transport. Whether Petrinaut ever drops `useChat` is a Petrinaut product decision, not a Brunch transport question; Brunch carries no further obligation here. -- **Restricted-ingress rule for the Flue route:** Mission 8's landed contract denied `/agents/chat/:id` publicly and routed restricted traffic through `/api/chat`. This recut makes the Flue route the only product route, so that rule must be re-expressed as the FE-1423 gates applying directly to `/agents/chat/:id`. Record the re-expression in `MISSION.next.md`; the release/deployment gate owns its enforcement. -- **Structured questions:** core-owned question semantics, binding, rendering, correlated reply, and resumed tool execution remain in the shared future-planning record. Re-enter when plain Voice turns demonstrably cannot preserve a required interaction. -- **Broader Voice quality:** multi-turn barge-in tuning, long-response ergonomics, optional deterministic spoken presentation, accessibility breadth, and response optimisation re-enter after measured strain on the direct canonical route. -- **Remote/public operation:** trusted identity and authorization, origin policy, hosted Flue reachability, rate/spend controls, replacement recovery, and remote observability remain with the Mission 8 release/deployment gate or a separately cut successor. -- **Product-data work:** prepared workpiece/Petrinaut viability remains Mission 6; capture-backed review remains Mission 7; automatic traceable projection remains Mission 9. This mission carries no document mutation or provenance claim beyond canonical conversation history. -- **Host breadth:** stock/Brunch picker behavior, session switching beyond the selected local Brunch conversation, and HASH embed parity wait for the first visible consumer that makes them load-bearing. +Mission 7 still owns capture-backed visible why/provenance and broken-link refusal after this fixture is viable. Mission 9 still owns repeatable automatic projection, broader nested provider-schema classes, stable generated-element derivations, repeated/changed-input behavior, and the breadth of semantic correspondence. Remote replacement durability and release infrastructure remain in the historical Mission 8 handoff. Multi-tab concurrent editing, a durable cross-store commit protocol, explicit localStorage failure injection and refusal of a concurrent write from a tab holding an older revision (distinct from the readiness-gate refusal to reopen onto stale or mismatched artifacts), and promotion of this prepared fixture into a reusable product seed re-enter only if the automatic mirror loses or overwrites state, a later consumer requires atomic bundle identity, or this mission otherwise exposes concrete strain; their current planning home and re-entry conditions remain in [`MISSION.next.md`](MISSION.next.md) and the linked Mission 7/9 drafts. diff --git a/libs/@hashintel/brunch-agent/MISSION.next.md b/libs/@hashintel/brunch-agent/MISSION.next.md index c3b7df518b9..2697366bd15 100644 --- a/libs/@hashintel/brunch-agent/MISSION.next.md +++ b/libs/@hashintel/brunch-agent/MISSION.next.md @@ -1,8 +1,8 @@ # Brunch future mission spine -> Canonical future-planning spine, shared frame, and backlog index only. This file is not execution authority and authorizes no implementation. [`MISSION.md`](MISSION.md) is the live Mission 5 authority on this branch. Detailed provisional clusters are context repositories, not missions; re-evaluate and convert one into `MISSION.md` on its own branch before acting. +> Canonical future-planning spine, shared frame, and backlog index only. This file is not execution authority and authorizes no implementation. [`MISSION.md`](MISSION.md) is the sole live Mission 6 authority on this branch, which is stacked on the live Mission 5 authority of the FE-1574 branch. Detailed provisional clusters are context repositories, not missions; re-evaluate and convert one into `MISSION.md` on its own branch before acting. -This spine and its five linked drafts form one future-planning record. Keep each consequential meaning in one authoritative planning home: shared contracts and unallocated concerns live here; mission-specific detail lives in its draft. A spine pointer is not a second contract. Material omitted from a future cut returns to this record at full fidelity, and the consumed draft is removed. +This spine and its four linked drafts form one future-planning record. Keep each consequential meaning in one authoritative planning home: shared contracts and unallocated concerns live here; mission-specific detail lives in its draft. A spine pointer is not a second contract. Material omitted from a future cut returns to this record at full fidelity, and the consumed draft is removed. ## Current authority and accepted spine @@ -10,15 +10,15 @@ Mission 4 closed on this branch by owner adjudication on 2026-09-03. The accepte A future Mission 4 close-out addendum requires its own issue, branch, PR, and mission authority. It may stack on this closed branch and own broader reliability/hardening if warranted, browser parity, fixture/seed promotion contracts, topology-neutral case allocation, contract/readiness sweeps, archive subtraction, and Mission 8 preparation. It also owns the observed S4 report-versus-immediate-ask decision unless a later numbered mission first makes it load-bearing: re-enter only when a real review must continue immediately or repeated gap-only reports create visible friction; preserve S3 restraint while testing S4 activation and asking under a fresh instrument. Its exact issue/name and minimum scope remain owner decisions; do not create another Mission 4 draft. -Mission 5 is now live on this branch under FE-1574 and owns the direct Voice/Flue transport cut; its full contract lives only in [`MISSION.md`](MISSION.md). Mission 6 remains independently cuttable from Mission 4 under its own issue, branch, PR, worktree, and mission authority: one deliberately prepared, honestly labelled fixture joins canonical conversation, session history, Markdown workpiece, and Petrinaut document; one browser-backed read/write change saves and resumes across tabs. Neither mission requires a Mission 4 full-run candidate, and neither is the other's prerequisite. +Mission 6 is now live on the FE-1575 branch under root [`MISSION.md`](MISSION.md): one deliberately prepared, honestly labelled fixture must join canonical conversation, session history, Markdown workpiece, and Petrinaut document through a browser-backed read/write change and cross-tab resume. Its consumed draft has been removed; its product-manager litmus, demo script, and readiness-gate completion bar live only in that authority. Mission 5 is live on the FE-1574 branch directly beneath this one and owns the direct Voice/Flue transport cut; its full contract lives only in that branch's root `MISSION.md`. Neither tracer requires a Mission 4 full-run candidate. The two were cut as independent siblings, but Mission 5's recut made the browser Flue `ChatTransport` the only door into a Brunch conversation and removed the `/api/chat` path Mission 6 had named as its departure point; the owner therefore corrected Mission 6 to consume Mission 5's landed transport, and this branch now stacks on Mission 5's committed typed-panel transport tracer. The earlier capture-backed provenance, automatic-projection, revision, and optimisation drafts remain later readiness/product advances. They are renumbered around the historical Mission 8 deployment track rather than forcing the two uncertainty-retiring tracers to inherit its unproved remote boundary. ```text M4 closed — core/plugin elicitation pattern accepted; S4 transition and full-run candidate deferred M4+ optional successor — broader hardening or source promotion only under separate authority -M5 live on this branch — direct Voice/Flue turn, canonical streamed reply, cancellation, and reopen -M6 resumable fixture tracer — conversation → Markdown workpiece → Petrinaut read/write → cross-tab resume +M5 live on FE-1574, beneath this branch — direct Voice/Flue turn, canonical streamed reply, cancellation, and reopen +M6 live on FE-1575 — conversation → Markdown workpiece → Petrinaut read/write → cross-tab resume over Mission 5's transport M7 capture-backed review — close selected-pair provenance breadth and visible why/refusal M8 deployment handoff — historical branch stopped after local application proof, before infrastructure deployment M9 automatic projection — broaden the proved fixture seam to repeatable traceable projection of one meaningful region @@ -26,16 +26,10 @@ M10 revision — ship bounded authorized reviewer revision and a scoped patch M11 optimisation — ship an accepted optimisation handoff after its consumer contract exists ``` -Every numbered product mission after the proof-of-life exception must pass the **product-manager litmus**: a product manager who did not watch the work must be able to notice that the product materially moved forward. Each mission therefore states, in its draft's visible-product-advance section, a release-note sentence, a demo script a product manager can run without an engineer, and the thing that was impossible before. Snapshots, manifests, event ledgers, and negative controls are oracles that belong in the evidence sections; they are not the visible advance. A mission is complete at its readiness gate, when the demo script works for the named scenario, not at the first green throughline tracer, which is an internal milestone inside the mission. Mission 5 names the Petrinaut Brunch panel's typed and Voice surface over one Flue route, with its litmus stated in the live [`MISSION.md`](MISSION.md#product-manager-litmus); Mission 6 names the stable fixture and browser Petrinaut document; Missions 7, 9, and 10 name the Petrinaut Brunch panel. Because Mission 8 stopped before remote deployment, those panel missions must name the deployment posture available at cut time, and a locally run panel is acceptable for the demo; a product-manager-noticeable claim must never depend on infrastructure that does not exist, while remote durability obligations stay in their readiness gates. Architecture, schema repair, fixtures, evaluation, rehearsal, and spikes may support the advance but cannot be the sole outcome. Parallel work means separate issue, branch, PR, worktree, and mission authority; it never means multiple live missions here. +Every numbered product mission after the proof-of-life exception must pass the **product-manager litmus**: a product manager who did not watch the work must be able to notice that the product materially moved forward. Each mission therefore states, in its draft's visible-product-advance section and then in its cut `MISSION.md` imperative, a release-note sentence, a demo script a product manager can run without an engineer, and the thing that was impossible before. Snapshots, manifests, event ledgers, and negative controls are oracles that belong in the evidence sections; they are not the visible advance. A mission is complete at its readiness gate, when the demo script works for the named scenario, not at the first green throughline tracer, which is an internal milestone inside the mission. Live Mission 5 names the Petrinaut Brunch panel's typed and Voice surface over one Flue route, with its litmus stated in the FE-1574 branch's live `MISSION.md`; live Mission 6 names the stable fixture and browser Petrinaut document, with its litmus stated in this branch's [`MISSION.md`](MISSION.md#visible-product-advance); Missions 7, 9, and 10 name the Petrinaut Brunch panel. Because Mission 8 stopped before remote deployment, those panel missions must name the deployment posture available at cut time, and a locally run panel is acceptable for the demo; a product-manager-noticeable claim must never depend on infrastructure that does not exist, while remote durability obligations stay in their readiness gates. Architecture, schema repair, fixtures, evaluation, rehearsal, and spikes may support the advance but cannot be the sole outcome. Parallel work means separate issue, branch, PR, worktree, and mission authority; it never means multiple live missions here. ## Successor mission précis -### M6 — Prove the Markdown/workpiece/Petrinaut loop - -Tracker projection: [FE-1575](https://linear.app/hash/issue/FE-1575/resume-one-brunch-workpiece-and-petrinaut-document-across-tabs). - -One honestly prepared fixture links a canonical conversation, session history, Markdown workpiece, and Petrinaut document; Brunch updates the workpiece, performs one meaningful browser-backed document change, saves, and resumes from a second tab. This can be cut immediately and independently of Voice. **Product-manager litmus:** Brunch edits the net you are looking at from the conversation, and the work survives closing the tab. Demo: open the demo fixture, say one new thing about the process, watch the net change, save, reopen in a second tab and continue. Previously impossible: Brunch only produced off-canvas net JSON for manual load. Complete at the [readiness gate](docs/mission-drafts/6-resumable-workpiece-petrinaut-fixture.md#readiness-gate-after-the-new-throughline), not at the first green mutation; see the [visible product advance](docs/mission-drafts/6-resumable-workpiece-petrinaut-fixture.md#visible-product-advance). - ### M7 — Make the demo net genuinely explainable Tracker projection: [FE-1573](https://linear.app/hash/issue/FE-1573/explain-one-prepared-petrinaut-net-from-exact-conversation-evidence), advancing stakeholder outcome [FE-1478](https://linear.app/hash/issue/FE-1478/provide-provenance-from-a-generated-net-back-to-the-requirements-graph). @@ -239,15 +233,14 @@ The deliberately provisional shared-interface names remain `EvidenceBackedWorkpi ## Detailed provisional clusters -Detailed mission-specific boundaries, tracer floors, readiness ratchets, risks, oracles, and stop conditions live only in these five context repositories: +Detailed mission-specific boundaries, tracer floors, readiness ratchets, risks, oracles, and stop conditions live only in these four context repositories: -- [Draft Mission 6 — resumable workpiece-to-Petrinaut fixture tracer](docs/mission-drafts/6-resumable-workpiece-petrinaut-fixture.md) - [Draft Mission 7 — capture-backed review](docs/mission-drafts/7-capture-backed-review.md) - [Draft Mission 9 — automatic traceable projection](docs/mission-drafts/9-traceable-projection.md) - [Draft Mission 10 — bounded reviewer revision](docs/mission-drafts/10-bounded-reviewer-revision.md) - [Draft Mission 11 — optimisation handoff](docs/mission-drafts/11-optimisation-handoff.md) -Do not create Mission 4 or Mission 8 drafts. Mission 5 is live here; Mission 6 remains an independent next cut that must become the sole live root `MISSION.md` in its own worktree. Mission 11 stays deliberately shallow until Chris and Yannis accept input artifacts, one optimisation question, scenario/parameter representation, execution boundary, expected result, and minimum credibility checks. +Do not create Mission 4 or Mission 8 drafts. Mission 5 is live on the FE-1574 branch beneath this one and is Mission 6's transport prerequisite; Mission 6 is live here and its authority exists only in root `MISSION.md`. Mission 11 stays deliberately shallow until Chris and Yannis accept input artifacts, one optimisation question, scenario/parameter representation, execution boundary, expected result, and minimum credibility checks. ## Unallocated backlog @@ -487,3 +480,5 @@ The owner subsequently changed the integration premise: Voice should use canonic ## 2026-09-03 product-manager litmus reframing Later on 2026-09-03 the owner replaced the "visible/usable proof" completion criterion with the product-manager litmus defined in the accepted spine above. The observed problem was that each précis pinned completion to an evidence bundle at the first green throughline tracer, which convinces a builder but is invisible to a product manager, and that Draft Mission 9 carried engineering internals in its visible-advance section. The change re-pins completion to each mission's readiness gate for the named demo scenario, moves oracles out of the visible-advance sections, expands Mission 7 from one element to every consequential element of the demo net, and names the deployment posture problem for Missions 7, 9, and 10. Mission 5 was live on its own branch and was not touched by that commit; on restack, the live branch adopted the litmus in [`MISSION.md`](MISSION.md#product-manager-litmus), naming Stop-that-really-stops and one shared typed/spoken conversation as its product-manager-noticeable advance and its single-route consolidation as internal sequencing. Mission-specific detail lives in the affected drafts' `Visible product advance` and `Throughline proof floor` sections and in the [draft README](docs/mission-drafts/README.md). + +Mission 6 had been cut into root [`MISSION.md`](MISSION.md) on the FE-1575 branch from the pre-litmus draft earlier the same day. That cut was recut on restack rather than left as it stood: its proof section had named the evidence bundle (selector, manifest, snapshots, revisions) as the visible proof artifact and read as if the first green two-tab pass were completion. The recut moves the release note, demo script, and previously-impossible statement into the imperative, names the readiness gate as the completion bar, keeps the seven discriminating oracles as builder evidence, and records the local-only demo posture explicitly. No Mission 6 draft remains here. diff --git a/libs/@hashintel/brunch-agent/docs/mission-drafts/6-resumable-workpiece-petrinaut-fixture.md b/libs/@hashintel/brunch-agent/docs/mission-drafts/6-resumable-workpiece-petrinaut-fixture.md deleted file mode 100644 index ce5541ecd89..00000000000 --- a/libs/@hashintel/brunch-agent/docs/mission-drafts/6-resumable-workpiece-petrinaut-fixture.md +++ /dev/null @@ -1,164 +0,0 @@ -# Draft Mission 6 — Resumable workpiece-to-Petrinaut fixture tracer - -> Draft cluster only. Not execution authority. Do not implement until this cluster is re-evaluated and cut into `MISSION.md`. - -## Cold-start reads - -- [FE-1575](https://linear.app/hash/issue/FE-1575/resume-one-brunch-workpiece-and-petrinaut-document-across-tabs) — tracker projection for this future branch mission; the eventual branch `MISSION.md` remains execution authority. -- [`../../MISSION.md`](../../MISSION.md) — live Mission 5 Voice authority on this branch; it supplies no Mission 6 execution authority and does not change Mission 4's explicit absence of a full-run candidate. -- [`../../MISSION.next.md`](../../MISSION.next.md) — shared workpiece, projection, evidence, and product constraints. -- [`../mission-archive/3-structurally-typed-runbook-to-headless-pn.md`](../mission-archive/3-structurally-typed-runbook-to-headless-pn.md) and [`../evidence/implementations/fe-1525-headless-runbook-pn.md`](../evidence/implementations/fe-1525-headless-runbook-pn.md) — accepted workpiece viability, hermetic callback route, and failed real-model nested-schema carrier. -- [`../mission-archive/4-core-plugin-elicitation-proof-of-life.md`](../mission-archive/4-core-plugin-elicitation-proof-of-life.md) — accepted core/plugin architecture and exact proof exclusions. -- [`../../packages/plugin-sdcpn/src/flue.ts`](../../packages/plugin-sdcpn/src/flue.ts), [`../../packages/plugin-sdcpn/src/tools/petrinaut-construction.ts`](../../packages/plugin-sdcpn/src/tools/petrinaut-construction.ts), and Petrinaut's canonical AI/action schemas — current read and bounded construction capabilities. -- [`../../../../../apps/brunch-agent/src/conversation/client-tools.ts`](../../../../../apps/brunch-agent/src/conversation/client-tools.ts), [`../../../../../apps/brunch-agent/src/conversation/ui-stream.ts`](../../../../../apps/brunch-agent/src/conversation/ui-stream.ts), and the current browser host — existing client-tool carriage and result correlation; reuse semantics without requiring the old chat UI. -- Flue `FlueClient` documentation for stable conversation history, observation, submission reattachment, and tool-part materialization. - -## Visible product advance - -**Release note:** Brunch edits the Petrinaut net you are looking at from the conversation, and your work survives closing the tab. - -**Demo script (no engineer present):** open the stable demo fixture; the canonical Brunch conversation, current Markdown workpiece, and associated Petrinaut document come back together. Tell Brunch one new realistic thing about the process. Watch the workpiece update and a meaningful change appear in the live net. Save. Open the same fixture in a second tab and continue the conversation from the saved state. - -**Previously impossible:** Brunch only produced off-canvas net JSON for manual load; nothing it did touched the live document or survived a reload. - -The fixture may be deliberately prepared. It need not be a complete persona-produced Mission 4 artifact, a promoted quality baseline, or proof of comprehensive provenance. Prepared status, authored material, limitations, and any model-produced updates remain explicit, and the demo script says so out loud. - -**Completion:** the mission is done when a product manager can run the demo script end to end at the readiness gate below, not when the first browser mutation lands. - -## Contract stratum - -Close the **single-fixture viability stratum** for these two transformations and their resumable product boundary: - -```text -canonical conversation evidence → maintained Markdown workpiece -maintained Markdown workpiece → meaningful Petrinaut read/write change -``` - -The fixture has separate stable identities for the demo case, conversation, current workpiece revision, and Petrinaut document revision. One id must not impersonate all four lifecycles. A small manifest records their relationships, exact prepared inputs, current coherent bundle revision, and hashes or revision tokens needed to detect stale state. - -The minimum fixture contains one process spine, one shared or constrained resource, one decision/policy, one contextual quantity, one explicit unknown, and enough meaning to change a small non-empty net region. It does not require a comprehensive typed domain IR, assertion-card ontology, graph database, or full provenance ledger. - -## Boundary crossings and current throughline hypothesis - -```text -stable demo fixture id -→ resolve conversation id + workpiece revision + Petrinaut document id/revision -→ hydrate canonical Flue history and current Markdown workpiece -→ one realistic evidence turn updates the workpiece at an explicit phase boundary -→ Brunch reads current Petrinaut state through a browser-owned client tool -→ SDCPN skill interprets the current workpiece, not the transcript as projection IR -→ Brunch requests the least canonical Petrinaut mutation(s) -→ browser validates and executes against the bound document -→ correlated client-tool result resumes the same Flue conversation -→ verify meaningful non-empty state -→ publish a new coherent fixture revision only after workpiece and document saves succeed -→ second tab resolves and resumes that revision -``` - -A partial save remains visible and does not advance the fixture's current coherent revision. The first tracer does not require simultaneous multi-tab collaboration or a distributed transaction service. - -## Throughline proof floor - -For one deliberately prepared fixture: - -1. a cold reader can reconstruct the selected operational spine and distinguish supplied evidence, agent inference/assumption, and the explicit unknown in the current Markdown workpiece; -2. one new realistic conversation turn produces an inspectable workpiece revision without erasing the unknown or unsupported meaning; -3. through the real browser client-tool boundary, Brunch reads the associated Petrinaut document and applies one meaningful supported change derived from the current workpiece; -4. canonical Petrinaut state is non-empty and visibly corresponds to the selected meaning; and -5. after save, a second tab opens the same fixture id, observes the same settled conversation/workpiece/document revision, and successfully continues or reads it without duplicate submission or identity drift. - -One pass through those five steps is the first internal milestone, not mission completion. The retained oracles are the stable demo URL or fixture selector plus the before/after fixture manifest, exact Flue snapshot, Markdown workpiece revisions, and canonical Petrinaut document revisions; they are evidence for the builder, not the visible advance. This proves viability, not automatic full-net projection, selected-pair provenance breadth, remote replacement durability, concurrent editing, or Mission 3/4 quality superiority. - -## Readiness ratchet - -### Inherited stratum closure - -- Consume Mission 4's accepted `useBrunchAgent()` + `useSdcpnPlugin()` architecture and no broader quality claim. -- Consume Petrinaut-owned schemas/mutations mechanically; parser acceptance alone remains vacuous. -- Treat Flue history as canonical and client-tool results as correlated execution evidence. -- Preserve the Mission 3 failure: provider-visible nested mutation shapes are unproved and may force a smaller first mutation or a crisp upstream blocker. - -### Readiness gate after the new throughline - -This gate is the mission's completion bar: the demo script above must work for the named fixture. Before accepting this single-fixture capability, close stale fixture/workpiece/document revision refusal, duplicate tool delivery, read/write failure visibility, unsupported meaning, no-op mutation honesty, partial-save behavior, second-tab rehydration, separate identity integrity, and one negative mutation case. Do not close every consequential-element provenance link, remote task replacement, broad scenario coverage, or repeated automatic projection here; those become Mission 7 or Mission 9 obligations only after this tracer exposes a finite peer set and load-bearing seams. - -## Candidate evidence and oracles - -| Claim leaf | Candidate oracle | -| --- | --- | -| Prepared fixture is honest and minimally sufficient | Frozen manifest plus cold-reader adjudication identifies the spine, resource, policy, quantity, unknown, authorship, and preparation route. | -| Conversation evidence can maintain Markdown | Before/after workpiece inspection against the exact Flue snapshot detects invention, hardening, lost prior meaning, and lost unknowns. | -| Browser executes real Petrinaut read/write tools | Production-boundary integration records tool call ids, canonical parsed inputs, execution outcomes, correlated result signals, and current document state. | -| Change is meaningful | Human comparison binds one workpiece meaning to a visible canonical type/parameter/place/transition/arc change appropriate to the fixture; non-empty/parser-valid alone fails. | -| Save is coherent | Injected workpiece-save or document-save failure leaves the prior current bundle revision selected and exposes the partial result for recovery. | -| Second tab resumes stable state | Open the same stable fixture selector after save and compare conversation id/history, workpiece revision/hash, document id/revision, and canonical definition before continuing. | -| No typed domain IR was smuggled in | Public-schema and dependency inspection finds only fixture identity/revision links and canonical Petrinaut payloads, not a closed process ontology or typed capture-to-workpiece model. | - -## Verification approach - -- **Inner:** fixture-manifest parse/version/stale checks, explicit identity separation, coherent-revision publication, idempotent client-tool result handling, and canonical Petrinaut mutation tests. -- **Middle:** drive the production Brunch agent through Flue, update the Markdown artifact, execute actual browser callbacks against the fixture-bound Petrinaut instance, and retain before/after artifacts plus one injected failure. -- **Outer:** from the real demo route or equivalent product selector, perform the update/save in Tab A and reopen/continue from the same fixture in Tab B. A headless callback alone does not establish this mission. -- **Semantic:** a cold human judges whether the workpiece remained honest and the changed net region corresponds to it. - -## Inputs and joins - -- This mission may cut directly from Mission 4 and run independently of the direct Voice mission. Typed text is sufficient for its first tracer; Voice can later become another input modality to the same canonical conversation. -- An owner selects one deliberately prepared fixture and records its non-claims. No full Mission 4 candidate or new persona campaign is prerequisite. -- Mission 7 inherits this fixture only if it needs to close capture-backed why/provenance breadth. Mission 9 inherits the browser mutation and semantic-projection seam only if the tracer proves them viable. -- Mission 8's local deployment artifact is terrain, not a prerequisite for a local two-tab viability proof and not evidence of remote durability. - -## Risks and assumptions - -- If a realistic prepared conversation/workpiece cannot support one meaningful mutation without richer typed structure, record the exact lookup, identity, or ambiguity strain before adding any schema. -- If existing per-action provider schemas cannot carry the required nested mutation, reduce to the smallest meaningful supported action only if semantic correspondence survives; otherwise stop with the crisp provider/Flue schema blocker. -- If coherent save cannot span existing workpiece/document stores, the least fixture-scoped commit marker may publish only after both writes; do not invent distributed transactions before a failure demonstrates the need. -- If direct browser tool servicing needs a transport abstraction, extract only tool-call/result correlation from the browser `ChatTransport` in `transport-aisdk` (recut Mission 5); do not require the chat UI or duplicate Flue observation. - -## Accepted constraints and guarded invariants - -- Separate demo, conversation, workpiece, and document identities with explicit links. -- One canonical Flue history; fixture log projections do not become another authority. -- Markdown is the semantic workpiece; no comprehensive typed domain IR. -- Projection consumes the current workpiece, not the transcript as primary IR. -- Petrinaut owns canonical schemas and mutation execution. -- Client tools execute in the browser against the bound document and return the original tool call id. -- Current coherent revision advances only after all required saves succeed. -- Prepared fixture status and unsupported meaning remain visible. -- No claim of remote replacement durability, automatic full projection, provenance breadth, or concurrent collaboration. - -## Cross-cutting obligations - -Preserve exact evidence attribution, visible failure, stable identity, workpiece sufficiency, semantic correspondence, stock-assistant isolation if it remains present, and same-change user documentation for the demo selector/save/resume behavior. - -## Expected touched paths - -```text -libs/@hashintel/brunch-agent/ -├── evaluations or docs/evidence fixture area + one prepared fixture and adjudication -├── packages/core/ ? only minimal workpiece/fixture contracts with a real second consumer -└── packages/plugin-sdcpn/ ~ least read/write capability and guidance needed by the tracer -apps/brunch-agent/ -├── src/agents/chat-agent/ ~ mount accepted fixture read/write path -├── src/conversation/ ~ client-tool correlation without UI-message authority -└── test/ + real Flue/browser-tool integration -libs/@hashintel/petrinaut-core/ ~ canonical contracts only if a source defect is found -libs/@hashintel/petrinaut/src/ ~ stable fixture resolution, save/resume, browser tool execution -``` - -## Fog-line - -- The exact prepared scenario and smallest meaningful document mutation. -- Where the fixture manifest and current coherent-revision marker belong. -- The current Petrinaut document persistence/revision API and whether the demo route already has a stable selector. -- Whether workpiece Markdown is a file, Flue data part, or product document for this tracer; choose the least real persistence boundary that supports two-tab reopen. -- The least browser host for direct Flue client-tool servicing after removal or bypass of the old assistant UI. -- The exact negative save/mutation case and acceptable local-only durability claim. - -## Stop or reorient - -Stop if the tracer requires pretending a Mission 4 candidate exists, makes a prepared fixture look model-produced, conflates all ids, treats parser validity as meaning, submits client-tool results without original correlation, advances the current bundle after a partial save, uses transcript text as the projection IR, or introduces a closed domain ontology before observed strain. Stop at provider-schema or host-persistence blockers rather than widening into Mission 7/9 readiness work. - -## Carried evidence and rejected alternatives - -Mission 3 showed that a Markdown workpiece can be useful and that a hermetic callback can build canonical non-empty state, while falsifying the exercised real-model nested-schema carrier. Mission 4 established capability composition but produced no full-run candidate. This mission intentionally joins those facts with a prepared fixture to test viability before requiring promoted-source quality, complete provenance, or a generalized semantic model. diff --git a/libs/@hashintel/brunch-agent/docs/mission-drafts/7-capture-backed-review.md b/libs/@hashintel/brunch-agent/docs/mission-drafts/7-capture-backed-review.md index 11a1e320719..07ab3f6ca0c 100644 --- a/libs/@hashintel/brunch-agent/docs/mission-drafts/7-capture-backed-review.md +++ b/libs/@hashintel/brunch-agent/docs/mission-drafts/7-capture-backed-review.md @@ -8,8 +8,8 @@ A fresh builder must resolve the current repository and the deployment handoff rather than treating this draft as a specification: -- [`../../MISSION.md`](../../MISSION.md) — live Mission 5 Voice authority on this branch; it supplies no Mission 7 execution authority or conversation/workpiece candidate, and Mission 4 produced no full-run candidate. -- [`6-resumable-workpiece-petrinaut-fixture.md`](6-resumable-workpiece-petrinaut-fixture.md) — independent viability predecessor. If accepted, its deliberately prepared and honestly labelled fixture may become this mission's selected pair after a separate provenance-suitability decision; a complete persona workpiece is not intrinsically required. +- [`../../MISSION.md`](../../MISSION.md) — live Mission 6 viability authority on this branch, stacked on the live Mission 5 transport authority of [FE-1574](https://linear.app/hash/issue/FE-1574/let-voice-speak-through-canonical-brunch-conversations); neither supplies Mission 7 execution authority or a conversation/workpiece candidate, and Mission 4 produced no full-run candidate. +- [FE-1575](https://linear.app/hash/issue/FE-1575/resume-one-brunch-workpiece-and-petrinaut-document-across-tabs) — live Mission 6 viability predecessor. If accepted, its deliberately prepared and honestly labelled fixture may become this mission's selected pair after a separate provenance-suitability decision; at cut time replace this live pointer with the accepted archive/evidence. A complete persona workpiece is not intrinsically required. - [`../../MISSION.next.md`](../../MISSION.next.md) — compact future spine, FE-1476 product frame, shared proof obligations, standing locks, and any later evidence admitted after this draft was written. - [`../mission-archive/2-mechanical-capture-sweep.md`](../mission-archive/2-mechanical-capture-sweep.md) — accepted mechanical capture throughline, exact close evidence, empty-payload boundary, conversation identity, and carried flags. - [`../mission-archive/3-structurally-typed-runbook-to-headless-pn.md`](../mission-archive/3-structurally-typed-runbook-to-headless-pn.md) and [`../evidence/implementations/fe-1525-headless-runbook-pn.md`](../evidence/implementations/fe-1525-headless-runbook-pn.md) — accepted runbook/workpiece leg, falsified real-model construction leg, and the distinction between a hermetic non-empty fixture and vacuous empty-net parser success. diff --git a/libs/@hashintel/brunch-agent/docs/mission-drafts/9-traceable-projection.md b/libs/@hashintel/brunch-agent/docs/mission-drafts/9-traceable-projection.md index 82b84336fc9..8412c4b41dd 100644 --- a/libs/@hashintel/brunch-agent/docs/mission-drafts/9-traceable-projection.md +++ b/libs/@hashintel/brunch-agent/docs/mission-drafts/9-traceable-projection.md @@ -10,7 +10,7 @@ A fresh builder must resolve these authorities and evidence before choosing a me - [`../../MISSION.md`](../../MISSION.md) — live Mission 5 Voice authority on this branch. Mission 9 may be cut only after Mission 7 validly closes its accepted join and a new owner-authorized mission replaces the then-current branch authority. - [`../../MISSION.next.md`](../../MISSION.next.md) — compact future spine, FE-1476 floor, cross-mission obligations, standing locks, and current Mission 10 handoff. -- [`6-resumable-workpiece-petrinaut-fixture.md`](6-resumable-workpiece-petrinaut-fixture.md) and [`7-capture-backed-review.md`](7-capture-backed-review.md) — provisional viability and provenance predecessors. At cut time replace assumptions with their accepted evidence, exact current workpiece/derivation seam, and real browser mutation behavior. +- [`../../MISSION.md`](../../MISSION.md), [FE-1575](https://linear.app/hash/issue/FE-1575/resume-one-brunch-workpiece-and-petrinaut-document-across-tabs), and [`7-capture-backed-review.md`](7-capture-backed-review.md) — live Mission 6 viability authority plus the provisional provenance predecessor. At cut time replace the live pointer and assumptions with accepted evidence, the exact current workpiece/derivation seam, and observed browser mutation behavior. - [`../mission-archive/3-structurally-typed-runbook-to-headless-pn.md`](../mission-archive/3-structurally-typed-runbook-to-headless-pn.md) and [`../evidence/implementations/fe-1525-headless-runbook-pn.md`](../evidence/implementations/fe-1525-headless-runbook-pn.md) — accepted workpiece leg, canonical callback fixture, provider-visible nested-schema failure, vacuous empty-net result, and explicit next-boundary decision. - [`../specs/petrinaut-batched-construction-tools.md`](../specs/petrinaut-batched-construction-tools.md) — candidate `pn_read`/`pn_edit` design input and its corrected transaction, outcome, identity, carrier, and ownership constraints. It does not select batching; this mission repairs the known single-action carrier first and admits a batch only if subsequent probes establish it as the least sufficient mechanism. - [`apps/brunch-agent/src/evaluations/runbook/headless-petrinaut-client.ts`](../../../../../apps/brunch-agent/src/evaluations/runbook/headless-petrinaut-client.ts), [`apps/brunch-agent/test/headless-petrinaut-client.test.ts`](../../../../../apps/brunch-agent/test/headless-petrinaut-client.test.ts), and [`../../packages/plugin-sdcpn/test/construction-tools.test.ts`](../../packages/plugin-sdcpn/test/construction-tools.test.ts) — current bounded six-tool callback route and its limits. From a634010528d5a739b875afdbd952f2ab4ce6b69b Mon Sep 17 00:00:00 2001 From: Lu Nelson Date: Thu, 3 Sep 2026 16:10:37 +0200 Subject: [PATCH 02/13] Accept tagged prepared workpiece history Co-authored-by: Cursor --- libs/@hashintel/brunch-agent/MISSION.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/libs/@hashintel/brunch-agent/MISSION.md b/libs/@hashintel/brunch-agent/MISSION.md index 30ee78c456d..2d06f55594a 100644 --- a/libs/@hashintel/brunch-agent/MISSION.md +++ b/libs/@hashintel/brunch-agent/MISSION.md @@ -2,7 +2,7 @@ ## Status -**Live on `ln/fe-1575-resumable-workpiece-petrinaut` from 2026-09-03.** [FE-1575](https://linear.app/hash/issue/FE-1575/resume-one-brunch-workpiece-and-petrinaut-document-across-tabs) is in progress. This authority cut is committed separately before product or evaluation implementation begins. It was recut on restack the same day to carry the product-manager litmus adopted in [`MISSION.next.md`](MISSION.next.md#current-authority-and-accepted-spine) after the first cut: completion is the readiness gate below, not the first green two-tab pass. +**Live on `ln/fe-1575-resumable-workpiece-petrinaut` from 2026-09-03.** [FE-1575](https://linear.app/hash/issue/FE-1575/resume-one-brunch-workpiece-and-petrinaut-document-across-tabs) is in progress. This authority cut is committed separately before product or evaluation implementation begins. It was recut on restack the same day to carry the product-manager litmus adopted in [`MISSION.next.md`](MISSION.next.md#current-authority-and-accepted-spine) after the first cut: completion is the readiness gate below, not the first green two-tab pass. The owner subsequently accepted the probe-backed prepared-history semantics under [Accepted fixture and boundary crossings](#accepted-fixture-and-boundary-crossings); that amendment must land separately before dependent implementation. ## Imperative @@ -39,13 +39,17 @@ The first unproved boundary is ordinary Brunch conversation → mounted canonica Prepare the existing final-inspection / dispatch-crew case as an explicitly test-authored fixture. Its starting workpiece and non-empty net preserve this narrow account: one crew is reserved during final inspection, sign-off releases it, the batch then becomes dispatch-ready, and timing plus failure/recovery remain unresolved. Its prepared material must identify its authorship and must not be presented as a Mission 4 candidate or model-produced evidence. +Deliver the prepared starting workpiece exactly once through Flue's public dispatch surface as a tagged structured signal. Its canonical record must remain `role: system`, `purpose: dispatch`, carry the fixture id, `test-authored` authorship, and non-claims as signal attributes, and preserve the exact Markdown body. This record is prepared revision zero. Later full `runbook-ir` blocks emitted in genuine assistant responses are model-produced revisions; the workpiece resolver selects the latest eligible revision without rewriting Flue's append-only history. This is analogous to last-one-wins selection of extension-contributed artifacts in a Pi raw session log, not permission to overwrite either log. + +The disposable production-route probe established the carrier facts: the tagged signal retained its exact body and attributes, an exact idempotent retry converged on the original submission without adding messages, and the snapshot survived process reopen unchanged. The current `ChatAgent` rejected fixture authorship supplied as `initialData` with `400` and created no history; `initialData` is not a substitute for the public workpiece source. A user delivery would impersonate the person, while faux-provider output, hand-authored assistant records, private canonical record types, direct database writes, and a second history store are not preparation routes. The probe's configured Anthropic credential was rejected with `401`, so its separately classified faux assistant response established no model-behavior claim. + Prepare the net with `Batch ready`, `Under final inspection`, `Ready for dispatch`, and `Dispatch crew available` places plus `Start final inspection` and `Sign-off` transitions. Preserve the batch-flow arcs and the return of the crew from sign-off, but deliberately omit the standard input arc that reserves the sole crew when final inspection starts. Use one realistic confirming answer: final inspection consumes the sole available dispatch crew, sign-off returns it, and timing plus recovery remain unknown. The least candidate mutation is one canonical weight-1 standard input arc from `Dispatch crew available` to `Start final inspection`. The exact before/after edge makes the semantic oracle discriminating while avoiding Mission 3's deeply nested schema failure. If that shallow mutation still cannot cross Flue faithfully, stop with the carrier blocker rather than weakening the claim. ```text stable prepared-fixture selector → resolve distinct fixture, Petrinaut document, and Flue conversation identities → open the prepared non-empty browser document and hydrate canonical Flue history -→ recover the latest Markdown workpiece revision by source message id plus content hash +→ recover prepared revision zero from the tagged dispatch record, or the latest eligible assistant revision, by source message id plus content hash → submit the realistic crew-reservation confirmation through the production panel door → Brunch emits an inspectable full workpiece revision without erasing prior meaning or the remaining unknown → SDCPN construction reads that current workpiece and the live browser document @@ -90,8 +94,8 @@ The mission completes only when the demo script works for this fixture and these Every final leaf has a discriminating oracle: -1. **The prepared fixture is honest and sufficient for this narrow test.** The committed fixture manifest and a cold-reader adjudication identify its test-authored source, process spine, constrained crew, release policy, quantity context, explicit unknown, prepared net meaning, and non-claims. The reader must do this without transcript archaeology. -2. **One evidence turn maintains the Markdown workpiece.** A production-agent fixture integration retains the exact Flue snapshot and mechanically recovers the latest `runbook-ir` block with source message id and SHA-256. Before/after adjudication must find the supplied contextual quantity, retained crew/release meaning, retained unsupported context, and no invented fact or hardened unknown. +1. **The prepared fixture is honest and sufficient for this narrow test.** The committed fixture manifest, raw Flue snapshot, and a cold-reader adjudication identify the prepared workpiece's tagged system/dispatch source, exact test-authored Markdown, process spine, constrained crew, release policy, quantity context, explicit unknown, prepared net meaning, and non-claims. The same inspection distinguishes every later assistant revision as model-produced and must not require transcript archaeology. +2. **One evidence turn maintains the Markdown workpiece.** A production-agent fixture integration mechanically recovers prepared revision zero from the tagged dispatch record, then selects the latest eligible assistant `runbook-ir` block after the confirming turn, retaining each source message id and SHA-256. Before/after adjudication must find the supplied contextual quantity, retained crew/release meaning, retained unsupported context, and no invented fact or hardened unknown. 3. **The real browser executes a correlated Petrinaut read and write.** Focused plugin/transport tests prove that `getLatestNetDefinition` and the selected `addArc` schema come mechanically from Petrinaut's canonical contracts, fixture mode advertises only the selected operations, duplicate result delivery does not apply the mutation twice, rejected input remains visible, and a mutation that would change nothing is reported as a no-op rather than as a change. The browser witness must retain tool name, call id, parsed input, execution output, resumed signal, and resulting canonical definition; a headless callback alone does not pass. 4. **The document change is meaningful rather than merely accepted.** A structural comparison proves there was no standard input arc from `Dispatch crew available` to `Start final inspection` before the turn and exactly one weight-1 arc afterward, while `Sign-off` still returns the crew and the prepared net remains non-empty. The changed workpiece retains the reservation/release meaning and unresolved timing/recovery. Parser/schema acceptance or a disconnected convenience element fails. 5. **The settled witness cannot bless partial state.** A focused failure test injects history/workpiece-recovery failure, rejected `addArc`, or missing/duplicate result correlation and shows that the prior settled manifest remains selected while the failure and any partial state are inspectable. Do not invent a localStorage failure interface solely to satisfy this leaf. @@ -110,6 +114,7 @@ Verification proceeds inside-out but closure requires the outer boundary: - Keep fixture id, Flue conversation id, latest workpiece source/revision, and Petrinaut document id/revision distinct and explicitly linked. One id must not impersonate all lifecycles. - Flue history remains the canonical conversation log. Browser message caches and fixture artifacts are projections or evidence, never a second authority. +- The tagged prepared signal is the only test-authored workpiece source admitted by this fixture. It remains a diagnostic system/dispatch record; latest-revision selection may supersede it with a genuine assistant workpiece but may not mutate, relabel, or hide its authorship. - Markdown remains the semantic workpiece. Recover its full latest version; do not introduce a comprehensive typed domain IR to make fixture lookup convenient. - Projection consumes the current workpiece. The transcript may establish provenance and help recover that artifact but may not become the primary construction IR. - Petrinaut owns canonical schemas, browser validation, mutations, and document state. Brunch imports or mechanically derives those contracts and does not hand-copy their field shapes. @@ -125,7 +130,6 @@ Verification proceeds inside-out but closure requires the outer boundary: - Whether the selected shallow `addArc` schema survives the provider-visible Flue carrier and results in exactly one browser mutation without reopening the broader nested-schema problem. - The least safe way to expose canonical `getLatestNetDefinition` plus `addArc` in a fixture conversation while retaining the headless-only guard for broader construction. -- How to prepare canonical Flue history reproducibly without pretending test-authored assistant content was model-produced; the preparation route and authorship must survive in the manifest. - Whether the latest `runbook-ir` message id and hash are sufficient workpiece revision identity or the two-tab consumer exposes a need for a separate persisted workpiece artifact. - Whether Mantine/localStorage synchronization plus the active `PetrinautDocHandle` is sufficient for the same-browser two-tab witness, and which document hash/revision signal best distinguishes settled from stale state. - Whether the known provider-visible nested-schema failure is absent for the selected flat mutation. Do not generalize one success to nested construction classes. @@ -137,7 +141,7 @@ Resolve these at the named production/browser boundaries. Clarifying prose alone Stop and surface evidence if: -- fixture preparation requires pretending a Mission 4 candidate exists or hides test-authored/model-authored boundaries; +- fixture preparation requires pretending a Mission 4 candidate exists, placing prepared text in a user or assistant record, accepting an untagged preparation signal, or otherwise hiding test-authored/model-authored boundaries; - the path conflates fixture, conversation, workpiece, and document identities or creates a second canonical conversation history; - the agent rereads transcript prose as its primary projection input because the current Markdown workpiece cannot carry the needed meaning; - parser/schema acceptance, document non-emptiness, or a disconnected convenience element is offered as semantic correspondence; From 9b5029fee2fe1b1122a36650d0c5a694ab4a65a4 Mon Sep 17 00:00:00 2001 From: Lu Nelson Date: Thu, 3 Sep 2026 16:17:21 +0200 Subject: [PATCH 03/13] Reconcile Mission 6 with browser Flue transport Co-authored-by: Cursor --- libs/@hashintel/brunch-agent/MISSION.md | 42 ++++++++++++++----------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/libs/@hashintel/brunch-agent/MISSION.md b/libs/@hashintel/brunch-agent/MISSION.md index 2d06f55594a..dff113ecec3 100644 --- a/libs/@hashintel/brunch-agent/MISSION.md +++ b/libs/@hashintel/brunch-agent/MISSION.md @@ -2,7 +2,7 @@ ## Status -**Live on `ln/fe-1575-resumable-workpiece-petrinaut` from 2026-09-03.** [FE-1575](https://linear.app/hash/issue/FE-1575/resume-one-brunch-workpiece-and-petrinaut-document-across-tabs) is in progress. This authority cut is committed separately before product or evaluation implementation begins. It was recut on restack the same day to carry the product-manager litmus adopted in [`MISSION.next.md`](MISSION.next.md#current-authority-and-accepted-spine) after the first cut: completion is the readiness gate below, not the first green two-tab pass. The owner subsequently accepted the probe-backed prepared-history semantics under [Accepted fixture and boundary crossings](#accepted-fixture-and-boundary-crossings); that amendment must land separately before dependent implementation. +**Live on `ln/fe-1575-resumable-workpiece-petrinaut` from 2026-09-03.** [FE-1575](https://linear.app/hash/issue/FE-1575/resume-one-brunch-workpiece-and-petrinaut-document-across-tabs) is in progress. This authority cut is committed separately before product or evaluation implementation begins. It was recut on restack the same day to carry the product-manager litmus adopted in [`MISSION.next.md`](MISSION.next.md#current-authority-and-accepted-spine) after the first cut: completion is the readiness gate below, not the first green two-tab pass. The owner subsequently accepted the probe-backed prepared-history semantics under [Accepted fixture and boundary crossings](#accepted-fixture-and-boundary-crossings), then corrected this mission to consume Mission 5's one-route browser Flue transport, automatic localStorage persistence, a runtime settled manifest, visible preparation language, and an actual Tab B continuation. Each authority amendment lands separately before dependent implementation. ## Imperative @@ -14,7 +14,7 @@ Mission 3 separately showed a recoverable Markdown workpiece and hermetic canoni **Release note:** Brunch edits the Petrinaut net you are looking at from the conversation, and your work survives closing the tab. -**Demo script (no engineer present):** with the local Brunch/Petrinaut development stack running, open the stable demo fixture selector for the labelled prepared crew-reservation case. Its canonical Brunch conversation, current Markdown workpiece, and non-empty Petrinaut net come back together. Tell Brunch the one new realistic fact the fixture is prepared for: final inspection uses the single dispatch crew, and sign-off releases it. Watch the workpiece update and a new arc appear in the live net from `Dispatch crew available` to `Start final inspection`. Save. Open the same fixture in a second tab and continue the conversation from the saved state. The fixture announces out loud that it is test-authored and prepared, and what it does not claim. +**Demo script (no engineer present):** with the local Brunch/Petrinaut development stack running, open the stable demo fixture selector for the labelled prepared crew-reservation case. Its canonical Brunch conversation, current Markdown workpiece, and non-empty Petrinaut net come back together. The fixture visibly states that it is test-authored and prepared, and what it does not claim. Tell Brunch the one new realistic fact the fixture is prepared for: final inspection uses the single dispatch crew, and sign-off releases it. Watch the workpiece update and a new arc appear in the live net from `Dispatch crew available` to `Start final inspection`. Wait until the fixture reports that the conversation, workpiece, and automatically mirrored document are settled. Open the same fixture in a second tab, submit one follow-up message, and receive Brunch's response in the same conversation without duplicate submission or identity drift. **Previously impossible:** Brunch only produced off-canvas net JSON for manual load; nothing it did touched the live document or survived a reload. @@ -28,12 +28,12 @@ Mission 3 separately showed a recoverable Markdown workpiece and hermetic canoni The production browser already has most local pieces: -- `apps/petrinaut-website`'s local-storage demo owns an editable `PetrinautDocHandle`, writes handle changes to `petrinaut-sdcpn`, maps each net to a persistent Brunch conversation id, and hydrates panel messages from the Brunch history door; +- `apps/petrinaut-website`'s local-storage demo owns an editable `PetrinautDocHandle`, automatically writes handle changes to `petrinaut-sdcpn`, and maps each net to a persistent Brunch conversation id; - Petrinaut's stock AI panel already validates and executes canonical read, mutation, and command tools against the active browser document and returns the original tool-call id; -- `apps/brunch-agent` already maps the principal plus conversation id to one Flue conversation, exposes `GET /api/chat?id=…` history, resumes client-tool results as correlated Flue signals, and projects the resulting stream back to the panel; and +- live Mission 5 is replacing the server-side `GET`/`POST /api/chat` adapter with one browser `FlueClient` plus host-supplied AI SDK `ChatTransport` over the mounted `/agents/chat/:instanceId` route; that route carries typed turns, `history()` hydration, and correlated client-tool-result signals, and Mission 6 must consume rather than duplicate or reverse that transport; and - the SDCPN skill already emits a full recoverable `runbook-ir` block and requires construction to consume that workpiece rather than transcript archaeology. -The first unproved boundary is ordinary Brunch conversation → mounted canonical document read / least mutation → browser execution → correlated continuation. Today ordinary SDCPN conversations mount only the Petrinaut documentation reader as a browser tool; the validated construction subset is headless-only, and no stable fixture selector or coherent cross-tab witness joins the conversation, workpiece, and document lifecycles. +The first unproved boundary is ordinary Brunch conversation over Mission 5's browser Flue transport → mounted canonical document read / least mutation → browser execution → correlated Flue continuation. Today ordinary SDCPN conversations mount only the Petrinaut documentation reader as a browser tool; the validated construction subset is headless-only, and no stable fixture selector or coherent cross-tab witness joins the conversation, workpiece, and document lifecycles. Mission 6 may develop independent fixture/workpiece/document logic while Mission 5 proceeds, but it must consume Mission 5's landed browser transport before integrated or outer proof and must not add another conversation route in the interim. ### Accepted fixture and boundary crossings @@ -48,19 +48,20 @@ Prepare the net with `Batch ready`, `Under final inspection`, `Ready for dispatc ```text stable prepared-fixture selector → resolve distinct fixture, Petrinaut document, and Flue conversation identities -→ open the prepared non-empty browser document and hydrate canonical Flue history +→ open the prepared non-empty browser document and use the browser Flue client to idempotently deliver or recover the tagged revision-zero signal +→ hydrate canonical Flue history through `history()` on the mounted route → recover prepared revision zero from the tagged dispatch record, or the latest eligible assistant revision, by source message id plus content hash -→ submit the realistic crew-reservation confirmation through the production panel door +→ submit the realistic crew-reservation confirmation through Mission 5's production browser Flue transport → Brunch emits an inspectable full workpiece revision without erasing prior meaning or the remaining unknown → SDCPN construction reads that current workpiece and the live browser document → Brunch requests the least canonical meaningful mutation → Petrinaut validates and executes it against the bound document -→ the original tool-call id and result resume the same Flue conversation -→ inspect the canonical non-empty document and record a settled fixture witness only after conversation/workpiece/document state is observable -→ a second tab opens the same fixture selector, resolves the same identities and settled hashes, and can continue +→ the original tool-call id and result return as one correlated signal through the same browser Flue transport and resume the same conversation +→ inspect the canonical non-empty document and advance the runtime settled manifest only after conversation/workpiece/document state is observable +→ a second tab opens the same fixture selector, resolves the same identities and settled hashes, submits one follow-up, and receives Brunch's response ``` -The fixture witness is a small local viability manifest, not a new event log, independent workpiece store, or distributed transaction. It records distinct ids, prepared inputs, latest settled workpiece source/hash, document hash or local revision token, and limitations. A failed history load, workpiece recovery, rejected/no-op mutation, or missing result correlation must not advance that witness; the partial state remains visible for diagnosis. The existing automatic localStorage mirror is the only document-save mechanism unless a real failure proves it insufficient. +The settled fixture manifest is runtime local product state, not merely retained evaluation evidence: the stable selector uses it to choose the latest coherent observed bundle of distinct fixture, Flue conversation, workpiece source/hash, and Petrinaut document/hash or revision identities across reopen. It is a small viability pointer, not a new event log, independent workpiece store, or distributed transaction. A failed history load, workpiece recovery, rejected/no-op mutation, or missing result correlation must leave the prior settled bundle selected while partial state and failure remain visible for diagnosis. Retained witness artifacts copy and inspect this runtime state but do not select the product bundle. The existing automatic localStorage mirror is the only document-save mechanism unless a real failure proves it insufficient; this mission adds no explicit Save affordance. ### Expected touched paths @@ -73,10 +74,11 @@ libs/@hashintel/brunch-agent/ ├── packages/plugin-sdcpn/ ~ mount only the read/mutation capability earned by this tracer └── docs/evidence/ + prepared fixture manifest and browser witness apps/brunch-agent/ -├── src/agents/chat-agent/ and src/conversation/ ? only if normal client-tool mounting/correlation requires it +├── src/agents/chat-agent/ and src/conversation/ ? only if fixture-scoped mounting or workpiece recovery belongs outside the landed browser transport └── test/ + real Flue/client-tool fixture integration apps/petrinaut-website/ -└── src/main/app/local-storage-demo/ ~ fixture selection, prepared seed, settled witness, and cross-tab resume +└── src/main/app/local-storage-demo/ ~ consume Mission 5 transport; fixture selection, prepared signal, runtime settled manifest, and cross-tab continuation +libs/@hashintel/brunch-agent/packages/transport-aisdk/ ? consume the landed Mission 5 public surface; do not duplicate its implementation here libs/@hashintel/petrinaut-core/ or libs/@hashintel/petrinaut/ ? only for an observed canonical contract or browser-host defect ``` @@ -98,14 +100,14 @@ Every final leaf has a discriminating oracle: 2. **One evidence turn maintains the Markdown workpiece.** A production-agent fixture integration mechanically recovers prepared revision zero from the tagged dispatch record, then selects the latest eligible assistant `runbook-ir` block after the confirming turn, retaining each source message id and SHA-256. Before/after adjudication must find the supplied contextual quantity, retained crew/release meaning, retained unsupported context, and no invented fact or hardened unknown. 3. **The real browser executes a correlated Petrinaut read and write.** Focused plugin/transport tests prove that `getLatestNetDefinition` and the selected `addArc` schema come mechanically from Petrinaut's canonical contracts, fixture mode advertises only the selected operations, duplicate result delivery does not apply the mutation twice, rejected input remains visible, and a mutation that would change nothing is reported as a no-op rather than as a change. The browser witness must retain tool name, call id, parsed input, execution output, resumed signal, and resulting canonical definition; a headless callback alone does not pass. 4. **The document change is meaningful rather than merely accepted.** A structural comparison proves there was no standard input arc from `Dispatch crew available` to `Start final inspection` before the turn and exactly one weight-1 arc afterward, while `Sign-off` still returns the crew and the prepared net remains non-empty. The changed workpiece retains the reservation/release meaning and unresolved timing/recovery. Parser/schema acceptance or a disconnected convenience element fails. -5. **The settled witness cannot bless partial state.** A focused failure test injects history/workpiece-recovery failure, rejected `addArc`, or missing/duplicate result correlation and shows that the prior settled manifest remains selected while the failure and any partial state are inspectable. Do not invent a localStorage failure interface solely to satisfy this leaf. -6. **A second tab resumes the same fixture.** With `yarn dev:brunch` running, the recorded browser protocol opens the stable selector in Tab A, performs and settles the turn, then opens it in Tab B. The witness compares fixture id, document id and canonical definition hash, Flue conversation id and history, latest workpiece source/hash, and absence of duplicate submission before one read or continuation succeeds in Tab B. Tab B opened against a stale or mismatched revision must refuse visibly rather than silently select older artifacts. +5. **The runtime settled manifest cannot bless partial state.** A focused failure test injects history/workpiece-recovery failure, rejected `addArc`, or missing/duplicate result correlation and shows that the prior coherent runtime bundle remains selected while the failure and any partial state are inspectable. A retained evidence manifest alone does not pass this leaf, and no localStorage failure interface is invented solely to satisfy it. +6. **A second tab resumes and continues the same fixture.** With `yarn dev:brunch` running, the recorded browser protocol opens the stable selector in Tab A, performs and settles the turn, then opens it in Tab B. The witness compares fixture id, document id and canonical definition hash, Flue conversation id and history, latest workpiece source/hash, runtime settled-manifest identity, and absence of duplicate submission; Tab B must then submit one follow-up message and receive its correlated Brunch response in that same conversation. A read alone does not pass. Tab B opened against a stale or mismatched revision must refuse visibly rather than silently select older artifacts. 7. **The cut has not smuggled in the later architecture.** Public-schema and dependency inspection finds only fixture identity/revision links, Markdown recovery metadata, and canonical Petrinaut payloads—no closed process ontology, typed capture-to-workpiece reducer, graph database, second conversation log, or general projection engine. Verification proceeds inside-out but closure requires the outer boundary: -- **Inner:** fixture parsing and prepared-label checks; identity separation; workpiece recovery/hash; canonical `addArc` schema and exact before/after edge assertion; idempotent client-tool result handling; settled-witness refusal. -- **Middle:** the built production `ChatAgent` and `/api/chat` path hydrate the prepared Flue conversation, accept the evidence turn, recover the revised workpiece, and carry actual browser-tool calls/results. Run the focused workspaces through root Turbo (`test:unit`, `lint:tsc`, `lint:eslint`, and `build` where changed). +- **Inner:** fixture parsing and prepared-label checks; identity separation; workpiece recovery/hash; canonical `addArc` schema and exact before/after edge assertion; idempotent client-tool result handling; runtime-manifest refusal. +- **Middle:** the built production `ChatAgent` and Mission 5 browser `FlueClient`/`ChatTransport` path at `/agents/chat/:instanceId` hydrate the prepared conversation, accept the evidence turn, recover the revised workpiece, and carry actual browser-tool calls/results. No `GET` or `POST /api/chat` evidence passes. Run the focused workspaces through root Turbo (`test:unit`, `lint:tsc`, `lint:eslint`, and `build` where changed). - **Outer:** the two-tab `yarn dev:brunch` witness above, with retained before/after artifacts. - **Semantic:** a cold human accepts fixture/workpiece honesty and the workpiece-to-document correspondence. The oracle may falsify those claims; it may not rewrite the interaction or architecture policy. - **Product:** a product manager who did not watch the work runs the demo script from the imperative without an engineer and notices the advance. This is the last check before close, after the readiness gate; it is not a substitute for the oracles above. @@ -114,12 +116,13 @@ Verification proceeds inside-out but closure requires the outer boundary: - Keep fixture id, Flue conversation id, latest workpiece source/revision, and Petrinaut document id/revision distinct and explicitly linked. One id must not impersonate all lifecycles. - Flue history remains the canonical conversation log. Browser message caches and fixture artifacts are projections or evidence, never a second authority. +- Consume Mission 5's browser `FlueClient` plus host-supplied AI SDK `ChatTransport`; typed turns, prepared signals, history hydration, and client-tool results all cross `/agents/chat/:instanceId`. Do not keep, restore, or add another product conversation route. - The tagged prepared signal is the only test-authored workpiece source admitted by this fixture. It remains a diagnostic system/dispatch record; latest-revision selection may supersede it with a genuine assistant workpiece but may not mutate, relabel, or hide its authorship. - Markdown remains the semantic workpiece. Recover its full latest version; do not introduce a comprehensive typed domain IR to make fixture lookup convenient. - Projection consumes the current workpiece. The transcript may establish provenance and help recover that artifact but may not become the primary construction IR. - Petrinaut owns canonical schemas, browser validation, mutations, and document state. Brunch imports or mechanically derives those contracts and does not hand-copy their field shapes. - Client tools execute against the active bound browser document and return the original tool-call id. Stale, duplicate, cross-document, malformed, failed, and no-op outcomes fail visibly. -- Publish a new settled fixture witness only after the claimed Flue snapshot, workpiece revision, and document state can all be inspected. The witness does not make the browser and Flue stores transactional. Do not invent explicit save or cross-store transaction machinery without an observed recovery failure requiring it. +- Advance the runtime settled manifest only after the claimed Flue snapshot, workpiece revision, and document state can all be inspected. It selects the coherent local bundle but does not make the browser and Flue stores transactional. Automatic localStorage mirroring remains the only save behavior; do not invent an explicit Save affordance or cross-store transaction machinery without an observed recovery failure requiring it. - Preserve the accepted Mission 4 `useBrunchAgent()` plus `useSdcpnPlugin()` architecture. The app composes; the plugin owns SDCPN operation semantics; the transport carries results; the UI executes them. - Keep construction tools unavailable to unrelated ordinary conversations unless the real path proves the smallest safe selection can be scoped to this fixture/mode. Stock-assistant behavior must remain unchanged when Brunch is absent or unselected. - The fixture is local and deliberately prepared. Make no remote durability, capture provenance, automatic projection, behavioral execution, or concurrent collaboration claim. @@ -143,10 +146,11 @@ Stop and surface evidence if: - fixture preparation requires pretending a Mission 4 candidate exists, placing prepared text in a user or assistant record, accepting an untagged preparation signal, or otherwise hiding test-authored/model-authored boundaries; - the path conflates fixture, conversation, workpiece, and document identities or creates a second canonical conversation history; +- typed traffic, prepared signals, history, or client-tool results cross a product route other than Mission 5's mounted browser Flue route; - the agent rereads transcript prose as its primary projection input because the current Markdown workpiece cannot carry the needed meaning; - parser/schema acceptance, document non-emptiness, or a disconnected convenience element is offered as semantic correspondence; - client-tool results lose their original call id, can target the wrong document, or duplicate execution on retry/reload; -- a partial or failed write advances the settled witness, or second-tab reopening silently selects stale/mismatched artifacts; +- a partial or failed write advances the runtime settled manifest, second-tab reopening silently selects stale/mismatched artifacts, or Tab B proves only a read without a real continuation; - exposing one browser mutation requires mounting an unrestricted construction surface for every ordinary conversation; - the selected provider/Flue schema cannot faithfully carry the least meaningful mutation—record the crisp blocker rather than hand-copying Petrinaut schemas or widening into Mission 9; - the tracer needs a closed ontology, typed claim ledger, general projection engine, distributed transaction, or new durable service before a concrete failure demonstrates that need; or From 26fe60e932418b55fe7de2365e657df64a320e1f Mon Sep 17 00:00:00 2001 From: Lu Nelson Date: Thu, 3 Sep 2026 16:50:35 +0200 Subject: [PATCH 04/13] Record Mission 5 as the Mission 6 transport prerequisite --- libs/@hashintel/brunch-agent/MISSION.next.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libs/@hashintel/brunch-agent/MISSION.next.md b/libs/@hashintel/brunch-agent/MISSION.next.md index 2697366bd15..ecaa6fb4d54 100644 --- a/libs/@hashintel/brunch-agent/MISSION.next.md +++ b/libs/@hashintel/brunch-agent/MISSION.next.md @@ -225,7 +225,7 @@ These tracks may start only under their own issue, branch, PR, and mission autho | Inferential observer fold | Decide before Mission 10 whether observed foreground strain earns promotion; otherwise retain phase-boundary synthesis | Missions 4–9 | | Provider-visible nested schema | Mission 6 tests only the least mutation needed by its meaningful fixture; Mission 9 closes the broader canonical projection classes after a crisp blocker or success | Mission 5 and non-construction Voice work | | Provenance interaction fixture | Mission 6 establishes minimal fixture identity; freeze the broader derivation fixture before Mission 7 why and Mission 9 automatic projection diverge | Voice work and prepared-fixture viability | -| Host choice/session lifecycle | Mission 5 proves Flue conversation reopen; Mission 6 proves fixture save/reopen; later host/picker breadth waits for its visible consumer | Either independent tracer | +| Host choice/session lifecycle | Mission 5 proves Flue conversation reopen; Mission 6 proves fixture save/reopen over Mission 5's landed browser transport; later host/picker breadth waits for its visible consumer | Mission 5 first, then Mission 6 | | Optimisation handoff contract | Chris/Yannis accept input/output contract and one fixture before Mission 11 is cut | Missions 4–10 | | Simulation-backed semantic check | Promote only if cheap and discriminating for the selected revision | First provenance tracer | @@ -482,3 +482,7 @@ The owner subsequently changed the integration premise: Voice should use canonic Later on 2026-09-03 the owner replaced the "visible/usable proof" completion criterion with the product-manager litmus defined in the accepted spine above. The observed problem was that each précis pinned completion to an evidence bundle at the first green throughline tracer, which convinces a builder but is invisible to a product manager, and that Draft Mission 9 carried engineering internals in its visible-advance section. The change re-pins completion to each mission's readiness gate for the named demo scenario, moves oracles out of the visible-advance sections, expands Mission 7 from one element to every consequential element of the demo net, and names the deployment posture problem for Missions 7, 9, and 10. Mission 5 was live on its own branch and was not touched by that commit; on restack, the live branch adopted the litmus in [`MISSION.md`](MISSION.md#product-manager-litmus), naming Stop-that-really-stops and one shared typed/spoken conversation as its product-manager-noticeable advance and its single-route consolidation as internal sequencing. Mission-specific detail lives in the affected drafts' `Visible product advance` and `Throughline proof floor` sections and in the [draft README](docs/mission-drafts/README.md). Mission 6 had been cut into root [`MISSION.md`](MISSION.md) on the FE-1575 branch from the pre-litmus draft earlier the same day. That cut was recut on restack rather than left as it stood: its proof section had named the evidence bundle (selector, manifest, snapshots, revisions) as the visible proof artifact and read as if the first green two-tab pass were completion. The recut moves the release note, demo script, and previously-impossible statement into the imperative, names the readiness gate as the completion bar, keeps the seven discriminating oracles as builder evidence, and records the local-only demo posture explicitly. No Mission 6 draft remains here. + +## 2026-09-03 Mission 5 becomes Mission 6's transport prerequisite + +Missions 5 and 6 were cut as independent siblings on this spine. Mission 5's recut then made one browser Flue `ChatTransport` the only door into a Brunch conversation and removed the server-side `/api/chat` route, `createPetrinautChatHandler`, the `GET ?id=` history door, and the app-side UI-stream projector that Mission 6's throughline had named as its departure point. The owner corrected Mission 6 to consume Mission 5's landed transport rather than wire against the route being deleted or copy Mission 5's in-progress implementation. Mission 6 implemented and verified its transport-independent substrate (prepared-signal recovery, fixture-scoped read and `addArc`, correlated-result settlement refusal, stable selector, document seed, runtime manifest) and then stopped at that boundary. The owner first chose to keep Mission 6 a sibling branch and wait for Mission 5 to land, because Mission 5's committed state was then documentation only and every line Mission 6 needed sat uncommitted. Mission 5 then committed its typed-panel transport tracer as three commits (`Expose the Flue browser chat transport`, `Wire the Petrinaut panel to the Flue route`, `Remove the legacy Petrinaut chat route`) ahead of its Voice work, and the owner reversed the wait: this branch was moved onto `ln/fe-1574-direct-voice-flue` so Mission 6 consumes only Mission 5's committed public surface. Splitting the transport consolidation into a shared substrate branch was rejected because it would sever half of Mission 5's imperative from its authority. Consequences accepted with the move: this branch's root `MISSION.md` is Mission 6's, so Mission 5's live authority is visible only on its own branch; Mission 6 cannot merge before Mission 5; and when Mission 5 closes and archives its authority this branch will need another restack. The independence claims in the spine above were corrected to match. From 0839295d34b6bdcd2c8e82d158a1bdb884751b32 Mon Sep 17 00:00:00 2001 From: Lu Nelson Date: Thu, 3 Sep 2026 22:42:49 +0200 Subject: [PATCH 05/13] Implement the Mission 6 resumable workpiece fixture over the Flue transport Prepare one honestly labelled crew-reservation fixture whose starting workpiece enters canonical Flue history exactly once as a tagged system dispatch signal with idempotent retry, scope the read/`addArc` client tools to that fixture, settle a runtime manifest only after conversation, workpiece, and document state are observable, and surface a visible refusal when the mounted Brunch route is absent. The fixture rides Mission 5's landed browser `ChatTransport`: the panel transport keeps the conversation tracker and accepts fixture-scoped client tool names as an option, the history hook keeps the live observation and additionally exposes the observed snapshot with its offset, and AI SDK user sends carry a deterministic idempotency key. The real two-tab witness remains blocked on the configured Anthropic credential; the blocker and handoff are recorded in the FE-1575 evidence note. No persona testing was run. --- .changeset/resumable-petrinaut-workpiece.md | 6 + .../src/conversation/client-tools.ts | 6 +- .../src/conversation/workpiece.ts | 68 ++++ .../src/evaluations/runbook/artifacts.ts | 58 +-- .../runbook/headless-petrinaut-client.ts | 21 +- .../architecture/boundaries.integration.ts | 7 +- .../test/architecture/boundaries.test.ts | 5 + .../prepared-workpiece.integration.test.ts | 70 ++++ .../test/prepared-workpiece.integration.ts | 276 +++++++++++++ apps/brunch-agent/test/workpiece.test.ts | 135 +++++++ .../brunch-panel-transport.test.ts | 79 ++++ .../brunch-panel-transport.ts | 17 +- .../crew-reservation-settled-manifest.test.ts | 380 ++++++++++++++++++ .../crew-reservation-settled-manifest.ts | 289 +++++++++++++ .../local-storage-demo-app.tsx | 158 +++++++- ...pare-crew-reservation-conversation.test.ts | 87 ++++ .../prepare-crew-reservation-conversation.ts | 90 +++++ .../prepared-crew-reservation-fixture.test.ts | 82 ++++ .../prepared-crew-reservation-fixture.ts | 154 +++++++ .../prepared-fixture-banner.test.tsx | 76 ++++ .../prepared-fixture-banner.tsx | 84 ++++ ...-crew-reservation-settled-manifest.test.ts | 113 ++++++ .../use-crew-reservation-settled-manifest.ts | 124 ++++++ .../use-flue-chat-history.test.ts | 81 +++- .../use-flue-chat-history.ts | 30 +- .../voice-preview.integration.test.ts | 1 + .../fe-1575-resumable-workpiece-petrinaut.md | 79 ++++ .../brunch-agent/packages/core/package.json | 4 + .../packages/core/src/workpiece.ts | 214 ++++++++++ .../packages/core/test/workpiece.test.ts | 174 ++++++++ .../brunch-agent/packages/core/vite.config.ts | 1 + .../packages/plugin-sdcpn/src/flue.ts | 25 +- .../src/tools/petrinaut-construction.ts | 9 + .../test/construction-tools.test.ts | 32 ++ .../packages/transport-aisdk/src/index.ts | 8 + .../test/chat-transport.test.ts | 26 ++ .../@hashintel/petrinaut/docs/ai-assistant.md | 12 + .../Editor/panels/ai-assistant-panel.tsx | 22 +- .../apply-petrinaut-ai-mutation.test.ts | 102 +++++ .../apply-petrinaut-ai-mutation.ts | 39 ++ 40 files changed, 3135 insertions(+), 109 deletions(-) create mode 100644 .changeset/resumable-petrinaut-workpiece.md create mode 100644 apps/brunch-agent/src/conversation/workpiece.ts create mode 100644 apps/brunch-agent/test/architecture/boundaries.test.ts create mode 100644 apps/brunch-agent/test/prepared-workpiece.integration.test.ts create mode 100644 apps/brunch-agent/test/prepared-workpiece.integration.ts create mode 100644 apps/brunch-agent/test/workpiece.test.ts create mode 100644 apps/petrinaut-website/src/main/app/local-storage-demo/crew-reservation-settled-manifest.test.ts create mode 100644 apps/petrinaut-website/src/main/app/local-storage-demo/crew-reservation-settled-manifest.ts create mode 100644 apps/petrinaut-website/src/main/app/local-storage-demo/prepare-crew-reservation-conversation.test.ts create mode 100644 apps/petrinaut-website/src/main/app/local-storage-demo/prepare-crew-reservation-conversation.ts create mode 100644 apps/petrinaut-website/src/main/app/local-storage-demo/prepared-crew-reservation-fixture.test.ts create mode 100644 apps/petrinaut-website/src/main/app/local-storage-demo/prepared-crew-reservation-fixture.ts create mode 100644 apps/petrinaut-website/src/main/app/local-storage-demo/prepared-fixture-banner.test.tsx create mode 100644 apps/petrinaut-website/src/main/app/local-storage-demo/prepared-fixture-banner.tsx create mode 100644 apps/petrinaut-website/src/main/app/local-storage-demo/use-crew-reservation-settled-manifest.test.ts create mode 100644 apps/petrinaut-website/src/main/app/local-storage-demo/use-crew-reservation-settled-manifest.ts create mode 100644 libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-resumable-workpiece-petrinaut.md create mode 100644 libs/@hashintel/brunch-agent/packages/core/src/workpiece.ts create mode 100644 libs/@hashintel/brunch-agent/packages/core/test/workpiece.test.ts create mode 100644 libs/@hashintel/petrinaut/src/ui/views/Editor/panels/ai-assistant-panel/apply-petrinaut-ai-mutation.test.ts create mode 100644 libs/@hashintel/petrinaut/src/ui/views/Editor/panels/ai-assistant-panel/apply-petrinaut-ai-mutation.ts diff --git a/.changeset/resumable-petrinaut-workpiece.md b/.changeset/resumable-petrinaut-workpiece.md new file mode 100644 index 00000000000..40e8ffd20ae --- /dev/null +++ b/.changeset/resumable-petrinaut-workpiece.md @@ -0,0 +1,6 @@ +--- +"@hashintel/petrinaut": patch +--- + +Report duplicate AI mutations as no-ops so hosts can distinguish an applied document change from +an already-present state when resuming a correlated browser tool call. diff --git a/apps/brunch-agent/src/conversation/client-tools.ts b/apps/brunch-agent/src/conversation/client-tools.ts index c238c9e3215..dd8e44d8b23 100644 --- a/apps/brunch-agent/src/conversation/client-tools.ts +++ b/apps/brunch-agent/src/conversation/client-tools.ts @@ -1,6 +1,9 @@ /** Flue-side client-tool signal contract: awaiting sentinel, result signal, tool names. */ -import { READ_PETRINAUT_DOC_TOOL_NAME } from "@hashintel/brunch-agent-plugin-sdcpn/flue"; +import { + PETRINAUT_FIXTURE_TOOL_NAMES, + READ_PETRINAUT_DOC_TOOL_NAME, +} from "@hashintel/brunch-agent-plugin-sdcpn/flue"; import { CLIENT_TOOL_RESULT_SIGNAL } from "@hashintel/brunch-agent-transport-aisdk"; import { AWAITING_CLIENT } from "@hashintel/brunch-agent/client-tools"; @@ -9,6 +12,7 @@ export { CLIENT_TOOL_RESULT_SIGNAL }; export const clientToolNames: ReadonlySet = new Set([ READ_PETRINAUT_DOC_TOOL_NAME, + ...PETRINAUT_FIXTURE_TOOL_NAMES, ]); const isRecord = (value: unknown): value is Record => diff --git a/apps/brunch-agent/src/conversation/workpiece.ts b/apps/brunch-agent/src/conversation/workpiece.ts new file mode 100644 index 00000000000..3a146af098b --- /dev/null +++ b/apps/brunch-agent/src/conversation/workpiece.ts @@ -0,0 +1,68 @@ +/** Recover the current Markdown workpiece from canonical Flue history. */ + +import { createHash } from "node:crypto"; + +import { + createPreparedWorkpieceDelivery, + latestRunbookIrBlock, + PREPARED_WORKPIECE_AUTHORSHIP, + PREPARED_WORKPIECE_CLAIM_BOUNDARY, + PREPARED_WORKPIECE_INITIAL_DATA_MODE, + PREPARED_WORKPIECE_SIGNAL_TAG, + PREPARED_WORKPIECE_SIGNAL_TYPE, + RUNBOOK_IR_FENCE, + selectRunbookWorkpiece, +} from "@hashintel/brunch-agent/workpiece"; + +import type { FlueConversationSnapshot } from "@flue/sdk"; + +const sha256 = (value: string): string => + createHash("sha256").update(value).digest("hex"); + +export { + createPreparedWorkpieceDelivery, + latestRunbookIrBlock, + PREPARED_WORKPIECE_AUTHORSHIP, + PREPARED_WORKPIECE_CLAIM_BOUNDARY, + PREPARED_WORKPIECE_INITIAL_DATA_MODE, + PREPARED_WORKPIECE_SIGNAL_TAG, + PREPARED_WORKPIECE_SIGNAL_TYPE, + RUNBOOK_IR_FENCE, +}; + +export interface RecoveredRunbookWorkpiece { + readonly authorship: "model-produced" | "test-authored"; + readonly content: string; + readonly fixtureId?: string; + readonly sha256: string; + readonly sourceKind: "assistant" | "prepared-signal"; + readonly sourceMessageId: string; + readonly sourceMessageSha256: string; + readonly sourceSubmissionId?: string; +} + +/** + * Add content and source hashes to the substrate-neutral current-workpiece + * selection used by both evaluations and the browser fixture. + */ +export const recoverRunbookWorkpiece = ( + snapshot: FlueConversationSnapshot, +): RecoveredRunbookWorkpiece | undefined => { + const selected = selectRunbookWorkpiece(snapshot); + if (selected === undefined) return undefined; + + return { + authorship: selected.authorship, + content: selected.content, + ...(selected.fixtureId === undefined + ? {} + : { fixtureId: selected.fixtureId }), + sha256: sha256(selected.content), + sourceKind: selected.sourceKind, + sourceMessageId: selected.sourceMessageId, + sourceMessageSha256: sha256(JSON.stringify(selected.sourceMessage)), + ...(selected.sourceSubmissionId === undefined + ? {} + : { sourceSubmissionId: selected.sourceSubmissionId }), + }; +}; diff --git a/apps/brunch-agent/src/evaluations/runbook/artifacts.ts b/apps/brunch-agent/src/evaluations/runbook/artifacts.ts index 05a50b46847..bdc39fc3035 100644 --- a/apps/brunch-agent/src/evaluations/runbook/artifacts.ts +++ b/apps/brunch-agent/src/evaluations/runbook/artifacts.ts @@ -2,56 +2,26 @@ import { basename } from "node:path"; -import { sha256 } from "./campaign-integrity.ts"; - -import type { FlueConversationPart, FlueConversationSnapshot } from "@flue/sdk"; - -export const RUNBOOK_IR_FENCE = "runbook-ir"; - -const runbookIrFencePattern = /```runbook-ir\s*\n([\s\S]*?)```/g; - -export const latestRunbookIrBlock = (text: string): string | undefined => { - const matches = [...text.matchAll(runbookIrFencePattern)]; - const last = matches.at(-1)?.[1]; - return last === undefined ? undefined : last.trim(); +import { + latestRunbookIrBlock, + recoverRunbookWorkpiece, + RUNBOOK_IR_FENCE, + type RecoveredRunbookWorkpiece, +} from "../../conversation/workpiece.ts"; + +import type { FlueConversationSnapshot } from "@flue/sdk"; + +export { + latestRunbookIrBlock, + recoverRunbookWorkpiece, + RUNBOOK_IR_FENCE, + type RecoveredRunbookWorkpiece, }; export const recoverRunbookIr = ( snapshot: FlueConversationSnapshot, ): string | undefined => recoverRunbookWorkpiece(snapshot)?.content; -export interface RecoveredRunbookWorkpiece { - readonly content: string; - readonly sha256: string; - readonly sourceMessageId: string; - readonly sourceMessageSha256: string; -} - -export const recoverRunbookWorkpiece = ( - snapshot: FlueConversationSnapshot, -): RecoveredRunbookWorkpiece | undefined => { - let recovered: RecoveredRunbookWorkpiece | undefined; - for (const message of snapshot.messages) { - if (message.purpose !== "assistant") continue; - const text = message.parts - .filter( - (part): part is Extract => - part.type === "text", - ) - .map((part) => part.text) - .join("\n"); - const content = latestRunbookIrBlock(text); - if (content === undefined) continue; - recovered = { - content, - sha256: sha256(content), - sourceMessageId: message.id, - sourceMessageSha256: sha256(JSON.stringify(message)), - }; - } - return recovered; -}; - export const interviewerToolNamesFrom = ( snapshot: FlueConversationSnapshot, ): readonly string[] => [ diff --git a/apps/brunch-agent/src/evaluations/runbook/headless-petrinaut-client.ts b/apps/brunch-agent/src/evaluations/runbook/headless-petrinaut-client.ts index 54cce1b64ee..b654e17eebf 100644 --- a/apps/brunch-agent/src/evaluations/runbook/headless-petrinaut-client.ts +++ b/apps/brunch-agent/src/evaluations/runbook/headless-petrinaut-client.ts @@ -12,7 +12,7 @@ import { getLatestNetDefinitionToolName, } from "@hashintel/petrinaut-core/ai"; -import type { Petrinaut } from "@hashintel/petrinaut-core"; +import type { Petrinaut, SDCPN } from "@hashintel/petrinaut-core"; export interface HeadlessPetrinautToolCall { readonly toolCallId: string; @@ -45,15 +45,18 @@ const constructionToolNames = new Set( const errorMessageFrom = (error: unknown): string => error instanceof Error ? error.message : String(error); -export const createHeadlessPetrinautClient = (title: string) => { +export const createHeadlessPetrinautClient = ( + title: string, + initial: SDCPN = { + places: [], + transitions: [], + types: [], + parameters: [], + differentialEquations: [], + }, +) => { const handle = createJsonDocHandle({ - initial: { - places: [], - transitions: [], - types: [], - parameters: [], - differentialEquations: [], - }, + initial, }); const instance = createPetrinaut({ document: handle }); const writableCallbacks = createPetrinautAiWritableCallbacks( diff --git a/apps/brunch-agent/test/architecture/boundaries.integration.ts b/apps/brunch-agent/test/architecture/boundaries.integration.ts index 5e4d4355c84..5aa1feea1fa 100644 --- a/apps/brunch-agent/test/architecture/boundaries.integration.ts +++ b/apps/brunch-agent/test/architecture/boundaries.integration.ts @@ -379,13 +379,14 @@ describe("recorded Flue constraints hold by construction (spec §10)", () => { }); describe("core auxiliary subpaths stay in their assigned lanes", () => { - test("core exposes Flue composition, browser contracts, and storage support as explicit subpaths", () => { + test("core exposes Flue composition, browser, storage, and workpiece contracts as explicit subpaths", () => { const core = PACKAGES.find((pkg) => pkg.name === CORE)!; expect(Object.keys(core.manifest.exports ?? {})).toEqual([ ".", "./client-tools", "./flue", "./storage", + "./workpiece", ]); }); @@ -429,6 +430,8 @@ describe("the HASH smoke is runnable without a model key or a network (spec §12 "Types Flue's public conversation snapshot so the transcript projector can be unit-tested; the import is type-only — no provider key, no socket, no model call, no runtime boot.", "apps/brunch-agent/test/petrinaut-chat.integration.ts": "Boots the plain Flue chat agent on Flue's node runtime with pi-ai's faux provider, drives the browser ChatTransport against the mounted Flue route over app.fetch, and proves streamed reasoning/text, server tools, client-tool resume, SDK history ownership, SQLite restart, and harness-side idempotent apply-sweep — no provider key, no socket, no extraction model call. Run as a child process by petrinaut-chat.test.ts.", + "apps/brunch-agent/test/prepared-workpiece.integration.ts": + "Boots the built Flue ChatAgent with pi-ai's faux provider, creates a prepared fixture through one tagged public signal with fixture-scoped initial data, retries its deterministic idempotency key, and proves prepared/model workpiece selection from canonical history — no provider key, socket, or network model call.", "apps/brunch-agent/test/proof-artifacts.test.ts": "Types Flue's public conversation snapshot so canonical trace derivation, workpiece binding, and atomic evidence retention can be unit-tested against an in-memory fixture — no provider key, no socket, no model call, no runtime boot.", "apps/brunch-agent/test/runbook-artifacts.test.ts": @@ -437,6 +440,8 @@ describe("the HASH smoke is runnable without a model key or a network (spec §12 "Defines the scripted pi-ai faux provider loaded only by the hermetic prospective-runner test — no provider key, no socket, and no network model call.", "apps/brunch-agent/test/runbook-headless.integration.ts": "Boots the built Flue ChatAgent with pi-ai's faux provider and a headless Petrinaut client to prove validated construct-only tool flow without a provider key, socket, or network model call.", + "apps/brunch-agent/test/workpiece.test.ts": + "Types Flue's public conversation snapshot so the substrate-neutral workpiece selector and app-owned SHA-256 projection can be unit-tested against in-memory messages — no provider key, no socket, no model call, no runtime boot.", "libs/@hashintel/brunch-agent/packages/transport-aisdk/test/chat-transport.test.ts": "Types a stubbed public Flue client and stream chunks to prove finite AI SDK projection and client-tool signal admission — no runtime boot, provider key, socket, or model call.", "libs/@hashintel/brunch-agent/packages/transport-aisdk/test/transcript.test.ts": diff --git a/apps/brunch-agent/test/architecture/boundaries.test.ts b/apps/brunch-agent/test/architecture/boundaries.test.ts new file mode 100644 index 00000000000..712624bb2b6 --- /dev/null +++ b/apps/brunch-agent/test/architecture/boundaries.test.ts @@ -0,0 +1,5 @@ +/** + * Keep the filesystem-wide architecture suite runnable by Vitest while its + * implementation remains a non-test entry point for boundary self-inspection. + */ +import "./boundaries.integration.ts"; diff --git a/apps/brunch-agent/test/prepared-workpiece.integration.test.ts b/apps/brunch-agent/test/prepared-workpiece.integration.test.ts new file mode 100644 index 00000000000..25f523efb82 --- /dev/null +++ b/apps/brunch-agent/test/prepared-workpiece.integration.test.ts @@ -0,0 +1,70 @@ +import { mkdtemp, rm } from "node:fs/promises"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; + +import { expect, test } from "vitest"; + +import { runNodeScript } from "./run-node-script"; + +test("the built ChatAgent preserves prepared and model workpiece provenance", async () => { + const databaseDirectory = await mkdtemp( + join(tmpdir(), "brunch-prepared-workpiece-"), + ); + try { + const { exitCode, stdout, stderr } = await runNodeScript( + join(import.meta.dirname, "prepared-workpiece.integration.ts"), + join(import.meta.dirname, "../../.."), + { + BRUNCH_CHAT_DB_PATH: join(databaseDirectory, "conversations.db"), + }, + ); + expect(exitCode, stderr || stdout).toBe(0); + const resultLine = stdout + .split("\n") + .find((line) => line.startsWith("PREPARED_WORKPIECE_HERMETIC ")); + expect(resultLine, stdout).toBeDefined(); + const result = JSON.parse( + resultLine!.slice("PREPARED_WORKPIECE_HERMETIC ".length), + ) as { + readonly clientToolCallIds: string[]; + readonly messageCountStableAcrossRetry: boolean; + readonly prepared: { + readonly authorship: string; + readonly content: string; + readonly sourceKind: string; + }; + readonly preparedDispatchCount: number; + readonly preparationSubmissionId: string; + readonly retryDeduplicated: boolean; + readonly retrySubmissionId: string; + readonly targetArcAdded: boolean; + readonly revision: { + readonly authorship: string; + readonly content: string; + readonly sourceKind: string; + }; + }; + + expect(result.retryDeduplicated).toBe(true); + expect(result.retrySubmissionId).toBe(result.preparationSubmissionId); + expect(result.messageCountStableAcrossRetry).toBe(true); + expect(result.preparedDispatchCount).toBe(1); + expect(result.clientToolCallIds).toEqual([ + "fixture-read-before-mutation", + "fixture-add-reservation-arc", + ]); + expect(result.targetArcAdded).toBe(true); + expect(result.prepared).toMatchObject({ + authorship: "test-authored", + content: "# Prepared revision\n\nTiming and recovery remain unresolved.", + sourceKind: "prepared-signal", + }); + expect(result.revision).toMatchObject({ + authorship: "model-produced", + sourceKind: "assistant", + }); + expect(result.revision.content).toContain("# Model revision one"); + } finally { + await rm(databaseDirectory, { recursive: true, force: true }); + } +}); diff --git a/apps/brunch-agent/test/prepared-workpiece.integration.ts b/apps/brunch-agent/test/prepared-workpiece.integration.ts new file mode 100644 index 00000000000..fa149429435 --- /dev/null +++ b/apps/brunch-agent/test/prepared-workpiece.integration.ts @@ -0,0 +1,276 @@ +import { tmpdir } from "node:os"; +import { join } from "node:path"; + +import { + fauxAssistantMessage, + fauxProvider, + fauxText, + fauxToolCall, +} from "@earendil-works/pi-ai"; +import { setProvider } from "@flue/runtime"; +import { createFlueClient } from "@flue/sdk"; + +import { + PETRINAUT_FIXTURE_TOOL_NAMES, + VALIDATED_FIXTURE_MUTATION_MODE, +} from "@hashintel/brunch-agent-plugin-sdcpn/flue"; + +import { + CLIENT_TOOL_RESULT_SIGNAL, + isAwaitingClient, +} from "../src/conversation/client-tools.ts"; +import { + agentOwnershipHeaders, + flueConversationIdFrom, +} from "../src/conversation/identity.ts"; +import { + createPreparedWorkpieceDelivery, + recoverRunbookWorkpiece, +} from "../src/conversation/workpiece.ts"; +import { createHeadlessPetrinautClient } from "../src/evaluations/runbook/headless-petrinaut-client.ts"; +import { loadBuiltBrunchApplication } from "../src/evaluations/runbook/load-built-application.ts"; +import { CHAT_AGENT_ROUTE } from "../src/http/routes.ts"; + +const modelId = "claude-haiku-4-5"; +const dispatchCrewPlaceId = "dispatch_crew_available"; +const startFinalInspectionTransitionId = "start_final_inspection"; +const preparedBody = [ + "Fixture authorship: test-authored.", + "```runbook-ir", + "# Prepared revision", + "", + "Timing and recovery remain unresolved.", + "```", +].join("\n"); +const preparedDelivery = createPreparedWorkpieceDelivery({ + body: preparedBody, + fixtureId: "crew-reservation-v1", + revision: 0, +}); + +process.env.BRUNCH_CHAT_MODEL = modelId; +process.env.BRUNCH_DEV_DB_PATH = + process.env.BRUNCH_CHAT_DB_PATH ?? + join(tmpdir(), `brunch-prepared-workpiece-${crypto.randomUUID()}.db`); + +const provider = fauxProvider({ + provider: "anthropic", + models: [{ id: modelId, reasoning: true }], +}); +setProvider(provider.provider); +provider.setResponses([ + fauxAssistantMessage([ + fauxText( + [ + "Preparation acknowledged.", + "```runbook-ir", + "# Echo that must not become a model revision", + "```", + ].join("\n"), + ), + ]), + fauxAssistantMessage( + [ + fauxToolCall( + "getLatestNetDefinition", + {}, + { id: "fixture-read-before-mutation" }, + ), + ], + { stopReason: "toolUse" }, + ), + fauxAssistantMessage( + [ + fauxToolCall( + "addArc", + { + transitionId: startFinalInspectionTransitionId, + arcDirection: "input", + placeId: dispatchCrewPlaceId, + weight: 1, + }, + { id: "fixture-add-reservation-arc" }, + ), + ], + { stopReason: "toolUse" }, + ), + fauxAssistantMessage([ + fauxText( + [ + "Confirmation incorporated while retaining the unknown.", + "```runbook-ir", + "# Model revision one", + "", + "The sole crew is reserved for final inspection and returned by sign-off.", + "", + "Timing and recovery remain unresolved.", + "```", + ].join("\n"), + ), + ]), +]); + +const identity = { + principalKey: "prepared-workpiece-test", + conversationId: "prepared-workpiece-test", +}; +const application = await loadBuiltBrunchApplication(); +const petrinautClient = createHeadlessPetrinautClient( + "Prepared crew reservation", + { + types: [], + parameters: [], + places: [ + { + id: dispatchCrewPlaceId, + name: "Dispatch crew available", + colorId: null, + dynamicsEnabled: false, + differentialEquationId: null, + x: 0, + y: 0, + }, + ], + transitions: [ + { + id: startFinalInspectionTransitionId, + name: "Start final inspection", + inputArcs: [], + outputArcs: [], + lambdaType: "predicate", + lambdaCode: "", + transitionKernelCode: "", + x: 180, + y: 0, + }, + ], + differentialEquations: [], + }, +); + +try { + const transport: typeof fetch = async (input, init) => + application.fetch( + input instanceof Request ? input : new Request(input, init), + ); + const client = createFlueClient({ + url: `http://brunch.local/agents/${CHAT_AGENT_ROUTE}/${flueConversationIdFrom(identity)}`, + fetch: transport, + headers: agentOwnershipHeaders(identity), + }); + const preparationPrompt = { + uid: null, + initialData: { mode: VALIDATED_FIXTURE_MUTATION_MODE }, + ...preparedDelivery, + } as const; + const preparation = await client.send(preparationPrompt); + await client.wait(preparation); + const preparedSnapshot = await client.history(); + const recoveredPrepared = recoverRunbookWorkpiece(preparedSnapshot); + + const retry = await client.send(preparationPrompt); + const afterRetry = await client.history(); + + const confirmation = await client.send({ + message: { + kind: "user", + body: "Final inspection consumes the sole crew; sign-off returns it.", + }, + }); + await client.wait(confirmation); + const completedCallIds = new Set(); + const serviceClientCalls = async (clientRound: number): Promise => { + if (clientRound >= 5) { + throw new Error("Prepared fixture exceeded five client-tool rounds."); + } + const snapshot = await client.history(); + const pendingCalls = snapshot.messages.flatMap((message) => + message.parts.flatMap((part) => { + if ( + part.type !== "dynamic-tool" || + !PETRINAUT_FIXTURE_TOOL_NAMES.includes( + part.toolName as (typeof PETRINAUT_FIXTURE_TOOL_NAMES)[number], + ) || + completedCallIds.has(part.toolCallId) || + part.state !== "output-available" || + !isAwaitingClient(part.output) + ) { + return []; + } + return [ + { + toolCallId: part.toolCallId, + toolName: part.toolName, + input: part.input, + }, + ]; + }), + ); + if (pendingCalls.length === 0) return; + + const results = await Promise.all( + pendingCalls.map((pendingCall) => petrinautClient.execute(pendingCall)), + ); + for (const result of results) completedCallIds.add(result.toolCallId); + const continuation = await client.send({ + message: { + kind: "signal", + type: CLIENT_TOOL_RESULT_SIGNAL, + tagName: CLIENT_TOOL_RESULT_SIGNAL, + body: JSON.stringify(results), + }, + }); + await client.wait(continuation); + await serviceClientCalls(clientRound + 1); + }; + await serviceClientCalls(0); + const revisedSnapshot = await client.history(); + const recoveredRevision = recoverRunbookWorkpiece(revisedSnapshot); + + process.stdout.write( + `PREPARED_WORKPIECE_HERMETIC ${JSON.stringify({ + preparationSubmissionId: preparation.submissionId, + retrySubmissionId: retry.submissionId, + retryDeduplicated: retry.deduplicated === true, + messageCountStableAcrossRetry: + preparedSnapshot.messages.length === afterRetry.messages.length, + prepared: recoveredPrepared, + revision: recoveredRevision, + clientToolCallIds: [...completedCallIds], + dynamicTools: revisedSnapshot.messages.flatMap((message) => + message.parts.flatMap((part) => + part.type === "dynamic-tool" + ? [ + { + toolCallId: part.toolCallId, + toolName: part.toolName, + state: part.state, + output: part.output, + errorText: part.errorText, + }, + ] + : [], + ), + ), + targetArcAdded: + petrinautClient + .definition() + .transitions.find(({ id }) => id === startFinalInspectionTransitionId) + ?.inputArcs.some( + (arc) => + arc.placeId === dispatchCrewPlaceId && + arc.type === "standard" && + arc.weight === 1, + ) === true, + preparedDispatchCount: revisedSnapshot.messages.filter( + (message) => + message.role === "system" && + message.purpose === "dispatch" && + message.signal?.tagName === "prepared-fixture", + ).length, + })}\n`, + ); +} finally { + petrinautClient.dispose(); + await application.stop(); +} diff --git a/apps/brunch-agent/test/workpiece.test.ts b/apps/brunch-agent/test/workpiece.test.ts new file mode 100644 index 00000000000..31419118c6a --- /dev/null +++ b/apps/brunch-agent/test/workpiece.test.ts @@ -0,0 +1,135 @@ +import { describe, expect, test } from "vitest"; + +import { + PREPARED_WORKPIECE_AUTHORSHIP, + PREPARED_WORKPIECE_CLAIM_BOUNDARY, + PREPARED_WORKPIECE_SIGNAL_TAG, + recoverRunbookWorkpiece, +} from "../src/conversation/workpiece.ts"; + +import type { + FlueConversationMessage, + FlueConversationSnapshot, +} from "@flue/sdk"; + +const workpiece = (name: string): string => + `\`\`\`runbook-ir\n# ${name}\n\`\`\``; + +const preparedMessage = ( + id = "prepared", + submissionId = "prepare-submission", +): FlueConversationMessage => ({ + id, + role: "system", + purpose: "dispatch", + display: "diagnostic", + submissionId, + signal: { + tagName: PREPARED_WORKPIECE_SIGNAL_TAG, + attributes: { + authorship: PREPARED_WORKPIECE_AUTHORSHIP, + claimBoundary: PREPARED_WORKPIECE_CLAIM_BOUNDARY, + fixtureId: "crew-reservation-v1", + }, + }, + parts: [{ type: "text", text: workpiece("Prepared"), state: "done" }], +}); + +const assistantMessage = ( + id: string, + submissionId: string, + name: string, +): FlueConversationMessage => ({ + id, + role: "assistant", + purpose: "assistant", + display: "visible", + submissionId, + parts: [{ type: "text", text: workpiece(name), state: "done" }], +}); + +const snapshot = ( + messages: FlueConversationMessage[], +): FlueConversationSnapshot => ({ + v: 1, + conversationId: "conversation", + offset: "1", + messages, + settlements: [], +}); + +describe("recoverRunbookWorkpiece", () => { + test("recovers the tagged prepared source without relabelling its authorship", () => { + expect( + recoverRunbookWorkpiece(snapshot([preparedMessage()])), + ).toMatchObject({ + authorship: "test-authored", + content: "# Prepared", + sourceKind: "prepared-signal", + sourceMessageId: "prepared", + sourceSubmissionId: "prepare-submission", + }); + }); + + test("does not treat the preparation response as a model-authored revision", () => { + expect( + recoverRunbookWorkpiece( + snapshot([ + preparedMessage(), + assistantMessage( + "preparation-response", + "prepare-submission", + "Echoed by preparation response", + ), + ]), + ), + ).toMatchObject({ + authorship: "test-authored", + content: "# Prepared", + sourceKind: "prepared-signal", + }); + }); + + test("selects the latest genuine assistant revision", () => { + expect( + recoverRunbookWorkpiece( + snapshot([ + preparedMessage(), + assistantMessage("revision-1", "turn-1", "Revision one"), + assistantMessage("revision-2", "turn-2", "Revision two"), + ]), + ), + ).toMatchObject({ + authorship: "model-produced", + content: "# Revision two", + sourceKind: "assistant", + sourceMessageId: "revision-2", + sourceSubmissionId: "turn-2", + }); + }); + + test("retains ordinary assistant-only workpiece recovery", () => { + expect( + recoverRunbookWorkpiece( + snapshot([ + assistantMessage("ordinary", "ordinary-turn", "Ordinary workpiece"), + ]), + ), + ).toMatchObject({ + authorship: "model-produced", + content: "# Ordinary workpiece", + sourceKind: "assistant", + }); + }); + + test("fails rather than choosing between multiple prepared sources", () => { + expect(() => + recoverRunbookWorkpiece( + snapshot([ + preparedMessage("prepared-1"), + preparedMessage("prepared-2", "prepare-submission-2"), + ]), + ), + ).toThrow(/more than one prepared workpiece source/u); + }); +}); diff --git a/apps/petrinaut-website/src/main/app/local-storage-demo/brunch-panel-transport.test.ts b/apps/petrinaut-website/src/main/app/local-storage-demo/brunch-panel-transport.test.ts index 6df757d8614..78d0abc3b90 100644 --- a/apps/petrinaut-website/src/main/app/local-storage-demo/brunch-panel-transport.test.ts +++ b/apps/petrinaut-website/src/main/app/local-storage-demo/brunch-panel-transport.test.ts @@ -3,6 +3,7 @@ import { expect, test, vi } from "vitest"; import { BrunchPanelConversationTracker, createBrunchPanelTransport, + createUnavailableBrunchPanelTransport, } from "./brunch-panel-transport"; import type { AgentSendResult, FlueClient } from "@flue/sdk"; @@ -71,6 +72,7 @@ test("delegates one typed message to the supplied Flue conversation", async () = expect(send).toHaveBeenCalledOnce(); expect(send).toHaveBeenCalledWith({ + idempotencyKey: "ai-sdk:user:user-1", message: { kind: "user", body: "Typed tracer." }, signal: undefined, }); @@ -175,3 +177,80 @@ test("settles in-flight submissions before a durable abort can target them", asy await expect(rejected).rejects.toThrow("rejected admission"); await expect(tracker.settleInFlightSubmissions()).resolves.toBeUndefined(); }); + +test("returns a fixture-scoped mutation result through the same Flue client", async () => { + const admission: AgentSendResult = { + streamUrl: "http://brunch.test/stream", + offset: "offset-2", + submissionId: "submission-2", + uid: "uid-2", + }; + const send = vi.fn(async () => admission); + const wait = vi.fn(async () => {}); + const client = { + send, + wait, + } as Pick as FlueClient; + const transport = createBrunchPanelTransport( + Promise.resolve(client), + new BrunchPanelConversationTracker(), + { clientToolNames: new Set(["addArc"]) }, + ); + const stream = await transport.sendMessages({ + trigger: "submit-message", + chatId: "conversation-stable", + messageId: "assistant-1", + messages: [ + { + id: "assistant-1", + role: "assistant", + parts: [ + { + type: "dynamic-tool", + toolName: "addArc", + toolCallId: "add-arc-1", + state: "output-available", + input: {}, + output: { applied: true }, + }, + ], + }, + ], + abortSignal: undefined, + }); + await stream.pipeTo(new WritableStream()); + + expect(send).toHaveBeenCalledWith({ + idempotencyKey: "ai-sdk:client-tools:assistant-1:add-arc-1", + message: { + kind: "signal", + type: "client-tool-result", + tagName: "client-tool-result", + body: JSON.stringify([ + { + toolCallId: "add-arc-1", + toolName: "addArc", + output: { applied: true }, + }, + ]), + attributes: { toolCallIds: "add-arc-1" }, + }, + signal: undefined, + }); +}); + +test("refuses fixture traffic when the mounted Flue route is unavailable", async () => { + const transport = createUnavailableBrunchPanelTransport( + "Fixture route unavailable.", + ); + + await expect( + transport.sendMessages({ + trigger: "submit-message", + chatId: "conversation-stable", + messageId: undefined, + messages: [], + abortSignal: undefined, + }), + ).rejects.toThrow("Fixture route unavailable."); +}); diff --git a/apps/petrinaut-website/src/main/app/local-storage-demo/brunch-panel-transport.ts b/apps/petrinaut-website/src/main/app/local-storage-demo/brunch-panel-transport.ts index 973075debb3..8e28759287d 100644 --- a/apps/petrinaut-website/src/main/app/local-storage-demo/brunch-panel-transport.ts +++ b/apps/petrinaut-website/src/main/app/local-storage-demo/brunch-panel-transport.ts @@ -233,7 +233,9 @@ const decorateBrunchStream = ( export const createBrunchPanelTransport = ( clientPromise: Promise, tracker: BrunchPanelConversationTracker, - hooks?: { + options?: { + /** Fixture-scoped client tools; defaults to the Petrinaut docs reader alone. */ + readonly clientToolNames?: ReadonlySet; readonly onAdmission?: (admission: AgentSendResult) => void; }, ): PetrinautAiChatTransport => ({ @@ -244,10 +246,10 @@ export const createBrunchPanelTransport = ( const client = await clientPromise; const transport = createFlueChatTransport({ client, - clientToolNames: brunchClientToolNames, + clientToolNames: options?.clientToolNames ?? brunchClientToolNames, onAdmission: (event) => { tracker.recordAdmission(event); - hooks?.onAdmission?.(event.admission); + options?.onAdmission?.(event.admission); }, onResponseMessage: ({ messageId, submissionId }) => tracker.recordResponse(messageId, submissionId), @@ -256,3 +258,12 @@ export const createBrunchPanelTransport = ( })(), ), }); + +export const createUnavailableBrunchPanelTransport = ( + reason: string, +): PetrinautAiChatTransport => ({ + reconnectToStream: async () => null, + sendMessages: async () => { + throw new Error(reason); + }, +}); diff --git a/apps/petrinaut-website/src/main/app/local-storage-demo/crew-reservation-settled-manifest.test.ts b/apps/petrinaut-website/src/main/app/local-storage-demo/crew-reservation-settled-manifest.test.ts new file mode 100644 index 00000000000..32bc94f8d21 --- /dev/null +++ b/apps/petrinaut-website/src/main/app/local-storage-demo/crew-reservation-settled-manifest.test.ts @@ -0,0 +1,380 @@ +import { describe, expect, test } from "vitest"; + +import { + PREPARED_WORKPIECE_AUTHORSHIP, + PREPARED_WORKPIECE_CLAIM_BOUNDARY, + PREPARED_WORKPIECE_SIGNAL_TAG, + type WorkpieceHistoryMessage, +} from "@hashintel/brunch-agent/workpiece"; + +import { + hasCrewReservationTargetArc, + settleCrewReservationManifest, +} from "./crew-reservation-settled-manifest"; +import { + CREW_RESERVATION_FIXTURE_ID, + DISPATCH_CREW_PLACE_ID, + preparedCrewReservationNet, + preparedCrewReservationWorkpiece, + START_FINAL_INSPECTION_TRANSITION_ID, +} from "./prepared-crew-reservation-fixture"; + +const preparedMessage: WorkpieceHistoryMessage = { + id: "prepared-message", + role: "system", + purpose: "dispatch", + submissionId: "prepare-submission", + signal: { + tagName: PREPARED_WORKPIECE_SIGNAL_TAG, + attributes: { + fixtureId: CREW_RESERVATION_FIXTURE_ID, + authorship: PREPARED_WORKPIECE_AUTHORSHIP, + claimBoundary: PREPARED_WORKPIECE_CLAIM_BOUNDARY, + }, + }, + parts: [ + { + type: "text", + text: preparedCrewReservationWorkpiece, + }, + ], +}; + +const settledHistory = ( + messages: readonly WorkpieceHistoryMessage[] = [preparedMessage], +) => ({ + conversationId: "canonical-flue-conversation", + offset: "10", + messages, + settlements: [{ submissionId: "prepare-submission", outcome: "completed" }], +}); + +const targetMutationMessages = (): readonly [ + WorkpieceHistoryMessage, + WorkpieceHistoryMessage, +] => [ + { + id: "target-mutation-request", + role: "assistant", + purpose: "assistant", + submissionId: "confirmation-turn", + parts: [ + { + type: "dynamic-tool", + toolCallId: "target-arc-call", + toolName: "addArc", + input: { + transitionId: START_FINAL_INSPECTION_TRANSITION_ID, + arcDirection: "input", + placeId: DISPATCH_CREW_PLACE_ID, + weight: 1, + }, + }, + ], + }, + { + id: "target-mutation-result", + role: "system", + purpose: "dispatch", + submissionId: "mutation-continuation", + signal: { + tagName: "client-tool-result", + }, + parts: [ + { + type: "text", + text: JSON.stringify([ + { + toolCallId: "target-arc-call", + toolName: "addArc", + output: { applied: true }, + }, + ]), + }, + ], + }, +]; + +describe("crew-reservation settled manifest", () => { + test("records a coherent prepared bundle without inventing the target arc", async () => { + const result = await settleCrewReservationManifest({ + definition: preparedCrewReservationNet, + history: settledHistory(), + settledAt: "2026-09-03T12:00:00.000Z", + }); + + expect(result).toMatchObject({ + status: "settled", + manifest: { + fixtureId: CREW_RESERVATION_FIXTURE_ID, + revision: 0, + conversation: { + canonicalId: "canonical-flue-conversation", + }, + latestWorkpiece: { + authorship: "test-authored", + sourceMessageId: "prepared-message", + }, + document: { + targetArc: "absent", + }, + }, + }); + }); + + test("advances only after a completed model revision and document change", async () => { + const initial = await settleCrewReservationManifest({ + definition: preparedCrewReservationNet, + history: settledHistory(), + settledAt: "2026-09-03T12:00:00.000Z", + }); + if (initial.status !== "settled") { + throw new Error("Expected the prepared fixture to settle"); + } + + const revisedMessage: WorkpieceHistoryMessage = { + id: "revised-workpiece", + role: "assistant", + purpose: "assistant", + submissionId: "confirmation-turn", + parts: [ + { + type: "text", + text: preparedCrewReservationWorkpiece.replace( + "It deliberately lacks", + "The confirmation resolves", + ), + }, + ], + }; + const revisedDefinition = structuredClone(preparedCrewReservationNet); + const startInspection = revisedDefinition.transitions.find( + ({ id }) => id === START_FINAL_INSPECTION_TRANSITION_ID, + ); + if (startInspection === undefined) { + throw new Error("Missing prepared start-inspection transition"); + } + startInspection.inputArcs.push({ + placeId: DISPATCH_CREW_PLACE_ID, + type: "standard", + weight: 1, + }); + + const result = await settleCrewReservationManifest({ + definition: revisedDefinition, + history: { + ...settledHistory([ + preparedMessage, + ...targetMutationMessages(), + revisedMessage, + ]), + offset: "20", + settlements: [ + { submissionId: "prepare-submission", outcome: "completed" }, + { submissionId: "confirmation-turn", outcome: "completed" }, + ], + }, + previous: initial.manifest, + settledAt: "2026-09-03T12:05:00.000Z", + }); + + expect(hasCrewReservationTargetArc(revisedDefinition)).toBe(true); + expect(result).toMatchObject({ + status: "settled", + manifest: { + revision: 1, + latestWorkpiece: { authorship: "model-produced" }, + document: { targetArc: "present" }, + }, + }); + }); + + test("refuses a model revision without one successful correlated target mutation", async () => { + const revisedMessage: WorkpieceHistoryMessage = { + id: "revised-workpiece", + role: "assistant", + purpose: "assistant", + submissionId: "confirmation-turn", + parts: [{ type: "text", text: preparedCrewReservationWorkpiece }], + }; + const revisedDefinition = structuredClone(preparedCrewReservationNet); + const startInspection = revisedDefinition.transitions.find( + ({ id }) => id === START_FINAL_INSPECTION_TRANSITION_ID, + ); + if (startInspection === undefined) { + throw new Error("Missing prepared start-inspection transition"); + } + startInspection.inputArcs.push({ + placeId: DISPATCH_CREW_PLACE_ID, + type: "standard", + weight: 1, + }); + const history = { + ...settledHistory([preparedMessage, revisedMessage]), + settlements: [ + { submissionId: "prepare-submission", outcome: "completed" }, + { submissionId: "confirmation-turn", outcome: "completed" }, + ], + }; + + await expect( + settleCrewReservationManifest({ + definition: revisedDefinition, + history, + settledAt: "2026-09-03T12:05:00.000Z", + }), + ).resolves.toEqual({ + status: "refused", + reason: "missing-correlated-mutation", + }); + + const [targetCall, targetResult] = targetMutationMessages(); + await expect( + settleCrewReservationManifest({ + definition: revisedDefinition, + history: { + ...history, + messages: [ + preparedMessage, + targetCall, + { + ...targetResult, + parts: [ + { + type: "text", + text: JSON.stringify([ + { + toolCallId: "target-arc-call", + toolName: "addArc", + output: { applied: false, reason: "no-op" }, + }, + ]), + }, + ], + }, + revisedMessage, + ], + }, + settledAt: "2026-09-03T12:05:00.000Z", + }), + ).resolves.toEqual({ + status: "refused", + reason: "missing-correlated-mutation", + }); + + await expect( + settleCrewReservationManifest({ + definition: revisedDefinition, + history: { + ...history, + messages: [ + preparedMessage, + ...targetMutationMessages(), + targetMutationMessages()[1], + revisedMessage, + ], + }, + settledAt: "2026-09-03T12:05:00.000Z", + }), + ).resolves.toEqual({ + status: "refused", + reason: "missing-correlated-mutation", + }); + }); + + test("retains the previous bundle when recovery is partial", async () => { + const initial = await settleCrewReservationManifest({ + definition: preparedCrewReservationNet, + history: settledHistory(), + settledAt: "2026-09-03T12:00:00.000Z", + }); + if (initial.status !== "settled") { + throw new Error("Expected the prepared fixture to settle"); + } + + await expect( + settleCrewReservationManifest({ + definition: preparedCrewReservationNet, + history: { + ...settledHistory(), + conversationId: "different-conversation", + }, + previous: initial.manifest, + settledAt: "2026-09-03T12:05:00.000Z", + }), + ).resolves.toEqual({ + status: "refused", + reason: "conversation-mismatch", + }); + + await expect( + settleCrewReservationManifest({ + definition: preparedCrewReservationNet, + history: { + ...settledHistory(), + settlements: [], + }, + previous: initial.manifest, + settledAt: "2026-09-03T12:05:00.000Z", + }), + ).resolves.toEqual({ + status: "refused", + reason: "missing-completed-settlement", + }); + }); + + test("does not publish a new revision for an unchanged coherent bundle", async () => { + const initial = await settleCrewReservationManifest({ + definition: preparedCrewReservationNet, + history: settledHistory(), + settledAt: "2026-09-03T12:00:00.000Z", + }); + if (initial.status !== "settled") { + throw new Error("Expected the prepared fixture to settle"); + } + + await expect( + settleCrewReservationManifest({ + definition: preparedCrewReservationNet, + history: { ...settledHistory(), offset: "11" }, + previous: initial.manifest, + settledAt: "2026-09-03T12:05:00.000Z", + }), + ).resolves.toEqual(initial); + }); + + test("keeps the prepared bundle selected when the document changes first", async () => { + const initial = await settleCrewReservationManifest({ + definition: preparedCrewReservationNet, + history: settledHistory(), + settledAt: "2026-09-03T12:00:00.000Z", + }); + if (initial.status !== "settled") { + throw new Error("Expected the prepared fixture to settle"); + } + const partialDefinition = structuredClone(preparedCrewReservationNet); + const startInspection = partialDefinition.transitions.find( + ({ id }) => id === START_FINAL_INSPECTION_TRANSITION_ID, + ); + if (startInspection === undefined) { + throw new Error("Missing prepared start-inspection transition"); + } + startInspection.inputArcs.push({ + placeId: DISPATCH_CREW_PLACE_ID, + type: "standard", + weight: 1, + }); + + await expect( + settleCrewReservationManifest({ + definition: partialDefinition, + history: settledHistory(), + previous: initial.manifest, + settledAt: "2026-09-03T12:05:00.000Z", + }), + ).resolves.toEqual({ + status: "refused", + reason: "bundle-mismatch", + }); + }); +}); diff --git a/apps/petrinaut-website/src/main/app/local-storage-demo/crew-reservation-settled-manifest.ts b/apps/petrinaut-website/src/main/app/local-storage-demo/crew-reservation-settled-manifest.ts new file mode 100644 index 00000000000..a3bea28e98a --- /dev/null +++ b/apps/petrinaut-website/src/main/app/local-storage-demo/crew-reservation-settled-manifest.ts @@ -0,0 +1,289 @@ +import { + selectRunbookWorkpiece, + type WorkpieceHistory, +} from "@hashintel/brunch-agent/workpiece"; +import { isSDCPNEqual, type SDCPN } from "@hashintel/petrinaut-core"; + +import { + CREW_RESERVATION_CONVERSATION_ID, + CREW_RESERVATION_DOCUMENT_ID, + CREW_RESERVATION_FIXTURE_ID, + DISPATCH_CREW_PLACE_ID, + preparedCrewReservationNet, + START_FINAL_INSPECTION_TRANSITION_ID, +} from "./prepared-crew-reservation-fixture"; + +export const CREW_RESERVATION_SETTLED_MANIFEST_STORAGE_KEY = + "brunch:prepared-fixture:crew-reservation-v1:settled"; + +export interface CrewReservationSettledManifest { + readonly conversation: { + readonly canonicalId: string; + readonly logicalId: typeof CREW_RESERVATION_CONVERSATION_ID; + readonly offset: string; + }; + readonly document: { + readonly id: typeof CREW_RESERVATION_DOCUMENT_ID; + readonly sha256: string; + readonly targetArc: "absent" | "present"; + }; + readonly fixtureId: typeof CREW_RESERVATION_FIXTURE_ID; + readonly latestWorkpiece: { + readonly authorship: "model-produced" | "test-authored"; + readonly contentSha256: string; + readonly sourceKind: "assistant" | "prepared-signal"; + readonly sourceMessageId: string; + readonly sourceMessageSha256: string; + readonly sourceSubmissionId: string; + }; + readonly manifestId: string; + readonly revision: number; + readonly settledAt: string; + readonly version: 1; +} + +export type CrewReservationSettlementResult = + | { + readonly manifest: CrewReservationSettledManifest; + readonly status: "settled"; + } + | { + readonly reason: + | "bundle-mismatch" + | "conversation-mismatch" + | "missing-correlated-mutation" + | "missing-completed-settlement" + | "missing-workpiece"; + readonly status: "refused"; + }; + +export type CrewReservationSettledHistory = WorkpieceHistory & { + readonly offset: string; + readonly settlements: readonly { + readonly outcome: string; + readonly submissionId: string; + }[]; +}; + +const isRecord = (value: unknown): value is Record => + typeof value === "object" && value !== null; + +const targetMutationCallIds = ( + history: CrewReservationSettledHistory, +): readonly string[] => + history.messages.flatMap((message) => + message.parts.flatMap((part) => { + if ( + !isRecord(part) || + part.type !== "dynamic-tool" || + part.toolName !== "addArc" || + typeof part.toolCallId !== "string" || + !isRecord(part.input) || + part.input.transitionId !== START_FINAL_INSPECTION_TRANSITION_ID || + part.input.arcDirection !== "input" || + part.input.placeId !== DISPATCH_CREW_PLACE_ID || + part.input.weight !== 1 + ) { + return []; + } + return [part.toolCallId]; + }), + ); + +const successfulMutationResultIds = ( + history: CrewReservationSettledHistory, +): readonly string[] => + history.messages.flatMap((message) => { + if ( + message.signal?.tagName !== "client-tool-result" && + message.signal?.type !== "client-tool-result" + ) { + return []; + } + const body = message.parts + .flatMap((part) => + part.type === "text" && typeof part.text === "string" + ? [part.text] + : [], + ) + .join(""); + try { + const results: unknown = JSON.parse(body); + if (!Array.isArray(results)) return []; + return results.flatMap((result) => { + if ( + !isRecord(result) || + result.toolName !== "addArc" || + typeof result.toolCallId !== "string" || + !isRecord(result.output) || + result.output.applied !== true + ) { + return []; + } + return [result.toolCallId]; + }); + } catch { + return []; + } + }); + +const hasOneCorrelatedTargetMutation = ( + history: CrewReservationSettledHistory, +): boolean => { + const targetCallIds = targetMutationCallIds(history); + const successfulResultIds = successfulMutationResultIds(history); + return ( + targetCallIds.length === 1 && + successfulResultIds.length === 1 && + targetCallIds[0] === successfulResultIds[0] + ); +}; + +const sha256 = async (value: string): Promise => { + const digest = await globalThis.crypto.subtle.digest( + "SHA-256", + new TextEncoder().encode(value), + ); + return [...new Uint8Array(digest)] + .map((byte) => byte.toString(16).padStart(2, "0")) + .join(""); +}; + +export const hasCrewReservationTargetArc = (definition: SDCPN): boolean => { + const transition = definition.transitions.find( + ({ id }) => id === START_FINAL_INSPECTION_TRANSITION_ID, + ); + return ( + transition?.inputArcs.some( + (arc) => + arc.placeId === DISPATCH_CREW_PLACE_ID && + arc.type === "standard" && + arc.weight === 1, + ) ?? false + ); +}; + +const preparedCrewReservationNetWithTargetArc = (): SDCPN => { + const definition = structuredClone(preparedCrewReservationNet); + const transition = definition.transitions.find( + ({ id }) => id === START_FINAL_INSPECTION_TRANSITION_ID, + ); + if (transition === undefined) { + throw new Error("The prepared fixture has no start-inspection transition."); + } + transition.inputArcs.push({ + placeId: DISPATCH_CREW_PLACE_ID, + type: "standard", + weight: 1, + }); + return definition; +}; + +export const settleCrewReservationManifest = async (input: { + readonly definition: SDCPN; + readonly history: CrewReservationSettledHistory; + readonly previous?: CrewReservationSettledManifest; + readonly settledAt: string; +}): Promise => { + if ( + input.previous !== undefined && + input.previous.conversation.canonicalId !== input.history.conversationId + ) { + return { status: "refused", reason: "conversation-mismatch" }; + } + + const workpiece = selectRunbookWorkpiece(input.history); + if (workpiece === undefined || workpiece.sourceSubmissionId === undefined) { + return { status: "refused", reason: "missing-workpiece" }; + } + const sourceSettlement = input.history.settlements.find( + ({ submissionId }) => submissionId === workpiece.sourceSubmissionId, + ); + if (sourceSettlement?.outcome !== "completed") { + return { + status: "refused", + reason: "missing-completed-settlement", + }; + } + const targetArcPresent = hasCrewReservationTargetArc(input.definition); + if ( + workpiece.authorship === "model-produced" && + (!targetArcPresent || + !isSDCPNEqual( + input.definition, + preparedCrewReservationNetWithTargetArc(), + ) || + !hasOneCorrelatedTargetMutation(input.history)) + ) { + return { + status: "refused", + reason: "missing-correlated-mutation", + }; + } + + const [contentSha256, documentSha256, sourceMessageSha256] = + await Promise.all([ + sha256(workpiece.content), + sha256(JSON.stringify(input.definition)), + sha256(JSON.stringify(workpiece.sourceMessage)), + ]); + if (workpiece.authorship === "test-authored") { + const preparedDocumentSha256 = await sha256( + JSON.stringify(preparedCrewReservationNet), + ); + if ( + targetArcPresent || + documentSha256 !== preparedDocumentSha256 || + !isSDCPNEqual(input.definition, preparedCrewReservationNet) + ) { + return { status: "refused", reason: "bundle-mismatch" }; + } + } + if ( + input.previous?.latestWorkpiece.sourceMessageId === + workpiece.sourceMessageId + ) { + if ( + input.previous.document.sha256 !== documentSha256 || + input.previous.latestWorkpiece.sourceMessageSha256 !== + sourceMessageSha256 || + input.previous.latestWorkpiece.contentSha256 !== contentSha256 + ) { + return { status: "refused", reason: "bundle-mismatch" }; + } + return { status: "settled", manifest: input.previous }; + } + const revision = (input.previous?.revision ?? -1) + 1; + const withoutId = { + version: 1 as const, + fixtureId: CREW_RESERVATION_FIXTURE_ID, + revision, + settledAt: input.settledAt, + conversation: { + logicalId: CREW_RESERVATION_CONVERSATION_ID, + canonicalId: input.history.conversationId, + offset: input.history.offset, + }, + latestWorkpiece: { + authorship: workpiece.authorship, + contentSha256, + sourceKind: workpiece.sourceKind, + sourceMessageId: workpiece.sourceMessageId, + sourceMessageSha256, + sourceSubmissionId: workpiece.sourceSubmissionId, + }, + document: { + id: CREW_RESERVATION_DOCUMENT_ID, + sha256: documentSha256, + targetArc: targetArcPresent ? ("present" as const) : ("absent" as const), + }, + } satisfies Omit; + + return { + status: "settled", + manifest: { + ...withoutId, + manifestId: await sha256(JSON.stringify(withoutId)), + }, + }; +}; diff --git a/apps/petrinaut-website/src/main/app/local-storage-demo/local-storage-demo-app.tsx b/apps/petrinaut-website/src/main/app/local-storage-demo/local-storage-demo-app.tsx index 39e4b466fa3..b3aa246df67 100644 --- a/apps/petrinaut-website/src/main/app/local-storage-demo/local-storage-demo-app.tsx +++ b/apps/petrinaut-website/src/main/app/local-storage-demo/local-storage-demo-app.tsx @@ -11,6 +11,7 @@ import { agentOwnershipHeaders, flueConversationIdWeb, } from "@hashintel/brunch-agent-transport-aisdk"; +import { selectRunbookWorkpiece } from "@hashintel/brunch-agent/workpiece"; import { createJsonDocHandle, type MinimalNetMetadata, @@ -50,9 +51,23 @@ import { getOrCreateBrunchConversationId } from "./brunch-conversation-id"; import { BrunchPanelConversationTracker, createBrunchPanelTransport, + createUnavailableBrunchPanelTransport, } from "./brunch-panel-transport"; import { resolveBrunchPreviewConfig } from "./brunch-preview-config"; import { getOrCreateBrunchPrincipal } from "./brunch-principal"; +import { prepareCrewReservationConversation } from "./prepare-crew-reservation-conversation"; +import { + CREW_RESERVATION_CLIENT_TOOL_NAMES, + CREW_RESERVATION_CONVERSATION_ID, + CREW_RESERVATION_DOCUMENT_ID, + isCrewReservationFixtureSelected, + preparedCrewReservationNet, +} from "./prepared-crew-reservation-fixture"; +import { + PreparedFixtureBanner, + PreparedFixtureSelector, +} from "./prepared-fixture-banner"; +import { useCrewReservationSettledManifest } from "./use-crew-reservation-settled-manifest"; import { useFlueChatHistory } from "./use-flue-chat-history"; import { useLocalStorageAiMessages } from "./use-local-storage-ai-messages"; import { @@ -89,6 +104,13 @@ const createDefaultStoredSDCPN = (): SDCPNInLocalStorage => ({ lastUpdated: new Date(0).toISOString(), }); +const preparedCrewReservationStoredSDCPN: SDCPNInLocalStorage = { + id: CREW_RESERVATION_DOCUMENT_ID, + title: "Prepared final inspection and dispatch", + sdcpn: preparedCrewReservationNet, + lastUpdated: new Date(0).toISOString(), +}; + /** * Creates the localStorage record for a newly created net, keeping the generated * id and last-updated timestamp in sync. @@ -152,6 +174,9 @@ const createHandle = (net: SDCPNInLocalStorage): PetrinautDocHandle => }); const brunchPrincipal = getOrCreateBrunchPrincipal(); +const crewReservationClientToolNames: ReadonlySet = new Set( + CREW_RESERVATION_CLIENT_TOOL_NAMES, +); /** Every widget here must answer a tool named in `brunchClientToolNames`. */ export const brunchInteractiveTools: readonly PetrinautAiInteractiveTool[] = [ @@ -201,7 +226,16 @@ const createConversationTrackerFor = ( const getStoredSDCPNsForDisplay = ( storedSDCPNs: Record, + crewReservationFixtureSelected: boolean, ): Record => { + if (crewReservationFixtureSelected) { + return { + ...storedSDCPNs, + [CREW_RESERVATION_DOCUMENT_ID]: + storedSDCPNs[CREW_RESERVATION_DOCUMENT_ID] ?? + preparedCrewReservationStoredSDCPN, + }; + } if (Object.values(storedSDCPNs).length > 0) { return storedSDCPNs; } @@ -351,7 +385,26 @@ export const LocalStorageDemoApp = ({ const { aiMessagesByNetId, setAiMessagesByNetId } = useLocalStorageAiMessages(); const { storedSDCPNs, setStoredSDCPNs } = useLocalStorageSDCPNs(); - const storedSDCPNsForDisplay = getStoredSDCPNsForDisplay(storedSDCPNs); + const crewReservationFixtureSelected = isCrewReservationFixtureSelected( + window.location.search, + ); + const storedSDCPNsForDisplay = getStoredSDCPNsForDisplay( + storedSDCPNs, + crewReservationFixtureSelected, + ); + + useEffect(() => { + if ( + !crewReservationFixtureSelected || + storedSDCPNs[CREW_RESERVATION_DOCUMENT_ID] !== undefined + ) { + return; + } + setStoredSDCPNs((previous) => ({ + ...previous, + [CREW_RESERVATION_DOCUMENT_ID]: preparedCrewReservationStoredSDCPN, + })); + }, [crewReservationFixtureSelected, setStoredSDCPNs, storedSDCPNs]); useEffect(() => { if (!brunchPreviewConfig.isBrunchConfigured) { @@ -377,10 +430,13 @@ export const LocalStorageDemoApp = ({ (a, b) => new Date(b.lastUpdated).getTime() - new Date(a.lastUpdated).getTime(), )[0] ?? null; + const initiallySelectedNet = crewReservationFixtureSelected + ? storedSDCPNsForDisplay[CREW_RESERVATION_DOCUMENT_ID] + : mostRecentlyModifiedNet; // The net currently selected in the UI. const [currentNetId, setCurrentNetId] = useState( - () => mostRecentlyModifiedNet?.id ?? null, + () => initiallySelectedNet?.id ?? null, ); // Metadata and persisted SDCPN snapshot for the selected net. @@ -390,9 +446,7 @@ export const LocalStorageDemoApp = ({ // Live editable document handle for the selected net only. const [activeHandle, setActiveHandle] = useState(() => - mostRecentlyModifiedNet - ? createActiveHandle(mostRecentlyModifiedNet) - : null, + initiallySelectedNet ? createActiveHandle(initiallySelectedNet) : null, ); useEffect(() => { @@ -419,7 +473,9 @@ export const LocalStorageDemoApp = ({ }); }, [activeHandle, setStoredSDCPNs]); - const existingNets: MinimalNetMetadata[] = Object.values(storedSDCPNs) + const existingNets: MinimalNetMetadata[] = Object.values( + storedSDCPNsForDisplay, + ) .map((net) => ({ netId: net.id, title: net.title, @@ -507,16 +563,31 @@ export const LocalStorageDemoApp = ({ ); }; - const conversationId = currentNetId - ? getOrCreateBrunchConversationId(currentNetId) - : null; - const flueClientPromise = useMemo( + const preparedFixtureIsCurrent = + crewReservationFixtureSelected && + currentNetId === CREW_RESERVATION_DOCUMENT_ID; + const conversationId = + currentNetId === null + ? null + : preparedFixtureIsCurrent + ? CREW_RESERVATION_CONVERSATION_ID + : getOrCreateBrunchConversationId(currentNetId); + const rawFlueClientPromise = useMemo( () => brunchPreviewConfig.isBrunchConfigured && conversationId !== null ? createBrunchFlueClient(conversationId) : null, [conversationId], ); + const flueClientPromise = useMemo(() => { + if (rawFlueClientPromise === null || !preparedFixtureIsCurrent) { + return rawFlueClientPromise; + } + return rawFlueClientPromise.then(async (client) => { + await prepareCrewReservationConversation(client); + return client; + }); + }, [preparedFixtureIsCurrent, rawFlueClientPromise]); const conversationTracker = useMemo( // Correlation state belongs to one conversation and must not cross a net switch. () => createConversationTrackerFor(conversationId), @@ -525,6 +596,7 @@ export const LocalStorageDemoApp = ({ const flueHistory = useFlueChatHistory( flueClientPromise, conversationId ?? "", + preparedFixtureIsCurrent ? crewReservationClientToolNames : undefined, ); const brunchVoiceMode = useMemo( () => @@ -535,15 +607,47 @@ export const LocalStorageDemoApp = ({ ), [conversationTracker, flueHistory.settlements, openAIVoiceConfig], ); - const petrinautAiChatTransport = useMemo( - () => - flueClientPromise === null - ? stockChatTransport - : createBrunchPanelTransport(flueClientPromise, conversationTracker, { - onAdmission: flueHistory.refresh, - }), - [conversationTracker, flueClientPromise, flueHistory.refresh], - ); + const { settledManifest, status: settlementStatus } = + useCrewReservationSettledManifest({ + definition: preparedFixtureIsCurrent ? currentNet?.sdcpn : undefined, + enabled: preparedFixtureIsCurrent, + history: preparedFixtureIsCurrent ? flueHistory.snapshot : undefined, + historyError: preparedFixtureIsCurrent + ? flueHistory.error?.message + : undefined, + }); + const currentWorkpiece = (() => { + if (flueHistory.snapshot === undefined) return undefined; + try { + return selectRunbookWorkpiece(flueHistory.snapshot)?.content; + } catch { + return undefined; + } + })(); + const petrinautAiChatTransport = useMemo(() => { + if (flueClientPromise !== null) { + return createBrunchPanelTransport( + flueClientPromise, + conversationTracker, + { + ...(preparedFixtureIsCurrent + ? { clientToolNames: crewReservationClientToolNames } + : {}), + onAdmission: flueHistory.refresh, + }, + ); + } + return preparedFixtureIsCurrent + ? createUnavailableBrunchPanelTransport( + "The prepared fixture requires the mounted Brunch Flue route.", + ) + : stockChatTransport; + }, [ + conversationTracker, + flueClientPromise, + flueHistory.refresh, + preparedFixtureIsCurrent, + ]); const aiAssistant = useMemo( () => ({ @@ -628,7 +732,21 @@ export const LocalStorageDemoApp = ({ } return ( -
+
+ {preparedFixtureIsCurrent && ( + + )} + {!preparedFixtureIsCurrent && } { + test("recovers an existing prepared conversation without resubmitting", async () => { + const send = vi.fn(); + const wait = vi.fn(); + + await expect( + prepareCrewReservationConversation({ + history: vi.fn().mockResolvedValue(preparedHistory), + send, + wait, + }), + ).resolves.toEqual(preparedHistory); + expect(send).not.toHaveBeenCalled(); + expect(wait).not.toHaveBeenCalled(); + }); + + test("creates revision zero once through the tagged signal delivery", async () => { + const history = vi + .fn() + .mockRejectedValueOnce({ status: 404 }) + .mockResolvedValueOnce(preparedHistory); + const admission = { submissionId: "prepare-submission" }; + const send = vi.fn().mockResolvedValue(admission); + const wait = vi.fn().mockResolvedValue(undefined); + + await expect( + prepareCrewReservationConversation({ history, send, wait }), + ).resolves.toEqual(preparedHistory); + expect(send).toHaveBeenCalledWith({ + uid: null, + initialData: { mode: PREPARED_WORKPIECE_INITIAL_DATA_MODE }, + ...preparedCrewReservationDelivery, + }); + expect(wait).toHaveBeenCalledWith(admission); + expect(history).toHaveBeenCalledTimes(2); + }); + + test("refuses an existing conversation without this fixture source", async () => { + await expect( + prepareCrewReservationConversation({ + history: vi.fn().mockResolvedValue({ + ...preparedHistory, + messages: [], + }), + send: vi.fn(), + wait: vi.fn(), + }), + ).rejects.toThrow(/no recoverable workpiece/u); + }); +}); diff --git a/apps/petrinaut-website/src/main/app/local-storage-demo/prepare-crew-reservation-conversation.ts b/apps/petrinaut-website/src/main/app/local-storage-demo/prepare-crew-reservation-conversation.ts new file mode 100644 index 00000000000..c0fcab5c3c5 --- /dev/null +++ b/apps/petrinaut-website/src/main/app/local-storage-demo/prepare-crew-reservation-conversation.ts @@ -0,0 +1,90 @@ +import { + PREPARED_WORKPIECE_INITIAL_DATA_MODE, + selectRunbookWorkpiece, + type WorkpieceHistory, +} from "@hashintel/brunch-agent/workpiece"; + +import { + CREW_RESERVATION_FIXTURE_ID, + preparedCrewReservationDelivery, +} from "./prepared-crew-reservation-fixture"; + +import type { AgentSendResult } from "@flue/sdk"; + +export type PreparedCrewReservationHistory = WorkpieceHistory & { + readonly offset: string; + readonly settlements: readonly { + readonly outcome: string; + readonly submissionId: string; + }[]; +}; + +export interface PreparedFixtureConversationClient { + readonly history: () => Promise; + readonly send: (input: { + readonly idempotencyKey: string; + readonly initialData: { + readonly mode: typeof PREPARED_WORKPIECE_INITIAL_DATA_MODE; + }; + readonly message: typeof preparedCrewReservationDelivery.message; + readonly uid: null; + }) => Promise; + readonly wait: (admission: AgentSendResult) => Promise; +} + +const isNotFound = (error: unknown): boolean => + typeof error === "object" && + error !== null && + "status" in error && + error.status === 404; + +const assertPreparedFixtureHistory = ( + history: PreparedCrewReservationHistory, +): PreparedCrewReservationHistory => { + const currentWorkpiece = selectRunbookWorkpiece(history); + if ( + currentWorkpiece?.sourceKind !== "prepared-signal" && + currentWorkpiece?.sourceKind !== "assistant" + ) { + throw new Error( + "The prepared fixture conversation has no recoverable workpiece.", + ); + } + const preparedSource = history.messages.find( + (message) => + message.signal?.tagName === + preparedCrewReservationDelivery.message.tagName, + ); + if ( + preparedSource?.signal?.attributes?.fixtureId !== + CREW_RESERVATION_FIXTURE_ID + ) { + throw new Error( + "The prepared fixture conversation belongs to a different fixture.", + ); + } + return history; +}; + +/** + * Create revision zero through Flue's public signal delivery, or recover the + * already-created append-only conversation. Concurrent tabs converge through + * the delivery's deterministic idempotency key. + */ +export const prepareCrewReservationConversation = async ( + client: PreparedFixtureConversationClient, +): Promise => { + try { + return assertPreparedFixtureHistory(await client.history()); + } catch (error) { + if (!isNotFound(error)) throw error; + } + + const admission = await client.send({ + uid: null, + initialData: { mode: PREPARED_WORKPIECE_INITIAL_DATA_MODE }, + ...preparedCrewReservationDelivery, + }); + await client.wait(admission); + return assertPreparedFixtureHistory(await client.history()); +}; diff --git a/apps/petrinaut-website/src/main/app/local-storage-demo/prepared-crew-reservation-fixture.test.ts b/apps/petrinaut-website/src/main/app/local-storage-demo/prepared-crew-reservation-fixture.test.ts new file mode 100644 index 00000000000..36bda9934fe --- /dev/null +++ b/apps/petrinaut-website/src/main/app/local-storage-demo/prepared-crew-reservation-fixture.test.ts @@ -0,0 +1,82 @@ +import { describe, expect, test } from "vitest"; + +import { + CREW_RESERVATION_CLIENT_TOOL_NAMES, + CREW_RESERVATION_FIXTURE_ID, + DISPATCH_CREW_PLACE_ID, + isCrewReservationFixtureSelected, + preparedCrewReservationDelivery, + preparedCrewReservationNet, + preparedCrewReservationWorkpiece, + START_FINAL_INSPECTION_TRANSITION_ID, +} from "./prepared-crew-reservation-fixture"; + +const transitionById = (transitionId: string) => { + const transition = preparedCrewReservationNet.transitions.find( + (candidate) => candidate.id === transitionId, + ); + if (transition === undefined) { + throw new Error(`Missing prepared transition ${transitionId}`); + } + return transition; +}; + +describe("prepared crew-reservation fixture", () => { + test("advertises only the selected canonical read and mutation", () => { + expect(CREW_RESERVATION_CLIENT_TOOL_NAMES).toEqual([ + "getLatestNetDefinition", + "addArc", + ]); + }); + + test("has the batch flow and crew return but omits the target input arc", () => { + const startInspection = transitionById( + START_FINAL_INSPECTION_TRANSITION_ID, + ); + const signOff = transitionById("sign-off"); + + expect(startInspection.inputArcs).toContainEqual({ + placeId: "batch-ready", + type: "standard", + weight: 1, + }); + expect(startInspection.inputArcs).not.toContainEqual( + expect.objectContaining({ placeId: DISPATCH_CREW_PLACE_ID }), + ); + expect(signOff.outputArcs).toEqual( + expect.arrayContaining([ + { placeId: "ready-for-dispatch", weight: 1 }, + { placeId: DISPATCH_CREW_PLACE_ID, weight: 1 }, + ]), + ); + }); + + test("carries the quantity, unknowns, and honest claim boundary", () => { + expect(preparedCrewReservationWorkpiece).toContain( + "Exactly one dispatch crew", + ); + expect(preparedCrewReservationWorkpiece).toContain( + "timing, failure modes, and recovery behavior remain unresolved", + ); + expect(preparedCrewReservationWorkpiece).toContain( + "not model-produced evidence", + ); + expect(preparedCrewReservationDelivery.message.attributes).toEqual({ + fixtureId: CREW_RESERVATION_FIXTURE_ID, + authorship: "test-authored", + claimBoundary: "prepared-not-model-produced", + }); + }); + + test("selects only the explicit stable query value", () => { + expect( + isCrewReservationFixtureSelected( + `?brunch-fixture=${CREW_RESERVATION_FIXTURE_ID}`, + ), + ).toBe(true); + expect( + isCrewReservationFixtureSelected("?brunch-fixture=another-fixture"), + ).toBe(false); + expect(isCrewReservationFixtureSelected("")).toBe(false); + }); +}); diff --git a/apps/petrinaut-website/src/main/app/local-storage-demo/prepared-crew-reservation-fixture.ts b/apps/petrinaut-website/src/main/app/local-storage-demo/prepared-crew-reservation-fixture.ts new file mode 100644 index 00000000000..69588ab02cf --- /dev/null +++ b/apps/petrinaut-website/src/main/app/local-storage-demo/prepared-crew-reservation-fixture.ts @@ -0,0 +1,154 @@ +import { createPreparedWorkpieceDelivery } from "@hashintel/brunch-agent/workpiece"; +import { + getLatestNetDefinitionToolName, + type PetrinautAiToolName, +} from "@hashintel/petrinaut-core/ai"; + +import type { SDCPN } from "@hashintel/petrinaut-core"; + +export const CREW_RESERVATION_FIXTURE_ID = "crew-reservation-v1"; +export const CREW_RESERVATION_DOCUMENT_ID = + "mission-6-crew-reservation-document-v1"; +export const CREW_RESERVATION_CONVERSATION_ID = + "mission-6-crew-reservation-conversation-v1"; +export const CREW_RESERVATION_FIXTURE_QUERY = "brunch-fixture"; +export const CREW_RESERVATION_CLIENT_TOOL_NAMES = [ + getLatestNetDefinitionToolName, + "addArc", +] as const satisfies readonly PetrinautAiToolName[]; + +export const DISPATCH_CREW_PLACE_ID = "dispatch-crew-available"; +export const START_FINAL_INSPECTION_TRANSITION_ID = "start-final-inspection"; + +export const preparedCrewReservationWorkpiece = [ + "Fixture authorship: test-authored preparation for Mission 6.", + "Non-claims: not a Mission 4 candidate, not model-produced evidence, not capture-backed provenance, and not proof of automatic full-net projection.", + "", + "```runbook-ir", + "# Final inspection and dispatch workpiece", + "", + "## Purpose and posture", + "Maintain the narrow batch path from final inspection to dispatch readiness and test one evidence-backed correction against the live Petrinaut document.", + "", + "## Operational account", + "- A batch that is ready enters final inspection.", + "- Final inspection reserves the sole available dispatch crew.", + "- Sign-off releases that crew and makes the batch ready for dispatch.", + "", + "## Quantity and resource policy", + "Exactly one dispatch crew is available in this fixture. Starting final inspection consumes that one available crew; sign-off returns it.", + "", + "## Current Petrinaut correspondence", + "The prepared non-empty net contains the batch path and the crew return from sign-off. It deliberately lacks the standard weight-1 input arc from `Dispatch crew available` to `Start final inspection`.", + "", + "## Explicit unknowns", + "Inspection and sign-off timing, failure modes, and recovery behavior remain unresolved.", + "", + "## Claim boundary", + "This prepared revision is test-authored diagnostic material. It is not model-produced evidence and does not establish capture provenance, behavioral execution, or broad projection quality.", + "```", +].join("\n"); + +export const preparedCrewReservationDelivery = createPreparedWorkpieceDelivery({ + body: preparedCrewReservationWorkpiece, + fixtureId: CREW_RESERVATION_FIXTURE_ID, + revision: 0, +}); + +export const preparedCrewReservationNet: SDCPN = { + places: [ + { + id: "batch-ready", + name: "Batch ready", + colorId: null, + dynamicsEnabled: false, + differentialEquationId: null, + x: 80, + y: 100, + }, + { + id: "under-final-inspection", + name: "Under final inspection", + colorId: null, + dynamicsEnabled: false, + differentialEquationId: null, + x: 420, + y: 100, + }, + { + id: "ready-for-dispatch", + name: "Ready for dispatch", + colorId: null, + dynamicsEnabled: false, + differentialEquationId: null, + x: 760, + y: 100, + }, + { + id: DISPATCH_CREW_PLACE_ID, + name: "Dispatch crew available", + colorId: null, + dynamicsEnabled: false, + differentialEquationId: null, + x: 420, + y: 360, + }, + ], + transitions: [ + { + id: START_FINAL_INSPECTION_TRANSITION_ID, + name: "Start final inspection", + inputArcs: [ + { + placeId: "batch-ready", + type: "standard", + weight: 1, + }, + ], + outputArcs: [ + { + placeId: "under-final-inspection", + weight: 1, + }, + ], + lambdaType: "predicate", + lambdaCode: "", + transitionKernelCode: "", + x: 250, + y: 100, + }, + { + id: "sign-off", + name: "Sign-off", + inputArcs: [ + { + placeId: "under-final-inspection", + type: "standard", + weight: 1, + }, + ], + outputArcs: [ + { + placeId: "ready-for-dispatch", + weight: 1, + }, + { + placeId: DISPATCH_CREW_PLACE_ID, + weight: 1, + }, + ], + lambdaType: "predicate", + lambdaCode: "", + transitionKernelCode: "", + x: 590, + y: 100, + }, + ], + types: [], + parameters: [], + differentialEquations: [], +}; + +export const isCrewReservationFixtureSelected = (search: string): boolean => + new URLSearchParams(search).get(CREW_RESERVATION_FIXTURE_QUERY) === + CREW_RESERVATION_FIXTURE_ID; diff --git a/apps/petrinaut-website/src/main/app/local-storage-demo/prepared-fixture-banner.test.tsx b/apps/petrinaut-website/src/main/app/local-storage-demo/prepared-fixture-banner.test.tsx new file mode 100644 index 00000000000..4d307764689 --- /dev/null +++ b/apps/petrinaut-website/src/main/app/local-storage-demo/prepared-fixture-banner.test.tsx @@ -0,0 +1,76 @@ +import { renderToStaticMarkup } from "react-dom/server"; +import { describe, expect, test } from "vitest"; + +import { + CREW_RESERVATION_CONVERSATION_ID, + CREW_RESERVATION_DOCUMENT_ID, + CREW_RESERVATION_FIXTURE_ID, +} from "./prepared-crew-reservation-fixture"; +import { + PreparedFixtureBanner, + PreparedFixtureSelector, +} from "./prepared-fixture-banner"; + +describe("PreparedFixtureBanner", () => { + test("offers a stable labelled fixture selector", () => { + const markup = renderToStaticMarkup(); + + expect(markup).toContain("Prepared fixture selector"); + expect(markup).toContain("Open the labelled crew-reservation fixture"); + expect(markup).toContain("?brunch-fixture=crew-reservation-v1"); + }); + + test("visibly states authorship, non-claims, and automatic settlement", () => { + const markup = renderToStaticMarkup( + , + ); + + expect(markup).toContain("Test-authored prepared fixture"); + expect(markup).toContain("not model-produced evidence"); + expect(markup).toContain("does not claim capture provenance"); + expect(markup).toContain("automatically mirrored document"); + expect(markup).toContain("Current Markdown workpiece"); + expect(markup).toContain("Final inspection and dispatch workpiece"); + }); + + test("visibly retains the prior bundle when settlement is refused", () => { + const markup = renderToStaticMarkup( + , + ); + + expect(markup).toContain( + "Settlement refused (missing-correlated-mutation)", + ); + expect(markup).toContain("bundle revision 3 remains selected"); + }); +}); diff --git a/apps/petrinaut-website/src/main/app/local-storage-demo/prepared-fixture-banner.tsx b/apps/petrinaut-website/src/main/app/local-storage-demo/prepared-fixture-banner.tsx new file mode 100644 index 00000000000..d73ce5b8735 --- /dev/null +++ b/apps/petrinaut-website/src/main/app/local-storage-demo/prepared-fixture-banner.tsx @@ -0,0 +1,84 @@ +import { latestRunbookIrBlock } from "@hashintel/brunch-agent/workpiece"; + +import { + CREW_RESERVATION_FIXTURE_ID, + CREW_RESERVATION_FIXTURE_QUERY, + preparedCrewReservationWorkpiece, +} from "./prepared-crew-reservation-fixture"; + +import type { CrewReservationSettledManifest } from "./crew-reservation-settled-manifest"; +import type { CrewReservationSettlementStatus } from "./use-crew-reservation-settled-manifest"; + +const fixturePanelStyle = { + background: "rgba(255, 255, 255, 0.96)", + border: "1px solid #c9d2df", + borderRadius: 8, + boxShadow: "0 2px 8px rgba(20, 33, 50, 0.12)", + left: 16, + maxWidth: 520, + padding: "10px 12px", + position: "absolute", + top: 16, + zIndex: 20, +} as const; + +export const PreparedFixtureSelector = () => ( + +); + +export const PreparedFixtureBanner = ({ + currentWorkpiece = latestRunbookIrBlock(preparedCrewReservationWorkpiece), + settledManifest, + settlementStatus = { state: "preparing" }, +}: { + readonly currentWorkpiece?: string; + readonly settledManifest: CrewReservationSettledManifest | null; + readonly settlementStatus?: CrewReservationSettlementStatus; +}) => { + if (currentWorkpiece === undefined) { + throw new Error("The prepared fixture has no recoverable workpiece."); + } + + return ( + + ); +}; diff --git a/apps/petrinaut-website/src/main/app/local-storage-demo/use-crew-reservation-settled-manifest.test.ts b/apps/petrinaut-website/src/main/app/local-storage-demo/use-crew-reservation-settled-manifest.test.ts new file mode 100644 index 00000000000..d36e10ce9bd --- /dev/null +++ b/apps/petrinaut-website/src/main/app/local-storage-demo/use-crew-reservation-settled-manifest.test.ts @@ -0,0 +1,113 @@ +/** + * @vitest-environment jsdom + */ +import { cleanup, renderHook, waitFor } from "@testing-library/react"; +import { afterEach, beforeEach, expect, test } from "vitest"; + +import { + PREPARED_WORKPIECE_AUTHORSHIP, + PREPARED_WORKPIECE_CLAIM_BOUNDARY, + PREPARED_WORKPIECE_SIGNAL_TAG, +} from "@hashintel/brunch-agent/workpiece"; + +import { CREW_RESERVATION_SETTLED_MANIFEST_STORAGE_KEY } from "./crew-reservation-settled-manifest"; +import { + CREW_RESERVATION_FIXTURE_ID, + DISPATCH_CREW_PLACE_ID, + preparedCrewReservationNet, + preparedCrewReservationWorkpiece, + START_FINAL_INSPECTION_TRANSITION_ID, +} from "./prepared-crew-reservation-fixture"; +import { useCrewReservationSettledManifest } from "./use-crew-reservation-settled-manifest"; + +const preparedHistory = { + conversationId: "canonical-conversation", + offset: "2", + settlements: [{ submissionId: "prepare-submission", outcome: "completed" }], + messages: [ + { + id: "prepared-message", + role: "system", + purpose: "dispatch", + submissionId: "prepare-submission", + signal: { + tagName: PREPARED_WORKPIECE_SIGNAL_TAG, + attributes: { + fixtureId: CREW_RESERVATION_FIXTURE_ID, + authorship: PREPARED_WORKPIECE_AUTHORSHIP, + claimBoundary: PREPARED_WORKPIECE_CLAIM_BOUNDARY, + }, + }, + parts: [{ type: "text", text: preparedCrewReservationWorkpiece }], + }, + ], +}; + +beforeEach(() => { + window.localStorage.clear(); +}); + +afterEach(() => { + cleanup(); + window.localStorage.clear(); +}); + +test("keeps the prior runtime bundle selected while a document write is partial", async () => { + const { result, rerender } = renderHook( + ({ definition }: { definition: typeof preparedCrewReservationNet }) => + useCrewReservationSettledManifest({ + definition, + enabled: true, + history: preparedHistory, + historyError: undefined, + }), + { initialProps: { definition: preparedCrewReservationNet } }, + ); + + await waitFor(() => expect(result.current.status.state).toBe("settled")); + const settledManifest = result.current.settledManifest; + expect(settledManifest?.revision).toBe(0); + + const partialDefinition = structuredClone(preparedCrewReservationNet); + const startInspection = partialDefinition.transitions.find( + ({ id }) => id === START_FINAL_INSPECTION_TRANSITION_ID, + ); + if (startInspection === undefined) { + throw new Error("Missing prepared start-inspection transition"); + } + startInspection.inputArcs.push({ + placeId: DISPATCH_CREW_PLACE_ID, + type: "standard", + weight: 1, + }); + rerender({ definition: partialDefinition }); + + await waitFor(() => expect(result.current.status.state).toBe("refused")); + expect(result.current.settledManifest).toEqual(settledManifest); + expect( + JSON.parse( + window.localStorage.getItem( + CREW_RESERVATION_SETTLED_MANIFEST_STORAGE_KEY, + ) ?? "null", + ), + ).toEqual(settledManifest); +}); + +test("surfaces canonical history failure without publishing a bundle", async () => { + const { result } = renderHook(() => + useCrewReservationSettledManifest({ + definition: preparedCrewReservationNet, + enabled: true, + history: undefined, + historyError: "History unavailable.", + }), + ); + + await waitFor(() => expect(result.current.status.state).toBe("refused")); + expect(result.current.status).toEqual({ + state: "refused", + reason: "history-unavailable", + detail: "History unavailable.", + }); + expect(result.current.settledManifest).toBeNull(); +}); diff --git a/apps/petrinaut-website/src/main/app/local-storage-demo/use-crew-reservation-settled-manifest.ts b/apps/petrinaut-website/src/main/app/local-storage-demo/use-crew-reservation-settled-manifest.ts new file mode 100644 index 00000000000..94ffe2328e9 --- /dev/null +++ b/apps/petrinaut-website/src/main/app/local-storage-demo/use-crew-reservation-settled-manifest.ts @@ -0,0 +1,124 @@ +import { useLocalStorage } from "@mantine/hooks"; +import { useEffect, useRef, useState } from "react"; + +import { + CREW_RESERVATION_SETTLED_MANIFEST_STORAGE_KEY, + settleCrewReservationManifest, + type CrewReservationSettledHistory, + type CrewReservationSettledManifest, + type CrewReservationSettlementResult, +} from "./crew-reservation-settled-manifest"; + +import type { SDCPN } from "@hashintel/petrinaut-core"; + +export type CrewReservationSettlementStatus = + | { readonly state: "idle" | "preparing" } + | { readonly state: "settled" } + | { + readonly detail?: string; + readonly reason: + | Extract< + CrewReservationSettlementResult, + { status: "refused" } + >["reason"] + | "history-unavailable" + | "settlement-failed"; + readonly state: "refused"; + }; + +export const useCrewReservationSettledManifest = (input: { + readonly definition: SDCPN | undefined; + readonly enabled: boolean; + readonly history: CrewReservationSettledHistory | undefined; + readonly historyError: string | undefined; +}) => { + const [settledManifest, setSettledManifest] = + useLocalStorage({ + key: CREW_RESERVATION_SETTLED_MANIFEST_STORAGE_KEY, + defaultValue: null, + getInitialValueInEffect: false, + }); + const [observedStatus, setObservedStatus] = + useState({ state: "preparing" }); + const manifestRef = useRef(settledManifest); + const observationIdRef = useRef(0); + const queueRef = useRef(Promise.resolve()); + + useEffect(() => { + manifestRef.current = settledManifest; + }, [settledManifest]); + + useEffect(() => { + const observationId = observationIdRef.current + 1; + observationIdRef.current = observationId; + if ( + !input.enabled || + input.historyError !== undefined || + input.definition === undefined || + input.history === undefined + ) { + return; + } + + const definition = structuredClone(input.definition); + const history = input.history; + queueRef.current = queueRef.current.then(async () => { + if (observationId !== observationIdRef.current) return; + let result: CrewReservationSettlementResult; + try { + result = await settleCrewReservationManifest({ + definition, + history, + ...(manifestRef.current === null + ? {} + : { previous: manifestRef.current }), + settledAt: new Date().toISOString(), + }); + } catch (error) { + if (observationId === observationIdRef.current) { + setObservedStatus({ + state: "refused", + reason: "settlement-failed", + detail: + error instanceof Error + ? error.message + : "The coherent bundle could not be inspected.", + }); + } + return; + } + if (observationId !== observationIdRef.current) return; + if (result.status === "refused") { + setObservedStatus({ + state: "refused", + reason: result.reason, + }); + return; + } + if (result.manifest.manifestId !== manifestRef.current?.manifestId) { + manifestRef.current = result.manifest; + setSettledManifest(result.manifest); + } + setObservedStatus({ state: "settled" }); + }); + }, [ + input.definition, + input.enabled, + input.history, + input.historyError, + setSettledManifest, + ]); + + const status: CrewReservationSettlementStatus = !input.enabled + ? { state: "idle" } + : input.historyError !== undefined + ? { + state: "refused", + reason: "history-unavailable", + detail: input.historyError, + } + : input.definition === undefined || input.history === undefined + ? { state: "preparing" } + : observedStatus; + return { settledManifest, status }; +}; diff --git a/apps/petrinaut-website/src/main/app/local-storage-demo/use-flue-chat-history.test.ts b/apps/petrinaut-website/src/main/app/local-storage-demo/use-flue-chat-history.test.ts index f21c7a30033..e361451207c 100644 --- a/apps/petrinaut-website/src/main/app/local-storage-demo/use-flue-chat-history.test.ts +++ b/apps/petrinaut-website/src/main/app/local-storage-demo/use-flue-chat-history.test.ts @@ -2,7 +2,7 @@ import { FlueApiError } from "@flue/sdk"; /** * @vitest-environment jsdom */ -import { cleanup, renderHook, waitFor } from "@testing-library/react"; +import { act, cleanup, renderHook, waitFor } from "@testing-library/react"; import { afterEach, expect, test, vi } from "vitest"; import { useFlueChatHistory } from "./use-flue-chat-history"; @@ -207,3 +207,82 @@ test("closes the SDK observation on unmount", async () => { expect(harness.close).toHaveBeenCalledOnce(); }); + +test("projects fixture client-tool results from canonical signal history", async () => { + const harness = createObservationHarness({ + conversation: { + conversationId: "conversation-1", + settlements: [], + messages: [ + { + id: "assistant-1", + role: "assistant", + purpose: "assistant", + display: "visible", + parts: [ + { + type: "dynamic-tool", + toolName: "addArc", + toolCallId: "arc-1", + state: "output-available", + input: { placeId: "crew" }, + output: { awaiting: "client" }, + }, + ], + }, + { + id: "result-1", + role: "system", + purpose: "dispatch", + display: "diagnostic", + signal: { tagName: "client-tool-result" }, + parts: [ + { + type: "text", + text: JSON.stringify([ + { + toolCallId: "arc-1", + toolName: "addArc", + output: { applied: true }, + }, + ]), + state: "done", + }, + ], + }, + ], + }, + offset: "offset-2", + phase: "live", + error: undefined, + }); + const clientToolNames = new Set(["addArc"]); + const { result } = renderHook(() => + useFlueChatHistory( + harness.clientPromise, + "conversation-1", + clientToolNames, + ), + ); + + await waitFor(() => expect(result.current.ready).toBe(true)); + expect(result.current.messages?.[0]?.parts).toEqual([ + { + type: "tool-addArc", + toolCallId: "arc-1", + state: "output-available", + input: { placeId: "crew" }, + output: { applied: true }, + }, + ]); + expect(result.current.snapshot?.offset).toBe("offset-2"); + expect(result.current.snapshot?.messages.map(({ id }) => id)).toEqual([ + "assistant-1", + "result-1", + ]); + + act(() => { + result.current.refresh(); + }); + expect(harness.refresh).toHaveBeenCalledTimes(1); +}); diff --git a/apps/petrinaut-website/src/main/app/local-storage-demo/use-flue-chat-history.ts b/apps/petrinaut-website/src/main/app/local-storage-demo/use-flue-chat-history.ts index 7e3bf752055..a8348381255 100644 --- a/apps/petrinaut-website/src/main/app/local-storage-demo/use-flue-chat-history.ts +++ b/apps/petrinaut-website/src/main/app/local-storage-demo/use-flue-chat-history.ts @@ -16,18 +16,29 @@ import type { PetrinautAiMessage } from "@hashintel/petrinaut/ui"; const noSettlements: readonly FlueConversationSettlement[] = []; +/** + * The observed canonical conversation together with the durable-stream offset + * it was read at. Fixture consumers use the offset to tell a settled bundle + * from a stale one; they never interpret it. + */ +export type FlueHistorySnapshot = FlueConversationState & { + readonly offset: string; +}; + const projectPetrinautMessages = ( conversation: FlueConversationState, + clientToolNames: ReadonlySet, ): PetrinautAiMessage[] => // The host owns this narrowing: its configured client-tool catalog is the // same catalog Petrinaut's message type exposes. snapshotToUiMessages(conversation, { - clientToolNames: brunchClientToolNames, + clientToolNames, }) as PetrinautAiMessage[]; export const useFlueChatHistory = ( clientPromise: Promise | null, conversationId: string, + clientToolNames: ReadonlySet = brunchClientToolNames, ): { readonly error: Error | undefined; readonly latestSettlement: FlueConversationSettlement | undefined; @@ -36,6 +47,7 @@ export const useFlueChatHistory = ( readonly ready: boolean; readonly refresh: () => void; readonly settlements: readonly FlueConversationSettlement[]; + readonly snapshot: FlueHistorySnapshot | undefined; } => { const observationRef = useRef(null); const [observed, setObserved] = useState<{ @@ -93,23 +105,27 @@ export const useFlueChatHistory = ( }; }, [clientPromise, conversationId]); - const snapshot = + const observation = observed?.conversationId === conversationId ? observed.snapshot : undefined; - const conversation = snapshot?.conversation; - const absent = snapshot?.phase === "absent"; + const conversation = observation?.conversation; + const absent = observation?.phase === "absent"; const ready = absent || conversation !== undefined; return { - error: snapshot?.error, + error: observation?.error, latestSettlement: conversation?.settlements.at(-1), messages: conversation === undefined ? absent ? [] : undefined - : projectPetrinautMessages(conversation), - phase: snapshot?.phase, + : projectPetrinautMessages(conversation, clientToolNames), + phase: observation?.phase, ready, refresh, settlements: conversation?.settlements ?? noSettlements, + snapshot: + conversation === undefined || observation?.offset === undefined + ? undefined + : { ...conversation, offset: observation.offset }, }; }; diff --git a/apps/petrinaut-website/src/main/app/voice-interview/voice-preview.integration.test.ts b/apps/petrinaut-website/src/main/app/voice-interview/voice-preview.integration.test.ts index 6e4a0a63095..ec153c77af7 100644 --- a/apps/petrinaut-website/src/main/app/voice-interview/voice-preview.integration.test.ts +++ b/apps/petrinaut-website/src/main/app/voice-interview/voice-preview.integration.test.ts @@ -522,6 +522,7 @@ describe("controlled voice preview", () => { expect.objectContaining({ type: "submission-accepted" }), ); expect(send).toHaveBeenCalledWith({ + idempotencyKey: "ai-sdk:user:voice-realtime:1:call-1", message: { kind: "user", body: "The supervisor approves it." }, signal: undefined, }); diff --git a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-resumable-workpiece-petrinaut.md b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-resumable-workpiece-petrinaut.md new file mode 100644 index 00000000000..9b6f4d47dad --- /dev/null +++ b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-resumable-workpiece-petrinaut.md @@ -0,0 +1,79 @@ +# FE-1575 — resumable workpiece and Petrinaut document + +## Deterministic implementation evidence + +The prepared crew-reservation fixture uses distinct fixture, logical +conversation, canonical Flue conversation, workpiece-source, and Petrinaut +document identities. Revision zero is delivered through the public mounted +Flue route as one `prepared-fixture` system/dispatch signal with a deterministic +idempotency key. The browser transport derives stable keys for typed messages +and correlated client-tool-result signals. + +Focused tests cover: + +- exact prepared-signal retry and append-only workpiece selection; +- fixture-only `getLatestNetDefinition` and `addArc` advertisement; +- the built agent's read, mutation, original call-id result, and continuation; +- rejected and duplicate/no-op canonical browser mutations; +- exact prepared and revised document structure; +- history, workpiece, mutation-result, and document mismatch refusal; and +- retention of the prior runtime manifest while partial state remains visible. + +The affected Brunch, transport, plugin, Petrinaut, and website builds, type +checks, and lint checks passed on 2026-09-03. The app-wide lint checks retain +pre-existing warning-only findings; no persona suite was run. + +## Live browser attempt and blocker + +The local `yarn dev:brunch` stack served the mounted agent at +`/agents/chat/:instanceId` and the Petrinaut fixture at: + +```text +http://127.0.0.1:4915/?brunch-fixture=crew-reservation-v1 +``` + +The browser opened the non-empty prepared document and created canonical Flue +conversation `conv_01M1KZ1Z32SJ0800V94ZE59ENR`. Snapshot offset +`0000000000000000_0000000000000006` contained exactly one tagged +`prepared-fixture` dispatch record under submission +`sub_ik_b224f8e328e14cfa803c63d06376e5e9`, preserving the test-authored Markdown +body and claim-boundary attributes. + +That submission settled as `failed` because the configured Anthropic +credential returned HTTP 401 `authentication_error: invalid x-api-key`. +Consequently: + +- no model-behavior claim was made; +- no typed confirmation, client-tool mutation, or Tab B continuation was + attempted; +- the runtime settled manifest remained `null`; and +- the visible fixture status refused settlement as `history-unavailable` + instead of blessing the prepared document alone. + +This is the Mission 6 carrier blocker required by the stop rule, not a passing +two-tab witness. No success screenshot was retained. + +## Remaining external checks + +After a valid provider credential is supplied, rerun the demo script to retain +the successful before/after Flue snapshots, canonical definitions, runtime +manifest, call/result IDs, and Tab A/Tab B screenshots. Cold-reader semantic +adjudication and the product-manager demo remain separate human-harness checks; +they were not replaced with persona testing here. + +### Cold-reader handoff + +Give the reviewer only the prepared and model-revised workpieces plus their +tagged Flue records. Ask them to identify authorship, the exactly-one-crew +policy, the intended reservation and return, and every unresolved timing, +failure, and recovery point. Fail the check if the reader attributes revision +zero to the model or infers unsupported behavioral execution. + +### Product-manager handoff + +With a valid live provider credential, have the reviewer open the labelled +fixture in Tab A, confirm the visible non-claims, submit the crew-reservation +fact once, and wait for a settled bundle. They must inspect the exact added +weight-1 input arc, open the same fixture in Tab B, verify matching identities +and hashes, submit a follow-up, and receive its correlated Brunch response +without a duplicate prepared submission. A read-only Tab B does not pass. diff --git a/libs/@hashintel/brunch-agent/packages/core/package.json b/libs/@hashintel/brunch-agent/packages/core/package.json index ca72a1d986e..1643df67d78 100644 --- a/libs/@hashintel/brunch-agent/packages/core/package.json +++ b/libs/@hashintel/brunch-agent/packages/core/package.json @@ -21,6 +21,10 @@ "./storage": { "types": "./src/storage.ts", "import": "./dist/storage.js" + }, + "./workpiece": { + "types": "./src/workpiece.ts", + "import": "./dist/workpiece.js" } }, "scripts": { diff --git a/libs/@hashintel/brunch-agent/packages/core/src/workpiece.ts b/libs/@hashintel/brunch-agent/packages/core/src/workpiece.ts new file mode 100644 index 00000000000..bd61a63c068 --- /dev/null +++ b/libs/@hashintel/brunch-agent/packages/core/src/workpiece.ts @@ -0,0 +1,214 @@ +/** + * Substrate-neutral selection of the current Markdown workpiece from an + * append-only conversation projection. + */ + +export const PREPARED_WORKPIECE_SIGNAL_TYPE = "brunch.fixture.prepared"; +export const PREPARED_WORKPIECE_SIGNAL_TAG = "prepared-fixture"; +export const PREPARED_WORKPIECE_AUTHORSHIP = "test-authored"; +export const PREPARED_WORKPIECE_CLAIM_BOUNDARY = "prepared-not-model-produced"; +export const PREPARED_WORKPIECE_INITIAL_DATA_MODE = + "validated-fixture-mutation"; +export const RUNBOOK_IR_FENCE = "runbook-ir"; + +type WorkpieceTextPart = { + readonly text: string; + readonly type: "text"; +}; + +export interface WorkpieceHistoryMessage { + readonly body?: string; + readonly id: string; + readonly parts: readonly ( + | WorkpieceTextPart + | { readonly type: string; readonly [key: string]: unknown } + )[]; + readonly purpose: string; + readonly role: string; + readonly signal?: { + readonly attributes?: Readonly>; + readonly tagName?: string; + readonly type?: string; + }; + readonly submissionId?: string; +} + +export interface WorkpieceHistory { + readonly conversationId: string; + readonly messages: readonly WorkpieceHistoryMessage[]; +} + +export interface PreparedWorkpieceDelivery { + readonly idempotencyKey: string; + readonly message: { + readonly attributes: { + readonly authorship: typeof PREPARED_WORKPIECE_AUTHORSHIP; + readonly claimBoundary: typeof PREPARED_WORKPIECE_CLAIM_BOUNDARY; + readonly fixtureId: string; + }; + readonly body: string; + readonly kind: "signal"; + readonly tagName: typeof PREPARED_WORKPIECE_SIGNAL_TAG; + readonly type: typeof PREPARED_WORKPIECE_SIGNAL_TYPE; + }; +} + +export interface SelectedRunbookWorkpiece { + readonly authorship: "model-produced" | "test-authored"; + readonly content: string; + readonly fixtureId?: string; + readonly sourceKind: "assistant" | "prepared-signal"; + readonly sourceMessage: WorkpieceHistoryMessage; + readonly sourceMessageId: string; + readonly sourceSubmissionId?: string; +} + +const runbookIrFencePattern = /```runbook-ir\s*\n([\s\S]*?)```/gu; + +export const latestRunbookIrBlock = (text: string): string | undefined => { + const matches = [...text.matchAll(runbookIrFencePattern)]; + const last = matches.at(-1)?.[1]; + return last === undefined ? undefined : last.trim(); +}; + +const textFrom = (message: WorkpieceHistoryMessage): string => + message.parts + .filter((part): part is WorkpieceTextPart => part.type === "text") + .map((part) => part.text) + .join("\n"); + +const preparedFixtureIdFrom = ( + message: WorkpieceHistoryMessage, +): string | undefined => { + const fixtureId = message.signal?.attributes?.fixtureId; + return typeof fixtureId === "string" && fixtureId.length > 0 + ? fixtureId + : undefined; +}; + +const isPreparedWorkpieceMessage = ( + message: WorkpieceHistoryMessage, +): boolean => + message.role === "system" && + message.purpose === "dispatch" && + message.signal?.tagName === PREPARED_WORKPIECE_SIGNAL_TAG && + message.signal.attributes?.authorship === PREPARED_WORKPIECE_AUTHORSHIP && + message.signal.attributes.claimBoundary === + PREPARED_WORKPIECE_CLAIM_BOUNDARY && + preparedFixtureIdFrom(message) !== undefined; + +const selectedFrom = ( + message: WorkpieceHistoryMessage, + source: Pick, +): SelectedRunbookWorkpiece | undefined => { + const content = latestRunbookIrBlock(textFrom(message)); + if (content === undefined) return undefined; + + return { + ...source, + content, + sourceMessage: message, + sourceMessageId: message.id, + ...(message.submissionId === undefined + ? {} + : { sourceSubmissionId: message.submissionId }), + }; +}; + +export const createPreparedWorkpieceDelivery = (input: { + readonly body: string; + readonly fixtureId: string; + readonly revision: number; +}): PreparedWorkpieceDelivery => { + if (input.fixtureId.length === 0) { + throw new Error("A prepared workpiece delivery requires a fixture id."); + } + if (latestRunbookIrBlock(input.body) === undefined) { + throw new Error( + "A prepared workpiece delivery requires a full runbook-ir block.", + ); + } + + return { + idempotencyKey: `${PREPARED_WORKPIECE_SIGNAL_TAG}:${input.fixtureId}:revision-${input.revision}`, + message: { + kind: "signal", + type: PREPARED_WORKPIECE_SIGNAL_TYPE, + tagName: PREPARED_WORKPIECE_SIGNAL_TAG, + body: input.body, + attributes: { + fixtureId: input.fixtureId, + authorship: PREPARED_WORKPIECE_AUTHORSHIP, + claimBoundary: PREPARED_WORKPIECE_CLAIM_BOUNDARY, + }, + }, + }; +}; + +/** + * Prepared revision zero is a tagged dispatch record. Later assistant + * workpieces win in log order, except for the assistant reply produced by the + * preparation submission itself. + */ +export const selectRunbookWorkpiece = ( + history: WorkpieceHistory, +): SelectedRunbookWorkpiece | undefined => { + const preparedCandidates = history.messages.filter( + (message) => message.signal?.tagName === PREPARED_WORKPIECE_SIGNAL_TAG, + ); + if (preparedCandidates.length > 1) { + throw new Error( + `Conversation ${history.conversationId} has more than one prepared workpiece source.`, + ); + } + + const preparedMessage = preparedCandidates.at(0); + if ( + preparedMessage !== undefined && + !isPreparedWorkpieceMessage(preparedMessage) + ) { + throw new Error( + `Conversation ${history.conversationId} has a malformed prepared workpiece source.`, + ); + } + + const preparationSubmissionId = preparedMessage?.submissionId; + let selected: SelectedRunbookWorkpiece | undefined; + + for (const message of history.messages) { + if (message === preparedMessage) { + const preparedWorkpiece = selectedFrom(message, { + authorship: PREPARED_WORKPIECE_AUTHORSHIP, + sourceKind: "prepared-signal", + }); + if (preparedWorkpiece === undefined) { + throw new Error( + `Conversation ${history.conversationId} has a prepared source without a runbook-ir block.`, + ); + } + const fixtureId = preparedFixtureIdFrom(message); + if (fixtureId === undefined) { + throw new Error( + `Conversation ${history.conversationId} has a malformed prepared workpiece source.`, + ); + } + selected = { ...preparedWorkpiece, fixtureId }; + continue; + } + if ( + message.purpose !== "assistant" || + message.role !== "assistant" || + (preparationSubmissionId !== undefined && + message.submissionId === preparationSubmissionId) + ) { + continue; + } + const assistantWorkpiece = selectedFrom(message, { + authorship: "model-produced", + sourceKind: "assistant", + }); + if (assistantWorkpiece !== undefined) selected = assistantWorkpiece; + } + + return selected; +}; diff --git a/libs/@hashintel/brunch-agent/packages/core/test/workpiece.test.ts b/libs/@hashintel/brunch-agent/packages/core/test/workpiece.test.ts new file mode 100644 index 00000000000..7b3c6f452d8 --- /dev/null +++ b/libs/@hashintel/brunch-agent/packages/core/test/workpiece.test.ts @@ -0,0 +1,174 @@ +import { describe, expect, test } from "vitest"; + +import { + createPreparedWorkpieceDelivery, + PREPARED_WORKPIECE_AUTHORSHIP, + PREPARED_WORKPIECE_CLAIM_BOUNDARY, + PREPARED_WORKPIECE_SIGNAL_TAG, + selectRunbookWorkpiece, + type WorkpieceHistory, + type WorkpieceHistoryMessage, +} from "../src/workpiece"; + +const workpiece = (name: string): string => + `\`\`\`runbook-ir\n# ${name}\n\`\`\``; + +const preparedMessage = ( + id = "prepared", + submissionId = "prepare-submission", +): WorkpieceHistoryMessage => ({ + id, + role: "system", + purpose: "dispatch", + submissionId, + signal: { + tagName: PREPARED_WORKPIECE_SIGNAL_TAG, + attributes: { + authorship: PREPARED_WORKPIECE_AUTHORSHIP, + claimBoundary: PREPARED_WORKPIECE_CLAIM_BOUNDARY, + fixtureId: "crew-reservation-v1", + }, + }, + parts: [{ type: "text", text: workpiece("Prepared") }], +}); + +const assistantMessage = ( + id: string, + submissionId: string, + name: string, +): WorkpieceHistoryMessage => ({ + id, + role: "assistant", + purpose: "assistant", + submissionId, + parts: [{ type: "text", text: workpiece(name) }], +}); + +const history = ( + messages: readonly WorkpieceHistoryMessage[], +): WorkpieceHistory => ({ + conversationId: "conversation", + messages, +}); + +describe("prepared workpiece delivery", () => { + test("carries explicit authorship and a revision-stable idempotency key", () => { + expect( + createPreparedWorkpieceDelivery({ + fixtureId: "crew-reservation-v1", + revision: 0, + body: workpiece("Prepared"), + }), + ).toEqual({ + idempotencyKey: "prepared-fixture:crew-reservation-v1:revision-0", + message: { + kind: "signal", + type: "brunch.fixture.prepared", + tagName: "prepared-fixture", + body: workpiece("Prepared"), + attributes: { + fixtureId: "crew-reservation-v1", + authorship: "test-authored", + claimBoundary: "prepared-not-model-produced", + }, + }, + }); + }); + + test("refuses prepared content without a runbook-ir block", () => { + expect(() => + createPreparedWorkpieceDelivery({ + fixtureId: "crew-reservation-v1", + revision: 0, + body: "# Not fenced", + }), + ).toThrow(/requires a full runbook-ir block/u); + }); +}); + +describe("selectRunbookWorkpiece", () => { + test("selects prepared revision zero with its honest authorship", () => { + expect(selectRunbookWorkpiece(history([preparedMessage()]))).toMatchObject({ + authorship: "test-authored", + content: "# Prepared", + fixtureId: "crew-reservation-v1", + sourceKind: "prepared-signal", + sourceMessageId: "prepared", + }); + }); + + test("ignores the assistant response to preparation", () => { + expect( + selectRunbookWorkpiece( + history([ + preparedMessage(), + assistantMessage( + "preparation-response", + "prepare-submission", + "Echo", + ), + ]), + ), + ).toMatchObject({ + authorship: "test-authored", + content: "# Prepared", + }); + }); + + test("selects the latest genuine assistant revision", () => { + expect( + selectRunbookWorkpiece( + history([ + preparedMessage(), + assistantMessage("revision-1", "turn-1", "Revision one"), + assistantMessage("revision-2", "turn-2", "Revision two"), + ]), + ), + ).toMatchObject({ + authorship: "model-produced", + content: "# Revision two", + sourceKind: "assistant", + sourceMessageId: "revision-2", + }); + }); + + test("uses canonical log order when the prepared source follows older assistant text", () => { + expect( + selectRunbookWorkpiece( + history([ + assistantMessage("older", "older-turn", "Older assistant text"), + preparedMessage(), + ]), + ), + ).toMatchObject({ + authorship: "test-authored", + content: "# Prepared", + sourceMessageId: "prepared", + }); + }); + + test("refuses malformed and duplicate prepared sources", () => { + expect(() => + selectRunbookWorkpiece( + history([ + { + ...preparedMessage(), + signal: { + tagName: PREPARED_WORKPIECE_SIGNAL_TAG, + attributes: { authorship: "model-produced" }, + }, + }, + ]), + ), + ).toThrow(/malformed prepared workpiece source/u); + + expect(() => + selectRunbookWorkpiece( + history([ + preparedMessage("prepared-1"), + preparedMessage("prepared-2", "prepare-submission-2"), + ]), + ), + ).toThrow(/more than one prepared workpiece source/u); + }); +}); diff --git a/libs/@hashintel/brunch-agent/packages/core/vite.config.ts b/libs/@hashintel/brunch-agent/packages/core/vite.config.ts index 291e5b9c4bf..986fb63fdc4 100644 --- a/libs/@hashintel/brunch-agent/packages/core/vite.config.ts +++ b/libs/@hashintel/brunch-agent/packages/core/vite.config.ts @@ -14,6 +14,7 @@ export default defineConfig({ flue: fileURLToPath(new URL("src/flue.ts", import.meta.url)), index: fileURLToPath(new URL("src/index.ts", import.meta.url)), storage: fileURLToPath(new URL("src/storage.ts", import.meta.url)), + workpiece: fileURLToPath(new URL("src/workpiece.ts", import.meta.url)), }, fileName: (_format, entryName) => `${entryName}.js`, formats: ["es"], diff --git a/libs/@hashintel/brunch-agent/packages/plugin-sdcpn/src/flue.ts b/libs/@hashintel/brunch-agent/packages/plugin-sdcpn/src/flue.ts index 3c48ef1a56f..5e106589f7f 100644 --- a/libs/@hashintel/brunch-agent/packages/plugin-sdcpn/src/flue.ts +++ b/libs/@hashintel/brunch-agent/packages/plugin-sdcpn/src/flue.ts @@ -6,22 +6,32 @@ import { } from "@flue/runtime"; import * as v from "valibot"; +import { PREPARED_WORKPIECE_INITIAL_DATA_MODE } from "@hashintel/brunch-agent/workpiece"; + import sdcpnAppend from "./prompts/APPEND_SYSTEM.md?raw"; import { SDCPN_MODELLING_SKILL_NAME, sdcpnModellingSkill, } from "./skills/sdcpn-modelling/skill"; -import { petrinautConstructionTools } from "./tools/petrinaut-construction"; +import { + petrinautConstructionTools, + petrinautFixtureTools, +} from "./tools/petrinaut-construction"; import { READ_PETRINAUT_DOC_TOOL_NAME, readPetrinautDoc, } from "./tools/read-petrinaut-doc"; export const VALIDATED_CONSTRUCTION_MODE = "validated-construction"; +export const VALIDATED_FIXTURE_MUTATION_MODE = + PREPARED_WORKPIECE_INITIAL_DATA_MODE; export const sdcpnInitialDataSchema = v.optional( v.object({ - mode: v.literal(VALIDATED_CONSTRUCTION_MODE), + mode: v.picklist([ + VALIDATED_CONSTRUCTION_MODE, + VALIDATED_FIXTURE_MUTATION_MODE, + ]), }), ); @@ -44,6 +54,15 @@ This is a construct-only headless conversation. Use only the supplied runbook IR for (const constructionTool of petrinautConstructionTools) { useTool(constructionTool); } + } else if (initialData?.mode === VALIDATED_FIXTURE_MUTATION_MODE) { + useInstruction( + ` +This is a visibly labelled prepared-fixture conversation. Treat its tagged prepared runbook-ir dispatch as test-authored revision zero, maintain the full Markdown workpiece in later responses, preserve explicit unknowns, and do not relabel prepared material as model-produced. Use only the mounted canonical Petrinaut read and least arc mutation when confirmed evidence calls for that change. Read the live document before mutating it, report rejected or no-op outcomes honestly, and do not construct unrelated net content. +`.replace(/^\s+|\s+$/gu, ""), + ); + for (const fixtureTool of petrinautFixtureTools) { + useTool(fixtureTool); + } } } @@ -51,6 +70,8 @@ export { READ_PETRINAUT_DOC_TOOL_NAME, readPetrinautDoc }; export { SDCPN_MODELLING_SKILL_NAME }; export { PETRINAUT_CONSTRUCTION_TOOL_NAMES, + PETRINAUT_FIXTURE_TOOL_NAMES, petrinautConstructionTools, + petrinautFixtureTools, type PetrinautConstructionToolName, } from "./tools/petrinaut-construction"; diff --git a/libs/@hashintel/brunch-agent/packages/plugin-sdcpn/src/tools/petrinaut-construction.ts b/libs/@hashintel/brunch-agent/packages/plugin-sdcpn/src/tools/petrinaut-construction.ts index 9f45f05ad1f..41167c67c23 100644 --- a/libs/@hashintel/brunch-agent/packages/plugin-sdcpn/src/tools/petrinaut-construction.ts +++ b/libs/@hashintel/brunch-agent/packages/plugin-sdcpn/src/tools/petrinaut-construction.ts @@ -13,6 +13,11 @@ export const PETRINAUT_CONSTRUCTION_TOOL_NAMES = [ "addArc", ] as const satisfies readonly (keyof typeof petrinautAiTools)[]; +export const PETRINAUT_FIXTURE_TOOL_NAMES = [ + "getLatestNetDefinition", + "addArc", +] as const satisfies readonly (keyof typeof petrinautAiTools)[]; + export type PetrinautConstructionToolName = (typeof PETRINAUT_CONSTRUCTION_TOOL_NAMES)[number]; @@ -91,3 +96,7 @@ const definePetrinautConstructionTool = ( export const petrinautConstructionTools = PETRINAUT_CONSTRUCTION_TOOL_NAMES.map( definePetrinautConstructionTool, ); + +export const petrinautFixtureTools = PETRINAUT_FIXTURE_TOOL_NAMES.map( + definePetrinautConstructionTool, +); diff --git a/libs/@hashintel/brunch-agent/packages/plugin-sdcpn/test/construction-tools.test.ts b/libs/@hashintel/brunch-agent/packages/plugin-sdcpn/test/construction-tools.test.ts index 1ca9cb0e53a..e259a3fa77b 100644 --- a/libs/@hashintel/brunch-agent/packages/plugin-sdcpn/test/construction-tools.test.ts +++ b/libs/@hashintel/brunch-agent/packages/plugin-sdcpn/test/construction-tools.test.ts @@ -3,9 +3,16 @@ import { describe, expect, test } from "vitest"; import { petrinautAiTools } from "@hashintel/petrinaut-core/ai"; +import { + sdcpnInitialDataSchema, + VALIDATED_CONSTRUCTION_MODE, + VALIDATED_FIXTURE_MUTATION_MODE, +} from "../src/flue"; import { PETRINAUT_CONSTRUCTION_TOOL_NAMES, + PETRINAUT_FIXTURE_TOOL_NAMES, petrinautConstructionTools, + petrinautFixtureTools, } from "../src/tools/petrinaut-construction"; const toolByName = (toolName: string) => { @@ -18,12 +25,37 @@ const toolByName = (toolName: string) => { }; describe("Petrinaut construction tools", () => { + test("accepts only the ordinary headless and prepared-fixture modes", () => { + expect(v.parse(sdcpnInitialDataSchema, undefined)).toBeUndefined(); + expect( + v.parse(sdcpnInitialDataSchema, { + mode: VALIDATED_CONSTRUCTION_MODE, + }), + ).toEqual({ mode: VALIDATED_CONSTRUCTION_MODE }); + expect( + v.parse(sdcpnInitialDataSchema, { + mode: VALIDATED_FIXTURE_MUTATION_MODE, + }), + ).toEqual({ mode: VALIDATED_FIXTURE_MUTATION_MODE }); + expect(() => + v.parse(sdcpnInitialDataSchema, { + mode: "unrestricted-construction", + }), + ).toThrow(/Invalid type/u); + }); + test("exposes exactly the bounded canonical subset", () => { expect(petrinautConstructionTools.map((tool) => tool.name)).toEqual([ ...PETRINAUT_CONSTRUCTION_TOOL_NAMES, ]); }); + test("limits prepared fixtures to one canonical read and arc mutation", () => { + expect(petrinautFixtureTools.map((tool) => tool.name)).toEqual([ + ...PETRINAUT_FIXTURE_TOOL_NAMES, + ]); + }); + test("mechanically carries the canonical input contract", () => { for (const toolName of PETRINAUT_CONSTRUCTION_TOOL_NAMES) { const constructionTool = toolByName(toolName); diff --git a/libs/@hashintel/brunch-agent/packages/transport-aisdk/src/index.ts b/libs/@hashintel/brunch-agent/packages/transport-aisdk/src/index.ts index 93b19f1e1be..772f309e053 100644 --- a/libs/@hashintel/brunch-agent/packages/transport-aisdk/src/index.ts +++ b/libs/@hashintel/brunch-agent/packages/transport-aisdk/src/index.ts @@ -265,10 +265,18 @@ export const createFlueChatTransport = < }, }; })(); + const idempotencyKey = + messageId === undefined + ? `ai-sdk:user:${userMessage!.id}` + : `ai-sdk:client-tools:${messageId}:${toolResults + .map(({ toolCallId }) => toolCallId) + .sort() + .join(",")}`; let admission: AgentSendResult; try { admission = await options.client.send({ + idempotencyKey, message, signal: abortSignal, }); diff --git a/libs/@hashintel/brunch-agent/packages/transport-aisdk/test/chat-transport.test.ts b/libs/@hashintel/brunch-agent/packages/transport-aisdk/test/chat-transport.test.ts index 3b982b101be..ffcef517172 100644 --- a/libs/@hashintel/brunch-agent/packages/transport-aisdk/test/chat-transport.test.ts +++ b/libs/@hashintel/brunch-agent/packages/transport-aisdk/test/chat-transport.test.ts @@ -114,6 +114,7 @@ test("admits one user message and projects a finite per-turn stream", async () = expect(send).toHaveBeenCalledOnce(); expect(send).toHaveBeenCalledWith({ + idempotencyKey: "ai-sdk:user:user-1", message: { kind: "user", body: "Run the transport tracer." }, signal: undefined, }); @@ -158,6 +159,7 @@ test("admits one client-tool result signal and resumes its assistant id", async ); expect(send).toHaveBeenCalledWith({ + idempotencyKey: "ai-sdk:client-tools:assistant-original:tool-1", message: { kind: "signal", type: "client-tool-result", @@ -179,6 +181,30 @@ test("admits one client-tool result signal and resumes its assistant id", async }); }); +test("derives the same idempotency key for exact AI SDK retries", async () => { + const { client, send } = clientWith(completedEvents); + const transport = createFlueChatTransport({ + client, + clientToolNames: new Set(), + }); + const options = sendOptions([ + { + id: "stable-user-message", + role: "user", + parts: [{ type: "text", text: "Admit this once." }], + }, + ]); + + await transport.sendMessages(options); + await transport.sendMessages(options); + + expect(send).toHaveBeenCalledTimes(2); + expect(send.mock.calls.map(([input]) => input.idempotencyKey)).toEqual([ + "ai-sdk:user:stable-user-message", + "ai-sdk:user:stable-user-message", + ]); +}); + test("starts with history-only reconnection", async () => { const { client } = clientWith([]); const transport = createFlueChatTransport({ diff --git a/libs/@hashintel/petrinaut/docs/ai-assistant.md b/libs/@hashintel/petrinaut/docs/ai-assistant.md index 6d56acb96e8..fe8c249e26b 100644 --- a/libs/@hashintel/petrinaut/docs/ai-assistant.md +++ b/libs/@hashintel/petrinaut/docs/ai-assistant.md @@ -26,6 +26,18 @@ If an assistant request fails, Petrinaut shows the error in a brief toast rather Hosts may provide canonical conversation rehydration. In that case, reopening the same assistant shows its settled and stopped turns without resubmitting a message or replaying Voice audio. +### Prepared local demo fixture + +The local Petrinaut development demo offers a labelled crew-reservation fixture when Brunch is +configured. Opening it restores a test-authored Markdown workpiece, a non-empty final-inspection +net, and their canonical Brunch conversation. The status panel distinguishes prepared text from +model-produced revisions and states the fixture's non-claims. + +The document is mirrored to browser local storage automatically; there is no separate Save action. +Wait for the status panel to report a settled bundle before reopening the same fixture in another +tab. A refused status leaves the previous coherent bundle selected and names the failed history, +workpiece, mutation-correlation, or document check instead of claiming that partial state settled. + When the Brunch voice preview is enabled and available, an empty composer shows a waveform action titled **Start voice mode**. Typing non-whitespace text replaces it with **Send**. The same dynamic action appears in the first-run prompt and the assistant panel; if voice is unavailable, the empty diff --git a/libs/@hashintel/petrinaut/src/ui/views/Editor/panels/ai-assistant-panel.tsx b/libs/@hashintel/petrinaut/src/ui/views/Editor/panels/ai-assistant-panel.tsx index 6c515cc2adf..d58a7f77c46 100644 --- a/libs/@hashintel/petrinaut/src/ui/views/Editor/panels/ai-assistant-panel.tsx +++ b/libs/@hashintel/petrinaut/src/ui/views/Editor/panels/ai-assistant-panel.tsx @@ -5,7 +5,6 @@ import { use, useCallback, useEffect, useRef, useState } from "react"; import { aiCommandActionInputSchemas, type AiCommandActionName, - createPetrinautAiWritableCallbacks, getLatestNetDefinitionToolName, getNetCompilationErrorsToolName, mutationActionInputSchemas as petrinautAiMutationToolInputSchemas, @@ -37,6 +36,7 @@ import { REVIEW_CHIPS, STARTER_CHIPS, } from "./ai-assistant-panel/ai-assistant-contents/prompt-chips"; +import { applyPetrinautAiMutation } from "./ai-assistant-panel/apply-petrinaut-ai-mutation"; import { createDiagnosticsAwareAiTransport } from "./ai-assistant-panel/create-diagnostics-aware-ai-transport"; import { createReasoningTimingAwareAiTransport } from "./ai-assistant-panel/create-reasoning-timing-aware-ai-transport"; import { finalizeStreamingMessageParts } from "./ai-assistant-panel/finalize-streaming-message-parts"; @@ -51,7 +51,6 @@ import { type AiToolCall, type AiToolTarget, summarizeApplyAutoLayout, - summarizePetrinautAiToolCall, toPetrinautAiToolOutput, } from "./ai-assistant-panel/tool-summaries"; @@ -256,25 +255,6 @@ const waitForDiagnosticsRefresh = async ({ }); }; -const applyPetrinautAiMutation = ({ - aiToolCall, - instance, -}: { - aiToolCall: Extract; - instance: Petrinaut; -}): AiToolOutput => { - const definition = instance.definition.get(); - const toolCallbacks = createPetrinautAiWritableCallbacks(instance); - const summary = summarizePetrinautAiToolCall(aiToolCall, { definition }); - const callback = toolCallbacks[aiToolCall.toolName] as ( - input: typeof aiToolCall.input, - ) => void; - - callback(aiToolCall.input); - - return toPetrinautAiToolOutput(summary); -}; - const applyPetrinautAiCommand = async ({ aiToolCall, instance, diff --git a/libs/@hashintel/petrinaut/src/ui/views/Editor/panels/ai-assistant-panel/apply-petrinaut-ai-mutation.test.ts b/libs/@hashintel/petrinaut/src/ui/views/Editor/panels/ai-assistant-panel/apply-petrinaut-ai-mutation.test.ts new file mode 100644 index 00000000000..8b221aad305 --- /dev/null +++ b/libs/@hashintel/petrinaut/src/ui/views/Editor/panels/ai-assistant-panel/apply-petrinaut-ai-mutation.test.ts @@ -0,0 +1,102 @@ +import { describe, expect, test } from "vitest"; + +import { + createJsonDocHandle, + createPetrinaut, + type SDCPN, +} from "@hashintel/petrinaut-core"; + +import { applyPetrinautAiMutation } from "./apply-petrinaut-ai-mutation"; + +const definition: SDCPN = { + places: [ + { + id: "crew", + name: "Crew", + colorId: null, + dynamicsEnabled: false, + differentialEquationId: null, + x: 0, + y: 0, + }, + ], + transitions: [ + { + id: "start", + name: "Start", + inputArcs: [], + outputArcs: [], + lambdaType: "predicate", + lambdaCode: "", + transitionKernelCode: "", + x: 100, + y: 0, + }, + ], + types: [], + parameters: [], + differentialEquations: [], +}; + +describe("applyPetrinautAiMutation", () => { + test("reports a duplicate canonical arc as a no-op", () => { + const instance = createPetrinaut({ + document: createJsonDocHandle({ + id: "document", + initial: definition, + capabilities: { disabledExtensions: [] }, + }), + }); + const call = { + toolName: "addArc" as const, + input: { + transitionId: "start", + arcDirection: "input" as const, + placeId: "crew", + weight: 1, + type: "standard" as const, + }, + }; + + expect(applyPetrinautAiMutation({ aiToolCall: call, instance })).toEqual( + expect.objectContaining({ applied: true }), + ); + expect(applyPetrinautAiMutation({ aiToolCall: call, instance })).toEqual({ + applied: false, + reason: + "Added input arc was a no-op because the document already had that state.", + }); + expect(instance.definition.get().transitions[0]?.inputArcs).toHaveLength(1); + + instance.dispose(); + }); + + test("leaves the document unchanged when a canonical arc is rejected", () => { + const instance = createPetrinaut({ + document: createJsonDocHandle({ + id: "document", + initial: definition, + capabilities: { disabledExtensions: [] }, + }), + }); + + expect(() => + applyPetrinautAiMutation({ + aiToolCall: { + toolName: "addArc", + input: { + transitionId: "start", + arcDirection: "input", + placeId: "missing-place", + weight: 1, + type: "standard", + }, + }, + instance, + }), + ).toThrow(/missing-place/u); + expect(instance.definition.get().transitions[0]?.inputArcs).toEqual([]); + + instance.dispose(); + }); +}); diff --git a/libs/@hashintel/petrinaut/src/ui/views/Editor/panels/ai-assistant-panel/apply-petrinaut-ai-mutation.ts b/libs/@hashintel/petrinaut/src/ui/views/Editor/panels/ai-assistant-panel/apply-petrinaut-ai-mutation.ts new file mode 100644 index 00000000000..3d475821387 --- /dev/null +++ b/libs/@hashintel/petrinaut/src/ui/views/Editor/panels/ai-assistant-panel/apply-petrinaut-ai-mutation.ts @@ -0,0 +1,39 @@ +import { + createPetrinautAiWritableCallbacks, + isSDCPNEqual, + type Petrinaut, + type PetrinautAiMutationToolName, +} from "@hashintel/petrinaut-core"; + +import { + type AiToolCall, + type AiToolOutput, + summarizePetrinautAiToolCall, + toPetrinautAiToolOutput, +} from "./tool-summaries"; + +export const applyPetrinautAiMutation = ({ + aiToolCall, + instance, +}: { + aiToolCall: Extract; + instance: Petrinaut; +}): AiToolOutput => { + const definition = instance.definition.get(); + const toolCallbacks = createPetrinautAiWritableCallbacks(instance); + const summary = summarizePetrinautAiToolCall(aiToolCall, { definition }); + const callback = toolCallbacks[aiToolCall.toolName] as ( + input: typeof aiToolCall.input, + ) => void; + + callback(aiToolCall.input); + + if (isSDCPNEqual(definition, instance.definition.get())) { + return { + applied: false, + reason: `${summary.title} was a no-op because the document already had that state.`, + }; + } + + return toPetrinautAiToolOutput(summary); +}; From 142c257c015db1365c2531349764e0ef820870f0 Mon Sep 17 00:00:00 2001 From: Lu Nelson Date: Fri, 4 Sep 2026 09:32:48 +0200 Subject: [PATCH 06/13] Correct Mission 6 bundle recovery and preparation Co-authored-by: Cursor --- .../src/conversation/client-tools.ts | 4 +- .../src/conversation/workpiece.ts | 23 +-- .../evaluations/persona/proof-artifacts.ts | 2 +- .../src/evaluations/runbook/artifacts.ts | 18 +- .../test/prepared-workpiece.integration.ts | 16 +- .../test/runbook-artifacts.test.ts | 13 +- apps/brunch-agent/test/workpiece.test.ts | 132 ++---------- .../crew-reservation-history.ts | 14 ++ .../crew-reservation-settled-manifest.test.ts | 38 ++-- .../crew-reservation-settled-manifest.ts | 195 ++++++++---------- .../local-storage-demo-app.tsx | 137 ++++++------ ...pare-crew-reservation-conversation.test.ts | 12 +- .../prepare-crew-reservation-conversation.ts | 29 +-- .../prepared-crew-reservation-fixture.test.ts | 22 +- .../prepared-crew-reservation-fixture.ts | 26 +-- .../prepared-fixture-banner.test.tsx | 36 ++-- .../prepared-fixture-banner.tsx | 58 +++--- .../resolve-crew-reservation-bundle.test.ts | 149 +++++++++++++ .../resolve-crew-reservation-bundle.ts | 66 ++++++ .../use-crew-reservation-fixture-session.ts | 103 +++++++++ ...-crew-reservation-settled-manifest.test.ts | 99 ++++++--- .../use-crew-reservation-settled-manifest.ts | 102 ++++++--- .../use-local-storage-sdcpns.ts | 6 + ...pare-crew-reservation-conversation.test.ts | 31 +++ ...e-prepare-crew-reservation-conversation.ts | 55 +++++ .../fe-1575-resumable-workpiece-petrinaut.md | 6 +- .../packages/core/src/workpiece.ts | 42 ++-- .../packages/core/test/workpiece.test.ts | 14 +- .../packages/plugin-sdcpn/src/flue.ts | 11 +- .../src/tools/petrinaut-construction.ts | 16 +- .../test/construction-tools.test.ts | 10 +- .../src/client-tool-history.ts | 104 ++++++++++ .../packages/transport-aisdk/src/index.ts | 7 + .../test/client-tool-history.test.ts | 64 ++++++ 34 files changed, 1123 insertions(+), 537 deletions(-) create mode 100644 apps/petrinaut-website/src/main/app/local-storage-demo/crew-reservation-history.ts create mode 100644 apps/petrinaut-website/src/main/app/local-storage-demo/resolve-crew-reservation-bundle.test.ts create mode 100644 apps/petrinaut-website/src/main/app/local-storage-demo/resolve-crew-reservation-bundle.ts create mode 100644 apps/petrinaut-website/src/main/app/local-storage-demo/use-crew-reservation-fixture-session.ts create mode 100644 apps/petrinaut-website/src/main/app/local-storage-demo/use-prepare-crew-reservation-conversation.test.ts create mode 100644 apps/petrinaut-website/src/main/app/local-storage-demo/use-prepare-crew-reservation-conversation.ts create mode 100644 libs/@hashintel/brunch-agent/packages/transport-aisdk/src/client-tool-history.ts create mode 100644 libs/@hashintel/brunch-agent/packages/transport-aisdk/test/client-tool-history.test.ts diff --git a/apps/brunch-agent/src/conversation/client-tools.ts b/apps/brunch-agent/src/conversation/client-tools.ts index dd8e44d8b23..68b48d43b5d 100644 --- a/apps/brunch-agent/src/conversation/client-tools.ts +++ b/apps/brunch-agent/src/conversation/client-tools.ts @@ -1,7 +1,7 @@ /** Flue-side client-tool signal contract: awaiting sentinel, result signal, tool names. */ import { - PETRINAUT_FIXTURE_TOOL_NAMES, + petrinautFixtureToolNames, READ_PETRINAUT_DOC_TOOL_NAME, } from "@hashintel/brunch-agent-plugin-sdcpn/flue"; import { CLIENT_TOOL_RESULT_SIGNAL } from "@hashintel/brunch-agent-transport-aisdk"; @@ -12,7 +12,7 @@ export { CLIENT_TOOL_RESULT_SIGNAL }; export const clientToolNames: ReadonlySet = new Set([ READ_PETRINAUT_DOC_TOOL_NAME, - ...PETRINAUT_FIXTURE_TOOL_NAMES, + ...petrinautFixtureToolNames, ]); const isRecord = (value: unknown): value is Record => diff --git a/apps/brunch-agent/src/conversation/workpiece.ts b/apps/brunch-agent/src/conversation/workpiece.ts index 3a146af098b..d8ac8ae9b69 100644 --- a/apps/brunch-agent/src/conversation/workpiece.ts +++ b/apps/brunch-agent/src/conversation/workpiece.ts @@ -2,34 +2,13 @@ import { createHash } from "node:crypto"; -import { - createPreparedWorkpieceDelivery, - latestRunbookIrBlock, - PREPARED_WORKPIECE_AUTHORSHIP, - PREPARED_WORKPIECE_CLAIM_BOUNDARY, - PREPARED_WORKPIECE_INITIAL_DATA_MODE, - PREPARED_WORKPIECE_SIGNAL_TAG, - PREPARED_WORKPIECE_SIGNAL_TYPE, - RUNBOOK_IR_FENCE, - selectRunbookWorkpiece, -} from "@hashintel/brunch-agent/workpiece"; +import { selectRunbookWorkpiece } from "@hashintel/brunch-agent/workpiece"; import type { FlueConversationSnapshot } from "@flue/sdk"; const sha256 = (value: string): string => createHash("sha256").update(value).digest("hex"); -export { - createPreparedWorkpieceDelivery, - latestRunbookIrBlock, - PREPARED_WORKPIECE_AUTHORSHIP, - PREPARED_WORKPIECE_CLAIM_BOUNDARY, - PREPARED_WORKPIECE_INITIAL_DATA_MODE, - PREPARED_WORKPIECE_SIGNAL_TAG, - PREPARED_WORKPIECE_SIGNAL_TYPE, - RUNBOOK_IR_FENCE, -}; - export interface RecoveredRunbookWorkpiece { readonly authorship: "model-produced" | "test-authored"; readonly content: string; diff --git a/apps/brunch-agent/src/evaluations/persona/proof-artifacts.ts b/apps/brunch-agent/src/evaluations/persona/proof-artifacts.ts index 0c3c71409e7..8d5d32c67a7 100644 --- a/apps/brunch-agent/src/evaluations/persona/proof-artifacts.ts +++ b/apps/brunch-agent/src/evaluations/persona/proof-artifacts.ts @@ -9,7 +9,7 @@ import { import { isAwaitingClient } from "../../conversation/client-tools.ts"; import { formatFlueTranscript } from "../../conversation/transcript.ts"; -import { recoverRunbookWorkpiece } from "../runbook/artifacts.ts"; +import { recoverRunbookWorkpiece } from "../../conversation/workpiece.ts"; interface ProofEventBase { readonly sequence: number; diff --git a/apps/brunch-agent/src/evaluations/runbook/artifacts.ts b/apps/brunch-agent/src/evaluations/runbook/artifacts.ts index bdc39fc3035..fb1923706d2 100644 --- a/apps/brunch-agent/src/evaluations/runbook/artifacts.ts +++ b/apps/brunch-agent/src/evaluations/runbook/artifacts.ts @@ -2,21 +2,11 @@ import { basename } from "node:path"; -import { - latestRunbookIrBlock, - recoverRunbookWorkpiece, - RUNBOOK_IR_FENCE, - type RecoveredRunbookWorkpiece, -} from "../../conversation/workpiece.ts"; +import { runbookIrFence } from "@hashintel/brunch-agent/workpiece"; -import type { FlueConversationSnapshot } from "@flue/sdk"; +import { recoverRunbookWorkpiece } from "../../conversation/workpiece.ts"; -export { - latestRunbookIrBlock, - recoverRunbookWorkpiece, - RUNBOOK_IR_FENCE, - type RecoveredRunbookWorkpiece, -}; +import type { FlueConversationSnapshot } from "@flue/sdk"; export const recoverRunbookIr = ( snapshot: FlueConversationSnapshot, @@ -123,7 +113,7 @@ export const ordinaryElicitationViolationsFrom = ( } if ( firstWorkpiecePosition === undefined && - part.text.includes(`\`\`\`${RUNBOOK_IR_FENCE}`) + part.text.includes(`\`\`\`${runbookIrFence}`) ) { firstWorkpiecePosition = position; } diff --git a/apps/brunch-agent/test/prepared-workpiece.integration.ts b/apps/brunch-agent/test/prepared-workpiece.integration.ts index fa149429435..3c6ea36699f 100644 --- a/apps/brunch-agent/test/prepared-workpiece.integration.ts +++ b/apps/brunch-agent/test/prepared-workpiece.integration.ts @@ -11,9 +11,10 @@ import { setProvider } from "@flue/runtime"; import { createFlueClient } from "@flue/sdk"; import { - PETRINAUT_FIXTURE_TOOL_NAMES, - VALIDATED_FIXTURE_MUTATION_MODE, + petrinautFixtureToolNames, + validatedFixtureMutationMode, } from "@hashintel/brunch-agent-plugin-sdcpn/flue"; +import { createPreparedWorkpieceDelivery } from "@hashintel/brunch-agent/workpiece"; import { CLIENT_TOOL_RESULT_SIGNAL, @@ -23,10 +24,7 @@ import { agentOwnershipHeaders, flueConversationIdFrom, } from "../src/conversation/identity.ts"; -import { - createPreparedWorkpieceDelivery, - recoverRunbookWorkpiece, -} from "../src/conversation/workpiece.ts"; +import { recoverRunbookWorkpiece } from "../src/conversation/workpiece.ts"; import { createHeadlessPetrinautClient } from "../src/evaluations/runbook/headless-petrinaut-client.ts"; import { loadBuiltBrunchApplication } from "../src/evaluations/runbook/load-built-application.ts"; import { CHAT_AGENT_ROUTE } from "../src/http/routes.ts"; @@ -160,7 +158,7 @@ try { }); const preparationPrompt = { uid: null, - initialData: { mode: VALIDATED_FIXTURE_MUTATION_MODE }, + initialData: { mode: validatedFixtureMutationMode }, ...preparedDelivery, } as const; const preparation = await client.send(preparationPrompt); @@ -188,8 +186,8 @@ try { message.parts.flatMap((part) => { if ( part.type !== "dynamic-tool" || - !PETRINAUT_FIXTURE_TOOL_NAMES.includes( - part.toolName as (typeof PETRINAUT_FIXTURE_TOOL_NAMES)[number], + !petrinautFixtureToolNames.includes( + part.toolName as (typeof petrinautFixtureToolNames)[number], ) || completedCallIds.has(part.toolCallId) || part.state !== "output-available" || diff --git a/apps/brunch-agent/test/runbook-artifacts.test.ts b/apps/brunch-agent/test/runbook-artifacts.test.ts index ec065240c0c..1203e25f189 100644 --- a/apps/brunch-agent/test/runbook-artifacts.test.ts +++ b/apps/brunch-agent/test/runbook-artifacts.test.ts @@ -2,10 +2,13 @@ import { describe, expect, test } from "vitest"; import { latestRunbookIrBlock, + runbookIrFence, +} from "@hashintel/brunch-agent/workpiece"; + +import { recoverRunbookWorkpiece } from "../src/conversation/workpiece.ts"; +import { ordinaryElicitationViolationsFrom, recoverRunbookIr, - recoverRunbookWorkpiece, - RUNBOOK_IR_FENCE, skillResourcePathsFrom, } from "../src/evaluations/runbook/artifacts.ts"; @@ -27,11 +30,11 @@ const snapshotWithAssistantText = (text: string): FlueConversationSnapshot => describe("runbook artifact recovery", () => { test("takes the last fenced IR block", () => { const text = [ - "```" + RUNBOOK_IR_FENCE, + "```" + runbookIrFence, "# first", "```", "later", - "```" + RUNBOOK_IR_FENCE, + "```" + runbookIrFence, "# second", "```", ].join("\n"); @@ -41,7 +44,7 @@ describe("runbook artifact recovery", () => { test("recovers an IR from assistant history", () => { const snapshot = snapshotWithAssistantText( [ - "```" + RUNBOOK_IR_FENCE, + "```" + runbookIrFence, "# Runbook IR", "## Purpose and outcome", "```", diff --git a/apps/brunch-agent/test/workpiece.test.ts b/apps/brunch-agent/test/workpiece.test.ts index 31419118c6a..490a18a7eec 100644 --- a/apps/brunch-agent/test/workpiece.test.ts +++ b/apps/brunch-agent/test/workpiece.test.ts @@ -1,135 +1,43 @@ import { describe, expect, test } from "vitest"; -import { - PREPARED_WORKPIECE_AUTHORSHIP, - PREPARED_WORKPIECE_CLAIM_BOUNDARY, - PREPARED_WORKPIECE_SIGNAL_TAG, - recoverRunbookWorkpiece, -} from "../src/conversation/workpiece.ts"; +import { recoverRunbookWorkpiece } from "../src/conversation/workpiece.ts"; import type { FlueConversationMessage, FlueConversationSnapshot, } from "@flue/sdk"; -const workpiece = (name: string): string => - `\`\`\`runbook-ir\n# ${name}\n\`\`\``; - -const preparedMessage = ( - id = "prepared", - submissionId = "prepare-submission", -): FlueConversationMessage => ({ - id, - role: "system", - purpose: "dispatch", - display: "diagnostic", - submissionId, - signal: { - tagName: PREPARED_WORKPIECE_SIGNAL_TAG, - attributes: { - authorship: PREPARED_WORKPIECE_AUTHORSHIP, - claimBoundary: PREPARED_WORKPIECE_CLAIM_BOUNDARY, - fixtureId: "crew-reservation-v1", - }, - }, - parts: [{ type: "text", text: workpiece("Prepared"), state: "done" }], -}); - -const assistantMessage = ( - id: string, - submissionId: string, - name: string, -): FlueConversationMessage => ({ - id, +const revisionMessage: FlueConversationMessage = { + id: "revision", role: "assistant", purpose: "assistant", display: "visible", - submissionId, - parts: [{ type: "text", text: workpiece(name), state: "done" }], -}); + submissionId: "turn-1", + parts: [ + { type: "text", text: "```runbook-ir\n# Revision\n```", state: "done" }, + ], +}; -const snapshot = ( - messages: FlueConversationMessage[], -): FlueConversationSnapshot => ({ +const snapshot: FlueConversationSnapshot = { v: 1, conversationId: "conversation", offset: "1", - messages, + messages: [revisionMessage], settlements: [], -}); +}; describe("recoverRunbookWorkpiece", () => { - test("recovers the tagged prepared source without relabelling its authorship", () => { - expect( - recoverRunbookWorkpiece(snapshot([preparedMessage()])), - ).toMatchObject({ - authorship: "test-authored", - content: "# Prepared", - sourceKind: "prepared-signal", - sourceMessageId: "prepared", - sourceSubmissionId: "prepare-submission", - }); - }); - - test("does not treat the preparation response as a model-authored revision", () => { - expect( - recoverRunbookWorkpiece( - snapshot([ - preparedMessage(), - assistantMessage( - "preparation-response", - "prepare-submission", - "Echoed by preparation response", - ), - ]), - ), - ).toMatchObject({ - authorship: "test-authored", - content: "# Prepared", - sourceKind: "prepared-signal", - }); - }); - - test("selects the latest genuine assistant revision", () => { - expect( - recoverRunbookWorkpiece( - snapshot([ - preparedMessage(), - assistantMessage("revision-1", "turn-1", "Revision one"), - assistantMessage("revision-2", "turn-2", "Revision two"), - ]), - ), - ).toMatchObject({ + test("accepts a Flue snapshot and adds stable content and source hashes", () => { + expect(recoverRunbookWorkpiece(snapshot)).toEqual({ authorship: "model-produced", - content: "# Revision two", + content: "# Revision", + sha256: + "330eeebe84d31400de2dad6ea1783ed1a0d0c5487ab32e63e58a6fffe201c4cb", sourceKind: "assistant", - sourceMessageId: "revision-2", - sourceSubmissionId: "turn-2", + sourceMessageId: "revision", + sourceMessageSha256: + "eced072a0cecc954fa63a7f9664e1dffea1a685f71d2b835a9af971a115718e5", + sourceSubmissionId: "turn-1", }); }); - - test("retains ordinary assistant-only workpiece recovery", () => { - expect( - recoverRunbookWorkpiece( - snapshot([ - assistantMessage("ordinary", "ordinary-turn", "Ordinary workpiece"), - ]), - ), - ).toMatchObject({ - authorship: "model-produced", - content: "# Ordinary workpiece", - sourceKind: "assistant", - }); - }); - - test("fails rather than choosing between multiple prepared sources", () => { - expect(() => - recoverRunbookWorkpiece( - snapshot([ - preparedMessage("prepared-1"), - preparedMessage("prepared-2", "prepare-submission-2"), - ]), - ), - ).toThrow(/more than one prepared workpiece source/u); - }); }); diff --git a/apps/petrinaut-website/src/main/app/local-storage-demo/crew-reservation-history.ts b/apps/petrinaut-website/src/main/app/local-storage-demo/crew-reservation-history.ts new file mode 100644 index 00000000000..f5030832123 --- /dev/null +++ b/apps/petrinaut-website/src/main/app/local-storage-demo/crew-reservation-history.ts @@ -0,0 +1,14 @@ +import type { WorkpieceHistory } from "@hashintel/brunch-agent/workpiece"; + +/** + * Canonical Flue history plus the durable offset observed by the browser. + * Preparation and settlement share this shape rather than independently + * extending the workpiece projection. + */ +export type CrewReservationHistory = WorkpieceHistory & { + readonly offset: string; + readonly settlements: readonly { + readonly outcome: string; + readonly submissionId: string; + }[]; +}; diff --git a/apps/petrinaut-website/src/main/app/local-storage-demo/crew-reservation-settled-manifest.test.ts b/apps/petrinaut-website/src/main/app/local-storage-demo/crew-reservation-settled-manifest.test.ts index 32bc94f8d21..ab6d5a6a626 100644 --- a/apps/petrinaut-website/src/main/app/local-storage-demo/crew-reservation-settled-manifest.test.ts +++ b/apps/petrinaut-website/src/main/app/local-storage-demo/crew-reservation-settled-manifest.test.ts @@ -1,9 +1,9 @@ import { describe, expect, test } from "vitest"; import { - PREPARED_WORKPIECE_AUTHORSHIP, - PREPARED_WORKPIECE_CLAIM_BOUNDARY, - PREPARED_WORKPIECE_SIGNAL_TAG, + preparedWorkpieceAuthorship, + preparedWorkpieceClaimBoundary, + preparedWorkpieceSignalTag, type WorkpieceHistoryMessage, } from "@hashintel/brunch-agent/workpiece"; @@ -12,11 +12,11 @@ import { settleCrewReservationManifest, } from "./crew-reservation-settled-manifest"; import { - CREW_RESERVATION_FIXTURE_ID, - DISPATCH_CREW_PLACE_ID, + crewReservationFixtureId, + dispatchCrewPlaceId, preparedCrewReservationNet, preparedCrewReservationWorkpiece, - START_FINAL_INSPECTION_TRANSITION_ID, + startFinalInspectionTransitionId, } from "./prepared-crew-reservation-fixture"; const preparedMessage: WorkpieceHistoryMessage = { @@ -25,11 +25,11 @@ const preparedMessage: WorkpieceHistoryMessage = { purpose: "dispatch", submissionId: "prepare-submission", signal: { - tagName: PREPARED_WORKPIECE_SIGNAL_TAG, + tagName: preparedWorkpieceSignalTag, attributes: { - fixtureId: CREW_RESERVATION_FIXTURE_ID, - authorship: PREPARED_WORKPIECE_AUTHORSHIP, - claimBoundary: PREPARED_WORKPIECE_CLAIM_BOUNDARY, + fixtureId: crewReservationFixtureId, + authorship: preparedWorkpieceAuthorship, + claimBoundary: preparedWorkpieceClaimBoundary, }, }, parts: [ @@ -64,9 +64,9 @@ const targetMutationMessages = (): readonly [ toolCallId: "target-arc-call", toolName: "addArc", input: { - transitionId: START_FINAL_INSPECTION_TRANSITION_ID, + transitionId: startFinalInspectionTransitionId, arcDirection: "input", - placeId: DISPATCH_CREW_PLACE_ID, + placeId: dispatchCrewPlaceId, weight: 1, }, }, @@ -106,7 +106,7 @@ describe("crew-reservation settled manifest", () => { expect(result).toMatchObject({ status: "settled", manifest: { - fixtureId: CREW_RESERVATION_FIXTURE_ID, + fixtureId: crewReservationFixtureId, revision: 0, conversation: { canonicalId: "canonical-flue-conversation", @@ -149,13 +149,13 @@ describe("crew-reservation settled manifest", () => { }; const revisedDefinition = structuredClone(preparedCrewReservationNet); const startInspection = revisedDefinition.transitions.find( - ({ id }) => id === START_FINAL_INSPECTION_TRANSITION_ID, + ({ id }) => id === startFinalInspectionTransitionId, ); if (startInspection === undefined) { throw new Error("Missing prepared start-inspection transition"); } startInspection.inputArcs.push({ - placeId: DISPATCH_CREW_PLACE_ID, + placeId: dispatchCrewPlaceId, type: "standard", weight: 1, }); @@ -199,13 +199,13 @@ describe("crew-reservation settled manifest", () => { }; const revisedDefinition = structuredClone(preparedCrewReservationNet); const startInspection = revisedDefinition.transitions.find( - ({ id }) => id === START_FINAL_INSPECTION_TRANSITION_ID, + ({ id }) => id === startFinalInspectionTransitionId, ); if (startInspection === undefined) { throw new Error("Missing prepared start-inspection transition"); } startInspection.inputArcs.push({ - placeId: DISPATCH_CREW_PLACE_ID, + placeId: dispatchCrewPlaceId, type: "standard", weight: 1, }); @@ -354,13 +354,13 @@ describe("crew-reservation settled manifest", () => { } const partialDefinition = structuredClone(preparedCrewReservationNet); const startInspection = partialDefinition.transitions.find( - ({ id }) => id === START_FINAL_INSPECTION_TRANSITION_ID, + ({ id }) => id === startFinalInspectionTransitionId, ); if (startInspection === undefined) { throw new Error("Missing prepared start-inspection transition"); } startInspection.inputArcs.push({ - placeId: DISPATCH_CREW_PLACE_ID, + placeId: dispatchCrewPlaceId, type: "standard", weight: 1, }); diff --git a/apps/petrinaut-website/src/main/app/local-storage-demo/crew-reservation-settled-manifest.ts b/apps/petrinaut-website/src/main/app/local-storage-demo/crew-reservation-settled-manifest.ts index a3bea28e98a..01767ed99a4 100644 --- a/apps/petrinaut-website/src/main/app/local-storage-demo/crew-reservation-settled-manifest.ts +++ b/apps/petrinaut-website/src/main/app/local-storage-demo/crew-reservation-settled-manifest.ts @@ -1,42 +1,67 @@ -import { - selectRunbookWorkpiece, - type WorkpieceHistory, -} from "@hashintel/brunch-agent/workpiece"; +import { clientToolHistoryFrom } from "@hashintel/brunch-agent-transport-aisdk"; +import { selectRunbookWorkpiece } from "@hashintel/brunch-agent/workpiece"; import { isSDCPNEqual, type SDCPN } from "@hashintel/petrinaut-core"; import { - CREW_RESERVATION_CONVERSATION_ID, - CREW_RESERVATION_DOCUMENT_ID, - CREW_RESERVATION_FIXTURE_ID, - DISPATCH_CREW_PLACE_ID, + crewReservationConversationId, + crewReservationDocumentId, + crewReservationFixtureId, + dispatchCrewPlaceId, preparedCrewReservationNet, - START_FINAL_INSPECTION_TRANSITION_ID, + startFinalInspectionTransitionId, } from "./prepared-crew-reservation-fixture"; -export const CREW_RESERVATION_SETTLED_MANIFEST_STORAGE_KEY = +import type { CrewReservationHistory } from "./crew-reservation-history"; + +export const crewReservationSettledManifestStorageKey = "brunch:prepared-fixture:crew-reservation-v1:settled"; +declare const manifestValueBrand: unique symbol; +type ManifestValue = string & { + readonly [manifestValueBrand]: Kind; +}; + +export type CanonicalConversationId = ManifestValue<"canonical-conversation">; +export type ConversationOffset = ManifestValue<"conversation-offset">; +export type FlueMessageId = ManifestValue<"flue-message">; +export type FlueSubmissionId = ManifestValue<"flue-submission">; +export type ManifestId = ManifestValue<"manifest">; +export type Sha256Digest = ManifestValue<"sha256">; + +export const asCanonicalConversationId = ( + value: string, +): CanonicalConversationId => value as CanonicalConversationId; +export const asConversationOffset = (value: string): ConversationOffset => + value as ConversationOffset; +export const asFlueMessageId = (value: string): FlueMessageId => + value as FlueMessageId; +export const asFlueSubmissionId = (value: string): FlueSubmissionId => + value as FlueSubmissionId; +export const asManifestId = (value: string): ManifestId => value as ManifestId; +export const asSha256Digest = (value: string): Sha256Digest => + value as Sha256Digest; + export interface CrewReservationSettledManifest { readonly conversation: { - readonly canonicalId: string; - readonly logicalId: typeof CREW_RESERVATION_CONVERSATION_ID; - readonly offset: string; + readonly canonicalId: CanonicalConversationId; + readonly logicalId: typeof crewReservationConversationId; + readonly offset: ConversationOffset; }; readonly document: { - readonly id: typeof CREW_RESERVATION_DOCUMENT_ID; - readonly sha256: string; + readonly id: typeof crewReservationDocumentId; + readonly sha256: Sha256Digest; readonly targetArc: "absent" | "present"; }; - readonly fixtureId: typeof CREW_RESERVATION_FIXTURE_ID; + readonly fixtureId: typeof crewReservationFixtureId; readonly latestWorkpiece: { readonly authorship: "model-produced" | "test-authored"; - readonly contentSha256: string; + readonly contentSha256: Sha256Digest; readonly sourceKind: "assistant" | "prepared-signal"; - readonly sourceMessageId: string; - readonly sourceMessageSha256: string; - readonly sourceSubmissionId: string; + readonly sourceMessageId: FlueMessageId; + readonly sourceMessageSha256: Sha256Digest; + readonly sourceSubmissionId: FlueSubmissionId; }; - readonly manifestId: string; + readonly manifestId: ManifestId; readonly revision: number; readonly settledAt: string; readonly version: 1; @@ -57,78 +82,38 @@ export type CrewReservationSettlementResult = readonly status: "refused"; }; -export type CrewReservationSettledHistory = WorkpieceHistory & { - readonly offset: string; - readonly settlements: readonly { - readonly outcome: string; - readonly submissionId: string; - }[]; -}; - -const isRecord = (value: unknown): value is Record => - typeof value === "object" && value !== null; - const targetMutationCallIds = ( - history: CrewReservationSettledHistory, -): readonly string[] => - history.messages.flatMap((message) => - message.parts.flatMap((part) => { - if ( - !isRecord(part) || - part.type !== "dynamic-tool" || - part.toolName !== "addArc" || - typeof part.toolCallId !== "string" || - !isRecord(part.input) || - part.input.transitionId !== START_FINAL_INSPECTION_TRANSITION_ID || - part.input.arcDirection !== "input" || - part.input.placeId !== DISPATCH_CREW_PLACE_ID || - part.input.weight !== 1 - ) { - return []; - } - return [part.toolCallId]; - }), + history: CrewReservationHistory, +): readonly string[] => { + const { calls } = clientToolHistoryFrom(history.messages); + return calls.flatMap(({ input, toolCallId, toolName }) => + toolName === "addArc" && + input.transitionId === startFinalInspectionTransitionId && + input.arcDirection === "input" && + input.placeId === dispatchCrewPlaceId && + input.weight === 1 + ? [toolCallId] + : [], ); +}; const successfulMutationResultIds = ( - history: CrewReservationSettledHistory, -): readonly string[] => - history.messages.flatMap((message) => { - if ( - message.signal?.tagName !== "client-tool-result" && - message.signal?.type !== "client-tool-result" - ) { - return []; - } - const body = message.parts - .flatMap((part) => - part.type === "text" && typeof part.text === "string" - ? [part.text] - : [], - ) - .join(""); - try { - const results: unknown = JSON.parse(body); - if (!Array.isArray(results)) return []; - return results.flatMap((result) => { - if ( - !isRecord(result) || - result.toolName !== "addArc" || - typeof result.toolCallId !== "string" || - !isRecord(result.output) || - result.output.applied !== true - ) { - return []; - } - return [result.toolCallId]; - }); - } catch { - return []; - } - }); + history: CrewReservationHistory, +): readonly string[] => { + const { results } = clientToolHistoryFrom(history.messages); + return results.flatMap(({ output, toolCallId, toolName }) => + toolName === "addArc" && + typeof output === "object" && + output !== null && + "applied" in output && + output.applied === true + ? [toolCallId] + : [], + ); +}; const hasOneCorrelatedTargetMutation = ( - history: CrewReservationSettledHistory, + history: CrewReservationHistory, ): boolean => { const targetCallIds = targetMutationCallIds(history); const successfulResultIds = successfulMutationResultIds(history); @@ -139,24 +124,26 @@ const hasOneCorrelatedTargetMutation = ( ); }; -const sha256 = async (value: string): Promise => { +const sha256 = async (value: string): Promise => { const digest = await globalThis.crypto.subtle.digest( "SHA-256", new TextEncoder().encode(value), ); - return [...new Uint8Array(digest)] - .map((byte) => byte.toString(16).padStart(2, "0")) - .join(""); + return asSha256Digest( + [...new Uint8Array(digest)] + .map((byte) => byte.toString(16).padStart(2, "0")) + .join(""), + ); }; export const hasCrewReservationTargetArc = (definition: SDCPN): boolean => { const transition = definition.transitions.find( - ({ id }) => id === START_FINAL_INSPECTION_TRANSITION_ID, + ({ id }) => id === startFinalInspectionTransitionId, ); return ( transition?.inputArcs.some( (arc) => - arc.placeId === DISPATCH_CREW_PLACE_ID && + arc.placeId === dispatchCrewPlaceId && arc.type === "standard" && arc.weight === 1, ) ?? false @@ -166,13 +153,13 @@ export const hasCrewReservationTargetArc = (definition: SDCPN): boolean => { const preparedCrewReservationNetWithTargetArc = (): SDCPN => { const definition = structuredClone(preparedCrewReservationNet); const transition = definition.transitions.find( - ({ id }) => id === START_FINAL_INSPECTION_TRANSITION_ID, + ({ id }) => id === startFinalInspectionTransitionId, ); if (transition === undefined) { throw new Error("The prepared fixture has no start-inspection transition."); } transition.inputArcs.push({ - placeId: DISPATCH_CREW_PLACE_ID, + placeId: dispatchCrewPlaceId, type: "standard", weight: 1, }); @@ -181,7 +168,7 @@ const preparedCrewReservationNetWithTargetArc = (): SDCPN => { export const settleCrewReservationManifest = async (input: { readonly definition: SDCPN; - readonly history: CrewReservationSettledHistory; + readonly history: CrewReservationHistory; readonly previous?: CrewReservationSettledManifest; readonly settledAt: string; }): Promise => { @@ -256,24 +243,24 @@ export const settleCrewReservationManifest = async (input: { const revision = (input.previous?.revision ?? -1) + 1; const withoutId = { version: 1 as const, - fixtureId: CREW_RESERVATION_FIXTURE_ID, + fixtureId: crewReservationFixtureId, revision, settledAt: input.settledAt, conversation: { - logicalId: CREW_RESERVATION_CONVERSATION_ID, - canonicalId: input.history.conversationId, - offset: input.history.offset, + logicalId: crewReservationConversationId, + canonicalId: asCanonicalConversationId(input.history.conversationId), + offset: asConversationOffset(input.history.offset), }, latestWorkpiece: { authorship: workpiece.authorship, contentSha256, sourceKind: workpiece.sourceKind, - sourceMessageId: workpiece.sourceMessageId, + sourceMessageId: asFlueMessageId(workpiece.sourceMessageId), sourceMessageSha256, - sourceSubmissionId: workpiece.sourceSubmissionId, + sourceSubmissionId: asFlueSubmissionId(workpiece.sourceSubmissionId), }, document: { - id: CREW_RESERVATION_DOCUMENT_ID, + id: crewReservationDocumentId, sha256: documentSha256, targetArc: targetArcPresent ? ("present" as const) : ("absent" as const), }, @@ -283,7 +270,7 @@ export const settleCrewReservationManifest = async (input: { status: "settled", manifest: { ...withoutId, - manifestId: await sha256(JSON.stringify(withoutId)), + manifestId: asManifestId(await sha256(JSON.stringify(withoutId))), }, }; }; diff --git a/apps/petrinaut-website/src/main/app/local-storage-demo/local-storage-demo-app.tsx b/apps/petrinaut-website/src/main/app/local-storage-demo/local-storage-demo-app.tsx index b3aa246df67..cc76b8edc74 100644 --- a/apps/petrinaut-website/src/main/app/local-storage-demo/local-storage-demo-app.tsx +++ b/apps/petrinaut-website/src/main/app/local-storage-demo/local-storage-demo-app.tsx @@ -5,13 +5,12 @@ import { createFlueClient, type FlueConversationSettlement } from "@flue/sdk"; import { produce } from "immer"; -import { useEffect, useMemo, useState } from "react"; +import { useCallback, useEffect, useMemo, useState } from "react"; import { agentOwnershipHeaders, flueConversationIdWeb, } from "@hashintel/brunch-agent-transport-aisdk"; -import { selectRunbookWorkpiece } from "@hashintel/brunch-agent/workpiece"; import { createJsonDocHandle, type MinimalNetMetadata, @@ -55,11 +54,8 @@ import { } from "./brunch-panel-transport"; import { resolveBrunchPreviewConfig } from "./brunch-preview-config"; import { getOrCreateBrunchPrincipal } from "./brunch-principal"; -import { prepareCrewReservationConversation } from "./prepare-crew-reservation-conversation"; import { - CREW_RESERVATION_CLIENT_TOOL_NAMES, - CREW_RESERVATION_CONVERSATION_ID, - CREW_RESERVATION_DOCUMENT_ID, + crewReservationDocumentId, isCrewReservationFixtureSelected, preparedCrewReservationNet, } from "./prepared-crew-reservation-fixture"; @@ -67,7 +63,12 @@ import { PreparedFixtureBanner, PreparedFixtureSelector, } from "./prepared-fixture-banner"; -import { useCrewReservationSettledManifest } from "./use-crew-reservation-settled-manifest"; +import { resolveCrewReservationBundle } from "./resolve-crew-reservation-bundle"; +import { + crewReservationFixtureConfiguration, + useCrewReservationFixtureSession, +} from "./use-crew-reservation-fixture-session"; +import { useCrewReservationSettledManifestStorage } from "./use-crew-reservation-settled-manifest"; import { useFlueChatHistory } from "./use-flue-chat-history"; import { useLocalStorageAiMessages } from "./use-local-storage-ai-messages"; import { @@ -105,7 +106,7 @@ const createDefaultStoredSDCPN = (): SDCPNInLocalStorage => ({ }); const preparedCrewReservationStoredSDCPN: SDCPNInLocalStorage = { - id: CREW_RESERVATION_DOCUMENT_ID, + id: crewReservationDocumentId, title: "Prepared final inspection and dispatch", sdcpn: preparedCrewReservationNet, lastUpdated: new Date(0).toISOString(), @@ -174,9 +175,6 @@ const createHandle = (net: SDCPNInLocalStorage): PetrinautDocHandle => }); const brunchPrincipal = getOrCreateBrunchPrincipal(); -const crewReservationClientToolNames: ReadonlySet = new Set( - CREW_RESERVATION_CLIENT_TOOL_NAMES, -); /** Every widget here must answer a tool named in `brunchClientToolNames`. */ export const brunchInteractiveTools: readonly PetrinautAiInteractiveTool[] = [ @@ -226,14 +224,12 @@ const createConversationTrackerFor = ( const getStoredSDCPNsForDisplay = ( storedSDCPNs: Record, - crewReservationFixtureSelected: boolean, + crewReservationDocument: SDCPNInLocalStorage | undefined, ): Record => { - if (crewReservationFixtureSelected) { + if (crewReservationDocument !== undefined) { return { ...storedSDCPNs, - [CREW_RESERVATION_DOCUMENT_ID]: - storedSDCPNs[CREW_RESERVATION_DOCUMENT_ID] ?? - preparedCrewReservationStoredSDCPN, + [crewReservationDocument.id]: crewReservationDocument, }; } if (Object.values(storedSDCPNs).length > 0) { @@ -385,27 +381,56 @@ export const LocalStorageDemoApp = ({ const { aiMessagesByNetId, setAiMessagesByNetId } = useLocalStorageAiMessages(); const { storedSDCPNs, setStoredSDCPNs } = useLocalStorageSDCPNs(); + const { settledManifest, setSettledManifest } = + useCrewReservationSettledManifestStorage(); const crewReservationFixtureSelected = isCrewReservationFixtureSelected( window.location.search, ); + const crewReservationBundle = crewReservationFixtureSelected + ? resolveCrewReservationBundle({ + fallbackDocument: preparedCrewReservationStoredSDCPN, + manifest: settledManifest, + storedDocument: storedSDCPNs[crewReservationDocumentId], + }) + : undefined; const storedSDCPNsForDisplay = getStoredSDCPNsForDisplay( storedSDCPNs, - crewReservationFixtureSelected, + crewReservationBundle?.selectedDocument, ); useEffect(() => { if ( !crewReservationFixtureSelected || - storedSDCPNs[CREW_RESERVATION_DOCUMENT_ID] !== undefined + storedSDCPNs[crewReservationDocumentId] !== undefined ) { return; } setStoredSDCPNs((previous) => ({ ...previous, - [CREW_RESERVATION_DOCUMENT_ID]: preparedCrewReservationStoredSDCPN, + [crewReservationDocumentId]: preparedCrewReservationStoredSDCPN, })); }, [crewReservationFixtureSelected, setStoredSDCPNs, storedSDCPNs]); + const persistCrewReservationSnapshot = useCallback( + (sha256: string, definition: SDCPN) => { + setStoredSDCPNs((previous) => + produce(previous, (draft) => { + const document = + draft[crewReservationDocumentId] ?? + preparedCrewReservationStoredSDCPN; + draft[crewReservationDocumentId] = { + ...document, + coherentSnapshots: { + ...document.coherentSnapshots, + [sha256]: structuredClone(definition), + }, + }; + }), + ); + }, + [setStoredSDCPNs], + ); + useEffect(() => { if (!brunchPreviewConfig.isBrunchConfigured) { return; @@ -431,7 +456,7 @@ export const LocalStorageDemoApp = ({ new Date(b.lastUpdated).getTime() - new Date(a.lastUpdated).getTime(), )[0] ?? null; const initiallySelectedNet = crewReservationFixtureSelected - ? storedSDCPNsForDisplay[CREW_RESERVATION_DOCUMENT_ID] + ? storedSDCPNsForDisplay[crewReservationDocumentId] : mostRecentlyModifiedNet; // The net currently selected in the UI. @@ -565,29 +590,22 @@ export const LocalStorageDemoApp = ({ const preparedFixtureIsCurrent = crewReservationFixtureSelected && - currentNetId === CREW_RESERVATION_DOCUMENT_ID; + currentNetId === crewReservationDocumentId; + const fixtureConfiguration = preparedFixtureIsCurrent + ? crewReservationFixtureConfiguration + : undefined; const conversationId = currentNetId === null ? null - : preparedFixtureIsCurrent - ? CREW_RESERVATION_CONVERSATION_ID - : getOrCreateBrunchConversationId(currentNetId); - const rawFlueClientPromise = useMemo( + : (fixtureConfiguration?.conversationId ?? + getOrCreateBrunchConversationId(currentNetId)); + const flueClientPromise = useMemo( () => brunchPreviewConfig.isBrunchConfigured && conversationId !== null ? createBrunchFlueClient(conversationId) : null, [conversationId], ); - const flueClientPromise = useMemo(() => { - if (rawFlueClientPromise === null || !preparedFixtureIsCurrent) { - return rawFlueClientPromise; - } - return rawFlueClientPromise.then(async (client) => { - await prepareCrewReservationConversation(client); - return client; - }); - }, [preparedFixtureIsCurrent, rawFlueClientPromise]); const conversationTracker = useMemo( // Correlation state belongs to one conversation and must not cross a net switch. () => createConversationTrackerFor(conversationId), @@ -596,7 +614,7 @@ export const LocalStorageDemoApp = ({ const flueHistory = useFlueChatHistory( flueClientPromise, conversationId ?? "", - preparedFixtureIsCurrent ? crewReservationClientToolNames : undefined, + fixtureConfiguration?.clientToolNames, ); const brunchVoiceMode = useMemo( () => @@ -607,46 +625,43 @@ export const LocalStorageDemoApp = ({ ), [conversationTracker, flueHistory.settlements, openAIVoiceConfig], ); - const { settledManifest, status: settlementStatus } = - useCrewReservationSettledManifest({ - definition: preparedFixtureIsCurrent ? currentNet?.sdcpn : undefined, - enabled: preparedFixtureIsCurrent, - history: preparedFixtureIsCurrent ? flueHistory.snapshot : undefined, - historyError: preparedFixtureIsCurrent - ? flueHistory.error?.message - : undefined, - }); - const currentWorkpiece = (() => { - if (flueHistory.snapshot === undefined) return undefined; - try { - return selectRunbookWorkpiece(flueHistory.snapshot)?.content; - } catch { - return undefined; - } - })(); + const crewReservationSession = useCrewReservationFixtureSession({ + clientPromise: flueClientPromise, + definition: storedSDCPNs[crewReservationDocumentId]?.sdcpn, + enabled: fixtureConfiguration !== undefined, + history: flueHistory.snapshot, + historyError: flueHistory.error?.message, + persistCoherentSnapshot: persistCrewReservationSnapshot, + refreshHistory: flueHistory.refresh, + setSettledManifest, + settledManifest, + snapshotMissing: crewReservationBundle?.snapshotMissing ?? false, + }); const petrinautAiChatTransport = useMemo(() => { - if (flueClientPromise !== null) { + if (flueClientPromise !== null && crewReservationSession.transportReady) { return createBrunchPanelTransport( flueClientPromise, conversationTracker, { - ...(preparedFixtureIsCurrent - ? { clientToolNames: crewReservationClientToolNames } - : {}), + ...(fixtureConfiguration === undefined + ? {} + : { clientToolNames: fixtureConfiguration.clientToolNames }), onAdmission: flueHistory.refresh, }, ); } - return preparedFixtureIsCurrent + return fixtureConfiguration !== undefined ? createUnavailableBrunchPanelTransport( - "The prepared fixture requires the mounted Brunch Flue route.", + crewReservationSession.transportUnavailableReason, ) : stockChatTransport; }, [ conversationTracker, + crewReservationSession.transportReady, + crewReservationSession.transportUnavailableReason, + fixtureConfiguration, flueClientPromise, flueHistory.refresh, - preparedFixtureIsCurrent, ]); const aiAssistant = useMemo( @@ -741,9 +756,9 @@ export const LocalStorageDemoApp = ({ > {preparedFixtureIsCurrent && ( )} {!preparedFixtureIsCurrent && } diff --git a/apps/petrinaut-website/src/main/app/local-storage-demo/prepare-crew-reservation-conversation.test.ts b/apps/petrinaut-website/src/main/app/local-storage-demo/prepare-crew-reservation-conversation.test.ts index 64270890faa..23a69be894d 100644 --- a/apps/petrinaut-website/src/main/app/local-storage-demo/prepare-crew-reservation-conversation.test.ts +++ b/apps/petrinaut-website/src/main/app/local-storage-demo/prepare-crew-reservation-conversation.test.ts @@ -1,13 +1,13 @@ import { describe, expect, test, vi } from "vitest"; import { - PREPARED_WORKPIECE_INITIAL_DATA_MODE, - PREPARED_WORKPIECE_SIGNAL_TAG, + preparedWorkpieceInitialDataMode, + preparedWorkpieceSignalTag, } from "@hashintel/brunch-agent/workpiece"; import { prepareCrewReservationConversation } from "./prepare-crew-reservation-conversation"; import { - CREW_RESERVATION_FIXTURE_ID, + crewReservationFixtureId, preparedCrewReservationDelivery, preparedCrewReservationWorkpiece, } from "./prepared-crew-reservation-fixture"; @@ -23,9 +23,9 @@ const preparedHistory = { purpose: "dispatch", submissionId: "prepare-submission", signal: { - tagName: PREPARED_WORKPIECE_SIGNAL_TAG, + tagName: preparedWorkpieceSignalTag, attributes: { - fixtureId: CREW_RESERVATION_FIXTURE_ID, + fixtureId: crewReservationFixtureId, authorship: "test-authored", claimBoundary: "prepared-not-model-produced", }, @@ -65,7 +65,7 @@ describe("prepareCrewReservationConversation", () => { ).resolves.toEqual(preparedHistory); expect(send).toHaveBeenCalledWith({ uid: null, - initialData: { mode: PREPARED_WORKPIECE_INITIAL_DATA_MODE }, + initialData: { mode: preparedWorkpieceInitialDataMode }, ...preparedCrewReservationDelivery, }); expect(wait).toHaveBeenCalledWith(admission); diff --git a/apps/petrinaut-website/src/main/app/local-storage-demo/prepare-crew-reservation-conversation.ts b/apps/petrinaut-website/src/main/app/local-storage-demo/prepare-crew-reservation-conversation.ts index c0fcab5c3c5..7c8625c06b7 100644 --- a/apps/petrinaut-website/src/main/app/local-storage-demo/prepare-crew-reservation-conversation.ts +++ b/apps/petrinaut-website/src/main/app/local-storage-demo/prepare-crew-reservation-conversation.ts @@ -1,30 +1,22 @@ import { - PREPARED_WORKPIECE_INITIAL_DATA_MODE, + preparedWorkpieceInitialDataMode, selectRunbookWorkpiece, - type WorkpieceHistory, } from "@hashintel/brunch-agent/workpiece"; import { - CREW_RESERVATION_FIXTURE_ID, + crewReservationFixtureId, preparedCrewReservationDelivery, } from "./prepared-crew-reservation-fixture"; +import type { CrewReservationHistory } from "./crew-reservation-history"; import type { AgentSendResult } from "@flue/sdk"; -export type PreparedCrewReservationHistory = WorkpieceHistory & { - readonly offset: string; - readonly settlements: readonly { - readonly outcome: string; - readonly submissionId: string; - }[]; -}; - export interface PreparedFixtureConversationClient { - readonly history: () => Promise; + readonly history: () => Promise; readonly send: (input: { readonly idempotencyKey: string; readonly initialData: { - readonly mode: typeof PREPARED_WORKPIECE_INITIAL_DATA_MODE; + readonly mode: typeof preparedWorkpieceInitialDataMode; }; readonly message: typeof preparedCrewReservationDelivery.message; readonly uid: null; @@ -39,8 +31,8 @@ const isNotFound = (error: unknown): boolean => error.status === 404; const assertPreparedFixtureHistory = ( - history: PreparedCrewReservationHistory, -): PreparedCrewReservationHistory => { + history: CrewReservationHistory, +): CrewReservationHistory => { const currentWorkpiece = selectRunbookWorkpiece(history); if ( currentWorkpiece?.sourceKind !== "prepared-signal" && @@ -56,8 +48,7 @@ const assertPreparedFixtureHistory = ( preparedCrewReservationDelivery.message.tagName, ); if ( - preparedSource?.signal?.attributes?.fixtureId !== - CREW_RESERVATION_FIXTURE_ID + preparedSource?.signal?.attributes?.fixtureId !== crewReservationFixtureId ) { throw new Error( "The prepared fixture conversation belongs to a different fixture.", @@ -73,7 +64,7 @@ const assertPreparedFixtureHistory = ( */ export const prepareCrewReservationConversation = async ( client: PreparedFixtureConversationClient, -): Promise => { +): Promise => { try { return assertPreparedFixtureHistory(await client.history()); } catch (error) { @@ -82,7 +73,7 @@ export const prepareCrewReservationConversation = async ( const admission = await client.send({ uid: null, - initialData: { mode: PREPARED_WORKPIECE_INITIAL_DATA_MODE }, + initialData: { mode: preparedWorkpieceInitialDataMode }, ...preparedCrewReservationDelivery, }); await client.wait(admission); diff --git a/apps/petrinaut-website/src/main/app/local-storage-demo/prepared-crew-reservation-fixture.test.ts b/apps/petrinaut-website/src/main/app/local-storage-demo/prepared-crew-reservation-fixture.test.ts index 36bda9934fe..9374b8df606 100644 --- a/apps/petrinaut-website/src/main/app/local-storage-demo/prepared-crew-reservation-fixture.test.ts +++ b/apps/petrinaut-website/src/main/app/local-storage-demo/prepared-crew-reservation-fixture.test.ts @@ -1,14 +1,14 @@ import { describe, expect, test } from "vitest"; import { - CREW_RESERVATION_CLIENT_TOOL_NAMES, - CREW_RESERVATION_FIXTURE_ID, - DISPATCH_CREW_PLACE_ID, + crewReservationFixtureClientToolNames, + crewReservationFixtureId, + dispatchCrewPlaceId, isCrewReservationFixtureSelected, preparedCrewReservationDelivery, preparedCrewReservationNet, preparedCrewReservationWorkpiece, - START_FINAL_INSPECTION_TRANSITION_ID, + startFinalInspectionTransitionId, } from "./prepared-crew-reservation-fixture"; const transitionById = (transitionId: string) => { @@ -23,16 +23,14 @@ const transitionById = (transitionId: string) => { describe("prepared crew-reservation fixture", () => { test("advertises only the selected canonical read and mutation", () => { - expect(CREW_RESERVATION_CLIENT_TOOL_NAMES).toEqual([ + expect(crewReservationFixtureClientToolNames).toEqual([ "getLatestNetDefinition", "addArc", ]); }); test("has the batch flow and crew return but omits the target input arc", () => { - const startInspection = transitionById( - START_FINAL_INSPECTION_TRANSITION_ID, - ); + const startInspection = transitionById(startFinalInspectionTransitionId); const signOff = transitionById("sign-off"); expect(startInspection.inputArcs).toContainEqual({ @@ -41,12 +39,12 @@ describe("prepared crew-reservation fixture", () => { weight: 1, }); expect(startInspection.inputArcs).not.toContainEqual( - expect.objectContaining({ placeId: DISPATCH_CREW_PLACE_ID }), + expect.objectContaining({ placeId: dispatchCrewPlaceId }), ); expect(signOff.outputArcs).toEqual( expect.arrayContaining([ { placeId: "ready-for-dispatch", weight: 1 }, - { placeId: DISPATCH_CREW_PLACE_ID, weight: 1 }, + { placeId: dispatchCrewPlaceId, weight: 1 }, ]), ); }); @@ -62,7 +60,7 @@ describe("prepared crew-reservation fixture", () => { "not model-produced evidence", ); expect(preparedCrewReservationDelivery.message.attributes).toEqual({ - fixtureId: CREW_RESERVATION_FIXTURE_ID, + fixtureId: crewReservationFixtureId, authorship: "test-authored", claimBoundary: "prepared-not-model-produced", }); @@ -71,7 +69,7 @@ describe("prepared crew-reservation fixture", () => { test("selects only the explicit stable query value", () => { expect( isCrewReservationFixtureSelected( - `?brunch-fixture=${CREW_RESERVATION_FIXTURE_ID}`, + `?brunch-fixture=${crewReservationFixtureId}`, ), ).toBe(true); expect( diff --git a/apps/petrinaut-website/src/main/app/local-storage-demo/prepared-crew-reservation-fixture.ts b/apps/petrinaut-website/src/main/app/local-storage-demo/prepared-crew-reservation-fixture.ts index 69588ab02cf..92be1cc9a9c 100644 --- a/apps/petrinaut-website/src/main/app/local-storage-demo/prepared-crew-reservation-fixture.ts +++ b/apps/petrinaut-website/src/main/app/local-storage-demo/prepared-crew-reservation-fixture.ts @@ -6,19 +6,19 @@ import { import type { SDCPN } from "@hashintel/petrinaut-core"; -export const CREW_RESERVATION_FIXTURE_ID = "crew-reservation-v1"; -export const CREW_RESERVATION_DOCUMENT_ID = +export const crewReservationFixtureId = "crew-reservation-v1"; +export const crewReservationDocumentId = "mission-6-crew-reservation-document-v1"; -export const CREW_RESERVATION_CONVERSATION_ID = +export const crewReservationConversationId = "mission-6-crew-reservation-conversation-v1"; -export const CREW_RESERVATION_FIXTURE_QUERY = "brunch-fixture"; -export const CREW_RESERVATION_CLIENT_TOOL_NAMES = [ +export const crewReservationFixtureQuery = "brunch-fixture"; +export const crewReservationFixtureClientToolNames = [ getLatestNetDefinitionToolName, "addArc", ] as const satisfies readonly PetrinautAiToolName[]; -export const DISPATCH_CREW_PLACE_ID = "dispatch-crew-available"; -export const START_FINAL_INSPECTION_TRANSITION_ID = "start-final-inspection"; +export const dispatchCrewPlaceId = "dispatch-crew-available"; +export const startFinalInspectionTransitionId = "start-final-inspection"; export const preparedCrewReservationWorkpiece = [ "Fixture authorship: test-authored preparation for Mission 6.", @@ -51,7 +51,7 @@ export const preparedCrewReservationWorkpiece = [ export const preparedCrewReservationDelivery = createPreparedWorkpieceDelivery({ body: preparedCrewReservationWorkpiece, - fixtureId: CREW_RESERVATION_FIXTURE_ID, + fixtureId: crewReservationFixtureId, revision: 0, }); @@ -85,7 +85,7 @@ export const preparedCrewReservationNet: SDCPN = { y: 100, }, { - id: DISPATCH_CREW_PLACE_ID, + id: dispatchCrewPlaceId, name: "Dispatch crew available", colorId: null, dynamicsEnabled: false, @@ -96,7 +96,7 @@ export const preparedCrewReservationNet: SDCPN = { ], transitions: [ { - id: START_FINAL_INSPECTION_TRANSITION_ID, + id: startFinalInspectionTransitionId, name: "Start final inspection", inputArcs: [ { @@ -133,7 +133,7 @@ export const preparedCrewReservationNet: SDCPN = { weight: 1, }, { - placeId: DISPATCH_CREW_PLACE_ID, + placeId: dispatchCrewPlaceId, weight: 1, }, ], @@ -150,5 +150,5 @@ export const preparedCrewReservationNet: SDCPN = { }; export const isCrewReservationFixtureSelected = (search: string): boolean => - new URLSearchParams(search).get(CREW_RESERVATION_FIXTURE_QUERY) === - CREW_RESERVATION_FIXTURE_ID; + new URLSearchParams(search).get(crewReservationFixtureQuery) === + crewReservationFixtureId; diff --git a/apps/petrinaut-website/src/main/app/local-storage-demo/prepared-fixture-banner.test.tsx b/apps/petrinaut-website/src/main/app/local-storage-demo/prepared-fixture-banner.test.tsx index 4d307764689..28ad5065b61 100644 --- a/apps/petrinaut-website/src/main/app/local-storage-demo/prepared-fixture-banner.test.tsx +++ b/apps/petrinaut-website/src/main/app/local-storage-demo/prepared-fixture-banner.test.tsx @@ -2,9 +2,17 @@ import { renderToStaticMarkup } from "react-dom/server"; import { describe, expect, test } from "vitest"; import { - CREW_RESERVATION_CONVERSATION_ID, - CREW_RESERVATION_DOCUMENT_ID, - CREW_RESERVATION_FIXTURE_ID, + asCanonicalConversationId, + asConversationOffset, + asFlueMessageId, + asFlueSubmissionId, + asManifestId, + asSha256Digest, +} from "./crew-reservation-settled-manifest"; +import { + crewReservationConversationId, + crewReservationDocumentId, + crewReservationFixtureId, } from "./prepared-crew-reservation-fixture"; import { PreparedFixtureBanner, @@ -38,26 +46,26 @@ describe("PreparedFixtureBanner", () => { (
{settlementStatus.state === "refused" - ? `Settlement refused (${settlementStatus.reason}); ${ - settledManifest === null - ? "no coherent bundle is selected" - : `bundle revision ${settledManifest.revision} remains selected` - }.${settlementStatus.detail === undefined ? "" : ` ${settlementStatus.detail}`}` + ? settlementStatus.reason === "bundle-snapshot-unavailable" + ? `Settlement refused (${settlementStatus.reason}); the selected document revision is unavailable and the live mirror is shown only for diagnosis.` + : `Settlement refused (${settlementStatus.reason}); ${ + settledManifest === null + ? "no coherent bundle is selected" + : `bundle revision ${settledManifest.revision} remains selected` + }.${settlementStatus.detail === undefined ? "" : ` ${settlementStatus.detail}`}` : settlementStatus.state !== "settled" || settledManifest === null ? "Preparing the conversation, workpiece, and automatically mirrored document…" : `Settled bundle revision ${settledManifest.revision}; target crew-reservation arc ${settledManifest.document.targetArc}.`}
-
- Current Markdown workpiece -
-          {currentWorkpiece}
-        
-
+ {displayedWorkpiece === undefined ? ( +
The selected bundle’s Markdown workpiece is unavailable.
+ ) : ( +
+ Current Markdown workpiece +
+            {displayedWorkpiece}
+          
+
+ )} ); }; diff --git a/apps/petrinaut-website/src/main/app/local-storage-demo/resolve-crew-reservation-bundle.test.ts b/apps/petrinaut-website/src/main/app/local-storage-demo/resolve-crew-reservation-bundle.test.ts new file mode 100644 index 00000000000..169ad433863 --- /dev/null +++ b/apps/petrinaut-website/src/main/app/local-storage-demo/resolve-crew-reservation-bundle.test.ts @@ -0,0 +1,149 @@ +import { describe, expect, test } from "vitest"; + +import { + preparedWorkpieceAuthorship, + preparedWorkpieceClaimBoundary, + preparedWorkpieceSignalTag, +} from "@hashintel/brunch-agent/workpiece"; + +import { + asCanonicalConversationId, + asConversationOffset, + asFlueMessageId, + asFlueSubmissionId, + asManifestId, + asSha256Digest, + type CrewReservationSettledManifest, +} from "./crew-reservation-settled-manifest"; +import { + crewReservationConversationId, + crewReservationDocumentId, + crewReservationFixtureId, + preparedCrewReservationNet, + preparedCrewReservationWorkpiece, +} from "./prepared-crew-reservation-fixture"; +import { + resolveCrewReservationBundle, + workpieceForCrewReservationBundle, +} from "./resolve-crew-reservation-bundle"; + +import type { SDCPNInLocalStorage } from "./use-local-storage-sdcpns"; + +const manifest: CrewReservationSettledManifest = { + version: 1, + fixtureId: crewReservationFixtureId, + manifestId: asManifestId("manifest"), + revision: 0, + settledAt: "2026-09-04T08:00:00.000Z", + conversation: { + canonicalId: asCanonicalConversationId("canonical"), + logicalId: crewReservationConversationId, + offset: asConversationOffset("2"), + }, + document: { + id: crewReservationDocumentId, + sha256: asSha256Digest("coherent-hash"), + targetArc: "absent", + }, + latestWorkpiece: { + authorship: "test-authored", + contentSha256: asSha256Digest("content"), + sourceKind: "prepared-signal", + sourceMessageId: asFlueMessageId("prepared-message"), + sourceMessageSha256: asSha256Digest("message"), + sourceSubmissionId: asFlueSubmissionId("prepare-submission"), + }, +}; + +const fallbackDocument: SDCPNInLocalStorage = { + id: crewReservationDocumentId, + title: "Prepared", + sdcpn: preparedCrewReservationNet, + lastUpdated: "1970-01-01T00:00:00.000Z", +}; + +describe("resolveCrewReservationBundle", () => { + test("selects the content-addressed coherent document over a partial mirror", () => { + const partialDefinition = structuredClone(preparedCrewReservationNet); + const firstPlace = partialDefinition.places.at(0); + if (firstPlace === undefined) { + throw new Error("The prepared fixture has no places."); + } + firstPlace.name = "Partial write"; + + const selection = resolveCrewReservationBundle({ + fallbackDocument, + manifest, + storedDocument: { + ...fallbackDocument, + sdcpn: partialDefinition, + coherentSnapshots: { + "coherent-hash": preparedCrewReservationNet, + }, + }, + }); + + expect(selection.snapshotMissing).toBe(false); + expect(selection.selectedDocument.sdcpn).toEqual( + preparedCrewReservationNet, + ); + expect(selection.selectedDocument.sdcpn).not.toEqual(partialDefinition); + expect(selection.observedDocument.sdcpn).toEqual(partialDefinition); + }); + + test("keeps a missing snapshot diagnosable without inventing a revision", () => { + const selection = resolveCrewReservationBundle({ + fallbackDocument, + manifest, + storedDocument: fallbackDocument, + }); + + expect(selection).toEqual({ + observedDocument: fallbackDocument, + selectedDocument: fallbackDocument, + snapshotMissing: true, + }); + }); +}); + +test("selects the workpiece source named by the settled manifest", () => { + const newerWorkpiece = "```runbook-ir\n# Unsettled newer workpiece\n```"; + expect( + workpieceForCrewReservationBundle( + { + conversationId: "canonical", + offset: "3", + settlements: [], + messages: [ + { + id: "prepared-message", + role: "system", + purpose: "dispatch", + submissionId: "prepare-submission", + signal: { + tagName: preparedWorkpieceSignalTag, + attributes: { + fixtureId: crewReservationFixtureId, + authorship: preparedWorkpieceAuthorship, + claimBoundary: preparedWorkpieceClaimBoundary, + }, + }, + parts: [ + { + type: "text", + text: preparedCrewReservationWorkpiece, + }, + ], + }, + { + id: "newer-message", + role: "assistant", + purpose: "assistant", + parts: [{ type: "text", text: newerWorkpiece }], + }, + ], + }, + manifest, + ), + ).toContain("# Final inspection and dispatch workpiece"); +}); diff --git a/apps/petrinaut-website/src/main/app/local-storage-demo/resolve-crew-reservation-bundle.ts b/apps/petrinaut-website/src/main/app/local-storage-demo/resolve-crew-reservation-bundle.ts new file mode 100644 index 00000000000..065568d3320 --- /dev/null +++ b/apps/petrinaut-website/src/main/app/local-storage-demo/resolve-crew-reservation-bundle.ts @@ -0,0 +1,66 @@ +import { + latestRunbookIrBlock, + selectRunbookWorkpiece, +} from "@hashintel/brunch-agent/workpiece"; + +import type { CrewReservationHistory } from "./crew-reservation-history"; +import type { CrewReservationSettledManifest } from "./crew-reservation-settled-manifest"; +import type { SDCPNInLocalStorage } from "./use-local-storage-sdcpns"; + +export interface CrewReservationBundleSelection { + readonly observedDocument: SDCPNInLocalStorage; + readonly selectedDocument: SDCPNInLocalStorage; + readonly snapshotMissing: boolean; +} + +export const resolveCrewReservationBundle = (input: { + readonly fallbackDocument: SDCPNInLocalStorage; + readonly manifest: CrewReservationSettledManifest | null; + readonly storedDocument: SDCPNInLocalStorage | undefined; +}): CrewReservationBundleSelection => { + const liveDocument = input.storedDocument ?? input.fallbackDocument; + if (input.manifest === null) { + return { + observedDocument: liveDocument, + selectedDocument: liveDocument, + snapshotMissing: false, + }; + } + + const coherentDefinition = + liveDocument.coherentSnapshots?.[input.manifest.document.sha256]; + if (coherentDefinition === undefined) { + return { + observedDocument: liveDocument, + selectedDocument: liveDocument, + snapshotMissing: true, + }; + } + + return { + observedDocument: liveDocument, + selectedDocument: { + ...liveDocument, + sdcpn: coherentDefinition, + }, + snapshotMissing: false, + }; +}; + +export const workpieceForCrewReservationBundle = ( + history: CrewReservationHistory | undefined, + manifest: CrewReservationSettledManifest | null, +): string | undefined => { + if (history === undefined) return undefined; + if (manifest === null) return selectRunbookWorkpiece(history)?.content; + + const selectedMessage = history.messages.find( + ({ id }) => id === manifest.latestWorkpiece.sourceMessageId, + ); + if (selectedMessage === undefined) return undefined; + return latestRunbookIrBlock( + selectedMessage.parts + .flatMap((part) => (part.type === "text" ? [part.text] : [])) + .join("\n"), + ); +}; diff --git a/apps/petrinaut-website/src/main/app/local-storage-demo/use-crew-reservation-fixture-session.ts b/apps/petrinaut-website/src/main/app/local-storage-demo/use-crew-reservation-fixture-session.ts new file mode 100644 index 00000000000..fa48ec861ed --- /dev/null +++ b/apps/petrinaut-website/src/main/app/local-storage-demo/use-crew-reservation-fixture-session.ts @@ -0,0 +1,103 @@ +import { useEffect, useMemo } from "react"; + +import { + crewReservationConversationId, + crewReservationFixtureClientToolNames, +} from "./prepared-crew-reservation-fixture"; +import { workpieceForCrewReservationBundle } from "./resolve-crew-reservation-bundle"; +import { useCrewReservationSettlement } from "./use-crew-reservation-settled-manifest"; +import { usePrepareCrewReservationConversation } from "./use-prepare-crew-reservation-conversation"; + +import type { CrewReservationHistory } from "./crew-reservation-history"; +import type { CrewReservationSettledManifest } from "./crew-reservation-settled-manifest"; +import type { FlueClient } from "@flue/sdk"; +import type { SDCPN } from "@hashintel/petrinaut-core"; + +const clientToolNames: ReadonlySet = new Set( + crewReservationFixtureClientToolNames, +); + +export const crewReservationFixtureConfiguration = { + clientToolNames, + conversationId: crewReservationConversationId, +} as const; + +export const useCrewReservationFixtureSession = (input: { + readonly clientPromise: Promise | null; + readonly definition: SDCPN | undefined; + readonly enabled: boolean; + readonly history: CrewReservationHistory | undefined; + readonly historyError: string | undefined; + readonly persistCoherentSnapshot: (sha256: string, definition: SDCPN) => void; + readonly refreshHistory: () => void; + readonly setSettledManifest: ( + value: + | CrewReservationSettledManifest + | null + | (( + previous: CrewReservationSettledManifest | null, + ) => CrewReservationSettledManifest | null), + ) => void; + readonly settledManifest: CrewReservationSettledManifest | null; + readonly snapshotMissing: boolean; +}) => { + const { + clientPromise, + definition, + enabled, + history, + historyError, + persistCoherentSnapshot, + refreshHistory, + setSettledManifest, + settledManifest, + snapshotMissing, + } = input; + const preparationStatus = usePrepareCrewReservationConversation( + clientPromise, + enabled, + ); + + useEffect(() => { + if ( + preparationStatus.state === "ready" || + preparationStatus.state === "failed" + ) { + refreshHistory(); + } + }, [preparationStatus.state, refreshHistory]); + + const settlementStatus = useCrewReservationSettlement({ + definition: enabled ? definition : undefined, + enabled, + history: enabled ? history : undefined, + historyError: enabled ? historyError : undefined, + persistCoherentSnapshot, + preparationError: + preparationStatus.state === "failed" + ? preparationStatus.error + : undefined, + setSettledManifest, + settledManifest, + snapshotMissing, + }); + + const currentWorkpiece = useMemo(() => { + try { + return workpieceForCrewReservationBundle(history, settledManifest); + } catch { + return undefined; + } + }, [history, settledManifest]); + + return { + currentWorkpiece, + preparationStatus, + settlementStatus, + transportReady: !enabled || preparationStatus.state === "ready", + transportUnavailableReason: + preparationStatus.state === "failed" + ? preparationStatus.error + : "The prepared fixture conversation is still being prepared.", + }; +}; diff --git a/apps/petrinaut-website/src/main/app/local-storage-demo/use-crew-reservation-settled-manifest.test.ts b/apps/petrinaut-website/src/main/app/local-storage-demo/use-crew-reservation-settled-manifest.test.ts index d36e10ce9bd..2d199f9577c 100644 --- a/apps/petrinaut-website/src/main/app/local-storage-demo/use-crew-reservation-settled-manifest.test.ts +++ b/apps/petrinaut-website/src/main/app/local-storage-demo/use-crew-reservation-settled-manifest.test.ts @@ -2,23 +2,26 @@ * @vitest-environment jsdom */ import { cleanup, renderHook, waitFor } from "@testing-library/react"; -import { afterEach, beforeEach, expect, test } from "vitest"; +import { afterEach, beforeEach, expect, test, vi } from "vitest"; import { - PREPARED_WORKPIECE_AUTHORSHIP, - PREPARED_WORKPIECE_CLAIM_BOUNDARY, - PREPARED_WORKPIECE_SIGNAL_TAG, + preparedWorkpieceAuthorship, + preparedWorkpieceClaimBoundary, + preparedWorkpieceSignalTag, } from "@hashintel/brunch-agent/workpiece"; -import { CREW_RESERVATION_SETTLED_MANIFEST_STORAGE_KEY } from "./crew-reservation-settled-manifest"; +import { crewReservationSettledManifestStorageKey } from "./crew-reservation-settled-manifest"; import { - CREW_RESERVATION_FIXTURE_ID, - DISPATCH_CREW_PLACE_ID, + crewReservationFixtureId, + dispatchCrewPlaceId, preparedCrewReservationNet, preparedCrewReservationWorkpiece, - START_FINAL_INSPECTION_TRANSITION_ID, + startFinalInspectionTransitionId, } from "./prepared-crew-reservation-fixture"; -import { useCrewReservationSettledManifest } from "./use-crew-reservation-settled-manifest"; +import { + useCrewReservationSettlement, + useCrewReservationSettledManifestStorage, +} from "./use-crew-reservation-settled-manifest"; const preparedHistory = { conversationId: "canonical-conversation", @@ -31,11 +34,11 @@ const preparedHistory = { purpose: "dispatch", submissionId: "prepare-submission", signal: { - tagName: PREPARED_WORKPIECE_SIGNAL_TAG, + tagName: preparedWorkpieceSignalTag, attributes: { - fixtureId: CREW_RESERVATION_FIXTURE_ID, - authorship: PREPARED_WORKPIECE_AUTHORSHIP, - claimBoundary: PREPARED_WORKPIECE_CLAIM_BOUNDARY, + fixtureId: crewReservationFixtureId, + authorship: preparedWorkpieceAuthorship, + claimBoundary: preparedWorkpieceClaimBoundary, }, }, parts: [{ type: "text", text: preparedCrewReservationWorkpiece }], @@ -53,30 +56,43 @@ afterEach(() => { }); test("keeps the prior runtime bundle selected while a document write is partial", async () => { + const persistCoherentSnapshot = vi.fn(); const { result, rerender } = renderHook( - ({ definition }: { definition: typeof preparedCrewReservationNet }) => - useCrewReservationSettledManifest({ + ({ definition }: { definition: typeof preparedCrewReservationNet }) => { + const storage = useCrewReservationSettledManifestStorage(); + const status = useCrewReservationSettlement({ definition, enabled: true, history: preparedHistory, historyError: undefined, - }), + persistCoherentSnapshot, + preparationError: undefined, + setSettledManifest: storage.setSettledManifest, + settledManifest: storage.settledManifest, + snapshotMissing: false, + }); + return { ...storage, status }; + }, { initialProps: { definition: preparedCrewReservationNet } }, ); await waitFor(() => expect(result.current.status.state).toBe("settled")); const settledManifest = result.current.settledManifest; expect(settledManifest?.revision).toBe(0); + expect(persistCoherentSnapshot).toHaveBeenCalledWith( + settledManifest?.document.sha256, + preparedCrewReservationNet, + ); const partialDefinition = structuredClone(preparedCrewReservationNet); const startInspection = partialDefinition.transitions.find( - ({ id }) => id === START_FINAL_INSPECTION_TRANSITION_ID, + ({ id }) => id === startFinalInspectionTransitionId, ); if (startInspection === undefined) { throw new Error("Missing prepared start-inspection transition"); } startInspection.inputArcs.push({ - placeId: DISPATCH_CREW_PLACE_ID, + placeId: dispatchCrewPlaceId, type: "standard", weight: 1, }); @@ -86,22 +102,29 @@ test("keeps the prior runtime bundle selected while a document write is partial" expect(result.current.settledManifest).toEqual(settledManifest); expect( JSON.parse( - window.localStorage.getItem( - CREW_RESERVATION_SETTLED_MANIFEST_STORAGE_KEY, - ) ?? "null", + window.localStorage.getItem(crewReservationSettledManifestStorageKey) ?? + "null", ), ).toEqual(settledManifest); }); test("surfaces canonical history failure without publishing a bundle", async () => { - const { result } = renderHook(() => - useCrewReservationSettledManifest({ + const persistCoherentSnapshot = vi.fn(); + const { result } = renderHook(() => { + const storage = useCrewReservationSettledManifestStorage(); + const status = useCrewReservationSettlement({ definition: preparedCrewReservationNet, enabled: true, history: undefined, historyError: "History unavailable.", - }), - ); + persistCoherentSnapshot, + preparationError: undefined, + setSettledManifest: storage.setSettledManifest, + settledManifest: storage.settledManifest, + snapshotMissing: false, + }); + return { ...storage, status }; + }); await waitFor(() => expect(result.current.status.state).toBe("refused")); expect(result.current.status).toEqual({ @@ -111,3 +134,29 @@ test("surfaces canonical history failure without publishing a bundle", async () }); expect(result.current.settledManifest).toBeNull(); }); + +test("distinguishes preparation failure from unavailable history", async () => { + const persistCoherentSnapshot = vi.fn(); + const { result } = renderHook(() => { + const storage = useCrewReservationSettledManifestStorage(); + const status = useCrewReservationSettlement({ + definition: preparedCrewReservationNet, + enabled: true, + history: undefined, + historyError: undefined, + persistCoherentSnapshot, + preparationError: "Provider authentication failed.", + setSettledManifest: storage.setSettledManifest, + settledManifest: storage.settledManifest, + snapshotMissing: false, + }); + return { ...storage, status }; + }); + + expect(result.current.status).toEqual({ + state: "refused", + reason: "preparation-failed", + detail: "Provider authentication failed.", + }); + expect(result.current.settledManifest).toBeNull(); +}); diff --git a/apps/petrinaut-website/src/main/app/local-storage-demo/use-crew-reservation-settled-manifest.ts b/apps/petrinaut-website/src/main/app/local-storage-demo/use-crew-reservation-settled-manifest.ts index 94ffe2328e9..003cca50400 100644 --- a/apps/petrinaut-website/src/main/app/local-storage-demo/use-crew-reservation-settled-manifest.ts +++ b/apps/petrinaut-website/src/main/app/local-storage-demo/use-crew-reservation-settled-manifest.ts @@ -2,13 +2,13 @@ import { useLocalStorage } from "@mantine/hooks"; import { useEffect, useRef, useState } from "react"; import { - CREW_RESERVATION_SETTLED_MANIFEST_STORAGE_KEY, + crewReservationSettledManifestStorageKey, settleCrewReservationManifest, - type CrewReservationSettledHistory, type CrewReservationSettledManifest, type CrewReservationSettlementResult, } from "./crew-reservation-settled-manifest"; +import type { CrewReservationHistory } from "./crew-reservation-history"; import type { SDCPN } from "@hashintel/petrinaut-core"; export type CrewReservationSettlementStatus = @@ -21,23 +21,52 @@ export type CrewReservationSettlementStatus = CrewReservationSettlementResult, { status: "refused" } >["reason"] + | "bundle-snapshot-unavailable" | "history-unavailable" + | "preparation-failed" | "settlement-failed"; readonly state: "refused"; }; -export const useCrewReservationSettledManifest = (input: { - readonly definition: SDCPN | undefined; - readonly enabled: boolean; - readonly history: CrewReservationSettledHistory | undefined; - readonly historyError: string | undefined; -}) => { +export const useCrewReservationSettledManifestStorage = () => { const [settledManifest, setSettledManifest] = useLocalStorage({ - key: CREW_RESERVATION_SETTLED_MANIFEST_STORAGE_KEY, + key: crewReservationSettledManifestStorageKey, defaultValue: null, getInitialValueInEffect: false, }); + return { settledManifest, setSettledManifest }; +}; + +export const useCrewReservationSettlement = (input: { + readonly definition: SDCPN | undefined; + readonly enabled: boolean; + readonly history: CrewReservationHistory | undefined; + readonly historyError: string | undefined; + readonly persistCoherentSnapshot: (sha256: string, definition: SDCPN) => void; + readonly preparationError: string | undefined; + readonly setSettledManifest: ( + value: + | CrewReservationSettledManifest + | null + | (( + previous: CrewReservationSettledManifest | null, + ) => CrewReservationSettledManifest | null), + ) => void; + readonly settledManifest: CrewReservationSettledManifest | null; + readonly snapshotMissing: boolean; +}) => { + const { + definition, + enabled, + history, + historyError, + persistCoherentSnapshot, + preparationError, + setSettledManifest, + settledManifest, + snapshotMissing, + } = input; const [observedStatus, setObservedStatus] = useState({ state: "preparing" }); const manifestRef = useRef(settledManifest); @@ -52,23 +81,23 @@ export const useCrewReservationSettledManifest = (input: { const observationId = observationIdRef.current + 1; observationIdRef.current = observationId; if ( - !input.enabled || - input.historyError !== undefined || - input.definition === undefined || - input.history === undefined + !enabled || + historyError !== undefined || + definition === undefined || + history === undefined ) { return; } - const definition = structuredClone(input.definition); - const history = input.history; + const definitionSnapshot = structuredClone(definition); + const historySnapshot = history; queueRef.current = queueRef.current.then(async () => { if (observationId !== observationIdRef.current) return; let result: CrewReservationSettlementResult; try { result = await settleCrewReservationManifest({ - definition, - history, + definition: definitionSnapshot, + history: historySnapshot, ...(manifestRef.current === null ? {} : { previous: manifestRef.current }), @@ -95,6 +124,10 @@ export const useCrewReservationSettledManifest = (input: { }); return; } + persistCoherentSnapshot( + result.manifest.document.sha256, + definitionSnapshot, + ); if (result.manifest.manifestId !== manifestRef.current?.manifestId) { manifestRef.current = result.manifest; setSettledManifest(result.manifest); @@ -102,23 +135,36 @@ export const useCrewReservationSettledManifest = (input: { setObservedStatus({ state: "settled" }); }); }, [ - input.definition, - input.enabled, - input.history, - input.historyError, + definition, + enabled, + history, + historyError, + persistCoherentSnapshot, setSettledManifest, ]); - const status: CrewReservationSettlementStatus = !input.enabled + const status: CrewReservationSettlementStatus = !enabled ? { state: "idle" } - : input.historyError !== undefined + : historyError !== undefined ? { state: "refused", reason: "history-unavailable", - detail: input.historyError, + detail: historyError, } - : input.definition === undefined || input.history === undefined - ? { state: "preparing" } - : observedStatus; - return { settledManifest, status }; + : snapshotMissing + ? { + state: "refused", + reason: "bundle-snapshot-unavailable", + } + : preparationError !== undefined && + (definition === undefined || history === undefined) + ? { + state: "refused", + reason: "preparation-failed", + detail: preparationError, + } + : definition === undefined || history === undefined + ? { state: "preparing" } + : observedStatus; + return status; }; diff --git a/apps/petrinaut-website/src/main/app/local-storage-demo/use-local-storage-sdcpns.ts b/apps/petrinaut-website/src/main/app/local-storage-demo/use-local-storage-sdcpns.ts index 796a72af1d6..dad4583d4c5 100644 --- a/apps/petrinaut-website/src/main/app/local-storage-demo/use-local-storage-sdcpns.ts +++ b/apps/petrinaut-website/src/main/app/local-storage-demo/use-local-storage-sdcpns.ts @@ -5,6 +5,12 @@ import type { SDCPN } from "@hashintel/petrinaut-core"; const rootLocalStorageKey = "petrinaut-sdcpn"; export type SDCPNInLocalStorage = { + /** + * Content-addressed coherent revisions retained by prepared fixtures. The + * live `sdcpn` remains the automatic mirror; these snapshots give a settled + * manifest a concrete document revision to select after a partial write. + */ + coherentSnapshots?: Record; id: string; lastUpdated: string; // ISO timestamp sdcpn: SDCPN; diff --git a/apps/petrinaut-website/src/main/app/local-storage-demo/use-prepare-crew-reservation-conversation.test.ts b/apps/petrinaut-website/src/main/app/local-storage-demo/use-prepare-crew-reservation-conversation.test.ts new file mode 100644 index 00000000000..d0d2bdc91c6 --- /dev/null +++ b/apps/petrinaut-website/src/main/app/local-storage-demo/use-prepare-crew-reservation-conversation.test.ts @@ -0,0 +1,31 @@ +/** + * @vitest-environment jsdom + */ +import { renderHook, waitFor } from "@testing-library/react"; +import { expect, test, vi } from "vitest"; + +import { usePrepareCrewReservationConversation } from "./use-prepare-crew-reservation-conversation"; + +import type { FlueClient } from "@flue/sdk"; + +test("reports preparation failure without rejecting the shared client", async () => { + const client = { + history: vi.fn().mockRejectedValue({ status: 404 }), + send: vi.fn().mockResolvedValue({ submissionId: "preparation" }), + wait: vi + .fn() + .mockRejectedValue(new Error("Provider authentication failed")), + } as unknown as FlueClient; + const clientPromise = Promise.resolve(client); + + const { result } = renderHook(() => + usePrepareCrewReservationConversation(clientPromise, true), + ); + + await waitFor(() => expect(result.current.state).toBe("failed")); + expect(result.current).toEqual({ + state: "failed", + error: "Provider authentication failed", + }); + await expect(clientPromise).resolves.toBe(client); +}); diff --git a/apps/petrinaut-website/src/main/app/local-storage-demo/use-prepare-crew-reservation-conversation.ts b/apps/petrinaut-website/src/main/app/local-storage-demo/use-prepare-crew-reservation-conversation.ts new file mode 100644 index 00000000000..cba89b08b3c --- /dev/null +++ b/apps/petrinaut-website/src/main/app/local-storage-demo/use-prepare-crew-reservation-conversation.ts @@ -0,0 +1,55 @@ +import { useEffect, useState } from "react"; + +import { prepareCrewReservationConversation } from "./prepare-crew-reservation-conversation"; + +import type { FlueClient } from "@flue/sdk"; + +export type CrewReservationPreparationStatus = + | { readonly state: "idle" | "preparing" | "ready" } + | { readonly error: string; readonly state: "failed" }; + +export const usePrepareCrewReservationConversation = ( + clientPromise: Promise | null, + enabled: boolean, +): CrewReservationPreparationStatus => { + const [observed, setObserved] = useState<{ + readonly clientPromise: Promise; + readonly status: CrewReservationPreparationStatus; + }>(); + + useEffect(() => { + if (!enabled || clientPromise === null) return; + + let cancelled = false; + const prepare = async (): Promise => { + try { + const client = await clientPromise; + await prepareCrewReservationConversation(client); + if (!cancelled) { + setObserved({ clientPromise, status: { state: "ready" } }); + } + } catch (error) { + if (cancelled) return; + setObserved({ + clientPromise, + status: { + state: "failed", + error: + error instanceof Error + ? error.message + : "The prepared conversation could not be initialized.", + }, + }); + } + }; + void prepare(); + return () => { + cancelled = true; + }; + }, [clientPromise, enabled]); + + if (!enabled) return { state: "idle" }; + return observed?.clientPromise === clientPromise + ? observed.status + : { state: "preparing" }; +}; diff --git a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-resumable-workpiece-petrinaut.md b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-resumable-workpiece-petrinaut.md index 9b6f4d47dad..145b4bc08cf 100644 --- a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-resumable-workpiece-petrinaut.md +++ b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-resumable-workpiece-petrinaut.md @@ -50,8 +50,10 @@ Consequently: - the visible fixture status refused settlement as `history-unavailable` instead of blessing the prepared document alone. -This is the Mission 6 carrier blocker required by the stop rule, not a passing -two-tab witness. No success screenshot was retained. +This is an authentication/environment blocker on the outer witness, not +evidence that the selected provider-visible schema or Flue carrier cannot +faithfully carry the mutation. It is not a passing two-tab witness. No success +screenshot was retained. ## Remaining external checks diff --git a/libs/@hashintel/brunch-agent/packages/core/src/workpiece.ts b/libs/@hashintel/brunch-agent/packages/core/src/workpiece.ts index bd61a63c068..ab1430aa1dc 100644 --- a/libs/@hashintel/brunch-agent/packages/core/src/workpiece.ts +++ b/libs/@hashintel/brunch-agent/packages/core/src/workpiece.ts @@ -3,13 +3,12 @@ * append-only conversation projection. */ -export const PREPARED_WORKPIECE_SIGNAL_TYPE = "brunch.fixture.prepared"; -export const PREPARED_WORKPIECE_SIGNAL_TAG = "prepared-fixture"; -export const PREPARED_WORKPIECE_AUTHORSHIP = "test-authored"; -export const PREPARED_WORKPIECE_CLAIM_BOUNDARY = "prepared-not-model-produced"; -export const PREPARED_WORKPIECE_INITIAL_DATA_MODE = - "validated-fixture-mutation"; -export const RUNBOOK_IR_FENCE = "runbook-ir"; +export const preparedWorkpieceSignalType = "brunch.fixture.prepared"; +export const preparedWorkpieceSignalTag = "prepared-fixture"; +export const preparedWorkpieceAuthorship = "test-authored"; +export const preparedWorkpieceClaimBoundary = "prepared-not-model-produced"; +export const preparedWorkpieceInitialDataMode = "validated-fixture-mutation"; +export const runbookIrFence = "runbook-ir"; type WorkpieceTextPart = { readonly text: string; @@ -42,14 +41,14 @@ export interface PreparedWorkpieceDelivery { readonly idempotencyKey: string; readonly message: { readonly attributes: { - readonly authorship: typeof PREPARED_WORKPIECE_AUTHORSHIP; - readonly claimBoundary: typeof PREPARED_WORKPIECE_CLAIM_BOUNDARY; + readonly authorship: typeof preparedWorkpieceAuthorship; + readonly claimBoundary: typeof preparedWorkpieceClaimBoundary; readonly fixtureId: string; }; readonly body: string; readonly kind: "signal"; - readonly tagName: typeof PREPARED_WORKPIECE_SIGNAL_TAG; - readonly type: typeof PREPARED_WORKPIECE_SIGNAL_TYPE; + readonly tagName: typeof preparedWorkpieceSignalTag; + readonly type: typeof preparedWorkpieceSignalType; }; } @@ -91,10 +90,9 @@ const isPreparedWorkpieceMessage = ( ): boolean => message.role === "system" && message.purpose === "dispatch" && - message.signal?.tagName === PREPARED_WORKPIECE_SIGNAL_TAG && - message.signal.attributes?.authorship === PREPARED_WORKPIECE_AUTHORSHIP && - message.signal.attributes.claimBoundary === - PREPARED_WORKPIECE_CLAIM_BOUNDARY && + message.signal?.tagName === preparedWorkpieceSignalTag && + message.signal.attributes?.authorship === preparedWorkpieceAuthorship && + message.signal.attributes.claimBoundary === preparedWorkpieceClaimBoundary && preparedFixtureIdFrom(message) !== undefined; const selectedFrom = ( @@ -130,16 +128,16 @@ export const createPreparedWorkpieceDelivery = (input: { } return { - idempotencyKey: `${PREPARED_WORKPIECE_SIGNAL_TAG}:${input.fixtureId}:revision-${input.revision}`, + idempotencyKey: `${preparedWorkpieceSignalTag}:${input.fixtureId}:revision-${input.revision}`, message: { kind: "signal", - type: PREPARED_WORKPIECE_SIGNAL_TYPE, - tagName: PREPARED_WORKPIECE_SIGNAL_TAG, + type: preparedWorkpieceSignalType, + tagName: preparedWorkpieceSignalTag, body: input.body, attributes: { fixtureId: input.fixtureId, - authorship: PREPARED_WORKPIECE_AUTHORSHIP, - claimBoundary: PREPARED_WORKPIECE_CLAIM_BOUNDARY, + authorship: preparedWorkpieceAuthorship, + claimBoundary: preparedWorkpieceClaimBoundary, }, }, }; @@ -154,7 +152,7 @@ export const selectRunbookWorkpiece = ( history: WorkpieceHistory, ): SelectedRunbookWorkpiece | undefined => { const preparedCandidates = history.messages.filter( - (message) => message.signal?.tagName === PREPARED_WORKPIECE_SIGNAL_TAG, + (message) => message.signal?.tagName === preparedWorkpieceSignalTag, ); if (preparedCandidates.length > 1) { throw new Error( @@ -178,7 +176,7 @@ export const selectRunbookWorkpiece = ( for (const message of history.messages) { if (message === preparedMessage) { const preparedWorkpiece = selectedFrom(message, { - authorship: PREPARED_WORKPIECE_AUTHORSHIP, + authorship: preparedWorkpieceAuthorship, sourceKind: "prepared-signal", }); if (preparedWorkpiece === undefined) { diff --git a/libs/@hashintel/brunch-agent/packages/core/test/workpiece.test.ts b/libs/@hashintel/brunch-agent/packages/core/test/workpiece.test.ts index 7b3c6f452d8..bb4ff0ffea0 100644 --- a/libs/@hashintel/brunch-agent/packages/core/test/workpiece.test.ts +++ b/libs/@hashintel/brunch-agent/packages/core/test/workpiece.test.ts @@ -2,9 +2,9 @@ import { describe, expect, test } from "vitest"; import { createPreparedWorkpieceDelivery, - PREPARED_WORKPIECE_AUTHORSHIP, - PREPARED_WORKPIECE_CLAIM_BOUNDARY, - PREPARED_WORKPIECE_SIGNAL_TAG, + preparedWorkpieceAuthorship, + preparedWorkpieceClaimBoundary, + preparedWorkpieceSignalTag, selectRunbookWorkpiece, type WorkpieceHistory, type WorkpieceHistoryMessage, @@ -22,10 +22,10 @@ const preparedMessage = ( purpose: "dispatch", submissionId, signal: { - tagName: PREPARED_WORKPIECE_SIGNAL_TAG, + tagName: preparedWorkpieceSignalTag, attributes: { - authorship: PREPARED_WORKPIECE_AUTHORSHIP, - claimBoundary: PREPARED_WORKPIECE_CLAIM_BOUNDARY, + authorship: preparedWorkpieceAuthorship, + claimBoundary: preparedWorkpieceClaimBoundary, fixtureId: "crew-reservation-v1", }, }, @@ -154,7 +154,7 @@ describe("selectRunbookWorkpiece", () => { { ...preparedMessage(), signal: { - tagName: PREPARED_WORKPIECE_SIGNAL_TAG, + tagName: preparedWorkpieceSignalTag, attributes: { authorship: "model-produced" }, }, }, diff --git a/libs/@hashintel/brunch-agent/packages/plugin-sdcpn/src/flue.ts b/libs/@hashintel/brunch-agent/packages/plugin-sdcpn/src/flue.ts index 5e106589f7f..6afa49c5ef0 100644 --- a/libs/@hashintel/brunch-agent/packages/plugin-sdcpn/src/flue.ts +++ b/libs/@hashintel/brunch-agent/packages/plugin-sdcpn/src/flue.ts @@ -6,7 +6,7 @@ import { } from "@flue/runtime"; import * as v from "valibot"; -import { PREPARED_WORKPIECE_INITIAL_DATA_MODE } from "@hashintel/brunch-agent/workpiece"; +import { preparedWorkpieceInitialDataMode } from "@hashintel/brunch-agent/workpiece"; import sdcpnAppend from "./prompts/APPEND_SYSTEM.md?raw"; import { @@ -23,14 +23,13 @@ import { } from "./tools/read-petrinaut-doc"; export const VALIDATED_CONSTRUCTION_MODE = "validated-construction"; -export const VALIDATED_FIXTURE_MUTATION_MODE = - PREPARED_WORKPIECE_INITIAL_DATA_MODE; +export const validatedFixtureMutationMode = preparedWorkpieceInitialDataMode; export const sdcpnInitialDataSchema = v.optional( v.object({ mode: v.picklist([ VALIDATED_CONSTRUCTION_MODE, - VALIDATED_FIXTURE_MUTATION_MODE, + validatedFixtureMutationMode, ]), }), ); @@ -54,7 +53,7 @@ This is a construct-only headless conversation. Use only the supplied runbook IR for (const constructionTool of petrinautConstructionTools) { useTool(constructionTool); } - } else if (initialData?.mode === VALIDATED_FIXTURE_MUTATION_MODE) { + } else if (initialData?.mode === validatedFixtureMutationMode) { useInstruction( ` This is a visibly labelled prepared-fixture conversation. Treat its tagged prepared runbook-ir dispatch as test-authored revision zero, maintain the full Markdown workpiece in later responses, preserve explicit unknowns, and do not relabel prepared material as model-produced. Use only the mounted canonical Petrinaut read and least arc mutation when confirmed evidence calls for that change. Read the live document before mutating it, report rejected or no-op outcomes honestly, and do not construct unrelated net content. @@ -70,7 +69,7 @@ export { READ_PETRINAUT_DOC_TOOL_NAME, readPetrinautDoc }; export { SDCPN_MODELLING_SKILL_NAME }; export { PETRINAUT_CONSTRUCTION_TOOL_NAMES, - PETRINAUT_FIXTURE_TOOL_NAMES, + petrinautFixtureToolNames, petrinautConstructionTools, petrinautFixtureTools, type PetrinautConstructionToolName, diff --git a/libs/@hashintel/brunch-agent/packages/plugin-sdcpn/src/tools/petrinaut-construction.ts b/libs/@hashintel/brunch-agent/packages/plugin-sdcpn/src/tools/petrinaut-construction.ts index 41167c67c23..42e5f49f57c 100644 --- a/libs/@hashintel/brunch-agent/packages/plugin-sdcpn/src/tools/petrinaut-construction.ts +++ b/libs/@hashintel/brunch-agent/packages/plugin-sdcpn/src/tools/petrinaut-construction.ts @@ -13,13 +13,14 @@ export const PETRINAUT_CONSTRUCTION_TOOL_NAMES = [ "addArc", ] as const satisfies readonly (keyof typeof petrinautAiTools)[]; -export const PETRINAUT_FIXTURE_TOOL_NAMES = [ +export const petrinautFixtureToolNames = [ "getLatestNetDefinition", "addArc", ] as const satisfies readonly (keyof typeof petrinautAiTools)[]; export type PetrinautConstructionToolName = (typeof PETRINAUT_CONSTRUCTION_TOOL_NAMES)[number]; +type PetrinautFixtureToolName = (typeof petrinautFixtureToolNames)[number]; const issuePathFrom = ( input: Record, @@ -97,6 +98,15 @@ export const petrinautConstructionTools = PETRINAUT_CONSTRUCTION_TOOL_NAMES.map( definePetrinautConstructionTool, ); -export const petrinautFixtureTools = PETRINAUT_FIXTURE_TOOL_NAMES.map( - definePetrinautConstructionTool, +const isPetrinautFixtureTool = ( + tool: (typeof petrinautConstructionTools)[number], +): tool is (typeof petrinautConstructionTools)[number] & { + readonly name: PetrinautFixtureToolName; +} => + petrinautFixtureToolNames.some((fixtureToolName) => { + return fixtureToolName === tool.name; + }); + +export const petrinautFixtureTools = petrinautConstructionTools.filter( + isPetrinautFixtureTool, ); diff --git a/libs/@hashintel/brunch-agent/packages/plugin-sdcpn/test/construction-tools.test.ts b/libs/@hashintel/brunch-agent/packages/plugin-sdcpn/test/construction-tools.test.ts index e259a3fa77b..95bd7df500d 100644 --- a/libs/@hashintel/brunch-agent/packages/plugin-sdcpn/test/construction-tools.test.ts +++ b/libs/@hashintel/brunch-agent/packages/plugin-sdcpn/test/construction-tools.test.ts @@ -6,11 +6,11 @@ import { petrinautAiTools } from "@hashintel/petrinaut-core/ai"; import { sdcpnInitialDataSchema, VALIDATED_CONSTRUCTION_MODE, - VALIDATED_FIXTURE_MUTATION_MODE, + validatedFixtureMutationMode, } from "../src/flue"; import { PETRINAUT_CONSTRUCTION_TOOL_NAMES, - PETRINAUT_FIXTURE_TOOL_NAMES, + petrinautFixtureToolNames, petrinautConstructionTools, petrinautFixtureTools, } from "../src/tools/petrinaut-construction"; @@ -34,9 +34,9 @@ describe("Petrinaut construction tools", () => { ).toEqual({ mode: VALIDATED_CONSTRUCTION_MODE }); expect( v.parse(sdcpnInitialDataSchema, { - mode: VALIDATED_FIXTURE_MUTATION_MODE, + mode: validatedFixtureMutationMode, }), - ).toEqual({ mode: VALIDATED_FIXTURE_MUTATION_MODE }); + ).toEqual({ mode: validatedFixtureMutationMode }); expect(() => v.parse(sdcpnInitialDataSchema, { mode: "unrestricted-construction", @@ -52,7 +52,7 @@ describe("Petrinaut construction tools", () => { test("limits prepared fixtures to one canonical read and arc mutation", () => { expect(petrinautFixtureTools.map((tool) => tool.name)).toEqual([ - ...PETRINAUT_FIXTURE_TOOL_NAMES, + ...petrinautFixtureToolNames, ]); }); diff --git a/libs/@hashintel/brunch-agent/packages/transport-aisdk/src/client-tool-history.ts b/libs/@hashintel/brunch-agent/packages/transport-aisdk/src/client-tool-history.ts new file mode 100644 index 00000000000..114150c2f83 --- /dev/null +++ b/libs/@hashintel/brunch-agent/packages/transport-aisdk/src/client-tool-history.ts @@ -0,0 +1,104 @@ +import { CLIENT_TOOL_RESULT_SIGNAL } from "./client-tool-result"; + +export interface ClientToolHistoryCall { + readonly input: Readonly>; + readonly toolCallId: string; + readonly toolName: string; +} + +export interface ClientToolHistoryResult { + readonly output: unknown; + readonly toolCallId: string; + readonly toolName: string; +} + +export interface ClientToolHistory { + readonly calls: readonly ClientToolHistoryCall[]; + readonly results: readonly ClientToolHistoryResult[]; +} + +export interface ClientToolHistoryMessage { + readonly parts: readonly unknown[]; + readonly signal?: { + readonly tagName?: string; + readonly type?: string; + }; +} + +const isRecord = (value: unknown): value is Record => + typeof value === "object" && value !== null; + +const callsFrom = ( + messages: readonly ClientToolHistoryMessage[], +): readonly ClientToolHistoryCall[] => + messages.flatMap((message) => + message.parts.flatMap((part) => { + if ( + !isRecord(part) || + part.type !== "dynamic-tool" || + typeof part.toolName !== "string" || + typeof part.toolCallId !== "string" || + !isRecord(part.input) + ) { + return []; + } + return [ + { + input: part.input, + toolCallId: part.toolCallId, + toolName: part.toolName, + }, + ]; + }), + ); + +const resultsFrom = ( + messages: readonly ClientToolHistoryMessage[], +): readonly ClientToolHistoryResult[] => + messages.flatMap((message) => { + if ( + message.signal?.tagName !== CLIENT_TOOL_RESULT_SIGNAL && + message.signal?.type !== CLIENT_TOOL_RESULT_SIGNAL + ) { + return []; + } + + const body = message.parts + .flatMap((part) => + isRecord(part) && part.type === "text" && typeof part.text === "string" + ? [part.text] + : [], + ) + .join(""); + + try { + const parsed: unknown = JSON.parse(body); + if (!Array.isArray(parsed)) return []; + return parsed.flatMap((result) => { + if ( + !isRecord(result) || + typeof result.toolName !== "string" || + typeof result.toolCallId !== "string" || + !("output" in result) + ) { + return []; + } + return [ + { + output: result.output, + toolCallId: result.toolCallId, + toolName: result.toolName, + }, + ]; + }); + } catch { + return []; + } + }); + +export const clientToolHistoryFrom = ( + messages: readonly ClientToolHistoryMessage[], +): ClientToolHistory => ({ + calls: callsFrom(messages), + results: resultsFrom(messages), +}); diff --git a/libs/@hashintel/brunch-agent/packages/transport-aisdk/src/index.ts b/libs/@hashintel/brunch-agent/packages/transport-aisdk/src/index.ts index 772f309e053..2d6a603d2cc 100644 --- a/libs/@hashintel/brunch-agent/packages/transport-aisdk/src/index.ts +++ b/libs/@hashintel/brunch-agent/packages/transport-aisdk/src/index.ts @@ -7,6 +7,13 @@ import { createFlueUiStream } from "./ui-stream"; import type { AgentSendResult, DeliveredMessage, FlueClient } from "@flue/sdk"; import type { ChatTransport, UIMessage, UIMessageChunk } from "ai"; +export { + clientToolHistoryFrom, + type ClientToolHistory, + type ClientToolHistoryCall, + type ClientToolHistoryMessage, + type ClientToolHistoryResult, +} from "./client-tool-history"; export { BRUNCH_CONVERSATION_HEADER, BRUNCH_PRINCIPAL_HEADER } from "./headers"; export { CLIENT_TOOL_RESULT_SIGNAL } from "./client-tool-result"; export { diff --git a/libs/@hashintel/brunch-agent/packages/transport-aisdk/test/client-tool-history.test.ts b/libs/@hashintel/brunch-agent/packages/transport-aisdk/test/client-tool-history.test.ts new file mode 100644 index 00000000000..bfc3abd64c8 --- /dev/null +++ b/libs/@hashintel/brunch-agent/packages/transport-aisdk/test/client-tool-history.test.ts @@ -0,0 +1,64 @@ +import { describe, expect, test } from "vitest"; + +import { CLIENT_TOOL_RESULT_SIGNAL, clientToolHistoryFrom } from "../src/index"; + +describe("clientToolHistoryFrom", () => { + test("projects generic calls and correlated client result envelopes", () => { + expect( + clientToolHistoryFrom([ + { + parts: [ + { + type: "dynamic-tool", + toolName: "addArc", + toolCallId: "call-1", + input: { placeId: "place-1" }, + }, + ], + }, + { + signal: { tagName: CLIENT_TOOL_RESULT_SIGNAL }, + parts: [ + { + type: "text", + text: JSON.stringify([ + { + toolName: "addArc", + toolCallId: "call-1", + output: { applied: true }, + }, + ]), + }, + ], + }, + ]), + ).toEqual({ + calls: [ + { + input: { placeId: "place-1" }, + toolCallId: "call-1", + toolName: "addArc", + }, + ], + results: [ + { + output: { applied: true }, + toolCallId: "call-1", + toolName: "addArc", + }, + ], + }); + }); + + test("ignores malformed calls and result bodies", () => { + expect( + clientToolHistoryFrom([ + { parts: [{ type: "dynamic-tool", toolName: "addArc" }] }, + { + signal: { type: CLIENT_TOOL_RESULT_SIGNAL }, + parts: [{ type: "text", text: "not-json" }], + }, + ]), + ).toEqual({ calls: [], results: [] }); + }); +}); From 8f881d1d29f7b6d06b580e9d1f31f6179e6047fe Mon Sep 17 00:00:00 2001 From: Lu Nelson Date: Fri, 4 Sep 2026 10:13:35 +0200 Subject: [PATCH 07/13] Normalize provider inputs for Petrinaut client tools Co-authored-by: Cursor --- .../brunch-panel-transport.ts | 7 ++++ .../crew-reservation-settled-manifest.test.ts | 27 ++++++++++--- .../crew-reservation-settled-manifest.ts | 34 ++++++++++------- .../local-storage-demo-app.tsx | 17 ++++++--- .../use-crew-reservation-fixture-session.ts | 20 +++++++++- .../use-flue-chat-history.ts | 17 ++++++++- ...pare-crew-reservation-conversation.test.ts | 7 +++- ...e-prepare-crew-reservation-conversation.ts | 38 +++++++++++++------ .../src/tools/petrinaut-construction.ts | 14 ++++++- .../test/construction-tools.test.ts | 13 +++++++ .../packages/transport-aisdk/src/index.ts | 5 +++ .../transport-aisdk/src/transcript.ts | 25 ++++++++---- .../packages/transport-aisdk/src/ui-stream.ts | 12 +++++- .../transport-aisdk/test/ui-stream.test.ts | 34 +++++++++++++++++ libs/@hashintel/petrinaut-core/src/ai.test.ts | 16 ++++++++ libs/@hashintel/petrinaut-core/src/ai.ts | 29 ++++++++++++++ 16 files changed, 263 insertions(+), 52 deletions(-) diff --git a/apps/petrinaut-website/src/main/app/local-storage-demo/brunch-panel-transport.ts b/apps/petrinaut-website/src/main/app/local-storage-demo/brunch-panel-transport.ts index 8e28759287d..3e289ff7bcb 100644 --- a/apps/petrinaut-website/src/main/app/local-storage-demo/brunch-panel-transport.ts +++ b/apps/petrinaut-website/src/main/app/local-storage-demo/brunch-panel-transport.ts @@ -236,6 +236,10 @@ export const createBrunchPanelTransport = ( options?: { /** Fixture-scoped client tools; defaults to the Petrinaut docs reader alone. */ readonly clientToolNames?: ReadonlySet; + readonly mapClientToolInput?: (input: { + readonly input: unknown; + readonly toolName: string; + }) => unknown; readonly onAdmission?: (admission: AgentSendResult) => void; }, ): PetrinautAiChatTransport => ({ @@ -247,6 +251,9 @@ export const createBrunchPanelTransport = ( const transport = createFlueChatTransport({ client, clientToolNames: options?.clientToolNames ?? brunchClientToolNames, + ...(options?.mapClientToolInput === undefined + ? {} + : { mapClientToolInput: options.mapClientToolInput }), onAdmission: (event) => { tracker.recordAdmission(event); options?.onAdmission?.(event.admission); diff --git a/apps/petrinaut-website/src/main/app/local-storage-demo/crew-reservation-settled-manifest.test.ts b/apps/petrinaut-website/src/main/app/local-storage-demo/crew-reservation-settled-manifest.test.ts index ab6d5a6a626..ddb0f5396c9 100644 --- a/apps/petrinaut-website/src/main/app/local-storage-demo/crew-reservation-settled-manifest.test.ts +++ b/apps/petrinaut-website/src/main/app/local-storage-demo/crew-reservation-settled-manifest.test.ts @@ -49,10 +49,9 @@ const settledHistory = ( settlements: [{ submissionId: "prepare-submission", outcome: "completed" }], }); -const targetMutationMessages = (): readonly [ - WorkpieceHistoryMessage, - WorkpieceHistoryMessage, -] => [ +const targetMutationMessages = ( + toolCallId = "target-arc-call", +): readonly [WorkpieceHistoryMessage, WorkpieceHistoryMessage] => [ { id: "target-mutation-request", role: "assistant", @@ -61,7 +60,7 @@ const targetMutationMessages = (): readonly [ parts: [ { type: "dynamic-tool", - toolCallId: "target-arc-call", + toolCallId, toolName: "addArc", input: { transitionId: startFinalInspectionTransitionId, @@ -85,7 +84,7 @@ const targetMutationMessages = (): readonly [ type: "text", text: JSON.stringify([ { - toolCallId: "target-arc-call", + toolCallId, toolName: "addArc", output: { applied: true }, }, @@ -276,6 +275,22 @@ describe("crew-reservation settled manifest", () => { }, settledAt: "2026-09-03T12:05:00.000Z", }), + ).resolves.toMatchObject({ status: "settled" }); + + await expect( + settleCrewReservationManifest({ + definition: revisedDefinition, + history: { + ...history, + messages: [ + preparedMessage, + ...targetMutationMessages(), + ...targetMutationMessages("second-target-arc-call"), + revisedMessage, + ], + }, + settledAt: "2026-09-03T12:05:00.000Z", + }), ).resolves.toEqual({ status: "refused", reason: "missing-correlated-mutation", diff --git a/apps/petrinaut-website/src/main/app/local-storage-demo/crew-reservation-settled-manifest.ts b/apps/petrinaut-website/src/main/app/local-storage-demo/crew-reservation-settled-manifest.ts index 01767ed99a4..d94d5111314 100644 --- a/apps/petrinaut-website/src/main/app/local-storage-demo/crew-reservation-settled-manifest.ts +++ b/apps/petrinaut-website/src/main/app/local-storage-demo/crew-reservation-settled-manifest.ts @@ -1,6 +1,7 @@ import { clientToolHistoryFrom } from "@hashintel/brunch-agent-transport-aisdk"; import { selectRunbookWorkpiece } from "@hashintel/brunch-agent/workpiece"; import { isSDCPNEqual, type SDCPN } from "@hashintel/petrinaut-core"; +import { normalizePetrinautAiToolInput } from "@hashintel/petrinaut-core/ai"; import { crewReservationConversationId, @@ -41,6 +42,9 @@ export const asManifestId = (value: string): ManifestId => value as ManifestId; export const asSha256Digest = (value: string): Sha256Digest => value as Sha256Digest; +const isRecord = (value: unknown): value is Record => + typeof value === "object" && value !== null; + export interface CrewReservationSettledManifest { readonly conversation: { readonly canonicalId: CanonicalConversationId; @@ -86,15 +90,17 @@ const targetMutationCallIds = ( history: CrewReservationHistory, ): readonly string[] => { const { calls } = clientToolHistoryFrom(history.messages); - return calls.flatMap(({ input, toolCallId, toolName }) => - toolName === "addArc" && - input.transitionId === startFinalInspectionTransitionId && - input.arcDirection === "input" && - input.placeId === dispatchCrewPlaceId && - input.weight === 1 + return calls.flatMap(({ input, toolCallId, toolName }) => { + if (toolName !== "addArc") return []; + const normalizedInput = normalizePetrinautAiToolInput("addArc", input); + return isRecord(normalizedInput) && + normalizedInput.transitionId === startFinalInspectionTransitionId && + normalizedInput.arcDirection === "input" && + normalizedInput.placeId === dispatchCrewPlaceId && + normalizedInput.weight === 1 ? [toolCallId] - : [], - ); + : []; + }); }; const successfulMutationResultIds = ( @@ -115,13 +121,13 @@ const successfulMutationResultIds = ( const hasOneCorrelatedTargetMutation = ( history: CrewReservationHistory, ): boolean => { - const targetCallIds = targetMutationCallIds(history); - const successfulResultIds = successfulMutationResultIds(history); - return ( - targetCallIds.length === 1 && - successfulResultIds.length === 1 && - targetCallIds[0] === successfulResultIds[0] + const successfulResultIds = new Set(successfulMutationResultIds(history)); + const correlatedTargetCallIds = new Set( + targetMutationCallIds(history).filter((toolCallId) => + successfulResultIds.has(toolCallId), + ), ); + return correlatedTargetCallIds.size === 1; }; const sha256 = async (value: string): Promise => { diff --git a/apps/petrinaut-website/src/main/app/local-storage-demo/local-storage-demo-app.tsx b/apps/petrinaut-website/src/main/app/local-storage-demo/local-storage-demo-app.tsx index cc76b8edc74..bac3cd5a72c 100644 --- a/apps/petrinaut-website/src/main/app/local-storage-demo/local-storage-demo-app.tsx +++ b/apps/petrinaut-website/src/main/app/local-storage-demo/local-storage-demo-app.tsx @@ -615,6 +615,7 @@ export const LocalStorageDemoApp = ({ flueClientPromise, conversationId ?? "", fixtureConfiguration?.clientToolNames, + fixtureConfiguration?.mapClientToolInput, ); const brunchVoiceMode = useMemo( () => @@ -637,15 +638,22 @@ export const LocalStorageDemoApp = ({ settledManifest, snapshotMissing: crewReservationBundle?.snapshotMissing ?? false, }); + const transportClientPromise = + fixtureConfiguration === undefined + ? flueClientPromise + : crewReservationSession.transportClientPromise; const petrinautAiChatTransport = useMemo(() => { - if (flueClientPromise !== null && crewReservationSession.transportReady) { + if (transportClientPromise !== null) { return createBrunchPanelTransport( - flueClientPromise, + transportClientPromise, conversationTracker, { ...(fixtureConfiguration === undefined ? {} - : { clientToolNames: fixtureConfiguration.clientToolNames }), + : { + clientToolNames: fixtureConfiguration.clientToolNames, + mapClientToolInput: fixtureConfiguration.mapClientToolInput, + }), onAdmission: flueHistory.refresh, }, ); @@ -657,11 +665,10 @@ export const LocalStorageDemoApp = ({ : stockChatTransport; }, [ conversationTracker, - crewReservationSession.transportReady, crewReservationSession.transportUnavailableReason, fixtureConfiguration, - flueClientPromise, flueHistory.refresh, + transportClientPromise, ]); const aiAssistant = useMemo( diff --git a/apps/petrinaut-website/src/main/app/local-storage-demo/use-crew-reservation-fixture-session.ts b/apps/petrinaut-website/src/main/app/local-storage-demo/use-crew-reservation-fixture-session.ts index fa48ec861ed..415c58f9e5a 100644 --- a/apps/petrinaut-website/src/main/app/local-storage-demo/use-crew-reservation-fixture-session.ts +++ b/apps/petrinaut-website/src/main/app/local-storage-demo/use-crew-reservation-fixture-session.ts @@ -1,5 +1,10 @@ import { useEffect, useMemo } from "react"; +import { + getLatestNetDefinitionToolName, + normalizePetrinautAiToolInput, +} from "@hashintel/petrinaut-core/ai"; + import { crewReservationConversationId, crewReservationFixtureClientToolNames, @@ -20,6 +25,16 @@ const clientToolNames: ReadonlySet = new Set( export const crewReservationFixtureConfiguration = { clientToolNames, conversationId: crewReservationConversationId, + mapClientToolInput: ({ + input, + toolName, + }: { + readonly input: unknown; + readonly toolName: string; + }) => + toolName === "addArc" || toolName === getLatestNetDefinitionToolName + ? normalizePetrinautAiToolInput(toolName, input) + : input, } as const; export const useCrewReservationFixtureSession = (input: { @@ -53,10 +68,11 @@ export const useCrewReservationFixtureSession = (input: { settledManifest, snapshotMissing, } = input; - const preparationStatus = usePrepareCrewReservationConversation( + const preparation = usePrepareCrewReservationConversation( clientPromise, enabled, ); + const preparationStatus = preparation.status; useEffect(() => { if ( @@ -94,7 +110,7 @@ export const useCrewReservationFixtureSession = (input: { currentWorkpiece, preparationStatus, settlementStatus, - transportReady: !enabled || preparationStatus.state === "ready", + transportClientPromise: preparation.clientPromise, transportUnavailableReason: preparationStatus.state === "failed" ? preparationStatus.error diff --git a/apps/petrinaut-website/src/main/app/local-storage-demo/use-flue-chat-history.ts b/apps/petrinaut-website/src/main/app/local-storage-demo/use-flue-chat-history.ts index a8348381255..075545ea8e6 100644 --- a/apps/petrinaut-website/src/main/app/local-storage-demo/use-flue-chat-history.ts +++ b/apps/petrinaut-website/src/main/app/local-storage-demo/use-flue-chat-history.ts @@ -28,17 +28,28 @@ export type FlueHistorySnapshot = FlueConversationState & { const projectPetrinautMessages = ( conversation: FlueConversationState, clientToolNames: ReadonlySet, + mapClientToolInput: + | ((input: { + readonly input: unknown; + readonly toolName: string; + }) => unknown) + | undefined, ): PetrinautAiMessage[] => // The host owns this narrowing: its configured client-tool catalog is the // same catalog Petrinaut's message type exposes. snapshotToUiMessages(conversation, { clientToolNames, + ...(mapClientToolInput === undefined ? {} : { mapClientToolInput }), }) as PetrinautAiMessage[]; export const useFlueChatHistory = ( clientPromise: Promise | null, conversationId: string, clientToolNames: ReadonlySet = brunchClientToolNames, + mapClientToolInput?: (input: { + readonly input: unknown; + readonly toolName: string; + }) => unknown, ): { readonly error: Error | undefined; readonly latestSettlement: FlueConversationSettlement | undefined; @@ -118,7 +129,11 @@ export const useFlueChatHistory = ( ? absent ? [] : undefined - : projectPetrinautMessages(conversation, clientToolNames), + : projectPetrinautMessages( + conversation, + clientToolNames, + mapClientToolInput, + ), phase: observation?.phase, ready, refresh, diff --git a/apps/petrinaut-website/src/main/app/local-storage-demo/use-prepare-crew-reservation-conversation.test.ts b/apps/petrinaut-website/src/main/app/local-storage-demo/use-prepare-crew-reservation-conversation.test.ts index d0d2bdc91c6..1d71f49b9b8 100644 --- a/apps/petrinaut-website/src/main/app/local-storage-demo/use-prepare-crew-reservation-conversation.test.ts +++ b/apps/petrinaut-website/src/main/app/local-storage-demo/use-prepare-crew-reservation-conversation.test.ts @@ -22,10 +22,13 @@ test("reports preparation failure without rejecting the shared client", async () usePrepareCrewReservationConversation(clientPromise, true), ); - await waitFor(() => expect(result.current.state).toBe("failed")); - expect(result.current).toEqual({ + await waitFor(() => expect(result.current.status.state).toBe("failed")); + expect(result.current.status).toEqual({ state: "failed", error: "Provider authentication failed", }); await expect(clientPromise).resolves.toBe(client); + await expect(result.current.clientPromise).rejects.toThrow( + "Provider authentication failed", + ); }); diff --git a/apps/petrinaut-website/src/main/app/local-storage-demo/use-prepare-crew-reservation-conversation.ts b/apps/petrinaut-website/src/main/app/local-storage-demo/use-prepare-crew-reservation-conversation.ts index cba89b08b3c..6b66fa2de3a 100644 --- a/apps/petrinaut-website/src/main/app/local-storage-demo/use-prepare-crew-reservation-conversation.ts +++ b/apps/petrinaut-website/src/main/app/local-storage-demo/use-prepare-crew-reservation-conversation.ts @@ -1,4 +1,4 @@ -import { useEffect, useState } from "react"; +import { useEffect, useMemo, useState } from "react"; import { prepareCrewReservationConversation } from "./prepare-crew-reservation-conversation"; @@ -11,27 +11,39 @@ export type CrewReservationPreparationStatus = export const usePrepareCrewReservationConversation = ( clientPromise: Promise | null, enabled: boolean, -): CrewReservationPreparationStatus => { +): { + readonly clientPromise: Promise | null; + readonly status: CrewReservationPreparationStatus; +} => { + const preparedClientPromise = useMemo(() => { + if (!enabled || clientPromise === null) return clientPromise; + return clientPromise.then(async (client) => { + await prepareCrewReservationConversation(client); + return client; + }); + }, [clientPromise, enabled]); const [observed, setObserved] = useState<{ readonly clientPromise: Promise; readonly status: CrewReservationPreparationStatus; }>(); useEffect(() => { - if (!enabled || clientPromise === null) return; + if (!enabled || preparedClientPromise === null) return; let cancelled = false; const prepare = async (): Promise => { try { - const client = await clientPromise; - await prepareCrewReservationConversation(client); + await preparedClientPromise; if (!cancelled) { - setObserved({ clientPromise, status: { state: "ready" } }); + setObserved({ + clientPromise: preparedClientPromise, + status: { state: "ready" }, + }); } } catch (error) { if (cancelled) return; setObserved({ - clientPromise, + clientPromise: preparedClientPromise, status: { state: "failed", error: @@ -46,10 +58,12 @@ export const usePrepareCrewReservationConversation = ( return () => { cancelled = true; }; - }, [clientPromise, enabled]); + }, [enabled, preparedClientPromise]); - if (!enabled) return { state: "idle" }; - return observed?.clientPromise === clientPromise - ? observed.status - : { state: "preparing" }; + const status: CrewReservationPreparationStatus = !enabled + ? { state: "idle" } + : observed?.clientPromise === preparedClientPromise + ? observed.status + : { state: "preparing" }; + return { clientPromise: preparedClientPromise, status }; }; diff --git a/libs/@hashintel/brunch-agent/packages/plugin-sdcpn/src/tools/petrinaut-construction.ts b/libs/@hashintel/brunch-agent/packages/plugin-sdcpn/src/tools/petrinaut-construction.ts index 42e5f49f57c..78c4b1f606b 100644 --- a/libs/@hashintel/brunch-agent/packages/plugin-sdcpn/src/tools/petrinaut-construction.ts +++ b/libs/@hashintel/brunch-agent/packages/plugin-sdcpn/src/tools/petrinaut-construction.ts @@ -2,7 +2,10 @@ import { defineTool } from "@flue/runtime"; import * as v from "valibot"; import { AWAITING_CLIENT } from "@hashintel/brunch-agent/client-tools"; -import { petrinautAiTools } from "@hashintel/petrinaut-core/ai"; +import { + normalizePetrinautAiToolInput, + petrinautAiTools, +} from "@hashintel/petrinaut-core/ai"; export const PETRINAUT_CONSTRUCTION_TOOL_NAMES = [ "getLatestNetDefinition", @@ -52,15 +55,22 @@ const canonicalInputFor = (toolName: PetrinautConstructionToolName) => { return { description: [ canonicalTool.description, + ...(toolName === "addArc" + ? [ + "A finite numeric-string weight is normalized to a number before canonical validation.", + ] + : []), "Canonical Petrinaut input JSON Schema:", JSON.stringify(jsonSchema), ].join("\n"), schema: v.pipe( v.looseObject({}), v.rawTransform((context) => { - const parsed = canonicalTool.inputSchema.safeParse( + const normalizedInput = normalizePetrinautAiToolInput( + toolName, context.dataset.value, ); + const parsed = canonicalTool.inputSchema.safeParse(normalizedInput); if (parsed.success) return parsed.data; for (const issue of parsed.error.issues) { diff --git a/libs/@hashintel/brunch-agent/packages/plugin-sdcpn/test/construction-tools.test.ts b/libs/@hashintel/brunch-agent/packages/plugin-sdcpn/test/construction-tools.test.ts index 95bd7df500d..ce2da8f9260 100644 --- a/libs/@hashintel/brunch-agent/packages/plugin-sdcpn/test/construction-tools.test.ts +++ b/libs/@hashintel/brunch-agent/packages/plugin-sdcpn/test/construction-tools.test.ts @@ -87,6 +87,19 @@ describe("Petrinaut construction tools", () => { ); }); + test("normalizes a finite provider numeric-string arc weight", () => { + const addArc = toolByName("addArc"); + const result = v.parse(addArc.input!, { + transitionId: "transition", + arcDirection: "input", + placeId: "place", + weight: "1", + type: "standard", + }); + + expect(result).toMatchObject({ weight: 1 }); + }); + test("retains nested values in canonical validation paths", () => { const addType = toolByName("addType"); const invalidElement = { diff --git a/libs/@hashintel/brunch-agent/packages/transport-aisdk/src/index.ts b/libs/@hashintel/brunch-agent/packages/transport-aisdk/src/index.ts index 2d6a603d2cc..e28d4e6ef75 100644 --- a/libs/@hashintel/brunch-agent/packages/transport-aisdk/src/index.ts +++ b/libs/@hashintel/brunch-agent/packages/transport-aisdk/src/index.ts @@ -38,6 +38,10 @@ export interface ClientToolResult { export interface FlueChatTransportOptions { readonly client: FlueClient; readonly clientToolNames: ReadonlySet; + readonly mapClientToolInput?: (input: { + readonly input: unknown; + readonly toolName: string; + }) => unknown; readonly onAdmission?: (event: { readonly admission: AgentSendResult; readonly kind: "client-tool-result" | "user"; @@ -189,6 +193,7 @@ const streamSubmission = ( const projector = createFlueUiStream({ submissionId: admission.submissionId, clientToolNames: options.clientToolNames, + mapClientToolInput: options.mapClientToolInput, write, }); diff --git a/libs/@hashintel/brunch-agent/packages/transport-aisdk/src/transcript.ts b/libs/@hashintel/brunch-agent/packages/transport-aisdk/src/transcript.ts index 089fc3dd4bc..49ca746eb7a 100644 --- a/libs/@hashintel/brunch-agent/packages/transport-aisdk/src/transcript.ts +++ b/libs/@hashintel/brunch-agent/packages/transport-aisdk/src/transcript.ts @@ -19,6 +19,10 @@ export type UiHistoryMessage = Omit< export interface SnapshotToUiMessagesOptions { readonly clientToolNames: ReadonlySet; + readonly mapClientToolInput?: (input: { + readonly input: unknown; + readonly toolName: string; + }) => unknown; } const unhandledConversationPart = (part: never): never => { @@ -71,17 +75,24 @@ const clientToolResultsFrom = ( const toolPartFrom = ( part: Extract, - clientToolNames: ReadonlySet, + options: SnapshotToUiMessagesOptions, clientOutputs: ReadonlyMap, ): UiMessagePart => { - const isClientTool = clientToolNames.has(part.toolName); + const isClientTool = options.clientToolNames.has(part.toolName); const hasClientOutput = clientOutputs.has(part.toolCallId); + const input = + isClientTool && options.mapClientToolInput !== undefined + ? options.mapClientToolInput({ + input: part.input, + toolName: part.toolName, + }) + : part.input; if (part.state === "output-error") { return { type: `tool-${part.toolName}`, toolCallId: part.toolCallId, state: "output-error", - input: part.input, + input, errorText: part.errorText, ...(isClientTool ? {} : { providerExecuted: true }), }; @@ -91,7 +102,7 @@ const toolPartFrom = ( type: `tool-${part.toolName}`, toolCallId: part.toolCallId, state: "input-available", - input: part.input, + input, }; } const output = isClientTool @@ -104,7 +115,7 @@ const toolPartFrom = ( type: `tool-${part.toolName}`, toolCallId: part.toolCallId, state: "output-available", - input: part.input, + input, output, ...(isClientTool ? {} : { providerExecuted: true }), }; @@ -113,7 +124,7 @@ const toolPartFrom = ( type: `tool-${part.toolName}`, toolCallId: part.toolCallId, state: "input-available", - input: part.input, + input, ...(isClientTool ? {} : { providerExecuted: true }), }; }; @@ -134,7 +145,7 @@ const partsFrom = ( continue; } if (part.type === "dynamic-tool") { - parts.push(toolPartFrom(part, options.clientToolNames, clientOutputs)); + parts.push(toolPartFrom(part, options, clientOutputs)); continue; } if (part.type === "file") { diff --git a/libs/@hashintel/brunch-agent/packages/transport-aisdk/src/ui-stream.ts b/libs/@hashintel/brunch-agent/packages/transport-aisdk/src/ui-stream.ts index 7270be320b2..a24f3398868 100644 --- a/libs/@hashintel/brunch-agent/packages/transport-aisdk/src/ui-stream.ts +++ b/libs/@hashintel/brunch-agent/packages/transport-aisdk/src/ui-stream.ts @@ -4,6 +4,10 @@ import type { UIMessageChunk } from "ai"; export interface FlueUiStreamOptions { readonly submissionId: AgentSendResult["submissionId"]; readonly clientToolNames: ReadonlySet; + readonly mapClientToolInput?: (input: { + readonly input: unknown; + readonly toolName: string; + }) => unknown; readonly write: (chunk: UIMessageChunk) => void; } @@ -129,7 +133,13 @@ export const createFlueUiStream = ( type: "tool-input-available", toolCallId: chunk.toolCallId, toolName: chunk.toolName, - input: chunk.input, + input: + isClientTool && options.mapClientToolInput !== undefined + ? options.mapClientToolInput({ + input: chunk.input, + toolName: chunk.toolName, + }) + : chunk.input, ...(isClientTool ? {} : { providerExecuted: true }), }); return; diff --git a/libs/@hashintel/brunch-agent/packages/transport-aisdk/test/ui-stream.test.ts b/libs/@hashintel/brunch-agent/packages/transport-aisdk/test/ui-stream.test.ts index c567fcd9b38..ce905e9dce1 100644 --- a/libs/@hashintel/brunch-agent/packages/transport-aisdk/test/ui-stream.test.ts +++ b/libs/@hashintel/brunch-agent/packages/transport-aisdk/test/ui-stream.test.ts @@ -118,3 +118,37 @@ test("ignores observation catch-up chunks in a submission stream", () => { "finish", ]); }); + +test("maps client-tool input before exposing it to the AI SDK", () => { + const written: UIMessageChunk[] = []; + const projector = createFlueUiStream({ + submissionId: "submission-1", + clientToolNames: new Set(["addArc"]), + mapClientToolInput: ({ input }) => ({ ...(input as object), weight: 1 }), + write: (chunk) => written.push(chunk), + }); + projector.accept({ + type: "message-started", + conversationId: "conversation-1", + messageId: "message-1", + submissionId: "submission-1", + turnId: "turn-1", + position: position(0), + }); + projector.accept({ + type: "tool-input", + conversationId: "conversation-1", + messageId: "message-1", + toolCallId: "call-1", + toolName: "addArc", + input: { weight: "1" }, + position: position(1), + }); + + expect(written).toContainEqual({ + type: "tool-input-available", + toolCallId: "call-1", + toolName: "addArc", + input: { weight: 1 }, + }); +}); diff --git a/libs/@hashintel/petrinaut-core/src/ai.test.ts b/libs/@hashintel/petrinaut-core/src/ai.test.ts index 26f38c743e1..124bed1dfb1 100644 --- a/libs/@hashintel/petrinaut-core/src/ai.test.ts +++ b/libs/@hashintel/petrinaut-core/src/ai.test.ts @@ -5,6 +5,7 @@ import { aiCommandActionInputSchemas, createPetrinautAiWritableCallbacks, getLatestNetDefinitionToolName, + normalizePetrinautAiToolInput, petrinautAiPrompt, petrinautAiToolInputSchemas, petrinautAiTools, @@ -46,6 +47,21 @@ describe("Petrinaut AI core exports", () => { expect(petrinautAiTools).toHaveProperty("applyAutoLayout"); }); + test("normalizes structured addArc values from text-oriented providers", () => { + expect( + normalizePetrinautAiToolInput("addArc", { + transitionId: "transition", + arcDirection: "input", + weight: "1", + type: "standard", + endpoint: '{"kind":"place","placeId":"place"}', + }), + ).toMatchObject({ + weight: 1, + endpoint: { kind: "place", placeId: "place" }, + }); + }); + test("latest net definition tool documents extension settings", () => { expect( petrinautAiTools[getLatestNetDefinitionToolName].description, diff --git a/libs/@hashintel/petrinaut-core/src/ai.ts b/libs/@hashintel/petrinaut-core/src/ai.ts index 61310b70a83..283046bde26 100644 --- a/libs/@hashintel/petrinaut-core/src/ai.ts +++ b/libs/@hashintel/petrinaut-core/src/ai.ts @@ -210,6 +210,35 @@ export type PetrinautAiToolInput = z.input< (typeof petrinautAiTools)[Name]["inputSchema"] >; +const isRecord = (value: unknown): value is Record => + typeof value === "object" && value !== null; + +/** + * Normalize the narrow structured values that text-oriented providers may + * serialize before applying the canonical Petrinaut tool schema. + */ +export const normalizePetrinautAiToolInput = ( + toolName: PetrinautAiToolName, + input: unknown, +): unknown => { + if (toolName !== "addArc" || !isRecord(input)) return input; + let normalized = input; + + if (typeof normalized.weight === "string") { + const weight = Number(normalized.weight); + if (Number.isFinite(weight)) normalized = { ...normalized, weight }; + } + if (typeof normalized.endpoint === "string") { + try { + const endpoint: unknown = JSON.parse(normalized.endpoint); + if (isRecord(endpoint)) normalized = { ...normalized, endpoint }; + } catch { + // Canonical validation reports the original malformed endpoint. + } + } + return normalized; +}; + /** * Writable tool callbacks exposed to the AI: every mutation, plus the subset * of commands registered in {@link aiCommandActionInputSchemas}. Read-only From 54f50846ede38c3486c493ce97e2f4ad2117276f Mon Sep 17 00:00:00 2001 From: Lu Nelson Date: Fri, 4 Sep 2026 10:15:33 +0200 Subject: [PATCH 08/13] Retain Mission 6 outer browser witness Co-authored-by: Cursor --- .../SHA256SUMS | 20 + .../call-result-correlation.json | 51 +++ .../cold-reader-gate.md | 36 ++ .../cold-reader-records.json | 39 ++ .../definition-after.json | 98 +++++ .../definition-before.json | 93 +++++ .../definition-tab-b.json | 98 +++++ .../flue-snapshot-after.json | 321 ++++++++++++++++ .../flue-snapshot-before.json | 113 ++++++ .../flue-snapshot-tab-b.json | 360 ++++++++++++++++++ .../latest-workpiece.md | 41 ++ .../prepared-workpiece.md | 22 ++ .../route-evidence.json | 7 + .../screenshot-tab-a-after.png | Bin 0 -> 142872 bytes .../screenshot-tab-a-before.png | Bin 0 -> 71412 bytes .../screenshot-tab-b-after.png | Bin 0 -> 153210 bytes .../settled-manifest-after.json | 25 ++ .../settled-manifest-before.json | 25 ++ .../settled-manifest-tab-b.json | 25 ++ .../tab-b-correlation.json | 18 + .../witness.md | 90 +++++ .../fe-1575-resumable-workpiece-petrinaut.md | 70 ++-- 22 files changed, 1517 insertions(+), 35 deletions(-) create mode 100644 libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/SHA256SUMS create mode 100644 libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/call-result-correlation.json create mode 100644 libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/cold-reader-gate.md create mode 100644 libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/cold-reader-records.json create mode 100644 libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/definition-after.json create mode 100644 libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/definition-before.json create mode 100644 libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/definition-tab-b.json create mode 100644 libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/flue-snapshot-after.json create mode 100644 libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/flue-snapshot-before.json create mode 100644 libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/flue-snapshot-tab-b.json create mode 100644 libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/latest-workpiece.md create mode 100644 libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/prepared-workpiece.md create mode 100644 libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/route-evidence.json create mode 100644 libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/screenshot-tab-a-after.png create mode 100644 libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/screenshot-tab-a-before.png create mode 100644 libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/screenshot-tab-b-after.png create mode 100644 libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/settled-manifest-after.json create mode 100644 libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/settled-manifest-before.json create mode 100644 libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/settled-manifest-tab-b.json create mode 100644 libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/tab-b-correlation.json create mode 100644 libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/witness.md diff --git a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/SHA256SUMS b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/SHA256SUMS new file mode 100644 index 00000000000..f44908b86b0 --- /dev/null +++ b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/SHA256SUMS @@ -0,0 +1,20 @@ +6c3a075636a5df23667c58c4ca005cc7da6b1927e13bfc54939f5e4416e5059f call-result-correlation.json +1d37d87803edd25905098bc957a1557ea7250a243b689c62c1d58ebc463135d0 cold-reader-gate.md +e5393930c436fac7bcb5f30b610ca4d28174a027f0b3fe8eab0045076379ce29 cold-reader-records.json +c17ae80cc22939f0af6c2675f6bcc20b025b17a5b7bfb9e8029813bcef9ad736 definition-after.json +0ec2b0c9bb82787602c359b41e6c1663001f8e42425ad2ab7f84ac019944766b definition-before.json +c17ae80cc22939f0af6c2675f6bcc20b025b17a5b7bfb9e8029813bcef9ad736 definition-tab-b.json +4fe368ef206e71e63173c1876ac9ca54e8b0d0971066be74dae5f78d4b612b0a flue-snapshot-after.json +ea20487150d8a329f4c2a6e0ac32e22de39d0d655646581ad2c56768a3591d1a flue-snapshot-before.json +7aaa993b395bc4ac84625fb2f472645ba13428bc39faac1f0f4ba948bfb3d9f5 flue-snapshot-tab-b.json +0f04053f623e488c522a3cca06bf34593004379dab0f0e551b26a355d87b1049 latest-workpiece.md +2859b2c9c756dd67589df04cdae498f63affffe0d65ca7f9ec6971b81eabfe94 prepared-workpiece.md +cfb79c8f52fc8f1758b1a61f67e520c67a31d2f19f561017899d0724b776100a route-evidence.json +a9bd4a4a18f52ebd5c0f0e9c7c5d80b1c37e85823bfa6a03bd9c1d329b4b4267 screenshot-tab-a-after.png +eaf49081a6ab7acba746f337fdb85e3829d473818dc7c96f83a40acd3cb6f383 screenshot-tab-a-before.png +d39ea91fc69fa049af169c6ebcfe1a09c5b085d350d5eb6f9020c31095549943 screenshot-tab-b-after.png +caf83c79b2526587794faf4ed8c59c0d3f4bb9ed88e3d547679efe429197797c settled-manifest-after.json +5b302df73ccd6ac0cec777c9e4ade15ac7318dca7023ed79e3bceaa0604c3ec0 settled-manifest-before.json +caf83c79b2526587794faf4ed8c59c0d3f4bb9ed88e3d547679efe429197797c settled-manifest-tab-b.json +08afa5150f33b8b19641118524880eca9b13f4e7a94a55eca7b76775cfa30770 tab-b-correlation.json +935fa33c714b6441622cb1c50f2ff5e7f8e56c434a5365f5857c2eb6a1ffd830 witness.md diff --git a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/call-result-correlation.json b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/call-result-correlation.json new file mode 100644 index 00000000000..bdc346ad17c --- /dev/null +++ b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/call-result-correlation.json @@ -0,0 +1,51 @@ +{ + "calls": [ + { + "messageId": "entry_01M1NQGD1NRR36CBAX78EA666J", + "submissionId": "sub_ik_dd2eb7be21980998b89ae9a9da085fb2", + "toolCallId": "toolu_01KLHzRE7gbPbFfPaXe3RTry", + "state": "output-available", + "input": { + "transitionId": "start-final-inspection", + "arcDirection": "input", + "placeId": "dispatch-crew-available", + "weight": "1", + "type": "standard" + } + } + ], + "results": [ + { + "toolCallId": "toolu_01KLHzRE7gbPbFfPaXe3RTry", + "toolName": "addArc", + "output": { + "title": "Added input arc", + "detail": "Dispatch crew available <-> Start final inspection", + "target": { + "kind": "selection", + "item": { + "type": "arc", + "id": "$A_place:dispatch-crew-available___start-final-inspection" + } + }, + "applied": true + } + }, + { + "toolCallId": "toolu_01KLHzRE7gbPbFfPaXe3RTry", + "toolName": "addArc", + "output": { + "title": "Added input arc", + "detail": "Dispatch crew available <-> Start final inspection", + "target": { + "kind": "selection", + "item": { + "type": "arc", + "id": "$A_place:dispatch-crew-available___start-final-inspection" + } + }, + "applied": true + } + } + ] +} diff --git a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/cold-reader-gate.md b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/cold-reader-gate.md new file mode 100644 index 00000000000..1d00d3e13f8 --- /dev/null +++ b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/cold-reader-gate.md @@ -0,0 +1,36 @@ +# Mission 6 cold-reader gate + +Reviewer qualification: a human who did not watch the implementation or outer +witness. Do not give the reviewer `witness.md`, screenshots, implementation +files, or this mission's expected conclusions. + +Give the reviewer only: + +- [prepared-workpiece.md](prepared-workpiece.md) +- [latest-workpiece.md](latest-workpiece.md) +- [cold-reader-records.json](cold-reader-records.json) + +Ask for a written response to these questions: + +1. Who authored each workpiece revision, and what in the supplied Flue records + establishes that attribution? +2. What exact dispatch-crew quantity or resource policy is recorded? +3. What operation reserves the crew, and what operation returns it? +4. List every unresolved timing, failure, and recovery point. +5. What behavioral execution or operational-provenance claims, if any, can be + made from these materials alone? + +Acceptance requires the human response to: + +- attribute revision zero to test preparation, not the model; +- attribute the later assistant record to model production; +- recover the exactly-one-crew policy and the intended reservation/return; +- preserve every timing, failure, and recovery unknown; and +- avoid inferring behavioral execution or capture provenance. + +Record the reviewer's identity, date, verbatim response, and explicit +accept/reject decision below only after the review occurs. + +## Human verdict + +Pending. diff --git a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/cold-reader-records.json b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/cold-reader-records.json new file mode 100644 index 00000000000..a5efc6ff2eb --- /dev/null +++ b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/cold-reader-records.json @@ -0,0 +1,39 @@ +{ + "preparedRecord": { + "id": "entry_direct_c3ViX2lrX2YyNDkzOWJlYmI4NDFmZmUxNDY5YTdmM2E0YTA2OTE1", + "role": "system", + "purpose": "dispatch", + "display": "diagnostic", + "submissionId": "sub_ik_f24939bebb841ffe1469a7f3a4a06915", + "signal": { + "tagName": "prepared-fixture", + "attributes": { + "fixtureId": "crew-reservation-v1", + "authorship": "test-authored", + "claimBoundary": "prepared-not-model-produced" + } + }, + "parts": [ + { + "type": "text", + "text": "Fixture authorship: test-authored preparation for Mission 6.\nNon-claims: not a Mission 4 candidate, not model-produced evidence, not capture-backed provenance, and not proof of automatic full-net projection.\n\n```runbook-ir\n# Final inspection and dispatch workpiece\n\n## Purpose and posture\nMaintain the narrow batch path from final inspection to dispatch readiness and test one evidence-backed correction against the live Petrinaut document.\n\n## Operational account\n- A batch that is ready enters final inspection.\n- Final inspection reserves the sole available dispatch crew.\n- Sign-off releases that crew and makes the batch ready for dispatch.\n\n## Quantity and resource policy\nExactly one dispatch crew is available in this fixture. Starting final inspection consumes that one available crew; sign-off returns it.\n\n## Current Petrinaut correspondence\nThe prepared non-empty net contains the batch path and the crew return from sign-off. It deliberately lacks the standard weight-1 input arc from `Dispatch crew available` to `Start final inspection`.\n\n## Explicit unknowns\nInspection and sign-off timing, failure modes, and recovery behavior remain unresolved.\n\n## Claim boundary\nThis prepared revision is test-authored diagnostic material. It is not model-produced evidence and does not establish capture provenance, behavioral execution, or broad projection quality.\n```", + "state": "done" + } + ] + }, + "revisedRecord": { + "id": "entry_01M1NQGRAKWG69MWYMPYTCFXCZ", + "role": "assistant", + "purpose": "assistant", + "display": "visible", + "submissionId": "sub_ik_6dbc187e4e72793b7539c02387d04715", + "turnId": "turn_01M1NQGQH38A3MMGGEWKN4VCDP", + "parts": [ + { + "type": "text", + "text": "**Verification successful.** The `start-final-inspection` transition now contains the corrected input arcs:\n```json\n\"inputArcs\":[\n {\"placeId\":\"batch-ready\",\"weight\":1,\"type\":\"standard\"},\n {\"type\":\"standard\",\"placeId\":\"dispatch-crew-available\",\"weight\":1}\n]\n```\n\nThe resource constraint is now satisfied: firing `start-final-inspection` requires both a ready batch AND an available crew token. The `sign-off` transition releases that crew back to `dispatch-crew-available`.\n\n---\n\n## Revised workpiece (runbook-ir)\n\n```runbook-ir\n# Final inspection and dispatch workpiece — Revised\n\n## Purpose and posture\nModel the batch path from final inspection to dispatch readiness with explicit crew resource management. This revision adds the missing crew-consumption arc to enforce the resource constraint.\n\n## Operational account\n- A batch that is ready enters final inspection.\n- Starting final inspection requires both a ready batch AND the sole available dispatch crew.\n- Starting final inspection consumes that crew token.\n- Sign-off releases that crew and makes the batch ready for dispatch.\n\n## Quantity and resource policy\nExactly one dispatch crew is available. Starting final inspection consumes that one available crew; sign-off returns it. No transition fires without sufficient tokens in all input places.\n\n## Petrinaut correspondence\nThe net contains four places:\n- `batch-ready`: batches awaiting final inspection\n- `under-final-inspection`: batches currently in inspection\n- `ready-for-dispatch`: batches cleared for dispatch\n- `dispatch-crew-available`: crew availability (1 token when free)\n\nTransitions:\n- `start-final-inspection`: requires 1 token from batch-ready AND 1 token from dispatch-crew-available; produces 1 token to under-final-inspection\n- `sign-off`: requires 1 token from under-final-inspection; produces 1 token to ready-for-dispatch AND 1 token to dispatch-crew-available\n\nThe missing standard weight-1 input arc from `dispatch-crew-available` to `start-final-inspection` has been **added and verified** in the live Petrinaut definition.\n\n## Explicit unknowns\n- Inspection timing: duration, stochasticity, or determinism remain unresolved\n- Sign-off timing: duration, stochasticity, or determinism remain unresolved\n- Failure modes: whether inspection can fail, halt, or reject a batch\n- Recovery behavior: how failures or rejections affect batch state or crew availability\n\n## Claim boundary\nThis workpiece and the corrected net establish only:\n- The crew-consumption constraint at start of inspection\n- The crew-release at sign-off completion\n- Token flow from ready batch through inspection to dispatch readiness\n\nThis is test-authored diagnostic material for the narrow final-inspection–to-dispatch path. It does not establish capture provenance, behavioral execution, failure handling, full process projection, or integration with upstream or downstream operations.\n```\n\nThe correction is complete and verified in the live Petrinaut definition.", + "state": "done" + } + ] + } +} diff --git a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/definition-after.json b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/definition-after.json new file mode 100644 index 00000000000..c92ed16c454 --- /dev/null +++ b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/definition-after.json @@ -0,0 +1,98 @@ +{ + "places": [ + { + "id": "batch-ready", + "name": "Batch ready", + "colorId": null, + "dynamicsEnabled": false, + "differentialEquationId": null, + "x": 80, + "y": 100 + }, + { + "id": "under-final-inspection", + "name": "Under final inspection", + "colorId": null, + "dynamicsEnabled": false, + "differentialEquationId": null, + "x": 420, + "y": 100 + }, + { + "id": "ready-for-dispatch", + "name": "Ready for dispatch", + "colorId": null, + "dynamicsEnabled": false, + "differentialEquationId": null, + "x": 760, + "y": 100 + }, + { + "id": "dispatch-crew-available", + "name": "Dispatch crew available", + "colorId": null, + "dynamicsEnabled": false, + "differentialEquationId": null, + "x": 420, + "y": 360 + } + ], + "transitions": [ + { + "id": "start-final-inspection", + "name": "Start final inspection", + "inputArcs": [ + { + "placeId": "batch-ready", + "weight": 1, + "type": "standard" + }, + { + "type": "standard", + "placeId": "dispatch-crew-available", + "weight": 1 + } + ], + "outputArcs": [ + { + "placeId": "under-final-inspection", + "weight": 1 + } + ], + "lambdaType": "predicate", + "lambdaCode": "", + "transitionKernelCode": "", + "x": 250, + "y": 100 + }, + { + "id": "sign-off", + "name": "Sign-off", + "inputArcs": [ + { + "placeId": "under-final-inspection", + "weight": 1, + "type": "standard" + } + ], + "outputArcs": [ + { + "placeId": "ready-for-dispatch", + "weight": 1 + }, + { + "placeId": "dispatch-crew-available", + "weight": 1 + } + ], + "lambdaType": "predicate", + "lambdaCode": "", + "transitionKernelCode": "", + "x": 590, + "y": 100 + } + ], + "types": [], + "differentialEquations": [], + "parameters": [] +} diff --git a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/definition-before.json b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/definition-before.json new file mode 100644 index 00000000000..5803556bfe8 --- /dev/null +++ b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/definition-before.json @@ -0,0 +1,93 @@ +{ + "places": [ + { + "id": "batch-ready", + "name": "Batch ready", + "colorId": null, + "dynamicsEnabled": false, + "differentialEquationId": null, + "x": 80, + "y": 100 + }, + { + "id": "under-final-inspection", + "name": "Under final inspection", + "colorId": null, + "dynamicsEnabled": false, + "differentialEquationId": null, + "x": 420, + "y": 100 + }, + { + "id": "ready-for-dispatch", + "name": "Ready for dispatch", + "colorId": null, + "dynamicsEnabled": false, + "differentialEquationId": null, + "x": 760, + "y": 100 + }, + { + "id": "dispatch-crew-available", + "name": "Dispatch crew available", + "colorId": null, + "dynamicsEnabled": false, + "differentialEquationId": null, + "x": 420, + "y": 360 + } + ], + "transitions": [ + { + "id": "start-final-inspection", + "name": "Start final inspection", + "inputArcs": [ + { + "placeId": "batch-ready", + "type": "standard", + "weight": 1 + } + ], + "outputArcs": [ + { + "placeId": "under-final-inspection", + "weight": 1 + } + ], + "lambdaType": "predicate", + "lambdaCode": "", + "transitionKernelCode": "", + "x": 250, + "y": 100 + }, + { + "id": "sign-off", + "name": "Sign-off", + "inputArcs": [ + { + "placeId": "under-final-inspection", + "type": "standard", + "weight": 1 + } + ], + "outputArcs": [ + { + "placeId": "ready-for-dispatch", + "weight": 1 + }, + { + "placeId": "dispatch-crew-available", + "weight": 1 + } + ], + "lambdaType": "predicate", + "lambdaCode": "", + "transitionKernelCode": "", + "x": 590, + "y": 100 + } + ], + "types": [], + "parameters": [], + "differentialEquations": [] +} diff --git a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/definition-tab-b.json b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/definition-tab-b.json new file mode 100644 index 00000000000..c92ed16c454 --- /dev/null +++ b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/definition-tab-b.json @@ -0,0 +1,98 @@ +{ + "places": [ + { + "id": "batch-ready", + "name": "Batch ready", + "colorId": null, + "dynamicsEnabled": false, + "differentialEquationId": null, + "x": 80, + "y": 100 + }, + { + "id": "under-final-inspection", + "name": "Under final inspection", + "colorId": null, + "dynamicsEnabled": false, + "differentialEquationId": null, + "x": 420, + "y": 100 + }, + { + "id": "ready-for-dispatch", + "name": "Ready for dispatch", + "colorId": null, + "dynamicsEnabled": false, + "differentialEquationId": null, + "x": 760, + "y": 100 + }, + { + "id": "dispatch-crew-available", + "name": "Dispatch crew available", + "colorId": null, + "dynamicsEnabled": false, + "differentialEquationId": null, + "x": 420, + "y": 360 + } + ], + "transitions": [ + { + "id": "start-final-inspection", + "name": "Start final inspection", + "inputArcs": [ + { + "placeId": "batch-ready", + "weight": 1, + "type": "standard" + }, + { + "type": "standard", + "placeId": "dispatch-crew-available", + "weight": 1 + } + ], + "outputArcs": [ + { + "placeId": "under-final-inspection", + "weight": 1 + } + ], + "lambdaType": "predicate", + "lambdaCode": "", + "transitionKernelCode": "", + "x": 250, + "y": 100 + }, + { + "id": "sign-off", + "name": "Sign-off", + "inputArcs": [ + { + "placeId": "under-final-inspection", + "weight": 1, + "type": "standard" + } + ], + "outputArcs": [ + { + "placeId": "ready-for-dispatch", + "weight": 1 + }, + { + "placeId": "dispatch-crew-available", + "weight": 1 + } + ], + "lambdaType": "predicate", + "lambdaCode": "", + "transitionKernelCode": "", + "x": 590, + "y": 100 + } + ], + "types": [], + "differentialEquations": [], + "parameters": [] +} diff --git a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/flue-snapshot-after.json b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/flue-snapshot-after.json new file mode 100644 index 00000000000..ba4e176112e --- /dev/null +++ b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/flue-snapshot-after.json @@ -0,0 +1,321 @@ +{ + "v": 1, + "conversationId": "conv_01M1NQEXM3CAPPTXM33ZE1YSRG", + "offset": "0000000000000000_0000000000000108", + "messages": [ + { + "id": "entry_direct_c3ViX2lrX2YyNDkzOWJlYmI4NDFmZmUxNDY5YTdmM2E0YTA2OTE1", + "role": "system", + "purpose": "dispatch", + "display": "diagnostic", + "submissionId": "sub_ik_f24939bebb841ffe1469a7f3a4a06915", + "signal": { + "tagName": "prepared-fixture", + "attributes": { + "fixtureId": "crew-reservation-v1", + "authorship": "test-authored", + "claimBoundary": "prepared-not-model-produced" + } + }, + "parts": [ + { + "type": "text", + "text": "Fixture authorship: test-authored preparation for Mission 6.\nNon-claims: not a Mission 4 candidate, not model-produced evidence, not capture-backed provenance, and not proof of automatic full-net projection.\n\n```runbook-ir\n# Final inspection and dispatch workpiece\n\n## Purpose and posture\nMaintain the narrow batch path from final inspection to dispatch readiness and test one evidence-backed correction against the live Petrinaut document.\n\n## Operational account\n- A batch that is ready enters final inspection.\n- Final inspection reserves the sole available dispatch crew.\n- Sign-off releases that crew and makes the batch ready for dispatch.\n\n## Quantity and resource policy\nExactly one dispatch crew is available in this fixture. Starting final inspection consumes that one available crew; sign-off returns it.\n\n## Current Petrinaut correspondence\nThe prepared non-empty net contains the batch path and the crew return from sign-off. It deliberately lacks the standard weight-1 input arc from `Dispatch crew available` to `Start final inspection`.\n\n## Explicit unknowns\nInspection and sign-off timing, failure modes, and recovery behavior remain unresolved.\n\n## Claim boundary\nThis prepared revision is test-authored diagnostic material. It is not model-produced evidence and does not establish capture provenance, behavioral execution, or broad projection quality.\n```", + "state": "done" + } + ] + }, + { + "id": "entry_01M1NQEYF9W60J2JVDYB2BJXK1", + "role": "assistant", + "purpose": "assistant", + "display": "visible", + "submissionId": "sub_ik_f24939bebb841ffe1469a7f3a4a06915", + "turnId": "turn_01M1NQEXM7MHJ94PF52Q54VAY4", + "parts": [ + { + "type": "reasoning", + "text": "The user has provided a prepared-fixture for SDCPN modelling work. This is test-authored material that is:\n- Part of a Mission 6 exercise\n- Focused on a narrow batch path from final inspection to dispatch readiness\n- Aimed at testing one evidence-backed correction against the live Petrinaut document\n- Not model-produced evidence, not a capture-backed provenance, not proof of automatic full-net projection\n\nThe operational account describes:\n1. A batch that is ready enters final inspection\n2. Final inspection reserves the sole available dispatch crew\n3. Sign-off releases that crew and makes the batch ready for dispatch\n\nThe key policy: Exactly one dispatch crew is available. Starting final inspection consumes it; sign-off returns it.\n\nThe current state: The prepared non-empty net contains the batch path and the crew return from sign-off, but deliberately LACKS the standard weight-1 input arc from \"Dispatch crew available\" to \"Start final inspection\".\n\nThe purpose is to test one evidence-backed correction against the live Petrinaut document.\n\nMy role here is:\n1. First, activate the sdcpn-modelling skill since this is a process-modelling task\n2. Understand the current state of the Petrinaut net\n3. Help verify the operational account against the net\n4. Work with the user to identify and potentially implement the missing arc correction\n5. Maintain the workpiece with clear documentation of what is known, what is missing, and what has been tested\n\nLet me start by activating the skill and getting the current net state.", + "state": "done" + }, + { + "type": "text", + "text": "I'll help you with this prepared-fixture exercise. Let me start by activating the SDCPN modelling skill and then retrieving the current state of the Petrinaut net to understand what we're working with.", + "state": "done" + }, + { + "type": "dynamic-tool", + "toolName": "activate_skill", + "toolCallId": "toolu_01WQaZveys8joHtboYvGQiuA", + "state": "output-available", + "input": { + "name": "sdcpn-modelling" + }, + "output": "Run the skill named \"sdcpn-modelling\".\n\n\n# Capability-aware lifecycle\n\nUse one conceptual lifecycle: orient, elicit or revise, maintain the workpiece, construct when supported, check, and deliver. The current conversation may expose only one branch of that lifecycle. Do not claim that an unavailable transition occurred.\n\n## Select the runtime branch\n\n### Interactive elicitation or revision\n\nInterview in the person's operational vocabulary. Activate the `elicitation` skill and read `references/profile.md` before substantive questions or revision. Read `templates/workpiece.md` when creating or materially revising the shared workpiece. Construct only when the mounted capabilities actually permit construction in this conversation.\n\n### Construct-only execution\n\nUse the supplied workpiece as the complete modelling input. Do not interview. Read `references/pn-construction.md` and `references/checks.md`, then use the mounted construction tools. If a consequential workpiece gap prevents faithful construction, report the gap and the smallest question a later interactive elicitation must answer; do not ask it or invent an answer in this conversation.\n\n## Procedure\n\n### Orient\n\nEstablish enough purpose and context to select one focused next action: the intended question or decision, audience, boundary, horizon, accuracy need, and available time. Orientation need not settle every concern before elicitation begins.\n\n### Elicit or revise\n\nFor a new account, follow one concrete case and re-evaluate the active gap after each useful answer. For an existing account, first locate the disputed or changed material and its consequence for the objective. Use the `elicitation` skill's universal guidance and `references/profile.md` for detailed operations and coverage; do not turn their register order into question order.\n\n### Maintain the workpiece\n\nTreat the workpiece as the recoverable account construction will consume. Update it after a useful stretch rather than waiting until the end. Preserve unrelated material unless new evidence affects it.\n\nWhenever the workpiece changes substantially, emit the full current document in a fenced block whose language tag is exactly `runbook-ir`. Emit it again before construction and before workpiece-only delivery. A delta or prose promise is not a recoverable workpiece.\n\n### Construct\n\nConstruct only from the current workpiece. Read `references/pn-construction.md` and `references/checks.md` before beginning. Use mounted Petrinaut tools for every net change and inspect the resulting definition rather than emitting free-form net JSON. If the required tools are absent, limit the result to the workpiece and construction-ready notes.\n\nConstruction may infer a representation from recorded operational meaning; it may not invent operational facts. Record construction inferences, approximations, defaults, and target losses in the workpiece.\n\n### Check and deliver\n\nApply `references/checks.md` whenever construction is prepared or attempted. Deliver the current workpiece in every branch. Deliver a net only when the mounted tool path has produced and checked one. State what the result can support, what remains open, what was assumed or simplified, and what the target or current tools could not represent.\n\nAn explicit stop opens no new topic. In an interactive conversation, emit the best current workpiece and any already-checked net with limitations visible. In construct-only execution, report a blocking gap rather than opening an interview.\n\n## Resource discipline\n\nRead resources directly from this skill's advertised resource list, using the exact `/.flue/packaged-skills/...` path shown in the activation briefing; the relative name is a label only. Do not treat Markdown links as includes, follow references recursively, or read construction material merely to frame ordinary interview questions.\n\n\nSupporting skill resources are available but are not loaded into context unless needed:\n\n- references/checks.md → read_skill_resource /.flue/packaged-skills/skill%3Asdcpn-modelling%3A99a447ec4bcbf6c0/references/checks.md\n- references/pn-construction.md → read_skill_resource /.flue/packaged-skills/skill%3Asdcpn-modelling%3A99a447ec4bcbf6c0/references/pn-construction.md\n- references/profile.md → read_skill_resource /.flue/packaged-skills/skill%3Asdcpn-modelling%3A99a447ec4bcbf6c0/references/profile.md\n- templates/workpiece.md → read_skill_resource /.flue/packaged-skills/skill%3Asdcpn-modelling%3A99a447ec4bcbf6c0/templates/workpiece.md\n", + "durationMs": 3 + }, + { + "type": "dynamic-tool", + "toolName": "getLatestNetDefinition", + "toolCallId": "toolu_01FjSrPHir7RNkmV1PUpZ1qu", + "state": "output-available", + "input": {}, + "output": { + "awaiting": "client" + }, + "durationMs": 3 + }, + { + "type": "reasoning", + "text": "The skill is activated. The net definition call shows `{\"awaiting\":\"client\"}` which means the browser needs to fetch it. Let me wait a moment for that result to come through via the client-tool-result signal, or I should ask the user about the current state. \n\nActually, I should ping first to confirm the server is in the loop, then proceed to understand what we have.", + "state": "done" + }, + { + "type": "text", + "text": "Let me confirm the server connection and then retrieve the current net definition:", + "state": "done" + }, + { + "type": "dynamic-tool", + "toolName": "ping", + "toolCallId": "toolu_01NpMVdLYpu7PeSDCfJqjwqA", + "state": "output-available", + "input": { + "note": "Confirming server ready for crew-reservation-v1 prepared-fixture work" + }, + "output": { + "ok": true, + "note": "Confirming server ready for crew-reservation-v1 prepared-fixture work" + }, + "durationMs": 1 + }, + { + "type": "reasoning", + "text": "Good, the server is ready. Now I should wait for the net definition from the browser. The getLatestNetDefinition returned `{\"awaiting\":\"client\"}` which means it's waiting for a client tool result. I should describe what I'm going to do next and wait for that result.", + "state": "done" + }, + { + "type": "text", + "text": "Good. Now let me work with the prepared-fixture material you've provided. \n\n## Understanding the prepared fixture\n\nYou've provided a **test-authored diagnostic workpiece** focused on the **final inspection → dispatch path** with one specific correction to test:\n\n**Operational account:**\n- A batch ready for dispatch enters final inspection\n- Starting final inspection *reserves* the single available dispatch crew\n- Sign-off *releases* that crew and marks the batch ready for dispatch\n\n**Current net state:**\n- Contains the batch path and the crew return from sign-off\n- **Deliberately omits** the weight-1 input arc from \"Dispatch crew available\" to \"Start final inspection\" \n\n**Purpose:** Test one evidence-backed correction against the live Petrinaut document.\n\n---\n\n## Next step\n\nThe Petrinaut net definition is being retrieved. Once I see the current structure, I can:\n\n1. **Verify** the operational account against what's in the net\n2. **Identify** the missing arc precisely \n3. **Test the correction** by adding that arc and confirming it satisfies the resource constraint (exactly one crew consumed at start, returned at sign-off)\n\nI'm waiting for the live net definition to come through. What I'll be looking for:\n- The places representing the batch states (ready, in-inspection, ready-for-dispatch)\n- The places for crew availability\n- The transitions for \"Start final inspection\" and \"Sign-off\"\n- Which arcs are already present and which are missing\n\nDoes this match your intention for this exercise?", + "state": "done" + } + ] + }, + { + "id": "entry_direct_c3ViX2lrX2I3YTI3NGI3YzI4MjVkNGMwOTE0ZGE0NDBlMjQxY2I2", + "role": "user", + "purpose": "user", + "display": "visible", + "submissionId": "sub_ik_b7a274b7c2825d4c0914da440e241cb6", + "parts": [ + { + "type": "text", + "text": "Confirmed: final inspection uses the single dispatch crew and sign-off releases it; timing, failure, and recovery remain unknown. Read the live Petrinaut definition, add the missing standard weight-1 input arc from Dispatch crew available to Start final inspection, verify it, and emit the full revised runbook-ir workpiece.", + "state": "done" + } + ] + }, + { + "id": "entry_01M1NQGAVZ00RTNPHG4MM610XE", + "role": "assistant", + "purpose": "assistant", + "display": "visible", + "submissionId": "sub_ik_b7a274b7c2825d4c0914da440e241cb6", + "turnId": "turn_01M1NQGA4WJ01NC2MS1JJB0QWJ", + "parts": [ + { + "type": "reasoning", + "text": "The user has confirmed the operational intent and is asking me to:\n1. Read the live Petrinaut definition\n2. Add the missing standard weight-1 input arc from \"Dispatch crew available\" to \"Start final inspection\"\n3. Verify it\n4. Emit the full revised runbook-ir workpiece\n\nI need to call getLatestNetDefinition again to get the actual net definition since the previous call returned {\"awaiting\":\"client\"}.", + "state": "done" + }, + { + "type": "dynamic-tool", + "toolName": "getLatestNetDefinition", + "toolCallId": "toolu_01BqoDEZeq7HTqu3S8p6ZLA6", + "state": "output-available", + "input": {}, + "output": { + "awaiting": "client" + }, + "durationMs": 0 + } + ] + }, + { + "id": "entry_direct_c3ViX2lrX2RkMmViN2JlMjE5ODA5OThiODlhZTlhOWRhMDg1ZmIy", + "role": "system", + "purpose": "dispatch", + "display": "diagnostic", + "submissionId": "sub_ik_dd2eb7be21980998b89ae9a9da085fb2", + "signal": { + "tagName": "client-tool-result", + "attributes": { + "toolCallIds": "toolu_01BqoDEZeq7HTqu3S8p6ZLA6" + } + }, + "parts": [ + { + "type": "text", + "text": "[{\"toolCallId\":\"toolu_01BqoDEZeq7HTqu3S8p6ZLA6\",\"toolName\":\"getLatestNetDefinition\",\"output\":{\"title\":\"Prepared final inspection and dispatch\",\"definition\":{\"places\":[{\"id\":\"batch-ready\",\"name\":\"Batch ready\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":80,\"y\":100},{\"id\":\"under-final-inspection\",\"name\":\"Under final inspection\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":420,\"y\":100},{\"id\":\"ready-for-dispatch\",\"name\":\"Ready for dispatch\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":760,\"y\":100},{\"id\":\"dispatch-crew-available\",\"name\":\"Dispatch crew available\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":420,\"y\":360}],\"transitions\":[{\"id\":\"start-final-inspection\",\"name\":\"Start final inspection\",\"inputArcs\":[{\"placeId\":\"batch-ready\",\"weight\":1,\"type\":\"standard\"}],\"outputArcs\":[{\"placeId\":\"under-final-inspection\",\"weight\":1}],\"lambdaType\":\"predicate\",\"lambdaCode\":\"\",\"transitionKernelCode\":\"\",\"x\":250,\"y\":100},{\"id\":\"sign-off\",\"name\":\"Sign-off\",\"inputArcs\":[{\"placeId\":\"under-final-inspection\",\"weight\":1,\"type\":\"standard\"}],\"outputArcs\":[{\"placeId\":\"ready-for-dispatch\",\"weight\":1},{\"placeId\":\"dispatch-crew-available\",\"weight\":1}],\"lambdaType\":\"predicate\",\"lambdaCode\":\"\",\"transitionKernelCode\":\"\",\"x\":590,\"y\":100}],\"types\":[],\"differentialEquations\":[],\"parameters\":[]},\"extensions\":{\"colors\":true,\"stochasticity\":true,\"dynamics\":true,\"parameters\":true,\"subnets\":true}}}]", + "state": "done" + } + ] + }, + { + "id": "entry_01M1NQGD1NRR36CBAX78EA666J", + "role": "assistant", + "purpose": "assistant", + "display": "visible", + "submissionId": "sub_ik_dd2eb7be21980998b89ae9a9da085fb2", + "turnId": "turn_01M1NQGC2ZFFFC5MFXN2949H93", + "parts": [ + { + "type": "reasoning", + "text": "Good! Now I have the live Petrinaut definition. Let me analyze it:\n\n**Current places:**\n1. `batch-ready` - batch waiting to enter inspection\n2. `under-final-inspection` - batch in inspection\n3. `ready-for-dispatch` - batch ready for dispatch (output state)\n4. `dispatch-crew-available` - represents availability of the single dispatch crew\n\n**Current transitions:**\n1. `start-final-inspection` - takes 1 batch from `batch-ready`, outputs 1 to `under-final-inspection`\n - Input arcs: `batch-ready` (weight 1, standard)\n - Output arcs: `under-final-inspection` (weight 1)\n\n2. `sign-off` - takes 1 batch from `under-final-inspection`, outputs 1 to `ready-for-dispatch` AND 1 to `dispatch-crew-available`\n - Input arcs: `under-final-inspection` (weight 1, standard)\n - Output arcs: `ready-for-dispatch` (weight 1), `dispatch-crew-available` (weight 1)\n\n**What's missing:**\nThe `start-final-inspection` transition is missing an input arc from `dispatch-crew-available`. When a batch starts final inspection, it should consume one crew token.\n\nAccording to the prepared fixture, this should be:\n- Arc direction: **input**\n- Source place: `dispatch-crew-available`\n- Weight: 1\n- Type: standard\n\nSo I need to add an input arc to `start-final-inspection` with:\n- placeId: `dispatch-crew-available`\n- weight: 1\n- type: `standard`\n\nLet me use the `addArc` function to add this arc.", + "state": "done" + }, + { + "type": "text", + "text": "Perfect. I can see the live net structure. Let me analyze it:\n\n**Current structure:**\n- **Places:** Batch-ready → Under-final-inspection → Ready-for-dispatch, plus Dispatch-crew-available\n- **start-final-inspection transition:** Currently has only one input arc (from batch-ready)\n- **sign-off transition:** Takes batch from inspection and outputs both the batch (to ready-for-dispatch) AND returns 1 crew token to dispatch-crew-available\n\n**Missing element:** The `start-final-inspection` transition lacks the input arc from `dispatch-crew-available`. This means the model currently allows inspection to begin without consuming the crew resource—violating the \"exactly one crew reserved\" constraint.\n\nNow I'll add the missing standard weight-1 input arc from `dispatch-crew-available` to `start-final-inspection`:", + "state": "done" + }, + { + "type": "dynamic-tool", + "toolName": "addArc", + "toolCallId": "toolu_01KLHzRE7gbPbFfPaXe3RTry", + "state": "output-available", + "input": { + "transitionId": "start-final-inspection", + "arcDirection": "input", + "placeId": "dispatch-crew-available", + "weight": "1", + "type": "standard" + }, + "output": { + "awaiting": "client" + }, + "durationMs": 0 + } + ] + }, + { + "id": "entry_direct_c3ViX2lrXzAwOGZhNmQ3MzU0NzQ5YTFjYjNmNjc0MTg0ZTdjYjFi", + "role": "system", + "purpose": "dispatch", + "display": "diagnostic", + "submissionId": "sub_ik_008fa6d7354749a1cb3f674184e7cb1b", + "signal": { + "tagName": "client-tool-result", + "attributes": { + "toolCallIds": "toolu_01BqoDEZeq7HTqu3S8p6ZLA6,toolu_01KLHzRE7gbPbFfPaXe3RTry" + } + }, + "parts": [ + { + "type": "text", + "text": "[{\"toolCallId\":\"toolu_01BqoDEZeq7HTqu3S8p6ZLA6\",\"toolName\":\"getLatestNetDefinition\",\"output\":{\"title\":\"Prepared final inspection and dispatch\",\"definition\":{\"places\":[{\"id\":\"batch-ready\",\"name\":\"Batch ready\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":80,\"y\":100},{\"id\":\"under-final-inspection\",\"name\":\"Under final inspection\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":420,\"y\":100},{\"id\":\"ready-for-dispatch\",\"name\":\"Ready for dispatch\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":760,\"y\":100},{\"id\":\"dispatch-crew-available\",\"name\":\"Dispatch crew available\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":420,\"y\":360}],\"transitions\":[{\"id\":\"start-final-inspection\",\"name\":\"Start final inspection\",\"inputArcs\":[{\"placeId\":\"batch-ready\",\"weight\":1,\"type\":\"standard\"}],\"outputArcs\":[{\"placeId\":\"under-final-inspection\",\"weight\":1}],\"lambdaType\":\"predicate\",\"lambdaCode\":\"\",\"transitionKernelCode\":\"\",\"x\":250,\"y\":100},{\"id\":\"sign-off\",\"name\":\"Sign-off\",\"inputArcs\":[{\"placeId\":\"under-final-inspection\",\"weight\":1,\"type\":\"standard\"}],\"outputArcs\":[{\"placeId\":\"ready-for-dispatch\",\"weight\":1},{\"placeId\":\"dispatch-crew-available\",\"weight\":1}],\"lambdaType\":\"predicate\",\"lambdaCode\":\"\",\"transitionKernelCode\":\"\",\"x\":590,\"y\":100}],\"types\":[],\"differentialEquations\":[],\"parameters\":[]},\"extensions\":{\"colors\":true,\"stochasticity\":true,\"dynamics\":true,\"parameters\":true,\"subnets\":true}}},{\"toolCallId\":\"toolu_01KLHzRE7gbPbFfPaXe3RTry\",\"toolName\":\"addArc\",\"output\":{\"title\":\"Added input arc\",\"detail\":\"Dispatch crew available <-> Start final inspection\",\"target\":{\"kind\":\"selection\",\"item\":{\"type\":\"arc\",\"id\":\"$A_place:dispatch-crew-available___start-final-inspection\"}},\"applied\":true}}]", + "state": "done" + } + ] + }, + { + "id": "entry_01M1NQGMV82KXETG8X23QZHPM3", + "role": "assistant", + "purpose": "assistant", + "display": "visible", + "submissionId": "sub_ik_008fa6d7354749a1cb3f674184e7cb1b", + "turnId": "turn_01M1NQGKXT0H69NP5JFRYQJ2J7", + "parts": [ + { + "type": "reasoning", + "text": "Good! The arc has been added successfully. Let me verify by checking the live definition again to confirm the arc is now present in the start-final-inspection transition.\n\nLooking at the addArc output, it says \"Applied: true\" and created an arc with ID \"$A_place:dispatch-crew-available___start-final-inspection\". This is the confirmation.\n\nHowever, I notice that the getLatestNetDefinition result that came back still shows the old structure—the start-final-inspection transition still shows only one inputArc (from batch-ready). This might be a timing issue in how the results came back, or the definition might not have refreshed yet.\n\nLet me read the live definition one more time to verify the arc was actually applied and is visible in the current state.", + "state": "done" + }, + { + "type": "text", + "text": "Excellent! The arc addition was successful: `\"applied\":true`. Let me verify the updated net definition:", + "state": "done" + }, + { + "type": "dynamic-tool", + "toolName": "getLatestNetDefinition", + "toolCallId": "toolu_01LuBH9HSYSzvkCMq5E3PN57", + "state": "output-available", + "input": {}, + "output": { + "awaiting": "client" + }, + "durationMs": 0 + } + ] + }, + { + "id": "entry_direct_c3ViX2lrXzZkYmMxODdlNGU3Mjc5M2I3NTM5YzAyMzg3ZDA0NzE1", + "role": "system", + "purpose": "dispatch", + "display": "diagnostic", + "submissionId": "sub_ik_6dbc187e4e72793b7539c02387d04715", + "signal": { + "tagName": "client-tool-result", + "attributes": { + "toolCallIds": "toolu_01BqoDEZeq7HTqu3S8p6ZLA6,toolu_01KLHzRE7gbPbFfPaXe3RTry,toolu_01LuBH9HSYSzvkCMq5E3PN57" + } + }, + "parts": [ + { + "type": "text", + "text": "[{\"toolCallId\":\"toolu_01BqoDEZeq7HTqu3S8p6ZLA6\",\"toolName\":\"getLatestNetDefinition\",\"output\":{\"title\":\"Prepared final inspection and dispatch\",\"definition\":{\"places\":[{\"id\":\"batch-ready\",\"name\":\"Batch ready\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":80,\"y\":100},{\"id\":\"under-final-inspection\",\"name\":\"Under final inspection\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":420,\"y\":100},{\"id\":\"ready-for-dispatch\",\"name\":\"Ready for dispatch\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":760,\"y\":100},{\"id\":\"dispatch-crew-available\",\"name\":\"Dispatch crew available\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":420,\"y\":360}],\"transitions\":[{\"id\":\"start-final-inspection\",\"name\":\"Start final inspection\",\"inputArcs\":[{\"placeId\":\"batch-ready\",\"weight\":1,\"type\":\"standard\"}],\"outputArcs\":[{\"placeId\":\"under-final-inspection\",\"weight\":1}],\"lambdaType\":\"predicate\",\"lambdaCode\":\"\",\"transitionKernelCode\":\"\",\"x\":250,\"y\":100},{\"id\":\"sign-off\",\"name\":\"Sign-off\",\"inputArcs\":[{\"placeId\":\"under-final-inspection\",\"weight\":1,\"type\":\"standard\"}],\"outputArcs\":[{\"placeId\":\"ready-for-dispatch\",\"weight\":1},{\"placeId\":\"dispatch-crew-available\",\"weight\":1}],\"lambdaType\":\"predicate\",\"lambdaCode\":\"\",\"transitionKernelCode\":\"\",\"x\":590,\"y\":100}],\"types\":[],\"differentialEquations\":[],\"parameters\":[]},\"extensions\":{\"colors\":true,\"stochasticity\":true,\"dynamics\":true,\"parameters\":true,\"subnets\":true}}},{\"toolCallId\":\"toolu_01KLHzRE7gbPbFfPaXe3RTry\",\"toolName\":\"addArc\",\"output\":{\"title\":\"Added input arc\",\"detail\":\"Dispatch crew available <-> Start final inspection\",\"target\":{\"kind\":\"selection\",\"item\":{\"type\":\"arc\",\"id\":\"$A_place:dispatch-crew-available___start-final-inspection\"}},\"applied\":true}},{\"toolCallId\":\"toolu_01LuBH9HSYSzvkCMq5E3PN57\",\"toolName\":\"getLatestNetDefinition\",\"output\":{\"title\":\"Prepared final inspection and dispatch\",\"definition\":{\"places\":[{\"id\":\"batch-ready\",\"name\":\"Batch ready\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":80,\"y\":100},{\"id\":\"under-final-inspection\",\"name\":\"Under final inspection\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":420,\"y\":100},{\"id\":\"ready-for-dispatch\",\"name\":\"Ready for dispatch\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":760,\"y\":100},{\"id\":\"dispatch-crew-available\",\"name\":\"Dispatch crew available\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":420,\"y\":360}],\"transitions\":[{\"id\":\"start-final-inspection\",\"name\":\"Start final inspection\",\"inputArcs\":[{\"placeId\":\"batch-ready\",\"weight\":1,\"type\":\"standard\"},{\"type\":\"standard\",\"placeId\":\"dispatch-crew-available\",\"weight\":1}],\"outputArcs\":[{\"placeId\":\"under-final-inspection\",\"weight\":1}],\"lambdaType\":\"predicate\",\"lambdaCode\":\"\",\"transitionKernelCode\":\"\",\"x\":250,\"y\":100},{\"id\":\"sign-off\",\"name\":\"Sign-off\",\"inputArcs\":[{\"placeId\":\"under-final-inspection\",\"weight\":1,\"type\":\"standard\"}],\"outputArcs\":[{\"placeId\":\"ready-for-dispatch\",\"weight\":1},{\"placeId\":\"dispatch-crew-available\",\"weight\":1}],\"lambdaType\":\"predicate\",\"lambdaCode\":\"\",\"transitionKernelCode\":\"\",\"x\":590,\"y\":100}],\"types\":[],\"differentialEquations\":[],\"parameters\":[]},\"extensions\":{\"colors\":true,\"stochasticity\":true,\"dynamics\":true,\"parameters\":true,\"subnets\":true}}}]", + "state": "done" + } + ] + }, + { + "id": "entry_01M1NQGRAKWG69MWYMPYTCFXCZ", + "role": "assistant", + "purpose": "assistant", + "display": "visible", + "submissionId": "sub_ik_6dbc187e4e72793b7539c02387d04715", + "turnId": "turn_01M1NQGQH38A3MMGGEWKN4VCDP", + "parts": [ + { + "type": "reasoning", + "text": "Perfect! The verification confirms the arc has been successfully added. Looking at the final definition:\n\nThe `start-final-inspection` transition now has two input arcs:\n1. `{\"placeId\":\"batch-ready\",\"weight\":1,\"type\":\"standard\"}`\n2. `{\"type\":\"standard\",\"placeId\":\"dispatch-crew-available\",\"weight\":1}`\n\nThis means:\n- Starting final inspection requires 1 token from \"batch-ready\" AND 1 token from \"dispatch-crew-available\"\n- It produces 1 token to \"under-final-inspection\"\n- The sign-off transition consumes the batch from inspection and returns 1 crew token\n\nThis satisfies the operational constraint: exactly one dispatch crew is consumed when inspection begins and released when sign-off completes.\n\nNow I need to emit the full revised runbook-ir workpiece as requested. I should update the prepared fixture material with:\n1. The operational account (confirmed)\n2. The current Petrinaut correspondence (UPDATED - the missing arc has been added)\n3. Explicit unknowns (unchanged)\n4. The claim boundary (adjusted to reflect what this correction establishes)", + "state": "done" + }, + { + "type": "text", + "text": "**Verification successful.** The `start-final-inspection` transition now contains the corrected input arcs:\n```json\n\"inputArcs\":[\n {\"placeId\":\"batch-ready\",\"weight\":1,\"type\":\"standard\"},\n {\"type\":\"standard\",\"placeId\":\"dispatch-crew-available\",\"weight\":1}\n]\n```\n\nThe resource constraint is now satisfied: firing `start-final-inspection` requires both a ready batch AND an available crew token. The `sign-off` transition releases that crew back to `dispatch-crew-available`.\n\n---\n\n## Revised workpiece (runbook-ir)\n\n```runbook-ir\n# Final inspection and dispatch workpiece — Revised\n\n## Purpose and posture\nModel the batch path from final inspection to dispatch readiness with explicit crew resource management. This revision adds the missing crew-consumption arc to enforce the resource constraint.\n\n## Operational account\n- A batch that is ready enters final inspection.\n- Starting final inspection requires both a ready batch AND the sole available dispatch crew.\n- Starting final inspection consumes that crew token.\n- Sign-off releases that crew and makes the batch ready for dispatch.\n\n## Quantity and resource policy\nExactly one dispatch crew is available. Starting final inspection consumes that one available crew; sign-off returns it. No transition fires without sufficient tokens in all input places.\n\n## Petrinaut correspondence\nThe net contains four places:\n- `batch-ready`: batches awaiting final inspection\n- `under-final-inspection`: batches currently in inspection\n- `ready-for-dispatch`: batches cleared for dispatch\n- `dispatch-crew-available`: crew availability (1 token when free)\n\nTransitions:\n- `start-final-inspection`: requires 1 token from batch-ready AND 1 token from dispatch-crew-available; produces 1 token to under-final-inspection\n- `sign-off`: requires 1 token from under-final-inspection; produces 1 token to ready-for-dispatch AND 1 token to dispatch-crew-available\n\nThe missing standard weight-1 input arc from `dispatch-crew-available` to `start-final-inspection` has been **added and verified** in the live Petrinaut definition.\n\n## Explicit unknowns\n- Inspection timing: duration, stochasticity, or determinism remain unresolved\n- Sign-off timing: duration, stochasticity, or determinism remain unresolved\n- Failure modes: whether inspection can fail, halt, or reject a batch\n- Recovery behavior: how failures or rejections affect batch state or crew availability\n\n## Claim boundary\nThis workpiece and the corrected net establish only:\n- The crew-consumption constraint at start of inspection\n- The crew-release at sign-off completion\n- Token flow from ready batch through inspection to dispatch readiness\n\nThis is test-authored diagnostic material for the narrow final-inspection–to-dispatch path. It does not establish capture provenance, behavioral execution, failure handling, full process projection, or integration with upstream or downstream operations.\n```\n\nThe correction is complete and verified in the live Petrinaut definition.", + "state": "done" + } + ] + } + ], + "settlements": [ + { + "submissionId": "sub_ik_f24939bebb841ffe1469a7f3a4a06915", + "outcome": "completed", + "answeredBySubmissionId": "sub_ik_f24939bebb841ffe1469a7f3a4a06915" + }, + { + "submissionId": "sub_ik_b7a274b7c2825d4c0914da440e241cb6", + "outcome": "completed", + "answeredBySubmissionId": "sub_ik_b7a274b7c2825d4c0914da440e241cb6" + }, + { + "submissionId": "sub_ik_dd2eb7be21980998b89ae9a9da085fb2", + "outcome": "completed", + "answeredBySubmissionId": "sub_ik_dd2eb7be21980998b89ae9a9da085fb2" + }, + { + "submissionId": "sub_ik_008fa6d7354749a1cb3f674184e7cb1b", + "outcome": "completed", + "answeredBySubmissionId": "sub_ik_008fa6d7354749a1cb3f674184e7cb1b" + }, + { + "submissionId": "sub_ik_6dbc187e4e72793b7539c02387d04715", + "outcome": "completed", + "answeredBySubmissionId": "sub_ik_6dbc187e4e72793b7539c02387d04715" + } + ], + "incarnation": "inc_01M1NQEXM24JHNYN40Q8RA5DH5" +} diff --git a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/flue-snapshot-before.json b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/flue-snapshot-before.json new file mode 100644 index 00000000000..a584f125feb --- /dev/null +++ b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/flue-snapshot-before.json @@ -0,0 +1,113 @@ +{ + "v": 1, + "conversationId": "conv_01M1NQEXM3CAPPTXM33ZE1YSRG", + "offset": "0000000000000000_0000000000000043", + "messages": [ + { + "id": "entry_direct_c3ViX2lrX2YyNDkzOWJlYmI4NDFmZmUxNDY5YTdmM2E0YTA2OTE1", + "role": "system", + "purpose": "dispatch", + "display": "diagnostic", + "submissionId": "sub_ik_f24939bebb841ffe1469a7f3a4a06915", + "signal": { + "tagName": "prepared-fixture", + "attributes": { + "fixtureId": "crew-reservation-v1", + "authorship": "test-authored", + "claimBoundary": "prepared-not-model-produced" + } + }, + "parts": [ + { + "type": "text", + "text": "Fixture authorship: test-authored preparation for Mission 6.\nNon-claims: not a Mission 4 candidate, not model-produced evidence, not capture-backed provenance, and not proof of automatic full-net projection.\n\n```runbook-ir\n# Final inspection and dispatch workpiece\n\n## Purpose and posture\nMaintain the narrow batch path from final inspection to dispatch readiness and test one evidence-backed correction against the live Petrinaut document.\n\n## Operational account\n- A batch that is ready enters final inspection.\n- Final inspection reserves the sole available dispatch crew.\n- Sign-off releases that crew and makes the batch ready for dispatch.\n\n## Quantity and resource policy\nExactly one dispatch crew is available in this fixture. Starting final inspection consumes that one available crew; sign-off returns it.\n\n## Current Petrinaut correspondence\nThe prepared non-empty net contains the batch path and the crew return from sign-off. It deliberately lacks the standard weight-1 input arc from `Dispatch crew available` to `Start final inspection`.\n\n## Explicit unknowns\nInspection and sign-off timing, failure modes, and recovery behavior remain unresolved.\n\n## Claim boundary\nThis prepared revision is test-authored diagnostic material. It is not model-produced evidence and does not establish capture provenance, behavioral execution, or broad projection quality.\n```", + "state": "done" + } + ] + }, + { + "id": "entry_01M1NQEYF9W60J2JVDYB2BJXK1", + "role": "assistant", + "purpose": "assistant", + "display": "visible", + "submissionId": "sub_ik_f24939bebb841ffe1469a7f3a4a06915", + "turnId": "turn_01M1NQEXM7MHJ94PF52Q54VAY4", + "parts": [ + { + "type": "reasoning", + "text": "The user has provided a prepared-fixture for SDCPN modelling work. This is test-authored material that is:\n- Part of a Mission 6 exercise\n- Focused on a narrow batch path from final inspection to dispatch readiness\n- Aimed at testing one evidence-backed correction against the live Petrinaut document\n- Not model-produced evidence, not a capture-backed provenance, not proof of automatic full-net projection\n\nThe operational account describes:\n1. A batch that is ready enters final inspection\n2. Final inspection reserves the sole available dispatch crew\n3. Sign-off releases that crew and makes the batch ready for dispatch\n\nThe key policy: Exactly one dispatch crew is available. Starting final inspection consumes it; sign-off returns it.\n\nThe current state: The prepared non-empty net contains the batch path and the crew return from sign-off, but deliberately LACKS the standard weight-1 input arc from \"Dispatch crew available\" to \"Start final inspection\".\n\nThe purpose is to test one evidence-backed correction against the live Petrinaut document.\n\nMy role here is:\n1. First, activate the sdcpn-modelling skill since this is a process-modelling task\n2. Understand the current state of the Petrinaut net\n3. Help verify the operational account against the net\n4. Work with the user to identify and potentially implement the missing arc correction\n5. Maintain the workpiece with clear documentation of what is known, what is missing, and what has been tested\n\nLet me start by activating the skill and getting the current net state.", + "state": "done" + }, + { + "type": "text", + "text": "I'll help you with this prepared-fixture exercise. Let me start by activating the SDCPN modelling skill and then retrieving the current state of the Petrinaut net to understand what we're working with.", + "state": "done" + }, + { + "type": "dynamic-tool", + "toolName": "activate_skill", + "toolCallId": "toolu_01WQaZveys8joHtboYvGQiuA", + "state": "output-available", + "input": { + "name": "sdcpn-modelling" + }, + "output": "Run the skill named \"sdcpn-modelling\".\n\n\n# Capability-aware lifecycle\n\nUse one conceptual lifecycle: orient, elicit or revise, maintain the workpiece, construct when supported, check, and deliver. The current conversation may expose only one branch of that lifecycle. Do not claim that an unavailable transition occurred.\n\n## Select the runtime branch\n\n### Interactive elicitation or revision\n\nInterview in the person's operational vocabulary. Activate the `elicitation` skill and read `references/profile.md` before substantive questions or revision. Read `templates/workpiece.md` when creating or materially revising the shared workpiece. Construct only when the mounted capabilities actually permit construction in this conversation.\n\n### Construct-only execution\n\nUse the supplied workpiece as the complete modelling input. Do not interview. Read `references/pn-construction.md` and `references/checks.md`, then use the mounted construction tools. If a consequential workpiece gap prevents faithful construction, report the gap and the smallest question a later interactive elicitation must answer; do not ask it or invent an answer in this conversation.\n\n## Procedure\n\n### Orient\n\nEstablish enough purpose and context to select one focused next action: the intended question or decision, audience, boundary, horizon, accuracy need, and available time. Orientation need not settle every concern before elicitation begins.\n\n### Elicit or revise\n\nFor a new account, follow one concrete case and re-evaluate the active gap after each useful answer. For an existing account, first locate the disputed or changed material and its consequence for the objective. Use the `elicitation` skill's universal guidance and `references/profile.md` for detailed operations and coverage; do not turn their register order into question order.\n\n### Maintain the workpiece\n\nTreat the workpiece as the recoverable account construction will consume. Update it after a useful stretch rather than waiting until the end. Preserve unrelated material unless new evidence affects it.\n\nWhenever the workpiece changes substantially, emit the full current document in a fenced block whose language tag is exactly `runbook-ir`. Emit it again before construction and before workpiece-only delivery. A delta or prose promise is not a recoverable workpiece.\n\n### Construct\n\nConstruct only from the current workpiece. Read `references/pn-construction.md` and `references/checks.md` before beginning. Use mounted Petrinaut tools for every net change and inspect the resulting definition rather than emitting free-form net JSON. If the required tools are absent, limit the result to the workpiece and construction-ready notes.\n\nConstruction may infer a representation from recorded operational meaning; it may not invent operational facts. Record construction inferences, approximations, defaults, and target losses in the workpiece.\n\n### Check and deliver\n\nApply `references/checks.md` whenever construction is prepared or attempted. Deliver the current workpiece in every branch. Deliver a net only when the mounted tool path has produced and checked one. State what the result can support, what remains open, what was assumed or simplified, and what the target or current tools could not represent.\n\nAn explicit stop opens no new topic. In an interactive conversation, emit the best current workpiece and any already-checked net with limitations visible. In construct-only execution, report a blocking gap rather than opening an interview.\n\n## Resource discipline\n\nRead resources directly from this skill's advertised resource list, using the exact `/.flue/packaged-skills/...` path shown in the activation briefing; the relative name is a label only. Do not treat Markdown links as includes, follow references recursively, or read construction material merely to frame ordinary interview questions.\n\n\nSupporting skill resources are available but are not loaded into context unless needed:\n\n- references/checks.md → read_skill_resource /.flue/packaged-skills/skill%3Asdcpn-modelling%3A99a447ec4bcbf6c0/references/checks.md\n- references/pn-construction.md → read_skill_resource /.flue/packaged-skills/skill%3Asdcpn-modelling%3A99a447ec4bcbf6c0/references/pn-construction.md\n- references/profile.md → read_skill_resource /.flue/packaged-skills/skill%3Asdcpn-modelling%3A99a447ec4bcbf6c0/references/profile.md\n- templates/workpiece.md → read_skill_resource /.flue/packaged-skills/skill%3Asdcpn-modelling%3A99a447ec4bcbf6c0/templates/workpiece.md\n", + "durationMs": 3 + }, + { + "type": "dynamic-tool", + "toolName": "getLatestNetDefinition", + "toolCallId": "toolu_01FjSrPHir7RNkmV1PUpZ1qu", + "state": "output-available", + "input": {}, + "output": { + "awaiting": "client" + }, + "durationMs": 3 + }, + { + "type": "reasoning", + "text": "The skill is activated. The net definition call shows `{\"awaiting\":\"client\"}` which means the browser needs to fetch it. Let me wait a moment for that result to come through via the client-tool-result signal, or I should ask the user about the current state. \n\nActually, I should ping first to confirm the server is in the loop, then proceed to understand what we have.", + "state": "done" + }, + { + "type": "text", + "text": "Let me confirm the server connection and then retrieve the current net definition:", + "state": "done" + }, + { + "type": "dynamic-tool", + "toolName": "ping", + "toolCallId": "toolu_01NpMVdLYpu7PeSDCfJqjwqA", + "state": "output-available", + "input": { + "note": "Confirming server ready for crew-reservation-v1 prepared-fixture work" + }, + "output": { + "ok": true, + "note": "Confirming server ready for crew-reservation-v1 prepared-fixture work" + }, + "durationMs": 1 + }, + { + "type": "reasoning", + "text": "Good, the server is ready. Now I should wait for the net definition from the browser. The getLatestNetDefinition returned `{\"awaiting\":\"client\"}` which means it's waiting for a client tool result. I should describe what I'm going to do next and wait for that result.", + "state": "done" + }, + { + "type": "text", + "text": "Good. Now let me work with the prepared-fixture material you've provided. \n\n## Understanding the prepared fixture\n\nYou've provided a **test-authored diagnostic workpiece** focused on the **final inspection → dispatch path** with one specific correction to test:\n\n**Operational account:**\n- A batch ready for dispatch enters final inspection\n- Starting final inspection *reserves* the single available dispatch crew\n- Sign-off *releases* that crew and marks the batch ready for dispatch\n\n**Current net state:**\n- Contains the batch path and the crew return from sign-off\n- **Deliberately omits** the weight-1 input arc from \"Dispatch crew available\" to \"Start final inspection\" \n\n**Purpose:** Test one evidence-backed correction against the live Petrinaut document.\n\n---\n\n## Next step\n\nThe Petrinaut net definition is being retrieved. Once I see the current structure, I can:\n\n1. **Verify** the operational account against what's in the net\n2. **Identify** the missing arc precisely \n3. **Test the correction** by adding that arc and confirming it satisfies the resource constraint (exactly one crew consumed at start, returned at sign-off)\n\nI'm waiting for the live net definition to come through. What I'll be looking for:\n- The places representing the batch states (ready, in-inspection, ready-for-dispatch)\n- The places for crew availability\n- The transitions for \"Start final inspection\" and \"Sign-off\"\n- Which arcs are already present and which are missing\n\nDoes this match your intention for this exercise?", + "state": "done" + } + ] + } + ], + "settlements": [ + { + "submissionId": "sub_ik_f24939bebb841ffe1469a7f3a4a06915", + "outcome": "completed", + "answeredBySubmissionId": "sub_ik_f24939bebb841ffe1469a7f3a4a06915" + } + ], + "incarnation": "inc_01M1NQEXM24JHNYN40Q8RA5DH5" +} diff --git a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/flue-snapshot-tab-b.json b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/flue-snapshot-tab-b.json new file mode 100644 index 00000000000..4cb95e7516d --- /dev/null +++ b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/flue-snapshot-tab-b.json @@ -0,0 +1,360 @@ +{ + "v": 1, + "conversationId": "conv_01M1NQEXM3CAPPTXM33ZE1YSRG", + "offset": "0000000000000000_0000000000000123", + "messages": [ + { + "id": "entry_direct_c3ViX2lrX2YyNDkzOWJlYmI4NDFmZmUxNDY5YTdmM2E0YTA2OTE1", + "role": "system", + "purpose": "dispatch", + "display": "diagnostic", + "submissionId": "sub_ik_f24939bebb841ffe1469a7f3a4a06915", + "signal": { + "tagName": "prepared-fixture", + "attributes": { + "fixtureId": "crew-reservation-v1", + "authorship": "test-authored", + "claimBoundary": "prepared-not-model-produced" + } + }, + "parts": [ + { + "type": "text", + "text": "Fixture authorship: test-authored preparation for Mission 6.\nNon-claims: not a Mission 4 candidate, not model-produced evidence, not capture-backed provenance, and not proof of automatic full-net projection.\n\n```runbook-ir\n# Final inspection and dispatch workpiece\n\n## Purpose and posture\nMaintain the narrow batch path from final inspection to dispatch readiness and test one evidence-backed correction against the live Petrinaut document.\n\n## Operational account\n- A batch that is ready enters final inspection.\n- Final inspection reserves the sole available dispatch crew.\n- Sign-off releases that crew and makes the batch ready for dispatch.\n\n## Quantity and resource policy\nExactly one dispatch crew is available in this fixture. Starting final inspection consumes that one available crew; sign-off returns it.\n\n## Current Petrinaut correspondence\nThe prepared non-empty net contains the batch path and the crew return from sign-off. It deliberately lacks the standard weight-1 input arc from `Dispatch crew available` to `Start final inspection`.\n\n## Explicit unknowns\nInspection and sign-off timing, failure modes, and recovery behavior remain unresolved.\n\n## Claim boundary\nThis prepared revision is test-authored diagnostic material. It is not model-produced evidence and does not establish capture provenance, behavioral execution, or broad projection quality.\n```", + "state": "done" + } + ] + }, + { + "id": "entry_01M1NQEYF9W60J2JVDYB2BJXK1", + "role": "assistant", + "purpose": "assistant", + "display": "visible", + "submissionId": "sub_ik_f24939bebb841ffe1469a7f3a4a06915", + "turnId": "turn_01M1NQEXM7MHJ94PF52Q54VAY4", + "parts": [ + { + "type": "reasoning", + "text": "The user has provided a prepared-fixture for SDCPN modelling work. This is test-authored material that is:\n- Part of a Mission 6 exercise\n- Focused on a narrow batch path from final inspection to dispatch readiness\n- Aimed at testing one evidence-backed correction against the live Petrinaut document\n- Not model-produced evidence, not a capture-backed provenance, not proof of automatic full-net projection\n\nThe operational account describes:\n1. A batch that is ready enters final inspection\n2. Final inspection reserves the sole available dispatch crew\n3. Sign-off releases that crew and makes the batch ready for dispatch\n\nThe key policy: Exactly one dispatch crew is available. Starting final inspection consumes it; sign-off returns it.\n\nThe current state: The prepared non-empty net contains the batch path and the crew return from sign-off, but deliberately LACKS the standard weight-1 input arc from \"Dispatch crew available\" to \"Start final inspection\".\n\nThe purpose is to test one evidence-backed correction against the live Petrinaut document.\n\nMy role here is:\n1. First, activate the sdcpn-modelling skill since this is a process-modelling task\n2. Understand the current state of the Petrinaut net\n3. Help verify the operational account against the net\n4. Work with the user to identify and potentially implement the missing arc correction\n5. Maintain the workpiece with clear documentation of what is known, what is missing, and what has been tested\n\nLet me start by activating the skill and getting the current net state.", + "state": "done" + }, + { + "type": "text", + "text": "I'll help you with this prepared-fixture exercise. Let me start by activating the SDCPN modelling skill and then retrieving the current state of the Petrinaut net to understand what we're working with.", + "state": "done" + }, + { + "type": "dynamic-tool", + "toolName": "activate_skill", + "toolCallId": "toolu_01WQaZveys8joHtboYvGQiuA", + "state": "output-available", + "input": { + "name": "sdcpn-modelling" + }, + "output": "Run the skill named \"sdcpn-modelling\".\n\n\n# Capability-aware lifecycle\n\nUse one conceptual lifecycle: orient, elicit or revise, maintain the workpiece, construct when supported, check, and deliver. The current conversation may expose only one branch of that lifecycle. Do not claim that an unavailable transition occurred.\n\n## Select the runtime branch\n\n### Interactive elicitation or revision\n\nInterview in the person's operational vocabulary. Activate the `elicitation` skill and read `references/profile.md` before substantive questions or revision. Read `templates/workpiece.md` when creating or materially revising the shared workpiece. Construct only when the mounted capabilities actually permit construction in this conversation.\n\n### Construct-only execution\n\nUse the supplied workpiece as the complete modelling input. Do not interview. Read `references/pn-construction.md` and `references/checks.md`, then use the mounted construction tools. If a consequential workpiece gap prevents faithful construction, report the gap and the smallest question a later interactive elicitation must answer; do not ask it or invent an answer in this conversation.\n\n## Procedure\n\n### Orient\n\nEstablish enough purpose and context to select one focused next action: the intended question or decision, audience, boundary, horizon, accuracy need, and available time. Orientation need not settle every concern before elicitation begins.\n\n### Elicit or revise\n\nFor a new account, follow one concrete case and re-evaluate the active gap after each useful answer. For an existing account, first locate the disputed or changed material and its consequence for the objective. Use the `elicitation` skill's universal guidance and `references/profile.md` for detailed operations and coverage; do not turn their register order into question order.\n\n### Maintain the workpiece\n\nTreat the workpiece as the recoverable account construction will consume. Update it after a useful stretch rather than waiting until the end. Preserve unrelated material unless new evidence affects it.\n\nWhenever the workpiece changes substantially, emit the full current document in a fenced block whose language tag is exactly `runbook-ir`. Emit it again before construction and before workpiece-only delivery. A delta or prose promise is not a recoverable workpiece.\n\n### Construct\n\nConstruct only from the current workpiece. Read `references/pn-construction.md` and `references/checks.md` before beginning. Use mounted Petrinaut tools for every net change and inspect the resulting definition rather than emitting free-form net JSON. If the required tools are absent, limit the result to the workpiece and construction-ready notes.\n\nConstruction may infer a representation from recorded operational meaning; it may not invent operational facts. Record construction inferences, approximations, defaults, and target losses in the workpiece.\n\n### Check and deliver\n\nApply `references/checks.md` whenever construction is prepared or attempted. Deliver the current workpiece in every branch. Deliver a net only when the mounted tool path has produced and checked one. State what the result can support, what remains open, what was assumed or simplified, and what the target or current tools could not represent.\n\nAn explicit stop opens no new topic. In an interactive conversation, emit the best current workpiece and any already-checked net with limitations visible. In construct-only execution, report a blocking gap rather than opening an interview.\n\n## Resource discipline\n\nRead resources directly from this skill's advertised resource list, using the exact `/.flue/packaged-skills/...` path shown in the activation briefing; the relative name is a label only. Do not treat Markdown links as includes, follow references recursively, or read construction material merely to frame ordinary interview questions.\n\n\nSupporting skill resources are available but are not loaded into context unless needed:\n\n- references/checks.md → read_skill_resource /.flue/packaged-skills/skill%3Asdcpn-modelling%3A99a447ec4bcbf6c0/references/checks.md\n- references/pn-construction.md → read_skill_resource /.flue/packaged-skills/skill%3Asdcpn-modelling%3A99a447ec4bcbf6c0/references/pn-construction.md\n- references/profile.md → read_skill_resource /.flue/packaged-skills/skill%3Asdcpn-modelling%3A99a447ec4bcbf6c0/references/profile.md\n- templates/workpiece.md → read_skill_resource /.flue/packaged-skills/skill%3Asdcpn-modelling%3A99a447ec4bcbf6c0/templates/workpiece.md\n", + "durationMs": 3 + }, + { + "type": "dynamic-tool", + "toolName": "getLatestNetDefinition", + "toolCallId": "toolu_01FjSrPHir7RNkmV1PUpZ1qu", + "state": "output-available", + "input": {}, + "output": { + "awaiting": "client" + }, + "durationMs": 3 + }, + { + "type": "reasoning", + "text": "The skill is activated. The net definition call shows `{\"awaiting\":\"client\"}` which means the browser needs to fetch it. Let me wait a moment for that result to come through via the client-tool-result signal, or I should ask the user about the current state. \n\nActually, I should ping first to confirm the server is in the loop, then proceed to understand what we have.", + "state": "done" + }, + { + "type": "text", + "text": "Let me confirm the server connection and then retrieve the current net definition:", + "state": "done" + }, + { + "type": "dynamic-tool", + "toolName": "ping", + "toolCallId": "toolu_01NpMVdLYpu7PeSDCfJqjwqA", + "state": "output-available", + "input": { + "note": "Confirming server ready for crew-reservation-v1 prepared-fixture work" + }, + "output": { + "ok": true, + "note": "Confirming server ready for crew-reservation-v1 prepared-fixture work" + }, + "durationMs": 1 + }, + { + "type": "reasoning", + "text": "Good, the server is ready. Now I should wait for the net definition from the browser. The getLatestNetDefinition returned `{\"awaiting\":\"client\"}` which means it's waiting for a client tool result. I should describe what I'm going to do next and wait for that result.", + "state": "done" + }, + { + "type": "text", + "text": "Good. Now let me work with the prepared-fixture material you've provided. \n\n## Understanding the prepared fixture\n\nYou've provided a **test-authored diagnostic workpiece** focused on the **final inspection → dispatch path** with one specific correction to test:\n\n**Operational account:**\n- A batch ready for dispatch enters final inspection\n- Starting final inspection *reserves* the single available dispatch crew\n- Sign-off *releases* that crew and marks the batch ready for dispatch\n\n**Current net state:**\n- Contains the batch path and the crew return from sign-off\n- **Deliberately omits** the weight-1 input arc from \"Dispatch crew available\" to \"Start final inspection\" \n\n**Purpose:** Test one evidence-backed correction against the live Petrinaut document.\n\n---\n\n## Next step\n\nThe Petrinaut net definition is being retrieved. Once I see the current structure, I can:\n\n1. **Verify** the operational account against what's in the net\n2. **Identify** the missing arc precisely \n3. **Test the correction** by adding that arc and confirming it satisfies the resource constraint (exactly one crew consumed at start, returned at sign-off)\n\nI'm waiting for the live net definition to come through. What I'll be looking for:\n- The places representing the batch states (ready, in-inspection, ready-for-dispatch)\n- The places for crew availability\n- The transitions for \"Start final inspection\" and \"Sign-off\"\n- Which arcs are already present and which are missing\n\nDoes this match your intention for this exercise?", + "state": "done" + } + ] + }, + { + "id": "entry_direct_c3ViX2lrX2I3YTI3NGI3YzI4MjVkNGMwOTE0ZGE0NDBlMjQxY2I2", + "role": "user", + "purpose": "user", + "display": "visible", + "submissionId": "sub_ik_b7a274b7c2825d4c0914da440e241cb6", + "parts": [ + { + "type": "text", + "text": "Confirmed: final inspection uses the single dispatch crew and sign-off releases it; timing, failure, and recovery remain unknown. Read the live Petrinaut definition, add the missing standard weight-1 input arc from Dispatch crew available to Start final inspection, verify it, and emit the full revised runbook-ir workpiece.", + "state": "done" + } + ] + }, + { + "id": "entry_01M1NQGAVZ00RTNPHG4MM610XE", + "role": "assistant", + "purpose": "assistant", + "display": "visible", + "submissionId": "sub_ik_b7a274b7c2825d4c0914da440e241cb6", + "turnId": "turn_01M1NQGA4WJ01NC2MS1JJB0QWJ", + "parts": [ + { + "type": "reasoning", + "text": "The user has confirmed the operational intent and is asking me to:\n1. Read the live Petrinaut definition\n2. Add the missing standard weight-1 input arc from \"Dispatch crew available\" to \"Start final inspection\"\n3. Verify it\n4. Emit the full revised runbook-ir workpiece\n\nI need to call getLatestNetDefinition again to get the actual net definition since the previous call returned {\"awaiting\":\"client\"}.", + "state": "done" + }, + { + "type": "dynamic-tool", + "toolName": "getLatestNetDefinition", + "toolCallId": "toolu_01BqoDEZeq7HTqu3S8p6ZLA6", + "state": "output-available", + "input": {}, + "output": { + "awaiting": "client" + }, + "durationMs": 0 + } + ] + }, + { + "id": "entry_direct_c3ViX2lrX2RkMmViN2JlMjE5ODA5OThiODlhZTlhOWRhMDg1ZmIy", + "role": "system", + "purpose": "dispatch", + "display": "diagnostic", + "submissionId": "sub_ik_dd2eb7be21980998b89ae9a9da085fb2", + "signal": { + "tagName": "client-tool-result", + "attributes": { + "toolCallIds": "toolu_01BqoDEZeq7HTqu3S8p6ZLA6" + } + }, + "parts": [ + { + "type": "text", + "text": "[{\"toolCallId\":\"toolu_01BqoDEZeq7HTqu3S8p6ZLA6\",\"toolName\":\"getLatestNetDefinition\",\"output\":{\"title\":\"Prepared final inspection and dispatch\",\"definition\":{\"places\":[{\"id\":\"batch-ready\",\"name\":\"Batch ready\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":80,\"y\":100},{\"id\":\"under-final-inspection\",\"name\":\"Under final inspection\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":420,\"y\":100},{\"id\":\"ready-for-dispatch\",\"name\":\"Ready for dispatch\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":760,\"y\":100},{\"id\":\"dispatch-crew-available\",\"name\":\"Dispatch crew available\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":420,\"y\":360}],\"transitions\":[{\"id\":\"start-final-inspection\",\"name\":\"Start final inspection\",\"inputArcs\":[{\"placeId\":\"batch-ready\",\"weight\":1,\"type\":\"standard\"}],\"outputArcs\":[{\"placeId\":\"under-final-inspection\",\"weight\":1}],\"lambdaType\":\"predicate\",\"lambdaCode\":\"\",\"transitionKernelCode\":\"\",\"x\":250,\"y\":100},{\"id\":\"sign-off\",\"name\":\"Sign-off\",\"inputArcs\":[{\"placeId\":\"under-final-inspection\",\"weight\":1,\"type\":\"standard\"}],\"outputArcs\":[{\"placeId\":\"ready-for-dispatch\",\"weight\":1},{\"placeId\":\"dispatch-crew-available\",\"weight\":1}],\"lambdaType\":\"predicate\",\"lambdaCode\":\"\",\"transitionKernelCode\":\"\",\"x\":590,\"y\":100}],\"types\":[],\"differentialEquations\":[],\"parameters\":[]},\"extensions\":{\"colors\":true,\"stochasticity\":true,\"dynamics\":true,\"parameters\":true,\"subnets\":true}}}]", + "state": "done" + } + ] + }, + { + "id": "entry_01M1NQGD1NRR36CBAX78EA666J", + "role": "assistant", + "purpose": "assistant", + "display": "visible", + "submissionId": "sub_ik_dd2eb7be21980998b89ae9a9da085fb2", + "turnId": "turn_01M1NQGC2ZFFFC5MFXN2949H93", + "parts": [ + { + "type": "reasoning", + "text": "Good! Now I have the live Petrinaut definition. Let me analyze it:\n\n**Current places:**\n1. `batch-ready` - batch waiting to enter inspection\n2. `under-final-inspection` - batch in inspection\n3. `ready-for-dispatch` - batch ready for dispatch (output state)\n4. `dispatch-crew-available` - represents availability of the single dispatch crew\n\n**Current transitions:**\n1. `start-final-inspection` - takes 1 batch from `batch-ready`, outputs 1 to `under-final-inspection`\n - Input arcs: `batch-ready` (weight 1, standard)\n - Output arcs: `under-final-inspection` (weight 1)\n\n2. `sign-off` - takes 1 batch from `under-final-inspection`, outputs 1 to `ready-for-dispatch` AND 1 to `dispatch-crew-available`\n - Input arcs: `under-final-inspection` (weight 1, standard)\n - Output arcs: `ready-for-dispatch` (weight 1), `dispatch-crew-available` (weight 1)\n\n**What's missing:**\nThe `start-final-inspection` transition is missing an input arc from `dispatch-crew-available`. When a batch starts final inspection, it should consume one crew token.\n\nAccording to the prepared fixture, this should be:\n- Arc direction: **input**\n- Source place: `dispatch-crew-available`\n- Weight: 1\n- Type: standard\n\nSo I need to add an input arc to `start-final-inspection` with:\n- placeId: `dispatch-crew-available`\n- weight: 1\n- type: `standard`\n\nLet me use the `addArc` function to add this arc.", + "state": "done" + }, + { + "type": "text", + "text": "Perfect. I can see the live net structure. Let me analyze it:\n\n**Current structure:**\n- **Places:** Batch-ready → Under-final-inspection → Ready-for-dispatch, plus Dispatch-crew-available\n- **start-final-inspection transition:** Currently has only one input arc (from batch-ready)\n- **sign-off transition:** Takes batch from inspection and outputs both the batch (to ready-for-dispatch) AND returns 1 crew token to dispatch-crew-available\n\n**Missing element:** The `start-final-inspection` transition lacks the input arc from `dispatch-crew-available`. This means the model currently allows inspection to begin without consuming the crew resource—violating the \"exactly one crew reserved\" constraint.\n\nNow I'll add the missing standard weight-1 input arc from `dispatch-crew-available` to `start-final-inspection`:", + "state": "done" + }, + { + "type": "dynamic-tool", + "toolName": "addArc", + "toolCallId": "toolu_01KLHzRE7gbPbFfPaXe3RTry", + "state": "output-available", + "input": { + "transitionId": "start-final-inspection", + "arcDirection": "input", + "placeId": "dispatch-crew-available", + "weight": "1", + "type": "standard" + }, + "output": { + "awaiting": "client" + }, + "durationMs": 0 + } + ] + }, + { + "id": "entry_direct_c3ViX2lrXzAwOGZhNmQ3MzU0NzQ5YTFjYjNmNjc0MTg0ZTdjYjFi", + "role": "system", + "purpose": "dispatch", + "display": "diagnostic", + "submissionId": "sub_ik_008fa6d7354749a1cb3f674184e7cb1b", + "signal": { + "tagName": "client-tool-result", + "attributes": { + "toolCallIds": "toolu_01BqoDEZeq7HTqu3S8p6ZLA6,toolu_01KLHzRE7gbPbFfPaXe3RTry" + } + }, + "parts": [ + { + "type": "text", + "text": "[{\"toolCallId\":\"toolu_01BqoDEZeq7HTqu3S8p6ZLA6\",\"toolName\":\"getLatestNetDefinition\",\"output\":{\"title\":\"Prepared final inspection and dispatch\",\"definition\":{\"places\":[{\"id\":\"batch-ready\",\"name\":\"Batch ready\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":80,\"y\":100},{\"id\":\"under-final-inspection\",\"name\":\"Under final inspection\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":420,\"y\":100},{\"id\":\"ready-for-dispatch\",\"name\":\"Ready for dispatch\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":760,\"y\":100},{\"id\":\"dispatch-crew-available\",\"name\":\"Dispatch crew available\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":420,\"y\":360}],\"transitions\":[{\"id\":\"start-final-inspection\",\"name\":\"Start final inspection\",\"inputArcs\":[{\"placeId\":\"batch-ready\",\"weight\":1,\"type\":\"standard\"}],\"outputArcs\":[{\"placeId\":\"under-final-inspection\",\"weight\":1}],\"lambdaType\":\"predicate\",\"lambdaCode\":\"\",\"transitionKernelCode\":\"\",\"x\":250,\"y\":100},{\"id\":\"sign-off\",\"name\":\"Sign-off\",\"inputArcs\":[{\"placeId\":\"under-final-inspection\",\"weight\":1,\"type\":\"standard\"}],\"outputArcs\":[{\"placeId\":\"ready-for-dispatch\",\"weight\":1},{\"placeId\":\"dispatch-crew-available\",\"weight\":1}],\"lambdaType\":\"predicate\",\"lambdaCode\":\"\",\"transitionKernelCode\":\"\",\"x\":590,\"y\":100}],\"types\":[],\"differentialEquations\":[],\"parameters\":[]},\"extensions\":{\"colors\":true,\"stochasticity\":true,\"dynamics\":true,\"parameters\":true,\"subnets\":true}}},{\"toolCallId\":\"toolu_01KLHzRE7gbPbFfPaXe3RTry\",\"toolName\":\"addArc\",\"output\":{\"title\":\"Added input arc\",\"detail\":\"Dispatch crew available <-> Start final inspection\",\"target\":{\"kind\":\"selection\",\"item\":{\"type\":\"arc\",\"id\":\"$A_place:dispatch-crew-available___start-final-inspection\"}},\"applied\":true}}]", + "state": "done" + } + ] + }, + { + "id": "entry_01M1NQGMV82KXETG8X23QZHPM3", + "role": "assistant", + "purpose": "assistant", + "display": "visible", + "submissionId": "sub_ik_008fa6d7354749a1cb3f674184e7cb1b", + "turnId": "turn_01M1NQGKXT0H69NP5JFRYQJ2J7", + "parts": [ + { + "type": "reasoning", + "text": "Good! The arc has been added successfully. Let me verify by checking the live definition again to confirm the arc is now present in the start-final-inspection transition.\n\nLooking at the addArc output, it says \"Applied: true\" and created an arc with ID \"$A_place:dispatch-crew-available___start-final-inspection\". This is the confirmation.\n\nHowever, I notice that the getLatestNetDefinition result that came back still shows the old structure—the start-final-inspection transition still shows only one inputArc (from batch-ready). This might be a timing issue in how the results came back, or the definition might not have refreshed yet.\n\nLet me read the live definition one more time to verify the arc was actually applied and is visible in the current state.", + "state": "done" + }, + { + "type": "text", + "text": "Excellent! The arc addition was successful: `\"applied\":true`. Let me verify the updated net definition:", + "state": "done" + }, + { + "type": "dynamic-tool", + "toolName": "getLatestNetDefinition", + "toolCallId": "toolu_01LuBH9HSYSzvkCMq5E3PN57", + "state": "output-available", + "input": {}, + "output": { + "awaiting": "client" + }, + "durationMs": 0 + } + ] + }, + { + "id": "entry_direct_c3ViX2lrXzZkYmMxODdlNGU3Mjc5M2I3NTM5YzAyMzg3ZDA0NzE1", + "role": "system", + "purpose": "dispatch", + "display": "diagnostic", + "submissionId": "sub_ik_6dbc187e4e72793b7539c02387d04715", + "signal": { + "tagName": "client-tool-result", + "attributes": { + "toolCallIds": "toolu_01BqoDEZeq7HTqu3S8p6ZLA6,toolu_01KLHzRE7gbPbFfPaXe3RTry,toolu_01LuBH9HSYSzvkCMq5E3PN57" + } + }, + "parts": [ + { + "type": "text", + "text": "[{\"toolCallId\":\"toolu_01BqoDEZeq7HTqu3S8p6ZLA6\",\"toolName\":\"getLatestNetDefinition\",\"output\":{\"title\":\"Prepared final inspection and dispatch\",\"definition\":{\"places\":[{\"id\":\"batch-ready\",\"name\":\"Batch ready\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":80,\"y\":100},{\"id\":\"under-final-inspection\",\"name\":\"Under final inspection\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":420,\"y\":100},{\"id\":\"ready-for-dispatch\",\"name\":\"Ready for dispatch\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":760,\"y\":100},{\"id\":\"dispatch-crew-available\",\"name\":\"Dispatch crew available\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":420,\"y\":360}],\"transitions\":[{\"id\":\"start-final-inspection\",\"name\":\"Start final inspection\",\"inputArcs\":[{\"placeId\":\"batch-ready\",\"weight\":1,\"type\":\"standard\"}],\"outputArcs\":[{\"placeId\":\"under-final-inspection\",\"weight\":1}],\"lambdaType\":\"predicate\",\"lambdaCode\":\"\",\"transitionKernelCode\":\"\",\"x\":250,\"y\":100},{\"id\":\"sign-off\",\"name\":\"Sign-off\",\"inputArcs\":[{\"placeId\":\"under-final-inspection\",\"weight\":1,\"type\":\"standard\"}],\"outputArcs\":[{\"placeId\":\"ready-for-dispatch\",\"weight\":1},{\"placeId\":\"dispatch-crew-available\",\"weight\":1}],\"lambdaType\":\"predicate\",\"lambdaCode\":\"\",\"transitionKernelCode\":\"\",\"x\":590,\"y\":100}],\"types\":[],\"differentialEquations\":[],\"parameters\":[]},\"extensions\":{\"colors\":true,\"stochasticity\":true,\"dynamics\":true,\"parameters\":true,\"subnets\":true}}},{\"toolCallId\":\"toolu_01KLHzRE7gbPbFfPaXe3RTry\",\"toolName\":\"addArc\",\"output\":{\"title\":\"Added input arc\",\"detail\":\"Dispatch crew available <-> Start final inspection\",\"target\":{\"kind\":\"selection\",\"item\":{\"type\":\"arc\",\"id\":\"$A_place:dispatch-crew-available___start-final-inspection\"}},\"applied\":true}},{\"toolCallId\":\"toolu_01LuBH9HSYSzvkCMq5E3PN57\",\"toolName\":\"getLatestNetDefinition\",\"output\":{\"title\":\"Prepared final inspection and dispatch\",\"definition\":{\"places\":[{\"id\":\"batch-ready\",\"name\":\"Batch ready\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":80,\"y\":100},{\"id\":\"under-final-inspection\",\"name\":\"Under final inspection\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":420,\"y\":100},{\"id\":\"ready-for-dispatch\",\"name\":\"Ready for dispatch\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":760,\"y\":100},{\"id\":\"dispatch-crew-available\",\"name\":\"Dispatch crew available\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":420,\"y\":360}],\"transitions\":[{\"id\":\"start-final-inspection\",\"name\":\"Start final inspection\",\"inputArcs\":[{\"placeId\":\"batch-ready\",\"weight\":1,\"type\":\"standard\"},{\"type\":\"standard\",\"placeId\":\"dispatch-crew-available\",\"weight\":1}],\"outputArcs\":[{\"placeId\":\"under-final-inspection\",\"weight\":1}],\"lambdaType\":\"predicate\",\"lambdaCode\":\"\",\"transitionKernelCode\":\"\",\"x\":250,\"y\":100},{\"id\":\"sign-off\",\"name\":\"Sign-off\",\"inputArcs\":[{\"placeId\":\"under-final-inspection\",\"weight\":1,\"type\":\"standard\"}],\"outputArcs\":[{\"placeId\":\"ready-for-dispatch\",\"weight\":1},{\"placeId\":\"dispatch-crew-available\",\"weight\":1}],\"lambdaType\":\"predicate\",\"lambdaCode\":\"\",\"transitionKernelCode\":\"\",\"x\":590,\"y\":100}],\"types\":[],\"differentialEquations\":[],\"parameters\":[]},\"extensions\":{\"colors\":true,\"stochasticity\":true,\"dynamics\":true,\"parameters\":true,\"subnets\":true}}}]", + "state": "done" + } + ] + }, + { + "id": "entry_01M1NQGRAKWG69MWYMPYTCFXCZ", + "role": "assistant", + "purpose": "assistant", + "display": "visible", + "submissionId": "sub_ik_6dbc187e4e72793b7539c02387d04715", + "turnId": "turn_01M1NQGQH38A3MMGGEWKN4VCDP", + "parts": [ + { + "type": "reasoning", + "text": "Perfect! The verification confirms the arc has been successfully added. Looking at the final definition:\n\nThe `start-final-inspection` transition now has two input arcs:\n1. `{\"placeId\":\"batch-ready\",\"weight\":1,\"type\":\"standard\"}`\n2. `{\"type\":\"standard\",\"placeId\":\"dispatch-crew-available\",\"weight\":1}`\n\nThis means:\n- Starting final inspection requires 1 token from \"batch-ready\" AND 1 token from \"dispatch-crew-available\"\n- It produces 1 token to \"under-final-inspection\"\n- The sign-off transition consumes the batch from inspection and returns 1 crew token\n\nThis satisfies the operational constraint: exactly one dispatch crew is consumed when inspection begins and released when sign-off completes.\n\nNow I need to emit the full revised runbook-ir workpiece as requested. I should update the prepared fixture material with:\n1. The operational account (confirmed)\n2. The current Petrinaut correspondence (UPDATED - the missing arc has been added)\n3. Explicit unknowns (unchanged)\n4. The claim boundary (adjusted to reflect what this correction establishes)", + "state": "done" + }, + { + "type": "text", + "text": "**Verification successful.** The `start-final-inspection` transition now contains the corrected input arcs:\n```json\n\"inputArcs\":[\n {\"placeId\":\"batch-ready\",\"weight\":1,\"type\":\"standard\"},\n {\"type\":\"standard\",\"placeId\":\"dispatch-crew-available\",\"weight\":1}\n]\n```\n\nThe resource constraint is now satisfied: firing `start-final-inspection` requires both a ready batch AND an available crew token. The `sign-off` transition releases that crew back to `dispatch-crew-available`.\n\n---\n\n## Revised workpiece (runbook-ir)\n\n```runbook-ir\n# Final inspection and dispatch workpiece — Revised\n\n## Purpose and posture\nModel the batch path from final inspection to dispatch readiness with explicit crew resource management. This revision adds the missing crew-consumption arc to enforce the resource constraint.\n\n## Operational account\n- A batch that is ready enters final inspection.\n- Starting final inspection requires both a ready batch AND the sole available dispatch crew.\n- Starting final inspection consumes that crew token.\n- Sign-off releases that crew and makes the batch ready for dispatch.\n\n## Quantity and resource policy\nExactly one dispatch crew is available. Starting final inspection consumes that one available crew; sign-off returns it. No transition fires without sufficient tokens in all input places.\n\n## Petrinaut correspondence\nThe net contains four places:\n- `batch-ready`: batches awaiting final inspection\n- `under-final-inspection`: batches currently in inspection\n- `ready-for-dispatch`: batches cleared for dispatch\n- `dispatch-crew-available`: crew availability (1 token when free)\n\nTransitions:\n- `start-final-inspection`: requires 1 token from batch-ready AND 1 token from dispatch-crew-available; produces 1 token to under-final-inspection\n- `sign-off`: requires 1 token from under-final-inspection; produces 1 token to ready-for-dispatch AND 1 token to dispatch-crew-available\n\nThe missing standard weight-1 input arc from `dispatch-crew-available` to `start-final-inspection` has been **added and verified** in the live Petrinaut definition.\n\n## Explicit unknowns\n- Inspection timing: duration, stochasticity, or determinism remain unresolved\n- Sign-off timing: duration, stochasticity, or determinism remain unresolved\n- Failure modes: whether inspection can fail, halt, or reject a batch\n- Recovery behavior: how failures or rejections affect batch state or crew availability\n\n## Claim boundary\nThis workpiece and the corrected net establish only:\n- The crew-consumption constraint at start of inspection\n- The crew-release at sign-off completion\n- Token flow from ready batch through inspection to dispatch readiness\n\nThis is test-authored diagnostic material for the narrow final-inspection–to-dispatch path. It does not establish capture provenance, behavioral execution, failure handling, full process projection, or integration with upstream or downstream operations.\n```\n\nThe correction is complete and verified in the live Petrinaut definition.", + "state": "done" + } + ] + }, + { + "id": "entry_direct_c3ViX2lrXzg4NDFkMzZmMWUyZTRiYTlmMzk4NTJiZTU0ZDJlMTc0", + "role": "user", + "purpose": "user", + "display": "visible", + "submissionId": "sub_ik_8841d36f1e2e4ba9f39852be54d2e174", + "parts": [ + { + "type": "text", + "text": "From the resumed workpiece, list the unresolved timing, failure, and recovery questions. Do not change the Petrinaut net.", + "state": "done" + } + ] + }, + { + "id": "entry_01M1NQJG7GRPC479PRF826T6F3", + "role": "assistant", + "purpose": "assistant", + "display": "visible", + "submissionId": "sub_ik_8841d36f1e2e4ba9f39852be54d2e174", + "turnId": "turn_01M1NQJFBBXYRZE472GFGHQF4K", + "parts": [ + { + "type": "reasoning", + "text": "The user wants me to extract and list the unresolved questions from the \"Explicit unknowns\" and \"Claim boundary\" sections of the workpiece I just delivered. They explicitly don't want me to change the Petrinaut net, just to articulate the open questions.\n\nLet me pull out the specific questions that remain unresolved:\n\nFrom \"Explicit unknowns\":\n1. Inspection timing: duration, stochasticity, or determinism remain unresolved\n2. Sign-off timing: duration, stochasticity, or determinism remain unresolved\n3. Failure modes: whether inspection can fail, halt, or reject a batch\n4. Recovery behavior: how failures or rejections affect batch state or crew availability\n\nI should unpack these into concrete questions that would need answering in a real operational investigation.", + "state": "done" + }, + { + "type": "text", + "text": "## Unresolved questions from the workpiece\n\n### Inspection timing\n1. How long does final inspection take—is it a fixed duration or variable?\n2. If variable, what distribution describes inspection duration (exponential, log-normal, empirical)?\n3. Does inspection timing depend on batch characteristics (size, composition, prior history)?\n4. Is inspection deterministic or does it include randomness?\n\n### Sign-off timing\n1. How long does sign-off take after inspection completes—is it immediate, fixed, or variable?\n2. If variable, what distribution describes sign-off duration?\n3. Does sign-off timing depend on inspection outcome or batch properties?\n4. Is sign-off deterministic or does it include randomness?\n\n### Failure modes\n1. Can a batch fail final inspection? If so, what triggers failure?\n2. Can inspection halt or pause without completing (e.g., awaiting additional information)?\n3. Can a batch be rejected at sign-off after passing inspection?\n4. Can the crew become unavailable during inspection (unavoidable absence, equipment failure, reassignment)?\n\n### Recovery behavior\n1. If a batch fails inspection, where does it go—back to ready, to a separate rework queue, or discarded?\n2. If a batch fails, does the crew become available immediately or does recovery consume crew time?\n3. If inspection halts mid-process, does the crew remain locked or become available?\n4. If rejected at sign-off, does the batch cycle back through inspection or follow a different path?\n5. If the crew becomes unavailable mid-inspection, what happens to the batch and the crew state?\n\nThese questions determine whether timing needs stochastic transitions, whether the batch path branches on failure, and how crew availability and batch state interact under exceptions. The current net cannot represent any of these behaviors.", + "state": "done" + } + ] + } + ], + "settlements": [ + { + "submissionId": "sub_ik_f24939bebb841ffe1469a7f3a4a06915", + "outcome": "completed", + "answeredBySubmissionId": "sub_ik_f24939bebb841ffe1469a7f3a4a06915" + }, + { + "submissionId": "sub_ik_b7a274b7c2825d4c0914da440e241cb6", + "outcome": "completed", + "answeredBySubmissionId": "sub_ik_b7a274b7c2825d4c0914da440e241cb6" + }, + { + "submissionId": "sub_ik_dd2eb7be21980998b89ae9a9da085fb2", + "outcome": "completed", + "answeredBySubmissionId": "sub_ik_dd2eb7be21980998b89ae9a9da085fb2" + }, + { + "submissionId": "sub_ik_008fa6d7354749a1cb3f674184e7cb1b", + "outcome": "completed", + "answeredBySubmissionId": "sub_ik_008fa6d7354749a1cb3f674184e7cb1b" + }, + { + "submissionId": "sub_ik_6dbc187e4e72793b7539c02387d04715", + "outcome": "completed", + "answeredBySubmissionId": "sub_ik_6dbc187e4e72793b7539c02387d04715" + }, + { + "submissionId": "sub_ik_8841d36f1e2e4ba9f39852be54d2e174", + "outcome": "completed", + "answeredBySubmissionId": "sub_ik_8841d36f1e2e4ba9f39852be54d2e174" + } + ], + "incarnation": "inc_01M1NQEXM24JHNYN40Q8RA5DH5" +} diff --git a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/latest-workpiece.md b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/latest-workpiece.md new file mode 100644 index 00000000000..596a87eb77c --- /dev/null +++ b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/latest-workpiece.md @@ -0,0 +1,41 @@ +# Final inspection and dispatch workpiece — Revised + +## Purpose and posture +Model the batch path from final inspection to dispatch readiness with explicit crew resource management. This revision adds the missing crew-consumption arc to enforce the resource constraint. + +## Operational account +- A batch that is ready enters final inspection. +- Starting final inspection requires both a ready batch AND the sole available dispatch crew. +- Starting final inspection consumes that crew token. +- Sign-off releases that crew and makes the batch ready for dispatch. + +## Quantity and resource policy +Exactly one dispatch crew is available. Starting final inspection consumes that one available crew; sign-off returns it. No transition fires without sufficient tokens in all input places. + +## Petrinaut correspondence +The net contains four places: +- `batch-ready`: batches awaiting final inspection +- `under-final-inspection`: batches currently in inspection +- `ready-for-dispatch`: batches cleared for dispatch +- `dispatch-crew-available`: crew availability (1 token when free) + +Transitions: +- `start-final-inspection`: requires 1 token from batch-ready AND 1 token from dispatch-crew-available; produces 1 token to under-final-inspection +- `sign-off`: requires 1 token from under-final-inspection; produces 1 token to ready-for-dispatch AND 1 token to dispatch-crew-available + +The missing standard weight-1 input arc from `dispatch-crew-available` to `start-final-inspection` has been **added and verified** in the live Petrinaut definition. + +## Explicit unknowns +- Inspection timing: duration, stochasticity, or determinism remain unresolved +- Sign-off timing: duration, stochasticity, or determinism remain unresolved +- Failure modes: whether inspection can fail, halt, or reject a batch +- Recovery behavior: how failures or rejections affect batch state or crew availability + +## Claim boundary +This workpiece and the corrected net establish only: +- The crew-consumption constraint at start of inspection +- The crew-release at sign-off completion +- Token flow from ready batch through inspection to dispatch readiness + +This is test-authored diagnostic material for the narrow final-inspection–to-dispatch path. It does not establish capture provenance, behavioral execution, failure handling, full process projection, or integration with upstream or downstream operations. + diff --git a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/prepared-workpiece.md b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/prepared-workpiece.md new file mode 100644 index 00000000000..9e99beae10e --- /dev/null +++ b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/prepared-workpiece.md @@ -0,0 +1,22 @@ +# Final inspection and dispatch workpiece + +## Purpose and posture +Maintain the narrow batch path from final inspection to dispatch readiness and test one evidence-backed correction against the live Petrinaut document. + +## Operational account +- A batch that is ready enters final inspection. +- Final inspection reserves the sole available dispatch crew. +- Sign-off releases that crew and makes the batch ready for dispatch. + +## Quantity and resource policy +Exactly one dispatch crew is available in this fixture. Starting final inspection consumes that one available crew; sign-off returns it. + +## Current Petrinaut correspondence +The prepared non-empty net contains the batch path and the crew return from sign-off. It deliberately lacks the standard weight-1 input arc from `Dispatch crew available` to `Start final inspection`. + +## Explicit unknowns +Inspection and sign-off timing, failure modes, and recovery behavior remain unresolved. + +## Claim boundary +This prepared revision is test-authored diagnostic material. It is not model-produced evidence and does not establish capture provenance, behavioral execution, or broad projection quality. + diff --git a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/route-evidence.json b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/route-evidence.json new file mode 100644 index 00000000000..da12d3d008a --- /dev/null +++ b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/route-evidence.json @@ -0,0 +1,7 @@ +{ + "origin": "http://127.0.0.1:4915", + "historyRoute": "/agents/chat/?view=history", + "status": 200, + "retainedAuthorizationHeaders": false, + "retainedProviderPayloads": false +} diff --git a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/screenshot-tab-a-after.png b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/screenshot-tab-a-after.png new file mode 100644 index 0000000000000000000000000000000000000000..0f42bfeaebf28d6cb26c8b26d5946534853c76b0 GIT binary patch literal 142872 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�aI_jA~Xm^Bd>#SmHNjp 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 AAOHXW literal 0 HcmV?d00001 diff --git a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/screenshot-tab-a-before.png b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/screenshot-tab-a-before.png new file mode 100644 index 0000000000000000000000000000000000000000..142e160b12bfd58af0790f4c4a93f16852b1493b GIT binary patch literal 71412 zcmd43bySsG_%%v*cXxx7G)R|7gMf%22nvW2BHhxRBA^l?snP<{A&nr?BHe;?N_@}O zbI$ks?zsQmaqqZeFo1L1y!+j2Ju#m-=XxV_wbk%(XmF5_knpdoE9)a6p~J5zgIFl= zL!MCs83~C9>AJFlp~uUOSD1InRDO4GHXvOO81z>2+G?OI)F4JyiRVy3&*lD%krPDr zHauW|S`TflVT?&Zk&}&RNL@$$f>50Cx7=1@uer

EEmzrOc<`668>{ri{9-mfoG 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
XfO>c>ly9m$X&#AH%)SaB% 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 E1Muu|SO5S3 literal 0 HcmV?d00001 diff --git a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/screenshot-tab-b-after.png b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/screenshot-tab-b-after.png new file mode 100644 index 0000000000000000000000000000000000000000..5527acbca57f235f725ae6ec2162b5a83105f26b GIT binary patch literal 153210 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�BP{S(m+9zTh58ogF`uv?S&;yoDP@FZ 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 T6ivYIAZe)RDpxDoMEw5%mJ=)g literal 0 HcmV?d00001 diff --git a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/settled-manifest-after.json b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/settled-manifest-after.json new file mode 100644 index 00000000000..cd937a8620a --- /dev/null +++ b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/settled-manifest-after.json @@ -0,0 +1,25 @@ +{ + "version": 1, + "fixtureId": "crew-reservation-v1", + "revision": 1, + "settledAt": "2026-09-04T08:10:58.162Z", + "conversation": { + "logicalId": "mission-6-crew-reservation-conversation-v1", + "canonicalId": "conv_01M1NQEXM3CAPPTXM33ZE1YSRG", + "offset": "0000000000000000_0000000000000108" + }, + "latestWorkpiece": { + "authorship": "model-produced", + "contentSha256": "785135be03f8cbe9156b835f34d463bf7111fc109dd90dbe9db55955670c050e", + "sourceKind": "assistant", + "sourceMessageId": "entry_01M1NQGRAKWG69MWYMPYTCFXCZ", + "sourceMessageSha256": "5c5645d0f63c9792ece099228cbc021e117853108a1501c0cc230334eb2a6af8", + "sourceSubmissionId": "sub_ik_6dbc187e4e72793b7539c02387d04715" + }, + "document": { + "id": "mission-6-crew-reservation-document-v1", + "sha256": "3c47961d02296c00131644d1aea0dac16a017f470a66aea919fcf324a2bc9e37", + "targetArc": "present" + }, + "manifestId": "a00f05964afc87b1ef34b50c96711232ac44c5b60eb6e8ce60a540af3b5dab49" +} diff --git a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/settled-manifest-before.json b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/settled-manifest-before.json new file mode 100644 index 00000000000..48e8013a09f --- /dev/null +++ b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/settled-manifest-before.json @@ -0,0 +1,25 @@ +{ + "version": 1, + "fixtureId": "crew-reservation-v1", + "revision": 0, + "settledAt": "2026-09-04T08:10:01.220Z", + "conversation": { + "logicalId": "mission-6-crew-reservation-conversation-v1", + "canonicalId": "conv_01M1NQEXM3CAPPTXM33ZE1YSRG", + "offset": "0000000000000000_0000000000000043" + }, + "latestWorkpiece": { + "authorship": "test-authored", + "contentSha256": "1cc7a1b5d961f9f6327b458cf8292703ced5627fe26ee3f7b878f6375e51501a", + "sourceKind": "prepared-signal", + "sourceMessageId": "entry_direct_c3ViX2lrX2YyNDkzOWJlYmI4NDFmZmUxNDY5YTdmM2E0YTA2OTE1", + "sourceMessageSha256": "05003ea859f0658266d92b24eeaca0103aa75d2c4a3ec4eddaffe606b6775fc6", + "sourceSubmissionId": "sub_ik_f24939bebb841ffe1469a7f3a4a06915" + }, + "document": { + "id": "mission-6-crew-reservation-document-v1", + "sha256": "8dfa723b8dabadad790d2552de8e191e4227b07fe6c4d4e9d8e2d365e6ec4abd", + "targetArc": "absent" + }, + "manifestId": "fef5b371de498d5c2e6bb0456878c21aeb05a0f68957cde4a859f194b5122fab" +} diff --git a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/settled-manifest-tab-b.json b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/settled-manifest-tab-b.json new file mode 100644 index 00000000000..cd937a8620a --- /dev/null +++ b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/settled-manifest-tab-b.json @@ -0,0 +1,25 @@ +{ + "version": 1, + "fixtureId": "crew-reservation-v1", + "revision": 1, + "settledAt": "2026-09-04T08:10:58.162Z", + "conversation": { + "logicalId": "mission-6-crew-reservation-conversation-v1", + "canonicalId": "conv_01M1NQEXM3CAPPTXM33ZE1YSRG", + "offset": "0000000000000000_0000000000000108" + }, + "latestWorkpiece": { + "authorship": "model-produced", + "contentSha256": "785135be03f8cbe9156b835f34d463bf7111fc109dd90dbe9db55955670c050e", + "sourceKind": "assistant", + "sourceMessageId": "entry_01M1NQGRAKWG69MWYMPYTCFXCZ", + "sourceMessageSha256": "5c5645d0f63c9792ece099228cbc021e117853108a1501c0cc230334eb2a6af8", + "sourceSubmissionId": "sub_ik_6dbc187e4e72793b7539c02387d04715" + }, + "document": { + "id": "mission-6-crew-reservation-document-v1", + "sha256": "3c47961d02296c00131644d1aea0dac16a017f470a66aea919fcf324a2bc9e37", + "targetArc": "present" + }, + "manifestId": "a00f05964afc87b1ef34b50c96711232ac44c5b60eb6e8ce60a540af3b5dab49" +} diff --git a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/tab-b-correlation.json b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/tab-b-correlation.json new file mode 100644 index 00000000000..d5c02471672 --- /dev/null +++ b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/tab-b-correlation.json @@ -0,0 +1,18 @@ +{ + "conversationId": "conv_01M1NQEXM3CAPPTXM33ZE1YSRG", + "offset": "0000000000000000_0000000000000123", + "manifestId": "a00f05964afc87b1ef34b50c96711232ac44c5b60eb6e8ce60a540af3b5dab49", + "documentSha256": "3c47961d02296c00131644d1aea0dac16a017f470a66aea919fcf324a2bc9e37", + "workpieceSha256": "785135be03f8cbe9156b835f34d463bf7111fc109dd90dbe9db55955670c050e", + "preparedSourceCount": 1, + "addArcCallCount": 1, + "followUp": { + "submissionId": "sub_ik_8841d36f1e2e4ba9f39852be54d2e174", + "responseMessageId": "entry_01M1NQJG7GRPC479PRF826T6F3", + "settlement": { + "submissionId": "sub_ik_8841d36f1e2e4ba9f39852be54d2e174", + "outcome": "completed", + "answeredBySubmissionId": "sub_ik_8841d36f1e2e4ba9f39852be54d2e174" + } + } +} diff --git a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/witness.md b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/witness.md new file mode 100644 index 00000000000..87c7d8d2fc5 --- /dev/null +++ b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/witness.md @@ -0,0 +1,90 @@ +# FE-1575 outer browser witness — 2026-09-04 + +## Scope + +This is the retained outer mechanical witness for Mission 6 at commit +`ace2968`. It used a clean browser principal in one Playwright context, the +stable `crew-reservation-v1` fixture route, the local Brunch Flue mount, and a +real configured provider credential. Credentials, authorization headers, the +browser principal, the Flue instance route component, and provider request +payloads are not retained. + +The provider serialized the `addArc` weight as `"1"`. The witnessed build +normalized that finite numeric string at the Petrinaut tool boundary before +canonical validation and browser execution. The retained raw Flue snapshot +preserves the provider-supplied input; the resulting Petrinaut definition +preserves the canonical numeric weight `1`. + +## Protocol and result + +1. Started `yarn dev:brunch` after loading `.env.local` without printing it. +2. Cleared browser local storage, opened + `http://127.0.0.1:4915/?brunch-fixture=crew-reservation-v1`, and waited for + settled revision zero. +3. Retained the before Flue snapshot, canonical definition, runtime manifest, + and Tab A screenshot. +4. Submitted one confirmation/construction turn: + + > Confirmed: final inspection uses the single dispatch crew and sign-off + > releases it; timing, failure, and recovery remain unknown. Read the live + > Petrinaut definition, add the missing standard weight-1 input arc from + > Dispatch crew available to Start final inspection, verify it, and emit + > the full revised runbook-ir workpiece. + +5. Observed one `addArc` call and one correlated successful client-tool result: + `toolu_01KLHzRE7gbPbFfPaXe3RTry`. +6. Verified that the only semantic definition delta was one standard, + weight-1 input arc from `dispatch-crew-available` to + `start-final-inspection`. +7. Observed runtime manifest revision 1 selecting the model-produced workpiece + and changed document, with target arc `present`. +8. Opened Tab B in the same browser context. It selected the same manifest, + workpiece hash, document hash, and canonical conversation, with exactly one + prepared source and one `addArc` call. +9. Submitted a non-mutating follow-up in Tab B: + + > From the resumed workpiece, list the unresolved timing, failure, and + > recovery questions. Do not change the Petrinaut net. + +10. Observed completed submission + `sub_ik_8841d36f1e2e4ba9f39852be54d2e174` and correlated response message + `entry_01M1NQJG7GRPC479PRF826T6F3`. The document and settled manifest were + unchanged. + +## Retained identities and invariants + +- Canonical conversation: `conv_01M1NQEXM3CAPPTXM33ZE1YSRG` +- Settled manifest revision: `1` +- Settled manifest ID: + `a00f05964afc87b1ef34b50c96711232ac44c5b60eb6e8ce60a540af3b5dab49` +- Prepared source count after Tab B: `1` +- `addArc` call count after Tab B: `1` +- Tab B follow-up outcome: `completed` +- `definition-after.json` and `definition-tab-b.json` have the same SHA-256. +- `settled-manifest-after.json` and `settled-manifest-tab-b.json` have the same + SHA-256. + +## Artifacts + +- Before state: [Flue](flue-snapshot-before.json), + [definition](definition-before.json), + [manifest](settled-manifest-before.json), + [screenshot](screenshot-tab-a-before.png) +- Settled Tab A state: [Flue](flue-snapshot-after.json), + [definition](definition-after.json), + [manifest](settled-manifest-after.json), + [call/result correlation](call-result-correlation.json), + [screenshot](screenshot-tab-a-after.png) +- Tab B continuation: [Flue](flue-snapshot-tab-b.json), + [definition](definition-tab-b.json), + [manifest](settled-manifest-tab-b.json), + [correlation](tab-b-correlation.json), + [screenshot](screenshot-tab-b-after.png) +- Semantic inputs: [prepared workpiece](prepared-workpiece.md), + [latest workpiece](latest-workpiece.md) +- Redacted route observation: [route evidence](route-evidence.json) +- Integrity: [SHA256SUMS](SHA256SUMS) + +This witness proves the bounded browser protocol above. It does not establish +capture provenance, timing behavior, failure/recovery behavior, simulation +validity, or broad automatic projection quality. diff --git a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-resumable-workpiece-petrinaut.md b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-resumable-workpiece-petrinaut.md index 145b4bc08cf..6b215ab5147 100644 --- a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-resumable-workpiece-petrinaut.md +++ b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-resumable-workpiece-petrinaut.md @@ -17,51 +17,51 @@ Focused tests cover: - rejected and duplicate/no-op canonical browser mutations; - exact prepared and revised document structure; - history, workpiece, mutation-result, and document mismatch refusal; and -- retention of the prior runtime manifest while partial state remains visible. +- content-addressed selection of the prior coherent document revision while a + partial mirrored value remains inspectable. The affected Brunch, transport, plugin, Petrinaut, and website builds, type -checks, and lint checks passed on 2026-09-03. The app-wide lint checks retain +checks, and lint checks passed on 2026-09-04. The app-wide lint checks retain pre-existing warning-only findings; no persona suite was run. -## Live browser attempt and blocker +## Live two-tab browser witness -The local `yarn dev:brunch` stack served the mounted agent at -`/agents/chat/:instanceId` and the Petrinaut fixture at: +The successful 2026-09-04 witness is retained in +[fe-1575-outer-browser-witness-2026-09-04](fe-1575-outer-browser-witness-2026-09-04/witness.md). +It used the local `yarn dev:brunch` stack, one clean Playwright browser +context, the mounted `/agents/chat/:instanceId` route, a real configured +provider credential, and the stable fixture URL: ```text http://127.0.0.1:4915/?brunch-fixture=crew-reservation-v1 ``` -The browser opened the non-empty prepared document and created canonical Flue -conversation `conv_01M1KZ1Z32SJ0800V94ZE59ENR`. Snapshot offset -`0000000000000000_0000000000000006` contained exactly one tagged -`prepared-fixture` dispatch record under submission -`sub_ik_b224f8e328e14cfa803c63d06376e5e9`, preserving the test-authored Markdown -body and claim-boundary attributes. - -That submission settled as `failed` because the configured Anthropic -credential returned HTTP 401 `authentication_error: invalid x-api-key`. -Consequently: - -- no model-behavior claim was made; -- no typed confirmation, client-tool mutation, or Tab B continuation was - attempted; -- the runtime settled manifest remained `null`; and -- the visible fixture status refused settlement as `history-unavailable` - instead of blessing the prepared document alone. - -This is an authentication/environment blocker on the outer witness, not -evidence that the selected provider-visible schema or Flue carrier cannot -faithfully carry the mutation. It is not a passing two-tab witness. No success -screenshot was retained. - -## Remaining external checks - -After a valid provider credential is supplied, rerun the demo script to retain -the successful before/after Flue snapshots, canonical definitions, runtime -manifest, call/result IDs, and Tab A/Tab B screenshots. Cold-reader semantic -adjudication and the product-manager demo remain separate human-harness checks; -they were not replaced with persona testing here. +The clean run created canonical conversation +`conv_01M1NQEXM3CAPPTXM33ZE1YSRG` and exactly one tagged prepared source. Tab A +advanced from settled revision zero with the target arc absent to revision 1 +with a model-produced workpiece and the target arc present. It retained one +`addArc` call and one correlated successful result, +`toolu_01KLHzRE7gbPbFfPaXe3RTry`. Mechanical comparison found exactly one +semantic document change: a standard weight-1 input arc from +`dispatch-crew-available` to `start-final-inspection`. + +Tab B reopened the same manifest, workpiece hash, document hash, and canonical +conversation. It submitted a non-mutating follow-up and received completed +correlated response `entry_01M1NQJG7GRPC479PRF826T6F3` without another prepared +source or `addArc` call. The post-Tab-A and Tab-B definitions and manifests +have identical hashes. + +The provider serialized the arc weight as `"1"`. The witnessed implementation +normalizes that finite numeric string before canonical server and browser +validation; the raw Flue snapshot retains the supplied representation while +the canonical Petrinaut definition contains numeric weight `1`. The earlier +HTTP 401 remains historical authentication/environment evidence only, not a +carrier/schema conclusion. + +## Remaining human checks + +Cold-reader semantic adjudication and the product-manager demo remain separate +human gates. They have not been replaced with persona or agent testing. ### Cold-reader handoff From 20ce3d9d70942d81af8dde720e84b096047f09f4 Mon Sep 17 00:00:00 2001 From: Lu Nelson Date: Fri, 4 Sep 2026 10:47:08 +0200 Subject: [PATCH 09/13] Simplify Mission 6 settlement coordination --- .../use-crew-reservation-settled-manifest.ts | 37 ++++++++----------- libs/@hashintel/brunch-agent/MISSION.md | 2 +- 2 files changed, 16 insertions(+), 23 deletions(-) diff --git a/apps/petrinaut-website/src/main/app/local-storage-demo/use-crew-reservation-settled-manifest.ts b/apps/petrinaut-website/src/main/app/local-storage-demo/use-crew-reservation-settled-manifest.ts index 003cca50400..510dd78d5f4 100644 --- a/apps/petrinaut-website/src/main/app/local-storage-demo/use-crew-reservation-settled-manifest.ts +++ b/apps/petrinaut-website/src/main/app/local-storage-demo/use-crew-reservation-settled-manifest.ts @@ -1,5 +1,5 @@ import { useLocalStorage } from "@mantine/hooks"; -import { useEffect, useRef, useState } from "react"; +import { useEffect, useState } from "react"; import { crewReservationSettledManifestStorageKey, @@ -69,17 +69,8 @@ export const useCrewReservationSettlement = (input: { } = input; const [observedStatus, setObservedStatus] = useState({ state: "preparing" }); - const manifestRef = useRef(settledManifest); - const observationIdRef = useRef(0); - const queueRef = useRef(Promise.resolve()); useEffect(() => { - manifestRef.current = settledManifest; - }, [settledManifest]); - - useEffect(() => { - const observationId = observationIdRef.current + 1; - observationIdRef.current = observationId; if ( !enabled || historyError !== undefined || @@ -89,22 +80,19 @@ export const useCrewReservationSettlement = (input: { return; } + let cancelled = false; const definitionSnapshot = structuredClone(definition); - const historySnapshot = history; - queueRef.current = queueRef.current.then(async () => { - if (observationId !== observationIdRef.current) return; + const settle = async (): Promise => { let result: CrewReservationSettlementResult; try { result = await settleCrewReservationManifest({ definition: definitionSnapshot, - history: historySnapshot, - ...(manifestRef.current === null - ? {} - : { previous: manifestRef.current }), + history, + ...(settledManifest === null ? {} : { previous: settledManifest }), settledAt: new Date().toISOString(), }); } catch (error) { - if (observationId === observationIdRef.current) { + if (!cancelled) { setObservedStatus({ state: "refused", reason: "settlement-failed", @@ -116,7 +104,7 @@ export const useCrewReservationSettlement = (input: { } return; } - if (observationId !== observationIdRef.current) return; + if (cancelled) return; if (result.status === "refused") { setObservedStatus({ state: "refused", @@ -128,12 +116,16 @@ export const useCrewReservationSettlement = (input: { result.manifest.document.sha256, definitionSnapshot, ); - if (result.manifest.manifestId !== manifestRef.current?.manifestId) { - manifestRef.current = result.manifest; + if (result.manifest.manifestId !== settledManifest?.manifestId) { setSettledManifest(result.manifest); } setObservedStatus({ state: "settled" }); - }); + }; + void settle(); + + return () => { + cancelled = true; + }; }, [ definition, enabled, @@ -141,6 +133,7 @@ export const useCrewReservationSettlement = (input: { historyError, persistCoherentSnapshot, setSettledManifest, + settledManifest, ]); const status: CrewReservationSettlementStatus = !enabled diff --git a/libs/@hashintel/brunch-agent/MISSION.md b/libs/@hashintel/brunch-agent/MISSION.md index dff113ecec3..4ceaa2f6e88 100644 --- a/libs/@hashintel/brunch-agent/MISSION.md +++ b/libs/@hashintel/brunch-agent/MISSION.md @@ -2,7 +2,7 @@ ## Status -**Live on `ln/fe-1575-resumable-workpiece-petrinaut` from 2026-09-03.** [FE-1575](https://linear.app/hash/issue/FE-1575/resume-one-brunch-workpiece-and-petrinaut-document-across-tabs) is in progress. This authority cut is committed separately before product or evaluation implementation begins. It was recut on restack the same day to carry the product-manager litmus adopted in [`MISSION.next.md`](MISSION.next.md#current-authority-and-accepted-spine) after the first cut: completion is the readiness gate below, not the first green two-tab pass. The owner subsequently accepted the probe-backed prepared-history semantics under [Accepted fixture and boundary crossings](#accepted-fixture-and-boundary-crossings), then corrected this mission to consume Mission 5's one-route browser Flue transport, automatic localStorage persistence, a runtime settled manifest, visible preparation language, and an actual Tab B continuation. Each authority amendment lands separately before dependent implementation. +**Live on `ln/fe-1575-resumable-workpiece-petrinaut`.** [FE-1575](https://linear.app/hash/issue/FE-1575/resume-one-brunch-workpiece-and-petrinaut-document-across-tabs) remains in progress. The implementation and outer mechanical witness are complete; cold-reader semantic adjudication and the product-manager demo remain the final acceptance gates. See the [retained implementation and witness evidence](docs/evidence/implementations/fe-1575-resumable-workpiece-petrinaut.md). ## Imperative From f7c92a79b08882272061fca904199af66165d995 Mon Sep 17 00:00:00 2001 From: Lu Nelson Date: Fri, 4 Sep 2026 10:48:18 +0200 Subject: [PATCH 10/13] Normalize Mission 6 witness workpiece files --- .../fe-1575-outer-browser-witness-2026-09-04/SHA256SUMS | 4 ++-- .../latest-workpiece.md | 1 - .../prepared-workpiece.md | 1 - 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/SHA256SUMS b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/SHA256SUMS index f44908b86b0..1d9c9bd912c 100644 --- a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/SHA256SUMS +++ b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/SHA256SUMS @@ -7,8 +7,8 @@ c17ae80cc22939f0af6c2675f6bcc20b025b17a5b7bfb9e8029813bcef9ad736 definition-tab 4fe368ef206e71e63173c1876ac9ca54e8b0d0971066be74dae5f78d4b612b0a flue-snapshot-after.json ea20487150d8a329f4c2a6e0ac32e22de39d0d655646581ad2c56768a3591d1a flue-snapshot-before.json 7aaa993b395bc4ac84625fb2f472645ba13428bc39faac1f0f4ba948bfb3d9f5 flue-snapshot-tab-b.json -0f04053f623e488c522a3cca06bf34593004379dab0f0e551b26a355d87b1049 latest-workpiece.md -2859b2c9c756dd67589df04cdae498f63affffe0d65ca7f9ec6971b81eabfe94 prepared-workpiece.md +a384aa803085d3ff350a347e18080503a78305f87eb5d91eec1ad1141b941eb3 latest-workpiece.md +17f99f53f8cf93285a7344f5e9687d94e5f59011e6895ce11a9722fde2e77511 prepared-workpiece.md cfb79c8f52fc8f1758b1a61f67e520c67a31d2f19f561017899d0724b776100a route-evidence.json a9bd4a4a18f52ebd5c0f0e9c7c5d80b1c37e85823bfa6a03bd9c1d329b4b4267 screenshot-tab-a-after.png eaf49081a6ab7acba746f337fdb85e3829d473818dc7c96f83a40acd3cb6f383 screenshot-tab-a-before.png diff --git a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/latest-workpiece.md b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/latest-workpiece.md index 596a87eb77c..be2a95f9fc4 100644 --- a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/latest-workpiece.md +++ b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/latest-workpiece.md @@ -38,4 +38,3 @@ This workpiece and the corrected net establish only: - Token flow from ready batch through inspection to dispatch readiness This is test-authored diagnostic material for the narrow final-inspection–to-dispatch path. It does not establish capture provenance, behavioral execution, failure handling, full process projection, or integration with upstream or downstream operations. - diff --git a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/prepared-workpiece.md b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/prepared-workpiece.md index 9e99beae10e..fa01def8c11 100644 --- a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/prepared-workpiece.md +++ b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04/prepared-workpiece.md @@ -19,4 +19,3 @@ Inspection and sign-off timing, failure modes, and recovery behavior remain unre ## Claim boundary This prepared revision is test-authored diagnostic material. It is not model-produced evidence and does not establish capture provenance, behavioral execution, or broad projection quality. - From 23b625bb37e8b80619cd75bfa0b5e13d7857680a Mon Sep 17 00:00:00 2001 From: Lu Nelson Date: Fri, 4 Sep 2026 10:55:15 +0200 Subject: [PATCH 11/13] Validate Mission 6 coherent bundle inputs --- .changeset/resumable-petrinaut-workpiece.md | 1 + apps/petrinaut-website/package.json | 1 + .../crew-reservation-settled-manifest.ts | 31 ++-- .../resolve-crew-reservation-bundle.test.ts | 149 +++++++++++------- .../resolve-crew-reservation-bundle.ts | 48 +++++- .../packages/plugin-sdcpn/src/flue.ts | 2 +- libs/@hashintel/petrinaut-core/src/ai.test.ts | 8 +- libs/@hashintel/petrinaut-core/src/ai.ts | 8 - yarn.lock | 1 + 9 files changed, 154 insertions(+), 95 deletions(-) diff --git a/.changeset/resumable-petrinaut-workpiece.md b/.changeset/resumable-petrinaut-workpiece.md index 40e8ffd20ae..4387d484672 100644 --- a/.changeset/resumable-petrinaut-workpiece.md +++ b/.changeset/resumable-petrinaut-workpiece.md @@ -1,5 +1,6 @@ --- "@hashintel/petrinaut": patch +"@hashintel/petrinaut-core": patch --- Report duplicate AI mutations as no-ops so hosts can distinguish an applied document change from diff --git a/apps/petrinaut-website/package.json b/apps/petrinaut-website/package.json index 37df3a79f40..8603d255e9f 100644 --- a/apps/petrinaut-website/package.json +++ b/apps/petrinaut-website/package.json @@ -27,6 +27,7 @@ "@hashintel/petrinaut-core": "workspace:*", "@local/petrinaut-optimizer-client": "workspace:*", "@mantine/hooks": "8.3.5", + "@noble/hashes": "2.0.1", "@pandacss/dev": "1.11.1", "@sentry/react": "10.64.0", "@tanstack/react-router": "1.170.31", diff --git a/apps/petrinaut-website/src/main/app/local-storage-demo/crew-reservation-settled-manifest.ts b/apps/petrinaut-website/src/main/app/local-storage-demo/crew-reservation-settled-manifest.ts index d94d5111314..b157dfef5a5 100644 --- a/apps/petrinaut-website/src/main/app/local-storage-demo/crew-reservation-settled-manifest.ts +++ b/apps/petrinaut-website/src/main/app/local-storage-demo/crew-reservation-settled-manifest.ts @@ -1,3 +1,6 @@ +import { sha256 as sha256Bytes } from "@noble/hashes/sha2.js"; +import { bytesToHex } from "@noble/hashes/utils.js"; + import { clientToolHistoryFrom } from "@hashintel/brunch-agent-transport-aisdk"; import { selectRunbookWorkpiece } from "@hashintel/brunch-agent/workpiece"; import { isSDCPNEqual, type SDCPN } from "@hashintel/petrinaut-core"; @@ -130,17 +133,8 @@ const hasOneCorrelatedTargetMutation = ( return correlatedTargetCallIds.size === 1; }; -const sha256 = async (value: string): Promise => { - const digest = await globalThis.crypto.subtle.digest( - "SHA-256", - new TextEncoder().encode(value), - ); - return asSha256Digest( - [...new Uint8Array(digest)] - .map((byte) => byte.toString(16).padStart(2, "0")) - .join(""), - ); -}; +export const sha256Digest = (value: string): Sha256Digest => + asSha256Digest(bytesToHex(sha256Bytes(new TextEncoder().encode(value)))); export const hasCrewReservationTargetArc = (definition: SDCPN): boolean => { const transition = definition.transitions.find( @@ -214,14 +208,13 @@ export const settleCrewReservationManifest = async (input: { }; } - const [contentSha256, documentSha256, sourceMessageSha256] = - await Promise.all([ - sha256(workpiece.content), - sha256(JSON.stringify(input.definition)), - sha256(JSON.stringify(workpiece.sourceMessage)), - ]); + const contentSha256 = sha256Digest(workpiece.content); + const documentSha256 = sha256Digest(JSON.stringify(input.definition)); + const sourceMessageSha256 = sha256Digest( + JSON.stringify(workpiece.sourceMessage), + ); if (workpiece.authorship === "test-authored") { - const preparedDocumentSha256 = await sha256( + const preparedDocumentSha256 = sha256Digest( JSON.stringify(preparedCrewReservationNet), ); if ( @@ -276,7 +269,7 @@ export const settleCrewReservationManifest = async (input: { status: "settled", manifest: { ...withoutId, - manifestId: asManifestId(await sha256(JSON.stringify(withoutId))), + manifestId: asManifestId(sha256Digest(JSON.stringify(withoutId))), }, }; }; diff --git a/apps/petrinaut-website/src/main/app/local-storage-demo/resolve-crew-reservation-bundle.test.ts b/apps/petrinaut-website/src/main/app/local-storage-demo/resolve-crew-reservation-bundle.test.ts index 169ad433863..7da06ba9129 100644 --- a/apps/petrinaut-website/src/main/app/local-storage-demo/resolve-crew-reservation-bundle.test.ts +++ b/apps/petrinaut-website/src/main/app/local-storage-demo/resolve-crew-reservation-bundle.test.ts @@ -1,6 +1,7 @@ import { describe, expect, test } from "vitest"; import { + latestRunbookIrBlock, preparedWorkpieceAuthorship, preparedWorkpieceClaimBoundary, preparedWorkpieceSignalTag, @@ -12,7 +13,7 @@ import { asFlueMessageId, asFlueSubmissionId, asManifestId, - asSha256Digest, + sha256Digest, type CrewReservationSettledManifest, } from "./crew-reservation-settled-manifest"; import { @@ -27,8 +28,30 @@ import { workpieceForCrewReservationBundle, } from "./resolve-crew-reservation-bundle"; +import type { CrewReservationHistory } from "./crew-reservation-history"; import type { SDCPNInLocalStorage } from "./use-local-storage-sdcpns"; +const preparedMessage = { + id: "prepared-message", + role: "system", + purpose: "dispatch", + submissionId: "prepare-submission", + signal: { + tagName: preparedWorkpieceSignalTag, + attributes: { + fixtureId: crewReservationFixtureId, + authorship: preparedWorkpieceAuthorship, + claimBoundary: preparedWorkpieceClaimBoundary, + }, + }, + parts: [{ type: "text", text: preparedCrewReservationWorkpiece }], +} as const; + +const preparedContent = latestRunbookIrBlock(preparedCrewReservationWorkpiece); +if (preparedContent === undefined) { + throw new Error("The prepared fixture has no runbook-ir workpiece."); +} + const manifest: CrewReservationSettledManifest = { version: 1, fixtureId: crewReservationFixtureId, @@ -42,16 +65,16 @@ const manifest: CrewReservationSettledManifest = { }, document: { id: crewReservationDocumentId, - sha256: asSha256Digest("coherent-hash"), + sha256: sha256Digest(JSON.stringify(preparedCrewReservationNet)), targetArc: "absent", }, latestWorkpiece: { authorship: "test-authored", - contentSha256: asSha256Digest("content"), + contentSha256: sha256Digest(preparedContent), sourceKind: "prepared-signal", - sourceMessageId: asFlueMessageId("prepared-message"), - sourceMessageSha256: asSha256Digest("message"), - sourceSubmissionId: asFlueSubmissionId("prepare-submission"), + sourceMessageId: asFlueMessageId(preparedMessage.id), + sourceMessageSha256: sha256Digest(JSON.stringify(preparedMessage)), + sourceSubmissionId: asFlueSubmissionId(preparedMessage.submissionId), }, }; @@ -62,8 +85,28 @@ const fallbackDocument: SDCPNInLocalStorage = { lastUpdated: "1970-01-01T00:00:00.000Z", }; +const history: CrewReservationHistory = { + conversationId: "canonical", + offset: "3", + settlements: [], + messages: [ + preparedMessage, + { + id: "newer-message", + role: "assistant", + purpose: "assistant", + parts: [ + { + type: "text", + text: "```runbook-ir\n# Unsettled newer workpiece\n```", + }, + ], + }, + ], +}; + describe("resolveCrewReservationBundle", () => { - test("selects the content-addressed coherent document over a partial mirror", () => { + test("selects a coherent document whose content matches the manifest digest", () => { const partialDefinition = structuredClone(preparedCrewReservationNet); const firstPlace = partialDefinition.places.at(0); if (firstPlace === undefined) { @@ -78,7 +121,7 @@ describe("resolveCrewReservationBundle", () => { ...fallbackDocument, sdcpn: partialDefinition, coherentSnapshots: { - "coherent-hash": preparedCrewReservationNet, + [manifest.document.sha256]: preparedCrewReservationNet, }, }, }); @@ -88,62 +131,62 @@ describe("resolveCrewReservationBundle", () => { preparedCrewReservationNet, ); expect(selection.selectedDocument.sdcpn).not.toEqual(partialDefinition); - expect(selection.observedDocument.sdcpn).toEqual(partialDefinition); }); - test("keeps a missing snapshot diagnosable without inventing a revision", () => { + test("refuses a snapshot stored under a digest that its content does not match", () => { + const corruptedSnapshot = structuredClone(preparedCrewReservationNet); + const firstPlace = corruptedSnapshot.places.at(0); + if (firstPlace === undefined) { + throw new Error("The prepared fixture has no places."); + } + firstPlace.name = "Corrupted snapshot"; + const selection = resolveCrewReservationBundle({ fallbackDocument, manifest, - storedDocument: fallbackDocument, + storedDocument: { + ...fallbackDocument, + coherentSnapshots: { + [manifest.document.sha256]: corruptedSnapshot, + }, + }, }); - expect(selection).toEqual({ - observedDocument: fallbackDocument, + expect(selection.snapshotMissing).toBe(true); + expect(selection.selectedDocument.sdcpn).toEqual(fallbackDocument.sdcpn); + expect(selection.selectedDocument.sdcpn).not.toEqual(corruptedSnapshot); + }); + + test("keeps a missing snapshot diagnosable without inventing a revision", () => { + expect( + resolveCrewReservationBundle({ + fallbackDocument, + manifest, + storedDocument: fallbackDocument, + }), + ).toEqual({ selectedDocument: fallbackDocument, snapshotMissing: true, }); }); }); -test("selects the workpiece source named by the settled manifest", () => { - const newerWorkpiece = "```runbook-ir\n# Unsettled newer workpiece\n```"; - expect( - workpieceForCrewReservationBundle( - { - conversationId: "canonical", - offset: "3", - settlements: [], - messages: [ - { - id: "prepared-message", - role: "system", - purpose: "dispatch", - submissionId: "prepare-submission", - signal: { - tagName: preparedWorkpieceSignalTag, - attributes: { - fixtureId: crewReservationFixtureId, - authorship: preparedWorkpieceAuthorship, - claimBoundary: preparedWorkpieceClaimBoundary, - }, - }, - parts: [ - { - type: "text", - text: preparedCrewReservationWorkpiece, - }, - ], - }, - { - id: "newer-message", - role: "assistant", - purpose: "assistant", - parts: [{ type: "text", text: newerWorkpiece }], - }, - ], - }, - manifest, - ), - ).toContain("# Final inspection and dispatch workpiece"); +describe("workpieceForCrewReservationBundle", () => { + test("selects the source whose content and record match the manifest hashes", () => { + expect(workpieceForCrewReservationBundle(history, manifest)).toContain( + "# Final inspection and dispatch workpiece", + ); + }); + + test("refuses a selected source whose manifest hash does not match", () => { + expect( + workpieceForCrewReservationBundle(history, { + ...manifest, + latestWorkpiece: { + ...manifest.latestWorkpiece, + sourceMessageSha256: sha256Digest("mismatched source"), + }, + }), + ).toBeUndefined(); + }); }); diff --git a/apps/petrinaut-website/src/main/app/local-storage-demo/resolve-crew-reservation-bundle.ts b/apps/petrinaut-website/src/main/app/local-storage-demo/resolve-crew-reservation-bundle.ts index 065568d3320..9a601aa517a 100644 --- a/apps/petrinaut-website/src/main/app/local-storage-demo/resolve-crew-reservation-bundle.ts +++ b/apps/petrinaut-website/src/main/app/local-storage-demo/resolve-crew-reservation-bundle.ts @@ -3,12 +3,15 @@ import { selectRunbookWorkpiece, } from "@hashintel/brunch-agent/workpiece"; +import { + sha256Digest, + type CrewReservationSettledManifest, +} from "./crew-reservation-settled-manifest"; + import type { CrewReservationHistory } from "./crew-reservation-history"; -import type { CrewReservationSettledManifest } from "./crew-reservation-settled-manifest"; import type { SDCPNInLocalStorage } from "./use-local-storage-sdcpns"; export interface CrewReservationBundleSelection { - readonly observedDocument: SDCPNInLocalStorage; readonly selectedDocument: SDCPNInLocalStorage; readonly snapshotMissing: boolean; } @@ -21,7 +24,6 @@ export const resolveCrewReservationBundle = (input: { const liveDocument = input.storedDocument ?? input.fallbackDocument; if (input.manifest === null) { return { - observedDocument: liveDocument, selectedDocument: liveDocument, snapshotMissing: false, }; @@ -29,16 +31,18 @@ export const resolveCrewReservationBundle = (input: { const coherentDefinition = liveDocument.coherentSnapshots?.[input.manifest.document.sha256]; - if (coherentDefinition === undefined) { + if ( + coherentDefinition === undefined || + sha256Digest(JSON.stringify(coherentDefinition)) !== + input.manifest.document.sha256 + ) { return { - observedDocument: liveDocument, selectedDocument: liveDocument, snapshotMissing: true, }; } return { - observedDocument: liveDocument, selectedDocument: { ...liveDocument, sdcpn: coherentDefinition, @@ -54,13 +58,41 @@ export const workpieceForCrewReservationBundle = ( if (history === undefined) return undefined; if (manifest === null) return selectRunbookWorkpiece(history)?.content; - const selectedMessage = history.messages.find( + const selectedMessageIndex = history.messages.findIndex( ({ id }) => id === manifest.latestWorkpiece.sourceMessageId, ); + if (selectedMessageIndex === -1) return undefined; + const selectedMessage = history.messages[selectedMessageIndex]; if (selectedMessage === undefined) return undefined; - return latestRunbookIrBlock( + + const content = latestRunbookIrBlock( selectedMessage.parts .flatMap((part) => (part.type === "text" ? [part.text] : [])) .join("\n"), ); + if ( + content === undefined || + sha256Digest(content) !== manifest.latestWorkpiece.contentSha256 || + sha256Digest(JSON.stringify(selectedMessage)) !== + manifest.latestWorkpiece.sourceMessageSha256 + ) { + return undefined; + } + + const selectedWorkpiece = selectRunbookWorkpiece({ + ...history, + messages: history.messages.slice(0, selectedMessageIndex + 1), + }); + if ( + selectedWorkpiece?.sourceMessageId !== + manifest.latestWorkpiece.sourceMessageId || + selectedWorkpiece.sourceSubmissionId !== + manifest.latestWorkpiece.sourceSubmissionId || + selectedWorkpiece.authorship !== manifest.latestWorkpiece.authorship || + selectedWorkpiece.sourceKind !== manifest.latestWorkpiece.sourceKind + ) { + return undefined; + } + + return content; }; diff --git a/libs/@hashintel/brunch-agent/packages/plugin-sdcpn/src/flue.ts b/libs/@hashintel/brunch-agent/packages/plugin-sdcpn/src/flue.ts index 6afa49c5ef0..06705585906 100644 --- a/libs/@hashintel/brunch-agent/packages/plugin-sdcpn/src/flue.ts +++ b/libs/@hashintel/brunch-agent/packages/plugin-sdcpn/src/flue.ts @@ -56,7 +56,7 @@ This is a construct-only headless conversation. Use only the supplied runbook IR } else if (initialData?.mode === validatedFixtureMutationMode) { useInstruction( ` -This is a visibly labelled prepared-fixture conversation. Treat its tagged prepared runbook-ir dispatch as test-authored revision zero, maintain the full Markdown workpiece in later responses, preserve explicit unknowns, and do not relabel prepared material as model-produced. Use only the mounted canonical Petrinaut read and least arc mutation when confirmed evidence calls for that change. Read the live document before mutating it, report rejected or no-op outcomes honestly, and do not construct unrelated net content. +This is a visibly labelled prepared-fixture conversation. Treat its tagged prepared runbook-ir dispatch as test-authored revision zero, maintain the full Markdown workpiece in later responses, preserve explicit unknowns, and do not relabel prepared material as model-produced. Every later assistant-authored workpiece is model-produced: label that revision accordingly and do not copy revision zero's claim that the current revision is test-authored. Use only the mounted canonical Petrinaut read and least arc mutation when confirmed evidence calls for that change. Read the live document before mutating it, report rejected or no-op outcomes honestly, and do not construct unrelated net content. `.replace(/^\s+|\s+$/gu, ""), ); for (const fixtureTool of petrinautFixtureTools) { diff --git a/libs/@hashintel/petrinaut-core/src/ai.test.ts b/libs/@hashintel/petrinaut-core/src/ai.test.ts index 124bed1dfb1..06f9ac185f0 100644 --- a/libs/@hashintel/petrinaut-core/src/ai.test.ts +++ b/libs/@hashintel/petrinaut-core/src/ai.test.ts @@ -47,19 +47,15 @@ describe("Petrinaut AI core exports", () => { expect(petrinautAiTools).toHaveProperty("applyAutoLayout"); }); - test("normalizes structured addArc values from text-oriented providers", () => { + test("normalizes an addArc weight serialized as text", () => { expect( normalizePetrinautAiToolInput("addArc", { transitionId: "transition", arcDirection: "input", weight: "1", type: "standard", - endpoint: '{"kind":"place","placeId":"place"}', }), - ).toMatchObject({ - weight: 1, - endpoint: { kind: "place", placeId: "place" }, - }); + ).toMatchObject({ weight: 1 }); }); test("latest net definition tool documents extension settings", () => { diff --git a/libs/@hashintel/petrinaut-core/src/ai.ts b/libs/@hashintel/petrinaut-core/src/ai.ts index 283046bde26..05778c0745c 100644 --- a/libs/@hashintel/petrinaut-core/src/ai.ts +++ b/libs/@hashintel/petrinaut-core/src/ai.ts @@ -228,14 +228,6 @@ export const normalizePetrinautAiToolInput = ( const weight = Number(normalized.weight); if (Number.isFinite(weight)) normalized = { ...normalized, weight }; } - if (typeof normalized.endpoint === "string") { - try { - const endpoint: unknown = JSON.parse(normalized.endpoint); - if (isRecord(endpoint)) normalized = { ...normalized, endpoint }; - } catch { - // Canonical validation reports the original malformed endpoint. - } - } return normalized; }; diff --git a/yarn.lock b/yarn.lock index 8d1c736db42..c50ba1aa15e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -933,6 +933,7 @@ __metadata: "@hashintel/petrinaut-core": "workspace:*" "@local/petrinaut-optimizer-client": "workspace:*" "@mantine/hooks": "npm:8.3.5" + "@noble/hashes": "npm:2.0.1" "@pandacss/dev": "npm:1.11.1" "@sentry/react": "npm:10.64.0" "@tanstack/react-router": "npm:1.170.31" From 92f0284c68606dcdfb2704a3a6b2376366aa24a9 Mon Sep 17 00:00:00 2001 From: Lu Nelson Date: Fri, 4 Sep 2026 11:19:03 +0200 Subject: [PATCH 12/13] Replace the Mission 6 outer witness with honest authorship evidence --- .../SHA256SUMS | 21 ++ .../call-result-correlation.json | 84 +++++ .../cold-reader-gate.md | 31 ++ .../cold-reader-records.json | 46 +++ .../definition-after.json | 98 ++++++ .../definition-before.json | 93 +++++ .../definition-tab-b.json | 98 ++++++ .../flue-snapshot-after.json | 287 +++++++++++++++ .../flue-snapshot-before.json | 89 +++++ .../flue-snapshot-tab-b.json | 326 ++++++++++++++++++ .../latest-workpiece.md | 45 +++ .../prepared-workpiece.md | 21 ++ .../route-evidence.json | 6 + .../run-metadata.json | 8 + .../screenshot-tab-a-after.png | Bin 0 -> 150019 bytes .../screenshot-tab-a-before.png | Bin 0 -> 88123 bytes .../screenshot-tab-b-after.png | Bin 0 -> 169940 bytes .../settled-manifest-after.json | 25 ++ .../settled-manifest-before.json | 25 ++ .../settled-manifest-tab-b.json | 25 ++ .../tab-b-correlation.json | 21 ++ .../witness.md | 48 +++ .../fe-1575-resumable-workpiece-petrinaut.md | 34 +- 23 files changed, 1405 insertions(+), 26 deletions(-) create mode 100644 libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/SHA256SUMS create mode 100644 libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/call-result-correlation.json create mode 100644 libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/cold-reader-gate.md create mode 100644 libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/cold-reader-records.json create mode 100644 libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/definition-after.json create mode 100644 libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/definition-before.json create mode 100644 libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/definition-tab-b.json create mode 100644 libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/flue-snapshot-after.json create mode 100644 libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/flue-snapshot-before.json create mode 100644 libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/flue-snapshot-tab-b.json create mode 100644 libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/latest-workpiece.md create mode 100644 libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/prepared-workpiece.md create mode 100644 libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/route-evidence.json create mode 100644 libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/run-metadata.json create mode 100644 libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/screenshot-tab-a-after.png create mode 100644 libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/screenshot-tab-a-before.png create mode 100644 libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/screenshot-tab-b-after.png create mode 100644 libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/settled-manifest-after.json create mode 100644 libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/settled-manifest-before.json create mode 100644 libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/settled-manifest-tab-b.json create mode 100644 libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/tab-b-correlation.json create mode 100644 libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/witness.md diff --git a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/SHA256SUMS b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/SHA256SUMS new file mode 100644 index 00000000000..f97c0ae270f --- /dev/null +++ b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/SHA256SUMS @@ -0,0 +1,21 @@ +6807ecb0e76a2e90193281fb48c3c5c69158f45e04ad55055b75600533fce367 call-result-correlation.json +183ea07ea977ed9a121da7a38f04cdb165d87533ba94de0034d85c07a4efa5db cold-reader-gate.md +c6c49657c8b40f552a4d829f8089027ac4538cff1fe0e5f1f0f58c533138748e cold-reader-records.json +c17ae80cc22939f0af6c2675f6bcc20b025b17a5b7bfb9e8029813bcef9ad736 definition-after.json +0ec2b0c9bb82787602c359b41e6c1663001f8e42425ad2ab7f84ac019944766b definition-before.json +c17ae80cc22939f0af6c2675f6bcc20b025b17a5b7bfb9e8029813bcef9ad736 definition-tab-b.json +64d50737a22eed36ca5d5605a414ba80d30c5bc776e6d2a0d90b454ecd2b7d9b flue-snapshot-after.json +1a8ed1a7463511807bc2f6b796a272bcc279b412fc4306701b9a12b7f9d15f81 flue-snapshot-before.json +b05b8def1ff005df8131f6a486c2f9f68d5e41455c2732fe83d36187dc28e824 flue-snapshot-tab-b.json +6df15e3e1f95a1df9bb0567a84e6808abfebcd089e9b2c0d95b5d3c39b0412f1 latest-workpiece.md +17f99f53f8cf93285a7344f5e9687d94e5f59011e6895ce11a9722fde2e77511 prepared-workpiece.md +9f7148397ddde657157199428147971cbde59a751d8ffc13e5ce9624b74e6bf7 route-evidence.json +9ac14c680bbf962e528fb18826737a61174a3e42aaaeab85745fee2aa923d7ec run-metadata.json +8d5c9ccde97fa2058ba12adf9b37ab911ed02b24ffa4f8175a3633b3d6a42c25 screenshot-tab-a-after.png +ae6811c466fa0f918dc74166f155ad0239ffe37b1ce9c7d27beec5d1ed92a72d screenshot-tab-a-before.png +772ad1314906a2fc67f34b1ca5ccf7c179c8b76751a03b1a3544b7ce289d756d screenshot-tab-b-after.png +ec0af35e2018e72dfb2b10df4be944bdb645c649dcda66685d868c1d33d71f60 settled-manifest-after.json +a29c4a8d3453298285e1b210eb816a2a5636587ecb3fe367a8646d3c02da4e86 settled-manifest-before.json +ec0af35e2018e72dfb2b10df4be944bdb645c649dcda66685d868c1d33d71f60 settled-manifest-tab-b.json +ac10a63dc246af73c123ca81fb24ba1d5b680ff33d21efda930156a36f16e02a tab-b-correlation.json +d5d8211d376ccb334879c52bc7fff6360696c3166ca8903695d99bbe0b75d26d witness.md diff --git a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/call-result-correlation.json b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/call-result-correlation.json new file mode 100644 index 00000000000..04bad3673e9 --- /dev/null +++ b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/call-result-correlation.json @@ -0,0 +1,84 @@ +{ + "calls": [ + { + "messageId": "entry_01M1NV6ARKVMJTM74GVBKS6VW4", + "submissionId": "sub_ik_a38b1133b7c7c65bf8f07814d23bcbcb", + "toolCallId": "toolu_01BQukCZTAhJ64VNE7oC1CWG", + "state": "output-available", + "rawInput": { + "transitionId": "start-final-inspection", + "arcDirection": "input", + "placeId": "dispatch-crew-available", + "weight": "1", + "type": "standard" + }, + "parsedInput": { + "transitionId": "start-final-inspection", + "arcDirection": "input", + "placeId": "dispatch-crew-available", + "weight": 1, + "type": "standard" + } + } + ], + "resultDeliveries": [ + { + "messageId": "entry_direct_c3ViX2lrX2FmOWNjY2IxZTk1NzI5ZjkyNDk0NDA2NTE0NTE3Y2Nl", + "submissionId": "sub_ik_af9cccb1e95729f92494406514517cce", + "result": { + "toolCallId": "toolu_01BQukCZTAhJ64VNE7oC1CWG", + "toolName": "addArc", + "output": { + "title": "Added input arc", + "detail": "Dispatch crew available <-> Start final inspection", + "target": { + "kind": "selection", + "item": { + "type": "arc", + "id": "$A_place:dispatch-crew-available___start-final-inspection" + } + }, + "applied": true + } + } + }, + { + "messageId": "entry_direct_c3ViX2lrX2Q3OTdiNGM2MDUzZTVkMGExNDRlYzE1NDdhMjJlMGNh", + "submissionId": "sub_ik_d797b4c6053e5d0a144ec1547a22e0ca", + "result": { + "toolCallId": "toolu_01BQukCZTAhJ64VNE7oC1CWG", + "toolName": "addArc", + "output": { + "title": "Added input arc", + "detail": "Dispatch crew available <-> Start final inspection", + "target": { + "kind": "selection", + "item": { + "type": "arc", + "id": "$A_place:dispatch-crew-available___start-final-inspection" + } + }, + "applied": true + } + } + } + ], + "uniqueResults": [ + { + "toolCallId": "toolu_01BQukCZTAhJ64VNE7oC1CWG", + "toolName": "addArc", + "output": { + "title": "Added input arc", + "detail": "Dispatch crew available <-> Start final inspection", + "target": { + "kind": "selection", + "item": { + "type": "arc", + "id": "$A_place:dispatch-crew-available___start-final-inspection" + } + }, + "applied": true + } + } + ] +} diff --git a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/cold-reader-gate.md b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/cold-reader-gate.md new file mode 100644 index 00000000000..eb90497ed0e --- /dev/null +++ b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/cold-reader-gate.md @@ -0,0 +1,31 @@ +# Mission 6 cold-reader gate + +Reviewer qualification: a human who did not watch the implementation or outer witness. Do not give the reviewer `witness.md`, screenshots, implementation files, or this mission's expected conclusions. + +Give the reviewer only: + +- [prepared-workpiece.md](prepared-workpiece.md) +- [latest-workpiece.md](latest-workpiece.md) +- [cold-reader-records.json](cold-reader-records.json) + +Ask for a written response to these questions: + +1. Who authored each workpiece revision, and what in the supplied Flue records establishes that attribution? +2. What exact dispatch-crew quantity or resource policy is recorded? +3. What operation reserves the crew, and what operation returns it? +4. List every unresolved timing, failure, and recovery point. +5. What behavioral execution or operational-provenance claims, if any, can be made from these materials alone? + +Acceptance requires the human response to: + +- attribute revision zero to test preparation, not the model; +- attribute the later assistant record to model production; +- recover the exactly-one-crew policy and the intended reservation/return; +- preserve every timing, failure, and recovery unknown; and +- avoid inferring behavioral execution or capture provenance. + +Record the reviewer's identity, date, verbatim response, and explicit accept/reject decision below only after the review occurs. + +## Human verdict + +Pending. diff --git a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/cold-reader-records.json b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/cold-reader-records.json new file mode 100644 index 00000000000..75fd835682f --- /dev/null +++ b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/cold-reader-records.json @@ -0,0 +1,46 @@ +{ + "records": [ + { + "id": "entry_direct_c3ViX2lrXzI4ODYzMWVhYWQ3OThjYzY5MDcwZTMzMTNlOTUxYmNi", + "role": "system", + "purpose": "dispatch", + "display": "diagnostic", + "submissionId": "sub_ik_288631eaad798cc69070e3313e951bcb", + "signal": { + "tagName": "prepared-fixture", + "attributes": { + "fixtureId": "crew-reservation-v1", + "authorship": "test-authored", + "claimBoundary": "prepared-not-model-produced" + } + }, + "parts": [ + { + "type": "text", + "text": "Fixture authorship: test-authored preparation for Mission 6.\nNon-claims: not a Mission 4 candidate, not model-produced evidence, not capture-backed provenance, and not proof of automatic full-net projection.\n\n```runbook-ir\n# Final inspection and dispatch workpiece\n\n## Purpose and posture\nMaintain the narrow batch path from final inspection to dispatch readiness and test one evidence-backed correction against the live Petrinaut document.\n\n## Operational account\n- A batch that is ready enters final inspection.\n- Final inspection reserves the sole available dispatch crew.\n- Sign-off releases that crew and makes the batch ready for dispatch.\n\n## Quantity and resource policy\nExactly one dispatch crew is available in this fixture. Starting final inspection consumes that one available crew; sign-off returns it.\n\n## Current Petrinaut correspondence\nThe prepared non-empty net contains the batch path and the crew return from sign-off. It deliberately lacks the standard weight-1 input arc from `Dispatch crew available` to `Start final inspection`.\n\n## Explicit unknowns\nInspection and sign-off timing, failure modes, and recovery behavior remain unresolved.\n\n## Claim boundary\nThis prepared revision is test-authored diagnostic material. It is not model-produced evidence and does not establish capture provenance, behavioral execution, or broad projection quality.\n```", + "state": "done" + } + ] + }, + { + "id": "entry_01M1NV6M4SBXB2WA46SM1B8QM3", + "role": "assistant", + "purpose": "assistant", + "display": "visible", + "submissionId": "sub_ik_d797b4c6053e5d0a144ec1547a22e0ca", + "turnId": "turn_01M1NV6KB8F7QJTRYHX0WT8AG5", + "parts": [ + { + "type": "reasoning", + "text": "Good! The arc has been successfully added. Looking at the final net definition, I can confirm:\n\n1. The arc was added successfully: `addArc` returned `\"applied\":true` with detail \"Dispatch crew available <-> Start final inspection\"\n\n2. In the final `getLatestNetDefinition` result, I can see that the `start-final-inspection` transition now has TWO input arcs:\n - `{\"placeId\":\"batch-ready\",\"weight\":1,\"type\":\"standard\"}`\n - `{\"type\":\"standard\",\"placeId\":\"dispatch-crew-available\",\"weight\":1\"}`\n\nThis confirms the missing arc from `Dispatch crew available` (weight 1, standard type) to `Start final inspection` is now in place.\n\nThe net structure is now:\n- **Places**: batch-ready, under-final-inspection, ready-for-dispatch, dispatch-crew-available\n- **Transitions**:\n - `start-final-inspection`: Takes a batch from batch-ready AND a crew token from dispatch-crew-available, produces under-final-inspection\n - `sign-off`: Takes under-final-inspection, produces both ready-for-dispatch AND returns dispatch-crew-available (crew token)\n\nThis correctly models the resource constraint: the single dispatch crew is reserved during inspection (consumed by start-final-inspection) and released at sign-off (produced by sign-off).\n\nNow I need to emit the revised runbook-ir workpiece, marking the revision as model-produced from test-authored revision zero.", + "state": "done" + }, + { + "type": "text", + "text": "✓ **Arc added successfully.** The Petrinaut tool confirms: `\"applied\":true` with detail \"Dispatch crew available ↔ Start final inspection\".\n\n**Verification of revised net structure:**\n- `Start final inspection` transition now has two standard input arcs (weight 1 each):\n 1. From `Batch ready` (original)\n 2. From `Dispatch crew available` (added, evidence-backed correction)\n- `Sign-off` transition correctly returns the crew token to `Dispatch crew available` (weight 1, output arc)\n\nThis enforces the resource constraint: the single dispatch crew is consumed when final inspection begins and restored at sign-off.\n\n---\n\n## Revised Workpiece (Model-Produced from Test-Authored Revision Zero)\n\n```runbook-ir\n# Final inspection and dispatch batch path\n\n## Purpose and posture\nModel the narrow batch path from final inspection to dispatch readiness with single-crew resource constraint. This revision incorporates the evidence-backed correction of the missing crew-availability input arc.\n\n## Operational account\n- A batch that is ready enters final inspection.\n- Final inspection requires and reserves the sole available dispatch crew.\n- Sign-off releases that crew and marks the batch ready for dispatch.\n\n## Quantity and resource policy\nExactly one dispatch crew is available in this system. Starting final inspection consumes that one available crew token; sign-off returns it. At most one batch can be under final inspection at a time because the sole crew is needed and cannot be in two places simultaneously.\n\n## Net structure (model-produced)\n**Places:**\n- `Batch ready`: batches waiting for inspection\n- `Under final inspection`: batches currently being inspected\n- `Ready for dispatch`: batches completed and awaiting dispatch\n- `Dispatch crew available`: availability token for the single crew (capacity 1)\n\n**Transitions:**\n- `Start final inspection`: consumes 1 batch token from `Batch ready` AND 1 crew token from `Dispatch crew available`; produces 1 token in `Under final inspection`\n- `Sign-off`: consumes 1 token from `Under final inspection`; produces 1 token each in `Ready for dispatch` and `Dispatch crew available` (returns the crew)\n\n**Arcs:**\n- `Batch ready` → `Start final inspection` (standard, weight 1) — original\n- `Dispatch crew available` → `Start final inspection` (standard, weight 1) — added in revision\n- `Start final inspection` → `Under final inspection` (standard, weight 1) — original\n- `Under final inspection` → `Sign-off` (standard, weight 1) — original\n- `Sign-off` → `Ready for dispatch` (standard, weight 1) — original\n- `Sign-off` → `Dispatch crew available` (standard, weight 1) — original\n\n## Explicit unknowns\n- Inspection and sign-off timing and duration\n- Failure modes, defect outcomes, and recovery behavior\n- Initial batch population and crew availability state\n- Repeat or recycling scenarios\n\n## Revision record\n**Revision 0** (test-authored): Prepared fixture identified missing standard weight-1 input arc from `Dispatch crew available` to `Start final inspection`.\n\n**Revision 1** (model-produced): Arc added via Petrinaut `addArc` tool and verified in net definition. Crew-availability constraint now enforced at net semantics level.\n\n## Claim boundary\nThis revision is model-produced evidence of arc correction applied to the test-authored source. It does not establish timing behavior, failure recovery, execution performance, or projection beyond this narrow batch-crew-inspection path.\n```", + "state": "done" + } + ] + } + ] +} diff --git a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/definition-after.json b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/definition-after.json new file mode 100644 index 00000000000..c92ed16c454 --- /dev/null +++ b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/definition-after.json @@ -0,0 +1,98 @@ +{ + "places": [ + { + "id": "batch-ready", + "name": "Batch ready", + "colorId": null, + "dynamicsEnabled": false, + "differentialEquationId": null, + "x": 80, + "y": 100 + }, + { + "id": "under-final-inspection", + "name": "Under final inspection", + "colorId": null, + "dynamicsEnabled": false, + "differentialEquationId": null, + "x": 420, + "y": 100 + }, + { + "id": "ready-for-dispatch", + "name": "Ready for dispatch", + "colorId": null, + "dynamicsEnabled": false, + "differentialEquationId": null, + "x": 760, + "y": 100 + }, + { + "id": "dispatch-crew-available", + "name": "Dispatch crew available", + "colorId": null, + "dynamicsEnabled": false, + "differentialEquationId": null, + "x": 420, + "y": 360 + } + ], + "transitions": [ + { + "id": "start-final-inspection", + "name": "Start final inspection", + "inputArcs": [ + { + "placeId": "batch-ready", + "weight": 1, + "type": "standard" + }, + { + "type": "standard", + "placeId": "dispatch-crew-available", + "weight": 1 + } + ], + "outputArcs": [ + { + "placeId": "under-final-inspection", + "weight": 1 + } + ], + "lambdaType": "predicate", + "lambdaCode": "", + "transitionKernelCode": "", + "x": 250, + "y": 100 + }, + { + "id": "sign-off", + "name": "Sign-off", + "inputArcs": [ + { + "placeId": "under-final-inspection", + "weight": 1, + "type": "standard" + } + ], + "outputArcs": [ + { + "placeId": "ready-for-dispatch", + "weight": 1 + }, + { + "placeId": "dispatch-crew-available", + "weight": 1 + } + ], + "lambdaType": "predicate", + "lambdaCode": "", + "transitionKernelCode": "", + "x": 590, + "y": 100 + } + ], + "types": [], + "differentialEquations": [], + "parameters": [] +} diff --git a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/definition-before.json b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/definition-before.json new file mode 100644 index 00000000000..5803556bfe8 --- /dev/null +++ b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/definition-before.json @@ -0,0 +1,93 @@ +{ + "places": [ + { + "id": "batch-ready", + "name": "Batch ready", + "colorId": null, + "dynamicsEnabled": false, + "differentialEquationId": null, + "x": 80, + "y": 100 + }, + { + "id": "under-final-inspection", + "name": "Under final inspection", + "colorId": null, + "dynamicsEnabled": false, + "differentialEquationId": null, + "x": 420, + "y": 100 + }, + { + "id": "ready-for-dispatch", + "name": "Ready for dispatch", + "colorId": null, + "dynamicsEnabled": false, + "differentialEquationId": null, + "x": 760, + "y": 100 + }, + { + "id": "dispatch-crew-available", + "name": "Dispatch crew available", + "colorId": null, + "dynamicsEnabled": false, + "differentialEquationId": null, + "x": 420, + "y": 360 + } + ], + "transitions": [ + { + "id": "start-final-inspection", + "name": "Start final inspection", + "inputArcs": [ + { + "placeId": "batch-ready", + "type": "standard", + "weight": 1 + } + ], + "outputArcs": [ + { + "placeId": "under-final-inspection", + "weight": 1 + } + ], + "lambdaType": "predicate", + "lambdaCode": "", + "transitionKernelCode": "", + "x": 250, + "y": 100 + }, + { + "id": "sign-off", + "name": "Sign-off", + "inputArcs": [ + { + "placeId": "under-final-inspection", + "type": "standard", + "weight": 1 + } + ], + "outputArcs": [ + { + "placeId": "ready-for-dispatch", + "weight": 1 + }, + { + "placeId": "dispatch-crew-available", + "weight": 1 + } + ], + "lambdaType": "predicate", + "lambdaCode": "", + "transitionKernelCode": "", + "x": 590, + "y": 100 + } + ], + "types": [], + "parameters": [], + "differentialEquations": [] +} diff --git a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/definition-tab-b.json b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/definition-tab-b.json new file mode 100644 index 00000000000..c92ed16c454 --- /dev/null +++ b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/definition-tab-b.json @@ -0,0 +1,98 @@ +{ + "places": [ + { + "id": "batch-ready", + "name": "Batch ready", + "colorId": null, + "dynamicsEnabled": false, + "differentialEquationId": null, + "x": 80, + "y": 100 + }, + { + "id": "under-final-inspection", + "name": "Under final inspection", + "colorId": null, + "dynamicsEnabled": false, + "differentialEquationId": null, + "x": 420, + "y": 100 + }, + { + "id": "ready-for-dispatch", + "name": "Ready for dispatch", + "colorId": null, + "dynamicsEnabled": false, + "differentialEquationId": null, + "x": 760, + "y": 100 + }, + { + "id": "dispatch-crew-available", + "name": "Dispatch crew available", + "colorId": null, + "dynamicsEnabled": false, + "differentialEquationId": null, + "x": 420, + "y": 360 + } + ], + "transitions": [ + { + "id": "start-final-inspection", + "name": "Start final inspection", + "inputArcs": [ + { + "placeId": "batch-ready", + "weight": 1, + "type": "standard" + }, + { + "type": "standard", + "placeId": "dispatch-crew-available", + "weight": 1 + } + ], + "outputArcs": [ + { + "placeId": "under-final-inspection", + "weight": 1 + } + ], + "lambdaType": "predicate", + "lambdaCode": "", + "transitionKernelCode": "", + "x": 250, + "y": 100 + }, + { + "id": "sign-off", + "name": "Sign-off", + "inputArcs": [ + { + "placeId": "under-final-inspection", + "weight": 1, + "type": "standard" + } + ], + "outputArcs": [ + { + "placeId": "ready-for-dispatch", + "weight": 1 + }, + { + "placeId": "dispatch-crew-available", + "weight": 1 + } + ], + "lambdaType": "predicate", + "lambdaCode": "", + "transitionKernelCode": "", + "x": 590, + "y": 100 + } + ], + "types": [], + "differentialEquations": [], + "parameters": [] +} diff --git a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/flue-snapshot-after.json b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/flue-snapshot-after.json new file mode 100644 index 00000000000..b35e84df234 --- /dev/null +++ b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/flue-snapshot-after.json @@ -0,0 +1,287 @@ +{ + "v": 1, + "conversationId": "conv_01M1NV5WZETMYEGGMFXNYDSTRS", + "offset": "0000000000000000_0000000000000092", + "messages": [ + { + "id": "entry_direct_c3ViX2lrXzI4ODYzMWVhYWQ3OThjYzY5MDcwZTMzMTNlOTUxYmNi", + "role": "system", + "purpose": "dispatch", + "display": "diagnostic", + "submissionId": "sub_ik_288631eaad798cc69070e3313e951bcb", + "signal": { + "tagName": "prepared-fixture", + "attributes": { + "fixtureId": "crew-reservation-v1", + "authorship": "test-authored", + "claimBoundary": "prepared-not-model-produced" + } + }, + "parts": [ + { + "type": "text", + "text": "Fixture authorship: test-authored preparation for Mission 6.\nNon-claims: not a Mission 4 candidate, not model-produced evidence, not capture-backed provenance, and not proof of automatic full-net projection.\n\n```runbook-ir\n# Final inspection and dispatch workpiece\n\n## Purpose and posture\nMaintain the narrow batch path from final inspection to dispatch readiness and test one evidence-backed correction against the live Petrinaut document.\n\n## Operational account\n- A batch that is ready enters final inspection.\n- Final inspection reserves the sole available dispatch crew.\n- Sign-off releases that crew and makes the batch ready for dispatch.\n\n## Quantity and resource policy\nExactly one dispatch crew is available in this fixture. Starting final inspection consumes that one available crew; sign-off returns it.\n\n## Current Petrinaut correspondence\nThe prepared non-empty net contains the batch path and the crew return from sign-off. It deliberately lacks the standard weight-1 input arc from `Dispatch crew available` to `Start final inspection`.\n\n## Explicit unknowns\nInspection and sign-off timing, failure modes, and recovery behavior remain unresolved.\n\n## Claim boundary\nThis prepared revision is test-authored diagnostic material. It is not model-produced evidence and does not establish capture provenance, behavioral execution, or broad projection quality.\n```", + "state": "done" + } + ] + }, + { + "id": "entry_01M1NV5XQCBVP3FC4JW5FH1WZJ", + "role": "assistant", + "purpose": "assistant", + "display": "visible", + "submissionId": "sub_ik_288631eaad798cc69070e3313e951bcb", + "turnId": "turn_01M1NV5WZH2J0S74S1Q24556EP", + "parts": [ + { + "type": "reasoning", + "text": "This is a prepared fixture for a conversation about operational process modeling using SDCPN (stochastic dynamic coloured Petri nets) in Petrinaut. Let me understand what's being presented:\n\nThe fixture describes a batch processing system with final inspection and dispatch:\n- Batches enter final inspection when ready\n- Final inspection reserves the sole available dispatch crew\n- Sign-off releases the crew and marks the batch as ready for dispatch\n- There's exactly one dispatch crew available\n\nThe fixture notes that the current Petrinaut document has a deliberate gap: it's missing the standard weight-1 input arc from \"Dispatch crew available\" to \"Start final inspection\".\n\nThe task seems to be to:\n1. Maintain this narrow batch path from final inspection to dispatch readiness\n2. Test one evidence-backed correction against the live Petrinaut document\n3. This means likely adding that missing arc\n\nThe explicit unknowns are:\n- Inspection and sign-off timing\n- Failure modes and recovery behavior\n\nThis is a test-authored diagnostic material, not model-produced evidence.\n\nBefore I proceed, I should:\n1. Activate the `sdcpn-modelling` skill since this is about SDCPN modeling\n2. Get the current Petrinaut net definition to see what we're working with\n3. Understand the current state and the specific correction needed\n\nLet me start by activating the skill and getting the current net state.", + "state": "done" + }, + { + "type": "text", + "text": "I'll help you maintain and test this final inspection and dispatch workpiece. Let me start by activating the SDCPN modelling skill and examining the current Petrinaut net definition.", + "state": "done" + }, + { + "type": "dynamic-tool", + "toolName": "activate_skill", + "toolCallId": "toolu_01Y9HuAi2cvi16UD9bTvcvfS", + "state": "output-available", + "input": { + "name": "sdcpn-modelling" + }, + "output": "Run the skill named \"sdcpn-modelling\".\n\n\n# Capability-aware lifecycle\n\nUse one conceptual lifecycle: orient, elicit or revise, maintain the workpiece, construct when supported, check, and deliver. The current conversation may expose only one branch of that lifecycle. Do not claim that an unavailable transition occurred.\n\n## Select the runtime branch\n\n### Interactive elicitation or revision\n\nInterview in the person's operational vocabulary. Activate the `elicitation` skill and read `references/profile.md` before substantive questions or revision. Read `templates/workpiece.md` when creating or materially revising the shared workpiece. Construct only when the mounted capabilities actually permit construction in this conversation.\n\n### Construct-only execution\n\nUse the supplied workpiece as the complete modelling input. Do not interview. Read `references/pn-construction.md` and `references/checks.md`, then use the mounted construction tools. If a consequential workpiece gap prevents faithful construction, report the gap and the smallest question a later interactive elicitation must answer; do not ask it or invent an answer in this conversation.\n\n## Procedure\n\n### Orient\n\nEstablish enough purpose and context to select one focused next action: the intended question or decision, audience, boundary, horizon, accuracy need, and available time. Orientation need not settle every concern before elicitation begins.\n\n### Elicit or revise\n\nFor a new account, follow one concrete case and re-evaluate the active gap after each useful answer. For an existing account, first locate the disputed or changed material and its consequence for the objective. Use the `elicitation` skill's universal guidance and `references/profile.md` for detailed operations and coverage; do not turn their register order into question order.\n\n### Maintain the workpiece\n\nTreat the workpiece as the recoverable account construction will consume. Update it after a useful stretch rather than waiting until the end. Preserve unrelated material unless new evidence affects it.\n\nWhenever the workpiece changes substantially, emit the full current document in a fenced block whose language tag is exactly `runbook-ir`. Emit it again before construction and before workpiece-only delivery. A delta or prose promise is not a recoverable workpiece.\n\n### Construct\n\nConstruct only from the current workpiece. Read `references/pn-construction.md` and `references/checks.md` before beginning. Use mounted Petrinaut tools for every net change and inspect the resulting definition rather than emitting free-form net JSON. If the required tools are absent, limit the result to the workpiece and construction-ready notes.\n\nConstruction may infer a representation from recorded operational meaning; it may not invent operational facts. Record construction inferences, approximations, defaults, and target losses in the workpiece.\n\n### Check and deliver\n\nApply `references/checks.md` whenever construction is prepared or attempted. Deliver the current workpiece in every branch. Deliver a net only when the mounted tool path has produced and checked one. State what the result can support, what remains open, what was assumed or simplified, and what the target or current tools could not represent.\n\nAn explicit stop opens no new topic. In an interactive conversation, emit the best current workpiece and any already-checked net with limitations visible. In construct-only execution, report a blocking gap rather than opening an interview.\n\n## Resource discipline\n\nRead resources directly from this skill's advertised resource list, using the exact `/.flue/packaged-skills/...` path shown in the activation briefing; the relative name is a label only. Do not treat Markdown links as includes, follow references recursively, or read construction material merely to frame ordinary interview questions.\n\n\nSupporting skill resources are available but are not loaded into context unless needed:\n\n- references/checks.md → read_skill_resource /.flue/packaged-skills/skill%3Asdcpn-modelling%3A99a447ec4bcbf6c0/references/checks.md\n- references/pn-construction.md → read_skill_resource /.flue/packaged-skills/skill%3Asdcpn-modelling%3A99a447ec4bcbf6c0/references/pn-construction.md\n- references/profile.md → read_skill_resource /.flue/packaged-skills/skill%3Asdcpn-modelling%3A99a447ec4bcbf6c0/references/profile.md\n- templates/workpiece.md → read_skill_resource /.flue/packaged-skills/skill%3Asdcpn-modelling%3A99a447ec4bcbf6c0/templates/workpiece.md\n", + "durationMs": 1 + }, + { + "type": "dynamic-tool", + "toolName": "getLatestNetDefinition", + "toolCallId": "toolu_018ayLcg31aA5nZjvPe3VLEz", + "state": "output-available", + "input": {}, + "output": { + "awaiting": "client" + }, + "durationMs": 1 + }, + { + "type": "reasoning", + "text": "The getLatestNetDefinition returned awaiting client signal, meaning the client needs to load the current document. I should wait for that and then proceed. But let me think about what to do next.\n\nThe skill has been activated successfully. Now I need to:\n1. Wait for the net definition from the client\n2. Read the workpiece template to understand how to structure the workpiece\n3. Understand the current gaps and what needs to be corrected\n\nBased on the prepared fixture, the key issue is:\n- The current Petrinaut document is missing the weight-1 input arc from \"Dispatch crew available\" to \"Start final inspection\"\n- This is a deliberate gap that we need to test correcting\n\nLet me wait for the client signal and then proceed with getting the live document and understanding what needs to be corrected.", + "state": "done" + }, + { + "type": "text", + "text": "The skill is now active. I'm awaiting the current Petrinaut net definition from the client. Once that arrives, I'll examine the current state and identify the specific gap mentioned in the fixture—the missing input arc from `Dispatch crew available` to `Start final inspection`—and we can verify the evidence-backed correction.\n\nThe fixture establishes a clear scope:\n- **Operational focus**: The narrow batch path from final inspection through dispatch readiness\n- **Resource constraint**: Exactly one dispatch crew available, reserved during inspection, returned at sign-off\n- **Known gap**: Missing standard weight-1 arc from crew availability to the start of inspection\n- **Boundary**: Timing, failure modes, and recovery are explicitly unresolved\n\nI'm ready to proceed once the net definition loads. What would you like to examine or correct first?", + "state": "done" + } + ] + }, + { + "id": "entry_direct_c3ViX2lrXzIzMzcwMWRlZDcxMDVkNWQ0M2M0YjhhZTI1MTRlYzhi", + "role": "user", + "purpose": "user", + "display": "visible", + "submissionId": "sub_ik_233701ded7105d5d43c4b8ae2514ec8b", + "parts": [ + { + "type": "text", + "text": "Confirmed: final inspection uses the single dispatch crew and sign-off releases it; timing, failure, and recovery remain unknown. Read the live Petrinaut definition, add the missing standard weight-1 input arc from Dispatch crew available to Start final inspection, verify it, and emit the full revised runbook-ir workpiece. In that revised workpiece, identify the revision itself as model-produced from test-authored revision zero; do not call the revised workpiece test-authored.", + "state": "done" + } + ] + }, + { + "id": "entry_01M1NV68Q36Q2ZMVFVMR3A2J1D", + "role": "assistant", + "purpose": "assistant", + "display": "visible", + "submissionId": "sub_ik_233701ded7105d5d43c4b8ae2514ec8b", + "turnId": "turn_01M1NV67W787NJDB98B4DVTMA1", + "parts": [ + { + "type": "reasoning", + "text": "The user wants me to:\n1. Read the live Petrinaut net definition\n2. Add the missing standard weight-1 input arc from \"Dispatch crew available\" to \"Start final inspection\"\n3. Verify the change\n4. Emit the full revised runbook-ir workpiece\n5. Label the revised workpiece as model-produced from test-authored revision zero (not test-authored itself)\n\nLet me start by reading the live definition, then adding the arc, then verifying it, and finally emitting the revised workpiece.", + "state": "done" + }, + { + "type": "dynamic-tool", + "toolName": "getLatestNetDefinition", + "toolCallId": "toolu_016Jkt4shRUg8hmtq6YyfcFB", + "state": "output-available", + "input": {}, + "output": { + "awaiting": "client" + }, + "durationMs": 1 + } + ] + }, + { + "id": "entry_direct_c3ViX2lrX2EzOGIxMTMzYjdjN2M2NWJmOGYwNzgxNGQyM2JjYmNi", + "role": "system", + "purpose": "dispatch", + "display": "diagnostic", + "submissionId": "sub_ik_a38b1133b7c7c65bf8f07814d23bcbcb", + "signal": { + "tagName": "client-tool-result", + "attributes": { + "toolCallIds": "toolu_016Jkt4shRUg8hmtq6YyfcFB" + } + }, + "parts": [ + { + "type": "text", + "text": "[{\"toolCallId\":\"toolu_016Jkt4shRUg8hmtq6YyfcFB\",\"toolName\":\"getLatestNetDefinition\",\"output\":{\"title\":\"Prepared final inspection and dispatch\",\"definition\":{\"places\":[{\"id\":\"batch-ready\",\"name\":\"Batch ready\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":80,\"y\":100},{\"id\":\"under-final-inspection\",\"name\":\"Under final inspection\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":420,\"y\":100},{\"id\":\"ready-for-dispatch\",\"name\":\"Ready for dispatch\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":760,\"y\":100},{\"id\":\"dispatch-crew-available\",\"name\":\"Dispatch crew available\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":420,\"y\":360}],\"transitions\":[{\"id\":\"start-final-inspection\",\"name\":\"Start final inspection\",\"inputArcs\":[{\"placeId\":\"batch-ready\",\"weight\":1,\"type\":\"standard\"}],\"outputArcs\":[{\"placeId\":\"under-final-inspection\",\"weight\":1}],\"lambdaType\":\"predicate\",\"lambdaCode\":\"\",\"transitionKernelCode\":\"\",\"x\":250,\"y\":100},{\"id\":\"sign-off\",\"name\":\"Sign-off\",\"inputArcs\":[{\"placeId\":\"under-final-inspection\",\"weight\":1,\"type\":\"standard\"}],\"outputArcs\":[{\"placeId\":\"ready-for-dispatch\",\"weight\":1},{\"placeId\":\"dispatch-crew-available\",\"weight\":1}],\"lambdaType\":\"predicate\",\"lambdaCode\":\"\",\"transitionKernelCode\":\"\",\"x\":590,\"y\":100}],\"types\":[],\"differentialEquations\":[],\"parameters\":[]},\"extensions\":{\"colors\":true,\"stochasticity\":true,\"dynamics\":true,\"parameters\":true,\"subnets\":true}}}]", + "state": "done" + } + ] + }, + { + "id": "entry_01M1NV6ARKVMJTM74GVBKS6VW4", + "role": "assistant", + "purpose": "assistant", + "display": "visible", + "submissionId": "sub_ik_a38b1133b7c7c65bf8f07814d23bcbcb", + "turnId": "turn_01M1NV6A1766CSNYQR9H1HEBKH", + "parts": [ + { + "type": "reasoning", + "text": "The net definition has been loaded. Let me analyze the current state:\n\n**Current state:**\n- Places:\n - `batch-ready`: Batch waiting for final inspection\n - `under-final-inspection`: Batch undergoing final inspection\n - `ready-for-dispatch`: Batch ready for dispatch\n - `dispatch-crew-available`: Dispatch crew available (resource)\n\n- Transitions:\n - `start-final-inspection`: Takes a batch from `batch-ready` to `under-final-inspection`. It has one input arc from `batch-ready` with weight 1.\n - `sign-off`: Takes a batch from `under-final-inspection` to `ready-for-dispatch` and returns the crew to `dispatch-crew-available`. Has input arc from `under-final-inspection` (weight 1) and output arcs to both `ready-for-dispatch` and `dispatch-crew-available`.\n\n**The missing arc:**\nThe fixture states that the missing arc is: standard weight-1 input arc from `Dispatch crew available` to `Start final inspection`.\n\nCurrently, `start-final-inspection` only has one input arc from `batch-ready`. It needs an additional input arc from `dispatch-crew-available` with weight 1 and type \"standard\".\n\n**What needs to happen:**\n1. Add an input arc to the `start-final-inspection` transition from the `dispatch-crew-available` place with weight 1 and type \"standard\"\n2. Verify the result\n3. Emit the full revised workpiece with the identification that this is model-produced from test-authored revision zero\n\nLet me use the addArc function to add this arc.\n\nThe parameters for addArc based on the schema:\n- transitionId: \"start-final-inspection\"\n- arcDirection: \"input\"\n- placeId: \"dispatch-crew-available\" (since we're using the legacy shorthand)\n- weight: 1\n- type: \"standard\"\n- targetSubnetId omitted, since this operates on the root net", + "state": "done" + }, + { + "type": "dynamic-tool", + "toolName": "addArc", + "toolCallId": "toolu_01BQukCZTAhJ64VNE7oC1CWG", + "state": "output-available", + "input": { + "transitionId": "start-final-inspection", + "arcDirection": "input", + "placeId": "dispatch-crew-available", + "weight": "1", + "type": "standard" + }, + "output": { + "awaiting": "client" + }, + "durationMs": 0 + } + ] + }, + { + "id": "entry_direct_c3ViX2lrX2FmOWNjY2IxZTk1NzI5ZjkyNDk0NDA2NTE0NTE3Y2Nl", + "role": "system", + "purpose": "dispatch", + "display": "diagnostic", + "submissionId": "sub_ik_af9cccb1e95729f92494406514517cce", + "signal": { + "tagName": "client-tool-result", + "attributes": { + "toolCallIds": "toolu_016Jkt4shRUg8hmtq6YyfcFB,toolu_01BQukCZTAhJ64VNE7oC1CWG" + } + }, + "parts": [ + { + "type": "text", + "text": "[{\"toolCallId\":\"toolu_016Jkt4shRUg8hmtq6YyfcFB\",\"toolName\":\"getLatestNetDefinition\",\"output\":{\"title\":\"Prepared final inspection and dispatch\",\"definition\":{\"places\":[{\"id\":\"batch-ready\",\"name\":\"Batch ready\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":80,\"y\":100},{\"id\":\"under-final-inspection\",\"name\":\"Under final inspection\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":420,\"y\":100},{\"id\":\"ready-for-dispatch\",\"name\":\"Ready for dispatch\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":760,\"y\":100},{\"id\":\"dispatch-crew-available\",\"name\":\"Dispatch crew available\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":420,\"y\":360}],\"transitions\":[{\"id\":\"start-final-inspection\",\"name\":\"Start final inspection\",\"inputArcs\":[{\"placeId\":\"batch-ready\",\"weight\":1,\"type\":\"standard\"}],\"outputArcs\":[{\"placeId\":\"under-final-inspection\",\"weight\":1}],\"lambdaType\":\"predicate\",\"lambdaCode\":\"\",\"transitionKernelCode\":\"\",\"x\":250,\"y\":100},{\"id\":\"sign-off\",\"name\":\"Sign-off\",\"inputArcs\":[{\"placeId\":\"under-final-inspection\",\"weight\":1,\"type\":\"standard\"}],\"outputArcs\":[{\"placeId\":\"ready-for-dispatch\",\"weight\":1},{\"placeId\":\"dispatch-crew-available\",\"weight\":1}],\"lambdaType\":\"predicate\",\"lambdaCode\":\"\",\"transitionKernelCode\":\"\",\"x\":590,\"y\":100}],\"types\":[],\"differentialEquations\":[],\"parameters\":[]},\"extensions\":{\"colors\":true,\"stochasticity\":true,\"dynamics\":true,\"parameters\":true,\"subnets\":true}}},{\"toolCallId\":\"toolu_01BQukCZTAhJ64VNE7oC1CWG\",\"toolName\":\"addArc\",\"output\":{\"title\":\"Added input arc\",\"detail\":\"Dispatch crew available <-> Start final inspection\",\"target\":{\"kind\":\"selection\",\"item\":{\"type\":\"arc\",\"id\":\"$A_place:dispatch-crew-available___start-final-inspection\"}},\"applied\":true}}]", + "state": "done" + } + ] + }, + { + "id": "entry_01M1NV6HRWJHSZ3QD2V8RZEWV3", + "role": "assistant", + "purpose": "assistant", + "display": "visible", + "submissionId": "sub_ik_af9cccb1e95729f92494406514517cce", + "turnId": "turn_01M1NV6GV7Q0BAMD0S09EEAY1E", + "parts": [ + { + "type": "reasoning", + "text": "Good! The arc has been added successfully. The tool output shows:\n- \"Applied: true\" - the arc was successfully added\n- Detail: \"Dispatch crew available <-> Start final inspection\"\n- The arc ID is \"$A_place:dispatch-crew-available___start-final-inspection\"\n\nNow I need to read the live net definition again to verify the change was applied correctly, then emit the revised workpiece with the full Markdown document showing the state of the net with the arc now in place.", + "state": "done" + }, + { + "type": "dynamic-tool", + "toolName": "getLatestNetDefinition", + "toolCallId": "toolu_017Ze5BnyBGXdaw7DJSGxZQb", + "state": "output-available", + "input": {}, + "output": { + "awaiting": "client" + }, + "durationMs": 0 + } + ] + }, + { + "id": "entry_direct_c3ViX2lrX2Q3OTdiNGM2MDUzZTVkMGExNDRlYzE1NDdhMjJlMGNh", + "role": "system", + "purpose": "dispatch", + "display": "diagnostic", + "submissionId": "sub_ik_d797b4c6053e5d0a144ec1547a22e0ca", + "signal": { + "tagName": "client-tool-result", + "attributes": { + "toolCallIds": "toolu_016Jkt4shRUg8hmtq6YyfcFB,toolu_01BQukCZTAhJ64VNE7oC1CWG,toolu_017Ze5BnyBGXdaw7DJSGxZQb" + } + }, + "parts": [ + { + "type": "text", + "text": "[{\"toolCallId\":\"toolu_016Jkt4shRUg8hmtq6YyfcFB\",\"toolName\":\"getLatestNetDefinition\",\"output\":{\"title\":\"Prepared final inspection and dispatch\",\"definition\":{\"places\":[{\"id\":\"batch-ready\",\"name\":\"Batch ready\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":80,\"y\":100},{\"id\":\"under-final-inspection\",\"name\":\"Under final inspection\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":420,\"y\":100},{\"id\":\"ready-for-dispatch\",\"name\":\"Ready for dispatch\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":760,\"y\":100},{\"id\":\"dispatch-crew-available\",\"name\":\"Dispatch crew available\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":420,\"y\":360}],\"transitions\":[{\"id\":\"start-final-inspection\",\"name\":\"Start final inspection\",\"inputArcs\":[{\"placeId\":\"batch-ready\",\"weight\":1,\"type\":\"standard\"}],\"outputArcs\":[{\"placeId\":\"under-final-inspection\",\"weight\":1}],\"lambdaType\":\"predicate\",\"lambdaCode\":\"\",\"transitionKernelCode\":\"\",\"x\":250,\"y\":100},{\"id\":\"sign-off\",\"name\":\"Sign-off\",\"inputArcs\":[{\"placeId\":\"under-final-inspection\",\"weight\":1,\"type\":\"standard\"}],\"outputArcs\":[{\"placeId\":\"ready-for-dispatch\",\"weight\":1},{\"placeId\":\"dispatch-crew-available\",\"weight\":1}],\"lambdaType\":\"predicate\",\"lambdaCode\":\"\",\"transitionKernelCode\":\"\",\"x\":590,\"y\":100}],\"types\":[],\"differentialEquations\":[],\"parameters\":[]},\"extensions\":{\"colors\":true,\"stochasticity\":true,\"dynamics\":true,\"parameters\":true,\"subnets\":true}}},{\"toolCallId\":\"toolu_01BQukCZTAhJ64VNE7oC1CWG\",\"toolName\":\"addArc\",\"output\":{\"title\":\"Added input arc\",\"detail\":\"Dispatch crew available <-> Start final inspection\",\"target\":{\"kind\":\"selection\",\"item\":{\"type\":\"arc\",\"id\":\"$A_place:dispatch-crew-available___start-final-inspection\"}},\"applied\":true}},{\"toolCallId\":\"toolu_017Ze5BnyBGXdaw7DJSGxZQb\",\"toolName\":\"getLatestNetDefinition\",\"output\":{\"title\":\"Prepared final inspection and dispatch\",\"definition\":{\"places\":[{\"id\":\"batch-ready\",\"name\":\"Batch ready\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":80,\"y\":100},{\"id\":\"under-final-inspection\",\"name\":\"Under final inspection\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":420,\"y\":100},{\"id\":\"ready-for-dispatch\",\"name\":\"Ready for dispatch\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":760,\"y\":100},{\"id\":\"dispatch-crew-available\",\"name\":\"Dispatch crew available\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":420,\"y\":360}],\"transitions\":[{\"id\":\"start-final-inspection\",\"name\":\"Start final inspection\",\"inputArcs\":[{\"placeId\":\"batch-ready\",\"weight\":1,\"type\":\"standard\"},{\"type\":\"standard\",\"placeId\":\"dispatch-crew-available\",\"weight\":1}],\"outputArcs\":[{\"placeId\":\"under-final-inspection\",\"weight\":1}],\"lambdaType\":\"predicate\",\"lambdaCode\":\"\",\"transitionKernelCode\":\"\",\"x\":250,\"y\":100},{\"id\":\"sign-off\",\"name\":\"Sign-off\",\"inputArcs\":[{\"placeId\":\"under-final-inspection\",\"weight\":1,\"type\":\"standard\"}],\"outputArcs\":[{\"placeId\":\"ready-for-dispatch\",\"weight\":1},{\"placeId\":\"dispatch-crew-available\",\"weight\":1}],\"lambdaType\":\"predicate\",\"lambdaCode\":\"\",\"transitionKernelCode\":\"\",\"x\":590,\"y\":100}],\"types\":[],\"differentialEquations\":[],\"parameters\":[]},\"extensions\":{\"colors\":true,\"stochasticity\":true,\"dynamics\":true,\"parameters\":true,\"subnets\":true}}}]", + "state": "done" + } + ] + }, + { + "id": "entry_01M1NV6M4SBXB2WA46SM1B8QM3", + "role": "assistant", + "purpose": "assistant", + "display": "visible", + "submissionId": "sub_ik_d797b4c6053e5d0a144ec1547a22e0ca", + "turnId": "turn_01M1NV6KB8F7QJTRYHX0WT8AG5", + "parts": [ + { + "type": "reasoning", + "text": "Good! The arc has been successfully added. Looking at the final net definition, I can confirm:\n\n1. The arc was added successfully: `addArc` returned `\"applied\":true` with detail \"Dispatch crew available <-> Start final inspection\"\n\n2. In the final `getLatestNetDefinition` result, I can see that the `start-final-inspection` transition now has TWO input arcs:\n - `{\"placeId\":\"batch-ready\",\"weight\":1,\"type\":\"standard\"}`\n - `{\"type\":\"standard\",\"placeId\":\"dispatch-crew-available\",\"weight\":1\"}`\n\nThis confirms the missing arc from `Dispatch crew available` (weight 1, standard type) to `Start final inspection` is now in place.\n\nThe net structure is now:\n- **Places**: batch-ready, under-final-inspection, ready-for-dispatch, dispatch-crew-available\n- **Transitions**:\n - `start-final-inspection`: Takes a batch from batch-ready AND a crew token from dispatch-crew-available, produces under-final-inspection\n - `sign-off`: Takes under-final-inspection, produces both ready-for-dispatch AND returns dispatch-crew-available (crew token)\n\nThis correctly models the resource constraint: the single dispatch crew is reserved during inspection (consumed by start-final-inspection) and released at sign-off (produced by sign-off).\n\nNow I need to emit the revised runbook-ir workpiece, marking the revision as model-produced from test-authored revision zero.", + "state": "done" + }, + { + "type": "text", + "text": "✓ **Arc added successfully.** The Petrinaut tool confirms: `\"applied\":true` with detail \"Dispatch crew available ↔ Start final inspection\".\n\n**Verification of revised net structure:**\n- `Start final inspection` transition now has two standard input arcs (weight 1 each):\n 1. From `Batch ready` (original)\n 2. From `Dispatch crew available` (added, evidence-backed correction)\n- `Sign-off` transition correctly returns the crew token to `Dispatch crew available` (weight 1, output arc)\n\nThis enforces the resource constraint: the single dispatch crew is consumed when final inspection begins and restored at sign-off.\n\n---\n\n## Revised Workpiece (Model-Produced from Test-Authored Revision Zero)\n\n```runbook-ir\n# Final inspection and dispatch batch path\n\n## Purpose and posture\nModel the narrow batch path from final inspection to dispatch readiness with single-crew resource constraint. This revision incorporates the evidence-backed correction of the missing crew-availability input arc.\n\n## Operational account\n- A batch that is ready enters final inspection.\n- Final inspection requires and reserves the sole available dispatch crew.\n- Sign-off releases that crew and marks the batch ready for dispatch.\n\n## Quantity and resource policy\nExactly one dispatch crew is available in this system. Starting final inspection consumes that one available crew token; sign-off returns it. At most one batch can be under final inspection at a time because the sole crew is needed and cannot be in two places simultaneously.\n\n## Net structure (model-produced)\n**Places:**\n- `Batch ready`: batches waiting for inspection\n- `Under final inspection`: batches currently being inspected\n- `Ready for dispatch`: batches completed and awaiting dispatch\n- `Dispatch crew available`: availability token for the single crew (capacity 1)\n\n**Transitions:**\n- `Start final inspection`: consumes 1 batch token from `Batch ready` AND 1 crew token from `Dispatch crew available`; produces 1 token in `Under final inspection`\n- `Sign-off`: consumes 1 token from `Under final inspection`; produces 1 token each in `Ready for dispatch` and `Dispatch crew available` (returns the crew)\n\n**Arcs:**\n- `Batch ready` → `Start final inspection` (standard, weight 1) — original\n- `Dispatch crew available` → `Start final inspection` (standard, weight 1) — added in revision\n- `Start final inspection` → `Under final inspection` (standard, weight 1) — original\n- `Under final inspection` → `Sign-off` (standard, weight 1) — original\n- `Sign-off` → `Ready for dispatch` (standard, weight 1) — original\n- `Sign-off` → `Dispatch crew available` (standard, weight 1) — original\n\n## Explicit unknowns\n- Inspection and sign-off timing and duration\n- Failure modes, defect outcomes, and recovery behavior\n- Initial batch population and crew availability state\n- Repeat or recycling scenarios\n\n## Revision record\n**Revision 0** (test-authored): Prepared fixture identified missing standard weight-1 input arc from `Dispatch crew available` to `Start final inspection`.\n\n**Revision 1** (model-produced): Arc added via Petrinaut `addArc` tool and verified in net definition. Crew-availability constraint now enforced at net semantics level.\n\n## Claim boundary\nThis revision is model-produced evidence of arc correction applied to the test-authored source. It does not establish timing behavior, failure recovery, execution performance, or projection beyond this narrow batch-crew-inspection path.\n```", + "state": "done" + } + ] + } + ], + "settlements": [ + { + "submissionId": "sub_ik_288631eaad798cc69070e3313e951bcb", + "outcome": "completed", + "answeredBySubmissionId": "sub_ik_288631eaad798cc69070e3313e951bcb" + }, + { + "submissionId": "sub_ik_233701ded7105d5d43c4b8ae2514ec8b", + "outcome": "completed", + "answeredBySubmissionId": "sub_ik_233701ded7105d5d43c4b8ae2514ec8b" + }, + { + "submissionId": "sub_ik_a38b1133b7c7c65bf8f07814d23bcbcb", + "outcome": "completed", + "answeredBySubmissionId": "sub_ik_a38b1133b7c7c65bf8f07814d23bcbcb" + }, + { + "submissionId": "sub_ik_af9cccb1e95729f92494406514517cce", + "outcome": "completed", + "answeredBySubmissionId": "sub_ik_af9cccb1e95729f92494406514517cce" + }, + { + "submissionId": "sub_ik_d797b4c6053e5d0a144ec1547a22e0ca", + "outcome": "completed", + "answeredBySubmissionId": "sub_ik_d797b4c6053e5d0a144ec1547a22e0ca" + } + ], + "incarnation": "inc_01M1NV5WZD6VQ76Z7C3JJRFFBA" +} diff --git a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/flue-snapshot-before.json b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/flue-snapshot-before.json new file mode 100644 index 00000000000..ab6482d39be --- /dev/null +++ b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/flue-snapshot-before.json @@ -0,0 +1,89 @@ +{ + "v": 1, + "conversationId": "conv_01M1NV5WZETMYEGGMFXNYDSTRS", + "offset": "0000000000000000_0000000000000032", + "messages": [ + { + "id": "entry_direct_c3ViX2lrXzI4ODYzMWVhYWQ3OThjYzY5MDcwZTMzMTNlOTUxYmNi", + "role": "system", + "purpose": "dispatch", + "display": "diagnostic", + "submissionId": "sub_ik_288631eaad798cc69070e3313e951bcb", + "signal": { + "tagName": "prepared-fixture", + "attributes": { + "fixtureId": "crew-reservation-v1", + "authorship": "test-authored", + "claimBoundary": "prepared-not-model-produced" + } + }, + "parts": [ + { + "type": "text", + "text": "Fixture authorship: test-authored preparation for Mission 6.\nNon-claims: not a Mission 4 candidate, not model-produced evidence, not capture-backed provenance, and not proof of automatic full-net projection.\n\n```runbook-ir\n# Final inspection and dispatch workpiece\n\n## Purpose and posture\nMaintain the narrow batch path from final inspection to dispatch readiness and test one evidence-backed correction against the live Petrinaut document.\n\n## Operational account\n- A batch that is ready enters final inspection.\n- Final inspection reserves the sole available dispatch crew.\n- Sign-off releases that crew and makes the batch ready for dispatch.\n\n## Quantity and resource policy\nExactly one dispatch crew is available in this fixture. Starting final inspection consumes that one available crew; sign-off returns it.\n\n## Current Petrinaut correspondence\nThe prepared non-empty net contains the batch path and the crew return from sign-off. It deliberately lacks the standard weight-1 input arc from `Dispatch crew available` to `Start final inspection`.\n\n## Explicit unknowns\nInspection and sign-off timing, failure modes, and recovery behavior remain unresolved.\n\n## Claim boundary\nThis prepared revision is test-authored diagnostic material. It is not model-produced evidence and does not establish capture provenance, behavioral execution, or broad projection quality.\n```", + "state": "done" + } + ] + }, + { + "id": "entry_01M1NV5XQCBVP3FC4JW5FH1WZJ", + "role": "assistant", + "purpose": "assistant", + "display": "visible", + "submissionId": "sub_ik_288631eaad798cc69070e3313e951bcb", + "turnId": "turn_01M1NV5WZH2J0S74S1Q24556EP", + "parts": [ + { + "type": "reasoning", + "text": "This is a prepared fixture for a conversation about operational process modeling using SDCPN (stochastic dynamic coloured Petri nets) in Petrinaut. Let me understand what's being presented:\n\nThe fixture describes a batch processing system with final inspection and dispatch:\n- Batches enter final inspection when ready\n- Final inspection reserves the sole available dispatch crew\n- Sign-off releases the crew and marks the batch as ready for dispatch\n- There's exactly one dispatch crew available\n\nThe fixture notes that the current Petrinaut document has a deliberate gap: it's missing the standard weight-1 input arc from \"Dispatch crew available\" to \"Start final inspection\".\n\nThe task seems to be to:\n1. Maintain this narrow batch path from final inspection to dispatch readiness\n2. Test one evidence-backed correction against the live Petrinaut document\n3. This means likely adding that missing arc\n\nThe explicit unknowns are:\n- Inspection and sign-off timing\n- Failure modes and recovery behavior\n\nThis is a test-authored diagnostic material, not model-produced evidence.\n\nBefore I proceed, I should:\n1. Activate the `sdcpn-modelling` skill since this is about SDCPN modeling\n2. Get the current Petrinaut net definition to see what we're working with\n3. Understand the current state and the specific correction needed\n\nLet me start by activating the skill and getting the current net state.", + "state": "done" + }, + { + "type": "text", + "text": "I'll help you maintain and test this final inspection and dispatch workpiece. Let me start by activating the SDCPN modelling skill and examining the current Petrinaut net definition.", + "state": "done" + }, + { + "type": "dynamic-tool", + "toolName": "activate_skill", + "toolCallId": "toolu_01Y9HuAi2cvi16UD9bTvcvfS", + "state": "output-available", + "input": { + "name": "sdcpn-modelling" + }, + "output": "Run the skill named \"sdcpn-modelling\".\n\n\n# Capability-aware lifecycle\n\nUse one conceptual lifecycle: orient, elicit or revise, maintain the workpiece, construct when supported, check, and deliver. The current conversation may expose only one branch of that lifecycle. Do not claim that an unavailable transition occurred.\n\n## Select the runtime branch\n\n### Interactive elicitation or revision\n\nInterview in the person's operational vocabulary. Activate the `elicitation` skill and read `references/profile.md` before substantive questions or revision. Read `templates/workpiece.md` when creating or materially revising the shared workpiece. Construct only when the mounted capabilities actually permit construction in this conversation.\n\n### Construct-only execution\n\nUse the supplied workpiece as the complete modelling input. Do not interview. Read `references/pn-construction.md` and `references/checks.md`, then use the mounted construction tools. If a consequential workpiece gap prevents faithful construction, report the gap and the smallest question a later interactive elicitation must answer; do not ask it or invent an answer in this conversation.\n\n## Procedure\n\n### Orient\n\nEstablish enough purpose and context to select one focused next action: the intended question or decision, audience, boundary, horizon, accuracy need, and available time. Orientation need not settle every concern before elicitation begins.\n\n### Elicit or revise\n\nFor a new account, follow one concrete case and re-evaluate the active gap after each useful answer. For an existing account, first locate the disputed or changed material and its consequence for the objective. Use the `elicitation` skill's universal guidance and `references/profile.md` for detailed operations and coverage; do not turn their register order into question order.\n\n### Maintain the workpiece\n\nTreat the workpiece as the recoverable account construction will consume. Update it after a useful stretch rather than waiting until the end. Preserve unrelated material unless new evidence affects it.\n\nWhenever the workpiece changes substantially, emit the full current document in a fenced block whose language tag is exactly `runbook-ir`. Emit it again before construction and before workpiece-only delivery. A delta or prose promise is not a recoverable workpiece.\n\n### Construct\n\nConstruct only from the current workpiece. Read `references/pn-construction.md` and `references/checks.md` before beginning. Use mounted Petrinaut tools for every net change and inspect the resulting definition rather than emitting free-form net JSON. If the required tools are absent, limit the result to the workpiece and construction-ready notes.\n\nConstruction may infer a representation from recorded operational meaning; it may not invent operational facts. Record construction inferences, approximations, defaults, and target losses in the workpiece.\n\n### Check and deliver\n\nApply `references/checks.md` whenever construction is prepared or attempted. Deliver the current workpiece in every branch. Deliver a net only when the mounted tool path has produced and checked one. State what the result can support, what remains open, what was assumed or simplified, and what the target or current tools could not represent.\n\nAn explicit stop opens no new topic. In an interactive conversation, emit the best current workpiece and any already-checked net with limitations visible. In construct-only execution, report a blocking gap rather than opening an interview.\n\n## Resource discipline\n\nRead resources directly from this skill's advertised resource list, using the exact `/.flue/packaged-skills/...` path shown in the activation briefing; the relative name is a label only. Do not treat Markdown links as includes, follow references recursively, or read construction material merely to frame ordinary interview questions.\n\n\nSupporting skill resources are available but are not loaded into context unless needed:\n\n- references/checks.md → read_skill_resource /.flue/packaged-skills/skill%3Asdcpn-modelling%3A99a447ec4bcbf6c0/references/checks.md\n- references/pn-construction.md → read_skill_resource /.flue/packaged-skills/skill%3Asdcpn-modelling%3A99a447ec4bcbf6c0/references/pn-construction.md\n- references/profile.md → read_skill_resource /.flue/packaged-skills/skill%3Asdcpn-modelling%3A99a447ec4bcbf6c0/references/profile.md\n- templates/workpiece.md → read_skill_resource /.flue/packaged-skills/skill%3Asdcpn-modelling%3A99a447ec4bcbf6c0/templates/workpiece.md\n", + "durationMs": 1 + }, + { + "type": "dynamic-tool", + "toolName": "getLatestNetDefinition", + "toolCallId": "toolu_018ayLcg31aA5nZjvPe3VLEz", + "state": "output-available", + "input": {}, + "output": { + "awaiting": "client" + }, + "durationMs": 1 + }, + { + "type": "reasoning", + "text": "The getLatestNetDefinition returned awaiting client signal, meaning the client needs to load the current document. I should wait for that and then proceed. But let me think about what to do next.\n\nThe skill has been activated successfully. Now I need to:\n1. Wait for the net definition from the client\n2. Read the workpiece template to understand how to structure the workpiece\n3. Understand the current gaps and what needs to be corrected\n\nBased on the prepared fixture, the key issue is:\n- The current Petrinaut document is missing the weight-1 input arc from \"Dispatch crew available\" to \"Start final inspection\"\n- This is a deliberate gap that we need to test correcting\n\nLet me wait for the client signal and then proceed with getting the live document and understanding what needs to be corrected.", + "state": "done" + }, + { + "type": "text", + "text": "The skill is now active. I'm awaiting the current Petrinaut net definition from the client. Once that arrives, I'll examine the current state and identify the specific gap mentioned in the fixture—the missing input arc from `Dispatch crew available` to `Start final inspection`—and we can verify the evidence-backed correction.\n\nThe fixture establishes a clear scope:\n- **Operational focus**: The narrow batch path from final inspection through dispatch readiness\n- **Resource constraint**: Exactly one dispatch crew available, reserved during inspection, returned at sign-off\n- **Known gap**: Missing standard weight-1 arc from crew availability to the start of inspection\n- **Boundary**: Timing, failure modes, and recovery are explicitly unresolved\n\nI'm ready to proceed once the net definition loads. What would you like to examine or correct first?", + "state": "done" + } + ] + } + ], + "settlements": [ + { + "submissionId": "sub_ik_288631eaad798cc69070e3313e951bcb", + "outcome": "completed", + "answeredBySubmissionId": "sub_ik_288631eaad798cc69070e3313e951bcb" + } + ], + "incarnation": "inc_01M1NV5WZD6VQ76Z7C3JJRFFBA" +} diff --git a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/flue-snapshot-tab-b.json b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/flue-snapshot-tab-b.json new file mode 100644 index 00000000000..c0f8e5b5153 --- /dev/null +++ b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/flue-snapshot-tab-b.json @@ -0,0 +1,326 @@ +{ + "v": 1, + "conversationId": "conv_01M1NV5WZETMYEGGMFXNYDSTRS", + "offset": "0000000000000000_0000000000000110", + "messages": [ + { + "id": "entry_direct_c3ViX2lrXzI4ODYzMWVhYWQ3OThjYzY5MDcwZTMzMTNlOTUxYmNi", + "role": "system", + "purpose": "dispatch", + "display": "diagnostic", + "submissionId": "sub_ik_288631eaad798cc69070e3313e951bcb", + "signal": { + "tagName": "prepared-fixture", + "attributes": { + "fixtureId": "crew-reservation-v1", + "authorship": "test-authored", + "claimBoundary": "prepared-not-model-produced" + } + }, + "parts": [ + { + "type": "text", + "text": "Fixture authorship: test-authored preparation for Mission 6.\nNon-claims: not a Mission 4 candidate, not model-produced evidence, not capture-backed provenance, and not proof of automatic full-net projection.\n\n```runbook-ir\n# Final inspection and dispatch workpiece\n\n## Purpose and posture\nMaintain the narrow batch path from final inspection to dispatch readiness and test one evidence-backed correction against the live Petrinaut document.\n\n## Operational account\n- A batch that is ready enters final inspection.\n- Final inspection reserves the sole available dispatch crew.\n- Sign-off releases that crew and makes the batch ready for dispatch.\n\n## Quantity and resource policy\nExactly one dispatch crew is available in this fixture. Starting final inspection consumes that one available crew; sign-off returns it.\n\n## Current Petrinaut correspondence\nThe prepared non-empty net contains the batch path and the crew return from sign-off. It deliberately lacks the standard weight-1 input arc from `Dispatch crew available` to `Start final inspection`.\n\n## Explicit unknowns\nInspection and sign-off timing, failure modes, and recovery behavior remain unresolved.\n\n## Claim boundary\nThis prepared revision is test-authored diagnostic material. It is not model-produced evidence and does not establish capture provenance, behavioral execution, or broad projection quality.\n```", + "state": "done" + } + ] + }, + { + "id": "entry_01M1NV5XQCBVP3FC4JW5FH1WZJ", + "role": "assistant", + "purpose": "assistant", + "display": "visible", + "submissionId": "sub_ik_288631eaad798cc69070e3313e951bcb", + "turnId": "turn_01M1NV5WZH2J0S74S1Q24556EP", + "parts": [ + { + "type": "reasoning", + "text": "This is a prepared fixture for a conversation about operational process modeling using SDCPN (stochastic dynamic coloured Petri nets) in Petrinaut. Let me understand what's being presented:\n\nThe fixture describes a batch processing system with final inspection and dispatch:\n- Batches enter final inspection when ready\n- Final inspection reserves the sole available dispatch crew\n- Sign-off releases the crew and marks the batch as ready for dispatch\n- There's exactly one dispatch crew available\n\nThe fixture notes that the current Petrinaut document has a deliberate gap: it's missing the standard weight-1 input arc from \"Dispatch crew available\" to \"Start final inspection\".\n\nThe task seems to be to:\n1. Maintain this narrow batch path from final inspection to dispatch readiness\n2. Test one evidence-backed correction against the live Petrinaut document\n3. This means likely adding that missing arc\n\nThe explicit unknowns are:\n- Inspection and sign-off timing\n- Failure modes and recovery behavior\n\nThis is a test-authored diagnostic material, not model-produced evidence.\n\nBefore I proceed, I should:\n1. Activate the `sdcpn-modelling` skill since this is about SDCPN modeling\n2. Get the current Petrinaut net definition to see what we're working with\n3. Understand the current state and the specific correction needed\n\nLet me start by activating the skill and getting the current net state.", + "state": "done" + }, + { + "type": "text", + "text": "I'll help you maintain and test this final inspection and dispatch workpiece. Let me start by activating the SDCPN modelling skill and examining the current Petrinaut net definition.", + "state": "done" + }, + { + "type": "dynamic-tool", + "toolName": "activate_skill", + "toolCallId": "toolu_01Y9HuAi2cvi16UD9bTvcvfS", + "state": "output-available", + "input": { + "name": "sdcpn-modelling" + }, + "output": "Run the skill named \"sdcpn-modelling\".\n\n\n# Capability-aware lifecycle\n\nUse one conceptual lifecycle: orient, elicit or revise, maintain the workpiece, construct when supported, check, and deliver. The current conversation may expose only one branch of that lifecycle. Do not claim that an unavailable transition occurred.\n\n## Select the runtime branch\n\n### Interactive elicitation or revision\n\nInterview in the person's operational vocabulary. Activate the `elicitation` skill and read `references/profile.md` before substantive questions or revision. Read `templates/workpiece.md` when creating or materially revising the shared workpiece. Construct only when the mounted capabilities actually permit construction in this conversation.\n\n### Construct-only execution\n\nUse the supplied workpiece as the complete modelling input. Do not interview. Read `references/pn-construction.md` and `references/checks.md`, then use the mounted construction tools. If a consequential workpiece gap prevents faithful construction, report the gap and the smallest question a later interactive elicitation must answer; do not ask it or invent an answer in this conversation.\n\n## Procedure\n\n### Orient\n\nEstablish enough purpose and context to select one focused next action: the intended question or decision, audience, boundary, horizon, accuracy need, and available time. Orientation need not settle every concern before elicitation begins.\n\n### Elicit or revise\n\nFor a new account, follow one concrete case and re-evaluate the active gap after each useful answer. For an existing account, first locate the disputed or changed material and its consequence for the objective. Use the `elicitation` skill's universal guidance and `references/profile.md` for detailed operations and coverage; do not turn their register order into question order.\n\n### Maintain the workpiece\n\nTreat the workpiece as the recoverable account construction will consume. Update it after a useful stretch rather than waiting until the end. Preserve unrelated material unless new evidence affects it.\n\nWhenever the workpiece changes substantially, emit the full current document in a fenced block whose language tag is exactly `runbook-ir`. Emit it again before construction and before workpiece-only delivery. A delta or prose promise is not a recoverable workpiece.\n\n### Construct\n\nConstruct only from the current workpiece. Read `references/pn-construction.md` and `references/checks.md` before beginning. Use mounted Petrinaut tools for every net change and inspect the resulting definition rather than emitting free-form net JSON. If the required tools are absent, limit the result to the workpiece and construction-ready notes.\n\nConstruction may infer a representation from recorded operational meaning; it may not invent operational facts. Record construction inferences, approximations, defaults, and target losses in the workpiece.\n\n### Check and deliver\n\nApply `references/checks.md` whenever construction is prepared or attempted. Deliver the current workpiece in every branch. Deliver a net only when the mounted tool path has produced and checked one. State what the result can support, what remains open, what was assumed or simplified, and what the target or current tools could not represent.\n\nAn explicit stop opens no new topic. In an interactive conversation, emit the best current workpiece and any already-checked net with limitations visible. In construct-only execution, report a blocking gap rather than opening an interview.\n\n## Resource discipline\n\nRead resources directly from this skill's advertised resource list, using the exact `/.flue/packaged-skills/...` path shown in the activation briefing; the relative name is a label only. Do not treat Markdown links as includes, follow references recursively, or read construction material merely to frame ordinary interview questions.\n\n\nSupporting skill resources are available but are not loaded into context unless needed:\n\n- references/checks.md → read_skill_resource /.flue/packaged-skills/skill%3Asdcpn-modelling%3A99a447ec4bcbf6c0/references/checks.md\n- references/pn-construction.md → read_skill_resource /.flue/packaged-skills/skill%3Asdcpn-modelling%3A99a447ec4bcbf6c0/references/pn-construction.md\n- references/profile.md → read_skill_resource /.flue/packaged-skills/skill%3Asdcpn-modelling%3A99a447ec4bcbf6c0/references/profile.md\n- templates/workpiece.md → read_skill_resource /.flue/packaged-skills/skill%3Asdcpn-modelling%3A99a447ec4bcbf6c0/templates/workpiece.md\n", + "durationMs": 1 + }, + { + "type": "dynamic-tool", + "toolName": "getLatestNetDefinition", + "toolCallId": "toolu_018ayLcg31aA5nZjvPe3VLEz", + "state": "output-available", + "input": {}, + "output": { + "awaiting": "client" + }, + "durationMs": 1 + }, + { + "type": "reasoning", + "text": "The getLatestNetDefinition returned awaiting client signal, meaning the client needs to load the current document. I should wait for that and then proceed. But let me think about what to do next.\n\nThe skill has been activated successfully. Now I need to:\n1. Wait for the net definition from the client\n2. Read the workpiece template to understand how to structure the workpiece\n3. Understand the current gaps and what needs to be corrected\n\nBased on the prepared fixture, the key issue is:\n- The current Petrinaut document is missing the weight-1 input arc from \"Dispatch crew available\" to \"Start final inspection\"\n- This is a deliberate gap that we need to test correcting\n\nLet me wait for the client signal and then proceed with getting the live document and understanding what needs to be corrected.", + "state": "done" + }, + { + "type": "text", + "text": "The skill is now active. I'm awaiting the current Petrinaut net definition from the client. Once that arrives, I'll examine the current state and identify the specific gap mentioned in the fixture—the missing input arc from `Dispatch crew available` to `Start final inspection`—and we can verify the evidence-backed correction.\n\nThe fixture establishes a clear scope:\n- **Operational focus**: The narrow batch path from final inspection through dispatch readiness\n- **Resource constraint**: Exactly one dispatch crew available, reserved during inspection, returned at sign-off\n- **Known gap**: Missing standard weight-1 arc from crew availability to the start of inspection\n- **Boundary**: Timing, failure modes, and recovery are explicitly unresolved\n\nI'm ready to proceed once the net definition loads. What would you like to examine or correct first?", + "state": "done" + } + ] + }, + { + "id": "entry_direct_c3ViX2lrXzIzMzcwMWRlZDcxMDVkNWQ0M2M0YjhhZTI1MTRlYzhi", + "role": "user", + "purpose": "user", + "display": "visible", + "submissionId": "sub_ik_233701ded7105d5d43c4b8ae2514ec8b", + "parts": [ + { + "type": "text", + "text": "Confirmed: final inspection uses the single dispatch crew and sign-off releases it; timing, failure, and recovery remain unknown. Read the live Petrinaut definition, add the missing standard weight-1 input arc from Dispatch crew available to Start final inspection, verify it, and emit the full revised runbook-ir workpiece. In that revised workpiece, identify the revision itself as model-produced from test-authored revision zero; do not call the revised workpiece test-authored.", + "state": "done" + } + ] + }, + { + "id": "entry_01M1NV68Q36Q2ZMVFVMR3A2J1D", + "role": "assistant", + "purpose": "assistant", + "display": "visible", + "submissionId": "sub_ik_233701ded7105d5d43c4b8ae2514ec8b", + "turnId": "turn_01M1NV67W787NJDB98B4DVTMA1", + "parts": [ + { + "type": "reasoning", + "text": "The user wants me to:\n1. Read the live Petrinaut net definition\n2. Add the missing standard weight-1 input arc from \"Dispatch crew available\" to \"Start final inspection\"\n3. Verify the change\n4. Emit the full revised runbook-ir workpiece\n5. Label the revised workpiece as model-produced from test-authored revision zero (not test-authored itself)\n\nLet me start by reading the live definition, then adding the arc, then verifying it, and finally emitting the revised workpiece.", + "state": "done" + }, + { + "type": "dynamic-tool", + "toolName": "getLatestNetDefinition", + "toolCallId": "toolu_016Jkt4shRUg8hmtq6YyfcFB", + "state": "output-available", + "input": {}, + "output": { + "awaiting": "client" + }, + "durationMs": 1 + } + ] + }, + { + "id": "entry_direct_c3ViX2lrX2EzOGIxMTMzYjdjN2M2NWJmOGYwNzgxNGQyM2JjYmNi", + "role": "system", + "purpose": "dispatch", + "display": "diagnostic", + "submissionId": "sub_ik_a38b1133b7c7c65bf8f07814d23bcbcb", + "signal": { + "tagName": "client-tool-result", + "attributes": { + "toolCallIds": "toolu_016Jkt4shRUg8hmtq6YyfcFB" + } + }, + "parts": [ + { + "type": "text", + "text": "[{\"toolCallId\":\"toolu_016Jkt4shRUg8hmtq6YyfcFB\",\"toolName\":\"getLatestNetDefinition\",\"output\":{\"title\":\"Prepared final inspection and dispatch\",\"definition\":{\"places\":[{\"id\":\"batch-ready\",\"name\":\"Batch ready\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":80,\"y\":100},{\"id\":\"under-final-inspection\",\"name\":\"Under final inspection\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":420,\"y\":100},{\"id\":\"ready-for-dispatch\",\"name\":\"Ready for dispatch\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":760,\"y\":100},{\"id\":\"dispatch-crew-available\",\"name\":\"Dispatch crew available\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":420,\"y\":360}],\"transitions\":[{\"id\":\"start-final-inspection\",\"name\":\"Start final inspection\",\"inputArcs\":[{\"placeId\":\"batch-ready\",\"weight\":1,\"type\":\"standard\"}],\"outputArcs\":[{\"placeId\":\"under-final-inspection\",\"weight\":1}],\"lambdaType\":\"predicate\",\"lambdaCode\":\"\",\"transitionKernelCode\":\"\",\"x\":250,\"y\":100},{\"id\":\"sign-off\",\"name\":\"Sign-off\",\"inputArcs\":[{\"placeId\":\"under-final-inspection\",\"weight\":1,\"type\":\"standard\"}],\"outputArcs\":[{\"placeId\":\"ready-for-dispatch\",\"weight\":1},{\"placeId\":\"dispatch-crew-available\",\"weight\":1}],\"lambdaType\":\"predicate\",\"lambdaCode\":\"\",\"transitionKernelCode\":\"\",\"x\":590,\"y\":100}],\"types\":[],\"differentialEquations\":[],\"parameters\":[]},\"extensions\":{\"colors\":true,\"stochasticity\":true,\"dynamics\":true,\"parameters\":true,\"subnets\":true}}}]", + "state": "done" + } + ] + }, + { + "id": "entry_01M1NV6ARKVMJTM74GVBKS6VW4", + "role": "assistant", + "purpose": "assistant", + "display": "visible", + "submissionId": "sub_ik_a38b1133b7c7c65bf8f07814d23bcbcb", + "turnId": "turn_01M1NV6A1766CSNYQR9H1HEBKH", + "parts": [ + { + "type": "reasoning", + "text": "The net definition has been loaded. Let me analyze the current state:\n\n**Current state:**\n- Places:\n - `batch-ready`: Batch waiting for final inspection\n - `under-final-inspection`: Batch undergoing final inspection\n - `ready-for-dispatch`: Batch ready for dispatch\n - `dispatch-crew-available`: Dispatch crew available (resource)\n\n- Transitions:\n - `start-final-inspection`: Takes a batch from `batch-ready` to `under-final-inspection`. It has one input arc from `batch-ready` with weight 1.\n - `sign-off`: Takes a batch from `under-final-inspection` to `ready-for-dispatch` and returns the crew to `dispatch-crew-available`. Has input arc from `under-final-inspection` (weight 1) and output arcs to both `ready-for-dispatch` and `dispatch-crew-available`.\n\n**The missing arc:**\nThe fixture states that the missing arc is: standard weight-1 input arc from `Dispatch crew available` to `Start final inspection`.\n\nCurrently, `start-final-inspection` only has one input arc from `batch-ready`. It needs an additional input arc from `dispatch-crew-available` with weight 1 and type \"standard\".\n\n**What needs to happen:**\n1. Add an input arc to the `start-final-inspection` transition from the `dispatch-crew-available` place with weight 1 and type \"standard\"\n2. Verify the result\n3. Emit the full revised workpiece with the identification that this is model-produced from test-authored revision zero\n\nLet me use the addArc function to add this arc.\n\nThe parameters for addArc based on the schema:\n- transitionId: \"start-final-inspection\"\n- arcDirection: \"input\"\n- placeId: \"dispatch-crew-available\" (since we're using the legacy shorthand)\n- weight: 1\n- type: \"standard\"\n- targetSubnetId omitted, since this operates on the root net", + "state": "done" + }, + { + "type": "dynamic-tool", + "toolName": "addArc", + "toolCallId": "toolu_01BQukCZTAhJ64VNE7oC1CWG", + "state": "output-available", + "input": { + "transitionId": "start-final-inspection", + "arcDirection": "input", + "placeId": "dispatch-crew-available", + "weight": "1", + "type": "standard" + }, + "output": { + "awaiting": "client" + }, + "durationMs": 0 + } + ] + }, + { + "id": "entry_direct_c3ViX2lrX2FmOWNjY2IxZTk1NzI5ZjkyNDk0NDA2NTE0NTE3Y2Nl", + "role": "system", + "purpose": "dispatch", + "display": "diagnostic", + "submissionId": "sub_ik_af9cccb1e95729f92494406514517cce", + "signal": { + "tagName": "client-tool-result", + "attributes": { + "toolCallIds": "toolu_016Jkt4shRUg8hmtq6YyfcFB,toolu_01BQukCZTAhJ64VNE7oC1CWG" + } + }, + "parts": [ + { + "type": "text", + "text": "[{\"toolCallId\":\"toolu_016Jkt4shRUg8hmtq6YyfcFB\",\"toolName\":\"getLatestNetDefinition\",\"output\":{\"title\":\"Prepared final inspection and dispatch\",\"definition\":{\"places\":[{\"id\":\"batch-ready\",\"name\":\"Batch ready\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":80,\"y\":100},{\"id\":\"under-final-inspection\",\"name\":\"Under final inspection\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":420,\"y\":100},{\"id\":\"ready-for-dispatch\",\"name\":\"Ready for dispatch\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":760,\"y\":100},{\"id\":\"dispatch-crew-available\",\"name\":\"Dispatch crew available\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":420,\"y\":360}],\"transitions\":[{\"id\":\"start-final-inspection\",\"name\":\"Start final inspection\",\"inputArcs\":[{\"placeId\":\"batch-ready\",\"weight\":1,\"type\":\"standard\"}],\"outputArcs\":[{\"placeId\":\"under-final-inspection\",\"weight\":1}],\"lambdaType\":\"predicate\",\"lambdaCode\":\"\",\"transitionKernelCode\":\"\",\"x\":250,\"y\":100},{\"id\":\"sign-off\",\"name\":\"Sign-off\",\"inputArcs\":[{\"placeId\":\"under-final-inspection\",\"weight\":1,\"type\":\"standard\"}],\"outputArcs\":[{\"placeId\":\"ready-for-dispatch\",\"weight\":1},{\"placeId\":\"dispatch-crew-available\",\"weight\":1}],\"lambdaType\":\"predicate\",\"lambdaCode\":\"\",\"transitionKernelCode\":\"\",\"x\":590,\"y\":100}],\"types\":[],\"differentialEquations\":[],\"parameters\":[]},\"extensions\":{\"colors\":true,\"stochasticity\":true,\"dynamics\":true,\"parameters\":true,\"subnets\":true}}},{\"toolCallId\":\"toolu_01BQukCZTAhJ64VNE7oC1CWG\",\"toolName\":\"addArc\",\"output\":{\"title\":\"Added input arc\",\"detail\":\"Dispatch crew available <-> Start final inspection\",\"target\":{\"kind\":\"selection\",\"item\":{\"type\":\"arc\",\"id\":\"$A_place:dispatch-crew-available___start-final-inspection\"}},\"applied\":true}}]", + "state": "done" + } + ] + }, + { + "id": "entry_01M1NV6HRWJHSZ3QD2V8RZEWV3", + "role": "assistant", + "purpose": "assistant", + "display": "visible", + "submissionId": "sub_ik_af9cccb1e95729f92494406514517cce", + "turnId": "turn_01M1NV6GV7Q0BAMD0S09EEAY1E", + "parts": [ + { + "type": "reasoning", + "text": "Good! The arc has been added successfully. The tool output shows:\n- \"Applied: true\" - the arc was successfully added\n- Detail: \"Dispatch crew available <-> Start final inspection\"\n- The arc ID is \"$A_place:dispatch-crew-available___start-final-inspection\"\n\nNow I need to read the live net definition again to verify the change was applied correctly, then emit the revised workpiece with the full Markdown document showing the state of the net with the arc now in place.", + "state": "done" + }, + { + "type": "dynamic-tool", + "toolName": "getLatestNetDefinition", + "toolCallId": "toolu_017Ze5BnyBGXdaw7DJSGxZQb", + "state": "output-available", + "input": {}, + "output": { + "awaiting": "client" + }, + "durationMs": 0 + } + ] + }, + { + "id": "entry_direct_c3ViX2lrX2Q3OTdiNGM2MDUzZTVkMGExNDRlYzE1NDdhMjJlMGNh", + "role": "system", + "purpose": "dispatch", + "display": "diagnostic", + "submissionId": "sub_ik_d797b4c6053e5d0a144ec1547a22e0ca", + "signal": { + "tagName": "client-tool-result", + "attributes": { + "toolCallIds": "toolu_016Jkt4shRUg8hmtq6YyfcFB,toolu_01BQukCZTAhJ64VNE7oC1CWG,toolu_017Ze5BnyBGXdaw7DJSGxZQb" + } + }, + "parts": [ + { + "type": "text", + "text": "[{\"toolCallId\":\"toolu_016Jkt4shRUg8hmtq6YyfcFB\",\"toolName\":\"getLatestNetDefinition\",\"output\":{\"title\":\"Prepared final inspection and dispatch\",\"definition\":{\"places\":[{\"id\":\"batch-ready\",\"name\":\"Batch ready\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":80,\"y\":100},{\"id\":\"under-final-inspection\",\"name\":\"Under final inspection\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":420,\"y\":100},{\"id\":\"ready-for-dispatch\",\"name\":\"Ready for dispatch\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":760,\"y\":100},{\"id\":\"dispatch-crew-available\",\"name\":\"Dispatch crew available\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":420,\"y\":360}],\"transitions\":[{\"id\":\"start-final-inspection\",\"name\":\"Start final inspection\",\"inputArcs\":[{\"placeId\":\"batch-ready\",\"weight\":1,\"type\":\"standard\"}],\"outputArcs\":[{\"placeId\":\"under-final-inspection\",\"weight\":1}],\"lambdaType\":\"predicate\",\"lambdaCode\":\"\",\"transitionKernelCode\":\"\",\"x\":250,\"y\":100},{\"id\":\"sign-off\",\"name\":\"Sign-off\",\"inputArcs\":[{\"placeId\":\"under-final-inspection\",\"weight\":1,\"type\":\"standard\"}],\"outputArcs\":[{\"placeId\":\"ready-for-dispatch\",\"weight\":1},{\"placeId\":\"dispatch-crew-available\",\"weight\":1}],\"lambdaType\":\"predicate\",\"lambdaCode\":\"\",\"transitionKernelCode\":\"\",\"x\":590,\"y\":100}],\"types\":[],\"differentialEquations\":[],\"parameters\":[]},\"extensions\":{\"colors\":true,\"stochasticity\":true,\"dynamics\":true,\"parameters\":true,\"subnets\":true}}},{\"toolCallId\":\"toolu_01BQukCZTAhJ64VNE7oC1CWG\",\"toolName\":\"addArc\",\"output\":{\"title\":\"Added input arc\",\"detail\":\"Dispatch crew available <-> Start final inspection\",\"target\":{\"kind\":\"selection\",\"item\":{\"type\":\"arc\",\"id\":\"$A_place:dispatch-crew-available___start-final-inspection\"}},\"applied\":true}},{\"toolCallId\":\"toolu_017Ze5BnyBGXdaw7DJSGxZQb\",\"toolName\":\"getLatestNetDefinition\",\"output\":{\"title\":\"Prepared final inspection and dispatch\",\"definition\":{\"places\":[{\"id\":\"batch-ready\",\"name\":\"Batch ready\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":80,\"y\":100},{\"id\":\"under-final-inspection\",\"name\":\"Under final inspection\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":420,\"y\":100},{\"id\":\"ready-for-dispatch\",\"name\":\"Ready for dispatch\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":760,\"y\":100},{\"id\":\"dispatch-crew-available\",\"name\":\"Dispatch crew available\",\"colorId\":null,\"dynamicsEnabled\":false,\"differentialEquationId\":null,\"x\":420,\"y\":360}],\"transitions\":[{\"id\":\"start-final-inspection\",\"name\":\"Start final inspection\",\"inputArcs\":[{\"placeId\":\"batch-ready\",\"weight\":1,\"type\":\"standard\"},{\"type\":\"standard\",\"placeId\":\"dispatch-crew-available\",\"weight\":1}],\"outputArcs\":[{\"placeId\":\"under-final-inspection\",\"weight\":1}],\"lambdaType\":\"predicate\",\"lambdaCode\":\"\",\"transitionKernelCode\":\"\",\"x\":250,\"y\":100},{\"id\":\"sign-off\",\"name\":\"Sign-off\",\"inputArcs\":[{\"placeId\":\"under-final-inspection\",\"weight\":1,\"type\":\"standard\"}],\"outputArcs\":[{\"placeId\":\"ready-for-dispatch\",\"weight\":1},{\"placeId\":\"dispatch-crew-available\",\"weight\":1}],\"lambdaType\":\"predicate\",\"lambdaCode\":\"\",\"transitionKernelCode\":\"\",\"x\":590,\"y\":100}],\"types\":[],\"differentialEquations\":[],\"parameters\":[]},\"extensions\":{\"colors\":true,\"stochasticity\":true,\"dynamics\":true,\"parameters\":true,\"subnets\":true}}}]", + "state": "done" + } + ] + }, + { + "id": "entry_01M1NV6M4SBXB2WA46SM1B8QM3", + "role": "assistant", + "purpose": "assistant", + "display": "visible", + "submissionId": "sub_ik_d797b4c6053e5d0a144ec1547a22e0ca", + "turnId": "turn_01M1NV6KB8F7QJTRYHX0WT8AG5", + "parts": [ + { + "type": "reasoning", + "text": "Good! The arc has been successfully added. Looking at the final net definition, I can confirm:\n\n1. The arc was added successfully: `addArc` returned `\"applied\":true` with detail \"Dispatch crew available <-> Start final inspection\"\n\n2. In the final `getLatestNetDefinition` result, I can see that the `start-final-inspection` transition now has TWO input arcs:\n - `{\"placeId\":\"batch-ready\",\"weight\":1,\"type\":\"standard\"}`\n - `{\"type\":\"standard\",\"placeId\":\"dispatch-crew-available\",\"weight\":1\"}`\n\nThis confirms the missing arc from `Dispatch crew available` (weight 1, standard type) to `Start final inspection` is now in place.\n\nThe net structure is now:\n- **Places**: batch-ready, under-final-inspection, ready-for-dispatch, dispatch-crew-available\n- **Transitions**:\n - `start-final-inspection`: Takes a batch from batch-ready AND a crew token from dispatch-crew-available, produces under-final-inspection\n - `sign-off`: Takes under-final-inspection, produces both ready-for-dispatch AND returns dispatch-crew-available (crew token)\n\nThis correctly models the resource constraint: the single dispatch crew is reserved during inspection (consumed by start-final-inspection) and released at sign-off (produced by sign-off).\n\nNow I need to emit the revised runbook-ir workpiece, marking the revision as model-produced from test-authored revision zero.", + "state": "done" + }, + { + "type": "text", + "text": "✓ **Arc added successfully.** The Petrinaut tool confirms: `\"applied\":true` with detail \"Dispatch crew available ↔ Start final inspection\".\n\n**Verification of revised net structure:**\n- `Start final inspection` transition now has two standard input arcs (weight 1 each):\n 1. From `Batch ready` (original)\n 2. From `Dispatch crew available` (added, evidence-backed correction)\n- `Sign-off` transition correctly returns the crew token to `Dispatch crew available` (weight 1, output arc)\n\nThis enforces the resource constraint: the single dispatch crew is consumed when final inspection begins and restored at sign-off.\n\n---\n\n## Revised Workpiece (Model-Produced from Test-Authored Revision Zero)\n\n```runbook-ir\n# Final inspection and dispatch batch path\n\n## Purpose and posture\nModel the narrow batch path from final inspection to dispatch readiness with single-crew resource constraint. This revision incorporates the evidence-backed correction of the missing crew-availability input arc.\n\n## Operational account\n- A batch that is ready enters final inspection.\n- Final inspection requires and reserves the sole available dispatch crew.\n- Sign-off releases that crew and marks the batch ready for dispatch.\n\n## Quantity and resource policy\nExactly one dispatch crew is available in this system. Starting final inspection consumes that one available crew token; sign-off returns it. At most one batch can be under final inspection at a time because the sole crew is needed and cannot be in two places simultaneously.\n\n## Net structure (model-produced)\n**Places:**\n- `Batch ready`: batches waiting for inspection\n- `Under final inspection`: batches currently being inspected\n- `Ready for dispatch`: batches completed and awaiting dispatch\n- `Dispatch crew available`: availability token for the single crew (capacity 1)\n\n**Transitions:**\n- `Start final inspection`: consumes 1 batch token from `Batch ready` AND 1 crew token from `Dispatch crew available`; produces 1 token in `Under final inspection`\n- `Sign-off`: consumes 1 token from `Under final inspection`; produces 1 token each in `Ready for dispatch` and `Dispatch crew available` (returns the crew)\n\n**Arcs:**\n- `Batch ready` → `Start final inspection` (standard, weight 1) — original\n- `Dispatch crew available` → `Start final inspection` (standard, weight 1) — added in revision\n- `Start final inspection` → `Under final inspection` (standard, weight 1) — original\n- `Under final inspection` → `Sign-off` (standard, weight 1) — original\n- `Sign-off` → `Ready for dispatch` (standard, weight 1) — original\n- `Sign-off` → `Dispatch crew available` (standard, weight 1) — original\n\n## Explicit unknowns\n- Inspection and sign-off timing and duration\n- Failure modes, defect outcomes, and recovery behavior\n- Initial batch population and crew availability state\n- Repeat or recycling scenarios\n\n## Revision record\n**Revision 0** (test-authored): Prepared fixture identified missing standard weight-1 input arc from `Dispatch crew available` to `Start final inspection`.\n\n**Revision 1** (model-produced): Arc added via Petrinaut `addArc` tool and verified in net definition. Crew-availability constraint now enforced at net semantics level.\n\n## Claim boundary\nThis revision is model-produced evidence of arc correction applied to the test-authored source. It does not establish timing behavior, failure recovery, execution performance, or projection beyond this narrow batch-crew-inspection path.\n```", + "state": "done" + } + ] + }, + { + "id": "entry_direct_c3ViX2lrX2IyZjk2ZmQ2MmI4MGE2ZGNmOTgwMzI5YWQ2MWY3MGU5", + "role": "user", + "purpose": "user", + "display": "visible", + "submissionId": "sub_ik_b2f96fd62b80a6dcf980329ad61f70e9", + "parts": [ + { + "type": "text", + "text": "From the resumed workpiece, list the unresolved timing, failure, and recovery questions. Do not change the Petrinaut net.", + "state": "done" + } + ] + }, + { + "id": "entry_01M1NV73Z110CY393GEB8T02SH", + "role": "assistant", + "purpose": "assistant", + "display": "visible", + "submissionId": "sub_ik_b2f96fd62b80a6dcf980329ad61f70e9", + "turnId": "turn_01M1NV7343YW19DZKMTGEDCWTF", + "parts": [ + { + "type": "reasoning", + "text": "The user is asking me to list the unresolved timing, failure, and recovery questions from the workpiece I just provided. They explicitly say not to change the Petrinaut net, so this is purely an analytical question about what remains open in the model.\n\nLet me look at the \"Explicit unknowns\" section I provided:\n- Inspection and sign-off timing and duration\n- Failure modes, defect outcomes, and recovery behavior\n- Initial batch population and crew availability state\n- Repeat or recycling scenarios\n\nBut the user wants me to be more specific about the timing, failure, and recovery questions. I should expand these into actual concrete questions that would need to be answered to make the model complete. Let me think about what operational questions are unresolved:\n\n**Timing questions:**\n- How long does final inspection take?\n- How long does sign-off take?\n- Are inspection and sign-off separate durations or combined?\n- Can inspection occur in parallel for multiple batches if crew were available?\n\n**Failure questions:**\n- What happens if a batch fails inspection?\n- Can inspection fail entirely or does sign-off always succeed?\n- Are there defect categories (reject, rework, accept)?\n- Does a failed batch consume the crew resource?\n\n**Recovery questions:**\n- If a batch fails inspection, where does it go? (Back to ready? To a separate fail queue? Removed entirely?)\n- Does failed inspection release the crew immediately, or after some remediation?\n- Can a reworked batch re-enter the inspection process?\n- What is the relationship between failed batches and crew availability?\n\nLet me provide a structured list of these unresolved questions organized by category.", + "state": "done" + }, + { + "type": "text", + "text": "## Unresolved Timing, Failure, and Recovery Questions\n\n### Timing\n1. **Inspection duration**: What is the stochastic or deterministic duration of the final inspection phase (from \"Start final inspection\" to \"Sign-off\")?\n2. **Sign-off duration**: Does \"Sign-off\" occur instantaneously, or does it have its own duration separate from inspection?\n3. **Crew engagement horizon**: Is the crew occupied only during the inspection phase, or does it remain engaged during batches' time in \"Ready for dispatch\"?\n4. **Parallel inspection capacity**: If additional crews became available, could multiple batches be inspected concurrently, or is there a single-batch constraint in the process?\n\n### Failure and Defect Outcomes\n1. **Inspection failure mode**: Can a batch fail inspection? If so, under what conditions?\n2. **Failure rate**: Is there a known or modeled probability that inspection produces a defect or rejection?\n3. **Defect categories**: Are there multiple outcomes (accept, reject, rework required)? If so, what distinguishes them?\n4. **Sign-off contingency**: Can sign-off always succeed after inspection, or can sign-off itself reject a batch?\n5. **Scrap or return**: What happens to batches that fail? Are they removed from the system, returned to \"Batch ready,\" sent to a separate rework queue, or diverted elsewhere?\n\n### Recovery and Rework Behavior\n1. **Failed batch crew release**: When a batch fails inspection, is the crew released immediately, or must it complete additional work before returning to availability?\n2. **Rework entry point**: If a batch requires rework, does it re-enter \"Batch ready,\" or is there a separate rework-staging place?\n3. **Rework limit**: Is there a maximum number of rework cycles, or can a batch cycle indefinitely?\n4. **Crew allocation to rework**: Does rework use the same dispatch crew, a different crew, or no dedicated crew?\n5. **Initial state**: How many batches start in \"Batch ready\" and how is \"Dispatch crew available\" initialized (1 token, or variable)?", + "state": "done" + } + ] + } + ], + "settlements": [ + { + "submissionId": "sub_ik_288631eaad798cc69070e3313e951bcb", + "outcome": "completed", + "answeredBySubmissionId": "sub_ik_288631eaad798cc69070e3313e951bcb" + }, + { + "submissionId": "sub_ik_233701ded7105d5d43c4b8ae2514ec8b", + "outcome": "completed", + "answeredBySubmissionId": "sub_ik_233701ded7105d5d43c4b8ae2514ec8b" + }, + { + "submissionId": "sub_ik_a38b1133b7c7c65bf8f07814d23bcbcb", + "outcome": "completed", + "answeredBySubmissionId": "sub_ik_a38b1133b7c7c65bf8f07814d23bcbcb" + }, + { + "submissionId": "sub_ik_af9cccb1e95729f92494406514517cce", + "outcome": "completed", + "answeredBySubmissionId": "sub_ik_af9cccb1e95729f92494406514517cce" + }, + { + "submissionId": "sub_ik_d797b4c6053e5d0a144ec1547a22e0ca", + "outcome": "completed", + "answeredBySubmissionId": "sub_ik_d797b4c6053e5d0a144ec1547a22e0ca" + }, + { + "submissionId": "sub_ik_b2f96fd62b80a6dcf980329ad61f70e9", + "outcome": "completed", + "answeredBySubmissionId": "sub_ik_b2f96fd62b80a6dcf980329ad61f70e9" + } + ], + "incarnation": "inc_01M1NV5WZD6VQ76Z7C3JJRFFBA" +} diff --git a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/latest-workpiece.md b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/latest-workpiece.md new file mode 100644 index 00000000000..4c89055d2b5 --- /dev/null +++ b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/latest-workpiece.md @@ -0,0 +1,45 @@ +# Final inspection and dispatch batch path + +## Purpose and posture +Model the narrow batch path from final inspection to dispatch readiness with single-crew resource constraint. This revision incorporates the evidence-backed correction of the missing crew-availability input arc. + +## Operational account +- A batch that is ready enters final inspection. +- Final inspection requires and reserves the sole available dispatch crew. +- Sign-off releases that crew and marks the batch ready for dispatch. + +## Quantity and resource policy +Exactly one dispatch crew is available in this system. Starting final inspection consumes that one available crew token; sign-off returns it. At most one batch can be under final inspection at a time because the sole crew is needed and cannot be in two places simultaneously. + +## Net structure (model-produced) +**Places:** +- `Batch ready`: batches waiting for inspection +- `Under final inspection`: batches currently being inspected +- `Ready for dispatch`: batches completed and awaiting dispatch +- `Dispatch crew available`: availability token for the single crew (capacity 1) + +**Transitions:** +- `Start final inspection`: consumes 1 batch token from `Batch ready` AND 1 crew token from `Dispatch crew available`; produces 1 token in `Under final inspection` +- `Sign-off`: consumes 1 token from `Under final inspection`; produces 1 token each in `Ready for dispatch` and `Dispatch crew available` (returns the crew) + +**Arcs:** +- `Batch ready` → `Start final inspection` (standard, weight 1) — original +- `Dispatch crew available` → `Start final inspection` (standard, weight 1) — added in revision +- `Start final inspection` → `Under final inspection` (standard, weight 1) — original +- `Under final inspection` → `Sign-off` (standard, weight 1) — original +- `Sign-off` → `Ready for dispatch` (standard, weight 1) — original +- `Sign-off` → `Dispatch crew available` (standard, weight 1) — original + +## Explicit unknowns +- Inspection and sign-off timing and duration +- Failure modes, defect outcomes, and recovery behavior +- Initial batch population and crew availability state +- Repeat or recycling scenarios + +## Revision record +**Revision 0** (test-authored): Prepared fixture identified missing standard weight-1 input arc from `Dispatch crew available` to `Start final inspection`. + +**Revision 1** (model-produced): Arc added via Petrinaut `addArc` tool and verified in net definition. Crew-availability constraint now enforced at net semantics level. + +## Claim boundary +This revision is model-produced evidence of arc correction applied to the test-authored source. It does not establish timing behavior, failure recovery, execution performance, or projection beyond this narrow batch-crew-inspection path. diff --git a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/prepared-workpiece.md b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/prepared-workpiece.md new file mode 100644 index 00000000000..fa01def8c11 --- /dev/null +++ b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/prepared-workpiece.md @@ -0,0 +1,21 @@ +# Final inspection and dispatch workpiece + +## Purpose and posture +Maintain the narrow batch path from final inspection to dispatch readiness and test one evidence-backed correction against the live Petrinaut document. + +## Operational account +- A batch that is ready enters final inspection. +- Final inspection reserves the sole available dispatch crew. +- Sign-off releases that crew and makes the batch ready for dispatch. + +## Quantity and resource policy +Exactly one dispatch crew is available in this fixture. Starting final inspection consumes that one available crew; sign-off returns it. + +## Current Petrinaut correspondence +The prepared non-empty net contains the batch path and the crew return from sign-off. It deliberately lacks the standard weight-1 input arc from `Dispatch crew available` to `Start final inspection`. + +## Explicit unknowns +Inspection and sign-off timing, failure modes, and recovery behavior remain unresolved. + +## Claim boundary +This prepared revision is test-authored diagnostic material. It is not model-produced evidence and does not establish capture provenance, behavioral execution, or broad projection quality. diff --git a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/route-evidence.json b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/route-evidence.json new file mode 100644 index 00000000000..85b3c90305b --- /dev/null +++ b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/route-evidence.json @@ -0,0 +1,6 @@ +{ + "fixtureUrl": "http://127.0.0.1:4915/?brunch-fixture=crew-reservation-v1", + "mountedRoute": "/agents/chat/", + "sameMountedInstanceAcrossTabs": true, + "browserErrors": [] +} diff --git a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/run-metadata.json b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/run-metadata.json new file mode 100644 index 00000000000..28615dac8f1 --- /dev/null +++ b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/run-metadata.json @@ -0,0 +1,8 @@ +{ + "implementationCommit": "8ef9cd967d", + "prompt": "Confirmed: final inspection uses the single dispatch crew and sign-off releases it; timing, failure, and recovery remain unknown. Read the live Petrinaut definition, add the missing standard weight-1 input arc from Dispatch crew available to Start final inspection, verify it, and emit the full revised runbook-ir workpiece. In that revised workpiece, identify the revision itself as model-produced from test-authored revision zero; do not call the revised workpiece test-authored.", + "followup": "From the resumed workpiece, list the unresolved timing, failure, and recovery questions. Do not change the Petrinaut net.", + "beforeOffset": "0000000000000000_0000000000000032", + "afterOffset": "0000000000000000_0000000000000092", + "tabBOffset": "0000000000000000_0000000000000110" +} diff --git a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/screenshot-tab-a-after.png b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/screenshot-tab-a-after.png new file mode 100644 index 0000000000000000000000000000000000000000..4e06ff085e777cd4ed93e4fb18946c84718b6c7d GIT binary patch literal 150019 zcmdpeg;$kZ^ert&34(x>bO};QcY}g-3(_Es0@B^mr8FWTl7e(dgGfjVD&5^6@z%Nb zci(vLPk7J47$9)Y`Of~(;#-CjVQ6^1mMlRqniIck5-y6aJ&Ze|&6Fu(i2)kY?#R&cwl?j1_PX z^WP6iy>7Yx<9~wUXyyO?C?J;O7V`c7`MrR9dDzlO*#G-+YbXS*|NB3Z_5Tk&%rPb` zENo+3 zD|+-!aza8vV&WtoOJ!-vowMOyJimkmP=d%wA39%SRuM_u2DH=}lSQ(()kLl@6<14E@MU(63>XMa} z-4Dk|cBRD(h|S#7f(J_qV&Jo`*F4RUEP6>>5fh^_*A{%%`1&B95bcJ$r>Eujcf=<< zCHggqaPwlL2@tm})<@z}Rz_y-uVxWNgddxbpr9UBfa%5MrNf_Q_ATjKXfz^pC_3=z zl8}ljlU@G{Z+RGzO!hqj0s_Tb6oJ(Ird?5SadC>b&?Mx`!jSI3rY2JEp;vUjBQ$z`|yqTPw+?uYT7WGPf-q)AJru|7LZd;E5mrV5P)RbWo zRi$nCz1#!xpy1%8p1AgDp(VloSN7J-sf=1;!9hV$R3aYRGj$)7Qo3x;jwXzzc27>U z?Fq@qUSFI#O>47o=vFSyehpmeOHyYEuQ2UaBS%I?UiY70Y}9d{YeQF7&lG+=iu(O5 zM=I2cCf$S~kG#~NE}qZf*+hG2Xz0oMSY&atJ9sZ6^sbQi3ee>gds>X z1CgH&Dh7H z8xijhOgc~g__lZ)twYT+st&kq&-7;h#D35?D@D2e<*KKE?L`4iCfS5>M~>rM+a882yHSge2v-@434Orv zTQOfB27t*tcdbu4T(8zggRx1j4hF>nF>u#^HPlcg%IQXt@hoqYwOHsJjA#@4wWz|a<8%2 zqba5=ul)g`or~ReeAXksy|4TcEUlc_<-gNC9@MrO>eSH+x*$KC|> zvpp{0ytw+ay7>K`QB1oZqaelJ+ffwKva*u%htDT7ZTgegQW8i_OiZe@vvQgO(6PHV z(3Z8x@7}c$8k9#sOoHQvu=8Tr7moGuk{8=2Cnvse@Aqg#pr|?{Np@!HKJPPU612|H zVH30Rx@{YLd0<$tQJ_q@s0CY_y?youzwcF}BJUE8hO<9Gh|x2$`nxWnG&eVy`tRXX zs)${_+?=f7zdim*xBZM<#Dll%siPxj=k;tLegrXFmnx2hv0l#PS(2x3cQmCy#!pP> z5v?heFW1yQyn41Stp6n>@T&D2vSime#Xiv zoI(nl)OHr40*kGm)wS`M$5(%MRt7Sr`;o-fZqgi>$zlZ{mn3GQ{fb;jEc;deYJu%Z zXObx@3QBEjiR(P~lH&72l4{d6hJ2=+OPa2(9vfrAA{jmt-(8>Fjxx1J?cMgf#2Fy;`<=!{1|WkOCGZ97w*Rl#Ynx61T$Y|&vTCQvrXE~)QMf}O68Hn$7DH{<&5*& zNrmDqF}~3=rBA!;F}G8rJrc?p3^sS?f3A)|MKsN?@ zdbHuTTd1t)*8(UwV|hI76*>-HkF0-4^AWKDxEH+A0G!-2On7~lOke{0L;Nj^sdNFC zdbgcu1qp)K*PGpHG}is^0Lq^)R8oh=B-niIpkXyn{VW~r)uu={5O@Rshs`TegQ4q- z1N`HSZff5siib>7CQoVaL7xge?US{{LkA(4*Ge}WN};)HP_P985^os`d%aB zT`VT3a7M>{pZsctbil;3VrzWpLK{Z$9UU+5vhces<4oK&q_|5Z$L!rOrLWf<9{M+UEAn-0Gmbx3 zbQeF-WotZx(yFbhhX+oyiq}M6>Tt~X&=oC)yAii{;(sQ#o!O|p95#!J zFlqF&bGZgKpqwT8q=*cwb2~@WT0ZExKH0*+x%Ijb#QSsMAgYJH0?aQv6B^l(Tx{LO9LL@U~)Y3^C1M4)nOG>!8ClXTm+2Q8nX(zu%WAM>)eL$8;?HI93^KB_== z2Ps!l>`Ger^wRN@DlxyxtsueTbn6bROewo9r!+Yin}(aj5vIr~C`JIPPH0%oS`_G~ zJbOdARMjJdk^VHdi~AF9Z(`h=Y?aEQw zO1|rfeez(LJD;cfk^KzmS*TdTL0eKg4YOPz?J*l3R*bfu_?CEUUn zJ(B%eGY^wPg#@0sz8Fk8$i<;1c+Zr6x0Glt!h-A zj^2>-MgJVfw%VGkkixcjhx{rmf{|w3HvxGpZ1?F&!K0ypBc8YX`kz=k=u}3rt^Fi} zZ_ce$X*8bU8VG0!u|DLrXmUi-d*?|NXwbL2rx!9j^wPS@YN6Dy!Nc*m*<9mL2DZ7S zRTP^W6kHUq_4OCST?Ou-j-$3}g^7+MdAzOCn_nNwSM}+{_~H5Eg+`-nDRvL6X1bIW zVeLUtX&VhtM5d*fu0@iPGAN6_!WZ`;ReXP7M!v&q$edF0i=&hMuupSOGG^V%Flrj3 zK6vQC@EeyGBa{yaGwcM(JbcV?7*;0^)OcRndkGpv#C-0u5?XU+4JSKNa@pT}FM=3j zxcw;Yg$76WF*>$l(kSUhsdUZTJ50+Y+OQ`+TdG{*lq)J8?$+HF79zZ;_Wxa~`o1fS zfUZBQ-#lVyapv3JZ4=_REmUGY1`eD)4jfnhRr=+|U#C7>R%r9Tr|7Zre)=>v^K(Q| zUSJZ7dROD+g6UVT+@nlxi#}CxJ&Y?&b7t`->V_wE_~Y?Dq%p^#b_Ii!T9_#KSbaJe zA6mCeE&7Q$8ICZ*H@@o1^xOq#)=9HBae*JV=Y8=vY{A_x@;Y2&|uqcgf zBlRhHI_4r@K6~afUcWldPw!JS<_uEsTZSL5&1sDes#@@wRQ2T+}(07Y*Z$RFeB<8hW-Jb+QwB5Hnmb>v&O>Q1$m@WSPiX5Dq zncl~`+trgI`C&g&pV@B}4O(ZP;E-}6U1$FO;*}Qsh2UtK2+Qs1*QokS#VaG$B+ zYauR$y?c2IyMC8WtJ@#%P|Ig!^k%Sw^95h6OTQ*FpS}Baxof0&QxkK_nE3EpqT5`#ThW3&o3vrA0Kp)JMf453y~2{IL9>qSZKN#e>Y^z6$YN& z+co9D+BR-5r?*$DkI!D59RPZnWS7HO#OgHZEo}u0ZqSB9;kc0_^{meMgB_{*>DwlX zw|hNl{RYC6$^mPhp-Z)#3psil@mpw(#J!&w>~BT&#J&WUE8tWb!-CLmSkk+xJaLqg zoLtgX+`Y+^Wc2h(->(q}AK%RbA;Na5QU=?2Y1TFKE;Z`*P)^{l-u7fGUq+^WgSMdQ z#yZAs07*Jp+C%3IQr;dy+fT8vu@7I2dtK~xd!HYwcJUg@#c7x5J>=&E~xjAHs* zIv8CmM-sh>BE?5yJX6FoF|;+WJ+C#c@FC%GsUmN!OVKT_wM8;*PRZ@>e1Aq?5t5P? zwhswUjz{(hvQ{6fsJ-!Ea4fwwQ#ZNfp}^jN8zpshwn8mw^FG#e*qwvJaO2#X+i9uM zxMmomC;Tdcsw>Hi9H%(Ccug0Tq7f#NQ~?*pSGg3ttQW04gv#lz_B(%C{;*1}%Qck0 zjPUr#6pshV74{z6(>h zG%hiGIig7=V}w3kW=D$<^e;$D-(y)^JES~ zJ+Y6*iC;HY zMhq^0Z}vJ7Y`7mPbH7i(#>QR{zqIhA{0ySXtsgfCt#1E-vow&i}f7g%hN+4wZmT$F<*0LU-^rgT?~d zgDkdocFKG^G0c5IWmxWiD@E+R*GbanR21jsZY>)_^+p@*b~>&`R_0fw?>t&TfA6;c z+~2wf1cs6I@YrQgB(zDHt+Qk+chcpO_ie5Fv)xSZ7k-~E|L(LrFsL;ay1p$o4KsCg zefFyoqZTR=TaIm;8r3yR^djU>bI@x!4C_Z<4y;C-f;x1B6G8Go884hHGQrEa{^(#m zz?ei3`IqN=KC2)cW!*ZL1#@7Edh9P8Fo0Ag3KsD2^yH*9ca5A<6M;;HsJb6)?bRiei_JoJ6u>J?#YFPX%jcm+X* zkr5^1#;;b|eadd#<&3DVRcvPLNQ@FR|W$HXx>R^Rdbt8FK%w09o}*lyuH=oWPQVQ*!}h0HxY@8ECT{Y5gcV zWX0kwN8|cE#Ilujafk_bIgkGn+a@8=y^~GQAguknOENe?aljHJ!=5cF$aKz2{HR%c zJfb2-L-0ynyvgf$%CgVh$_55&hnCAn0}4@r1az{XR_MGAfI0WBsZyCou-52c03$|! z_D=I(Jgko^kLQc&SMoKbr}j{u-%yVrG4fJvS?g9ULLQdar2Fmo^4>$Nd`tFtyO|Od z;k}L&BcI-aw}N;oZRH7-#>QNt`)4az4XG{@Dhc6{D@#i$MqN!8P!AiO?Fib~uT{*c zL85&H5|#}8Vji$vi@ME6A7QRh_cYTfQ;FU;sjivAOXa@TSME#6b@2hR_#=+mbgUef^_YSx z-!ucByc{vV9~JkY)H}(l=M0#C?BhdQfXA0F=A}S%>1B=9z3dR3Pblu+CpIY!eD*z0Hqw>V_GY5mCX5jqT4mhfvevcR5m0;d7ICc$^f zUEth&d)r5QBt&1#Gi1LYFjpwIGN1-8g3xoojh=ex)Vsx2)4PF|(uyDH2Lk!ld&b+5B zifE2%rZ&V3lkG&UijHK~8UZ&1TsKK0xa=MyixYqcaAzWyQ23^+WTHQJCT@sElRTB_ z4IOQc=C4W!@#~SJeU87=phl^|+Z-GH?$iSLkM8KWrv3Zw@wXL|@2}0XaiQNvJn7ta zTSgb%H%1XhX8HN1$^iBrLnG8AMouF+gi({nyub8qqC}rB=`ifZKhnPQ_KZN#n>r1L zkIS$PqHudt-_257-fcAV+^IrX1wVFo+a(dioE4>x^v<2+a<{WQX2*>+2BgG${2}>N zl$05d@`VvR0!s?v3`w4&GsH3|C3m!JZTjE7dv|?j=Ye`Q`pW8uw!93)6<(zVCqBV|aO2hp6HHIvc+vA0ah0wV0Tg_A>@{#I?QtzYVO{`2W9KUH>?F zMX9y5{M}+6EOW@SyHW11MP_;C;m#o(1;htUiD^$B5nZTs3YKJB`K<}8rz6jlyOp3Q zhdKS0Ha0xheth`xL8(|;Tv)s8S;^C!07YKVAk+9907XA2D$LZsdhw^(yZXh1&un0{ zb&TELfQaRT?~eEm4i6lzkgtob@%CipxgodRm=CO_K68331<82%diwkQ zG7nPXcb$c>n0o3QMZ%+~p3Jv!e^u(Oi>0S>Cv?J#4|6FDvP(dikwv6IFT}-L0lW_Y z{Xa?%y_buDas+RPL5*5DoqrF!gYd90d27mVsa&SdJk~z6wzfjoV*UEQmKn;$ap2N^ zMEdP#bw8B6{7n(y1-K&+ z!ku3YZcr3__A@=14_Yp`!3C3vykiK4h|%@w0)8{X2I`KXz6Skc%J*d3(0jAWdgL9i zwOR{o(^u>LX?!svDG!Vo&A{0K<5Gt8!iEov$r1bFc-kR6K^kE?g@s|xdo91UWYzpQ z3PujRpxF89d+FkZ3fxb0Q#B4oFd4ziP8F)Y55LU>vr%vvk=NKq%@hv9w(sALSBKxX zx3%fj*n98IchX3OWP6qwHav3O)ak2)kx~vF2N(AeL_=mwBcSv zT4(xJtI~!v&tJ(*U8_@_s#`F=iR!v8_;fup5c_wGRK@Gg6!(6P@Lv*ga?6V%PhY3& zGgI64(}SmyPEK7}ij#ku(%sj@mR28Vb^f|mzdnmpIyEwgI9FHr>vm01_qRapB5OKW zas8v~(#wthKX00h+GQ>CHMg(%FiaQzJh;O>c?WFb*!8oyP-^hkc)(7=CgI4Q_mY=9 z|4$2;yiG_Lz%7k7kjjNBaI)R7Q|SU!9d@8BMeg`%pO5qo6s#8*HXuNv-MFzanGZg~ zGJ+`aIs69C`vg>s?-@cQxOJed!v^xXJeug}_jgTjL zC%Y{6aJei$#yeXp$O887a(Vtru?Bw5gx(*|@C|IwJ#t^zN)Am&<6!)?R`fVCF*sM` zBJROE-%A|V;pOj;Di|l0y zS4!PoGM}a^(DDYFlUGEKU*c@IkiOX2u{TKX%&I(()O>b*sZRCx^DUX^YmI6$L#<8q86*t9{R2$x_&8&>;iA4^xX{+NCj2x5iI;aJMTob7qIs`^2ZxT(o-iG?Twy3iZxL2?7U1HzqZ`{(>r*Q{O54LFO};(J~>(A zk-JKIj!#qL)xwQ0eMJbcJ32kR@T8&Z8v4-pG;gFp#i-mES#clC>184liZ8H4S^Q44 zD5N(Se=9W^l}%xv#yaKRVbzfL?R*e%cLq$#T%w9TsskoDSU&~@q(eJ#aU>%Wc0DuK zcXmIkB;@Iw_Ob=>8)3yjhgj$Aj36FqwqHptN+nmmX;tUwG>|TE){*>*=<^0*W!_2a zYt&mxoI_~hSDgzJ0Iu%mbMnYs%h+Hf=#=qzg1?1erl?aoA@`=^Cd5r=P+G?6`WAha zf%)c6^g(5@zYG$#U5EE;L5rzy2*S zsLivA`n4|xF za{4Lw==Tib8Zdu4FZBh7gfv4^!sAyFtxQDY>3n3ZFD3f;pg@hyn9cfV5r2iiO_B;9 z`qWl_((J^h`@AE}9Y|Dj_@jM$Y9RzR$v z#0zimza=CjAdDchR`G_=^qOZ-_%oyr5SfmdIv1%B92kauK|nkiRaaRfInMPtSQ(7L z8IOaz9*i2!%Fj>wcB0B!J?Ia(z;YUpg;<}dJ9tsn^aZFx%^x4~osFx@ziis2Q97M= zFVfHq2LUqVG*$+)9Dd}5e^3gtn)sy40|?&nv8Cl29Q2^f&C#OU(?3Z>z;@`KU2ey7VJ=;wC^JuLX; zOYVXR1;S|Y=d^8hSt70?oK$+71F+`$OXGusgWcVsS(8IT1ig^>dcD6`L0-p(&Kn*c zeg-=VM$uo{5`i5Z35-);9u!)M8kr7L)9s@zQYX>q!ee8J?!%qUsY0OhmWvA#C-<%S`W9&|$b%6%2?)K2x^|2>cJLkFc0HX%@aG&u(l) zPB!~odH@&hAch%pme!|Pw>0=qt>;QEA6;_ z=T1KCc@sy*j)te7iG$o;c*y@$ZtGR@{*Y@x&$&B$v@us&KzQd)h1(8IjanQ%J=P#2 zeC-?0sU8s?K3t5Snym@|T=WNd+bQf3Y#NVOA~39cm8mrABXwE9GdyW-3N16lj#PJA z=FJScA8-Wh#^GmG_;Y2KZ3fgV7%-lvS6U6{mUiOgXnjf9%7Jrj;tg#{rYOZJko|SS0v+duJ+y%g;S<(OtwY zIXxzA1gk9P)_=U<)4_5;To0D&@bKI1C;5AI6K^edxhy4^ylx%>ctRd5NqQk8;GTOj zeUems5Iw;I;OfpBv9LLp1~P_A;Mo;u*Wz38ZSA|eI@gGgk}B?wLro++XSeDv0l14# z-*{&P&0?(#ey0FVX$WY!c)Qhs{sb;_Kw#impHFnW zr7>(DHA-%^Sm`;2a5Kd=6LQN>&z7Hn{wHLl`X>-(6O;QNrqNem?w*kx%&6n@D%vi4 z?%qPDl8wYDShZ^8d#PFHycA01(X(H$ySob!wUNQWG5{QC56>!0(EX1Zr0zU;MnOud z)8J|svp-jg>=e&-Ab^6^}pECAWg%K<;$uk_-6&=Ek2EB$RaTd|~&BfVz7(x6*{K@ADiUh=gD`(J|JbccqAhm+suc%)^x`+YA<7Gqg>gVN_-E3@(` z%-?6r6N+i56_$Cr@ikB8Vl<_YR;hvRzp-FpBtix^CgpTe3W^yRyf!JC1#z zDR$C_2u>zjRds+$*~BVZfx-_B!*2S^B?R@pi(rm|IyC?RT-Xm#sa-Dm!0D+`^LD!4 zkh_q6(*4|JFbFBhd8qAoko*OPQEAp&Y0`Of`xZoAqNAd~@5^F?VKq-7!7&ha6e1D} zylfPso&>cN@)ht#I%gHW)Qy0WhJP~=(IYhGTZ;wZf#lwAm;)YPRPVn*&&XptNFsR*yMCZs0rtWV|!Q_o4a^$yZ{r0}= zZLQfD`*`;tU6-8cl!cVRc-ahb*JdM%wqzws8jrt+Yqw3av#!Q8cpy_ZtMmG-;a^!Q z4nQs>D2VgZV74#JOk`6eK>Q@npPy|1f^4KzG$0fYu)n@1H;Gx{S_|N=mIE(eK|#M+ zC>Yah4ukRFPhSeM7$W?90}yh3>MPdnpG?T%lzC{@IzDf9T^)K3 z&*g=fTo^F_i_H(nFM52p`USP6*L+?G+7XlpjL%;XPcvfH6H5cv1BJ7k2_{|I161eW z$w{5jvbuF*?pn(r+vESV0AN`liRY zn*PfcHtV}VzIKturX7*Y1#{64reu~nIzd@RcN&U?Cm9%*mCY7QHm5%SAHA<44egP- zyH4uV-ZQABxEB?*=-xhXSAeHTuG7%cnn1!E=nnVE>`eqLx3sh5NFAE7AnVFLoB;H*ys4Ty1b_f_(cfL@ztVsHXO7U5j(4SqqvE=cK5PiwB|+uCkI z?=(EwQ6L0eF}#DG<{w9Fw5@11)j&L2i6YTI0}uQ< zbUXzI0PO|K(diwp%9rrg0Gl?c;{9~TVfuU`F03V2r)*|M-;N9lnCib*Bk9pO z{`24Gfx!unj2pt0?Jm%Cps`JrKM%aJ{#j-Hqb_WI zP_7nAExfP?Rdq{?SQbUFb5}-W0K-Q&Tu^uMJJ{<}kP5XDp(kmw(|z?cfCd#CdyBp> zB}E(3*x!=bBe72wV#K;4mFhuh5ZQx%6Zx3%EC}oNp?{Al8mGPf;Vz7`QWlN|pR;m_ zSv4@_c&B9|h$KkqhGC=W!@GnouJ-I$9rY*br@j4sHFztTAp;{esHD%TE^M$X-_nRB z{S1qUh=_^;8LLJy11tb1xse(k8kw)Ns?g;~kF?qXQB%60c?n>rV<#mV@5J50NOPtx zop<-tZt&KSb}Za$seZUh_g(pxnoxc}4ZwC6cRoQE$rH*1_*U(Pk3V&&Mm-9{O}`H$rY4dr6u48DhAHb*Q$YueNmt#77>WC z(#u}=AIFWh*Cbnwy~t^ZCZm;I9}EB8Ck)oLy@yYGqk_puNk}Z;1#_e8-BJ_L8_^>q zC;zrG*B<&^_-nwIg~;=8 zqx5z-rBgZc=c6VY_Y6S7#4}IaxF{S(`UPM2@}zJ7oc%%2nfq}vgk7rZNe?5fN%#HiLccrm>nq z?rtzEDW$`R^3Vu&%NzXTpME`LdQ?ys(CvI z5rsIFTv`VYJ){x4I!@gD+qh~c=qW14+xpVPU?3RBR*B%^_GKLnBm1W-1A z0M5$5wVYa<*(5c=+u!+FjorNiWEQg=xDZU05USY*?4Z#u)b(m)o`$?buC)Rl+2+np zO#1QBQ3jVO21^KR!%_GpT_DgmgNc|Xfe}Yji3s{!oWcNUtiQXL*FeeRYu&E~l1<&7mm_iuu{t)`>7JO=mm- zYl^+;egNHSg8ET=6|5URn#V81wpLj*jHz8qV~Cs(30(X=@pn9Yzta05wEUvrp`jtb z`)oqW5_$qEs%X6XnjeYUejKYlXPRXm4;_-Zrxh3N8aSuh$rMGe)wPbIr7-(h#y6AS z3B}g|=v&F+Q(N0lMTtndnJnsz>Y*FepLVS`l1g7*+_HaKWu>a!L3|YWbfQj@bi`AT zHO!pQUNcdXWu9S+p~BAS>9AKb*|tC0l{SWcX>~ppj<8OndmM#8WnHSGj!wtg$X7TX zmIWZiRT#kX%AoI8_n#B&x(FCY=)|~|MhYn&dt$HQbl=plXHi2-=n9( z&wPhghT^?$U{#tffVU}Rkn27N*51w(%X%hKGGddzYPTEg6^wvQR;E?*j+-db`Njo# z{_VkVE9t|@hiDIbSnZ8_^cuSSljgZ6K8>$V*O@Oa_l=d7<-~CFCGt?@NNFwzq$D>HVK|18x0u0yS9WuZfxO;^bKEuc6y#{ml&;742zRRQi;K- ztT0-h6`X5GO4HrD*BXdI8rly>hV-he2plE^ofmt+|6Dhx`$38`y8W{{^5f76zbsku z1EW&kyWD1B2NRz-eVhPRU=GpSrV#O{^7*+6c3Qr@rWX;L7VJDb*b%RxC6A%b!)wEl zyN(~mL+M;ETx9UImFp9}IPK0#VAxk7xl)ywWAtaFhXLJpp(#Y0GdaM+!g`A+BZy)DKVQ?6rUGL{I0t@NJDtN8A2)gp~gbX|H(!3 zUm4^2fy}h_Rks;i6)0z{zJjBYa~m5kI0VBY)mk181ZH3EZpGe6ik5i08qCfMeN{Z} zS*@c)+3Pr@Os{8< zx7L5 zGBI$J;e=obC~u1L-97RWguyBFY8r&SQDYr#h*NM6G4b$Zk*ts}Ai8Jc59Y3Z(|R+v zur`49J)G!lfS~noNq583yLaz;to>j(PSxVJurfBD1zTaa0BBK=28j2CDO8{}YlYyD z$?xrTQ?I;u`g8~$+1B0;KnX^)w~H*TQ#{3#)o5XyOTi3qRfXtSASUf77LzDUgnV%z zCL?m3fP8>yQmt5-b8U-^yIHe+hCY_v3##3)HpRyfi5c~d1)=KTi0zzy5`tX_lb6~c@9 zsNZ#oS#KJLx&2stK}K47$ar_~vt_Fva+KnIgWA|V^pXgKQ!mT*lEv0(wDHw~w3Kr* zKepDGvJ^u{);w=y4;K1dXvK#}><*le4lsZJwpamg>RwJ2naq**NqToGEKTO z@a!j2=m-*Y)6p`c7TANI|C~v+*gt={eEk-aWn>9mLY|N`+2>L;*9WA=cwC%r!2J!o zL`^uI1ai^yvo_&Gnq>>Hf`%UfEgRlJ7teg|tyQFkULF2S27^s1%b4Ol7FR$Fg@7cI zIe%7l#v6A=XLfq|J(xULo@R@KHxWk-hrsy~q+(4sG0@QNv1FK$r+FT&k9CAwv@*() zv9?>j0wT_hIN|Cn-}O>&@)AO>2%W_Utf@~pm*FSm2^sOvxE#5$rtIq=?-XWTihA$( z>4Q;1vU@(1-YNE6##RI zX0G-=$szWj!C0Z=cl{RpGp8t9ZPEf&^L;1zdd3#i?}+hJA>cZiUBX^Aejdg>?PsQ1 z(d$piN|%gfWdG9w^xiRl$CxXjlW@MxE-?K0Ylbl&Dzm;T?Ic1G9!084ip1vtDZ(kuz$cyrzbst~quwaB4-7PUg|A z(mtyLOl?_Te(Y79U&~2*LD&AMH%L#0Q`l4d^q16Rh4L6xN2{bn_9nNFmM}}z*KaQk z68B-CB1bFZ4)3!S$kx2hxTBW!v0c&3Hu8~0b5FZEY0(DuoLGv~{%b$7zr)2pnN1aI zB6sNCka*b1&RR|N)>YDq2(f?CsW9=7mqIX5G#ajK!lTHI#OECil@~E=iJ&UOiAB8$3 z$qQRd44$8G05lh^JiH<)u2PSFvIKckO2jf=zUuzO?Dz5Ch7>Q%GOK#<XC9(+0 z;anUi8Rs6thEP-C_iUu<`TRs=Yr#RE^&YlIKoXF86PzlsxOXM(D1*|PaFlSmKk#>J&v^6` z3hvsRLjxn1YNiI`#P@rLx#4xV{aG)o&Y4C?Od^-kly|vwuJTO9+p|{`f~zs=Js5DQcLB_XF-HOGX85Lxo-uO1GI1pvU`7xML5>@-729|Gg!dnv8 z5w&YOj9w`e^xY-42@(z?-<5$DOWwu#q+gyfRWE*V8c|smf0(oL-6*Lkl$O4R%oL1e zmvDx(UEvfIr}>i|V1IqScyj-4ysxtlz@UxWM+@Uy$)~@fj$%9P0$IfoZ$b2j$3sR& z*&D`EX*;!F%AXp!&!P7ldC9rUQFex(MV3Sv4q%9KH9k|ecqVS&P{c*qb4<_GZ>rJM@e_FQl zDjsnwc~tTxt1TJ#UNg<50@!polQa~AGb+z?c7NpB+n9troL z^kBuAG6`EhqkmNRA<&W~&GY&P&GIy#bhtxE0n#LsOAMu7@XZ-IcWt|R5&wKL2OqUg%XZ-^;m zv;$9bJN1p9s^h}^k? zCI-i?a&GSC05mqh8KBlsFy+tTFxE<@XDRrb8WepAk4_+X>9UX6rP5ic@~gaTto|gE&KnSh zCqBR9Vy2SPqn#8Wp?F@*h)unKr{w)=dsbZV^+$mJcp4gFOjKd#h z0CO}R)L>hICTdf?2Ii-9WVjTavxNpa9-~-y^3TrS0t2NKc6aPgZuuOLO{+df4JCo*+@6MnFUmkdiJbDM1>fyA=Je?YZZ7?>q0AGiMy;xY>Ju zpIGZtD`QKgWnZ=7g=0fzfwiyy^z*O5=h6m02ovG$u%bJ5XyT}gpAeG;dzNlVq2h{& zfvV2w(`_MC%Kj}GV?IgINhR+dN_C9kgxkG;Nc*(kZ#V2yNdIDYX}L2wxU zO()S$Kk({{lSXzSkz&h!>b+3bRjZcdM=9$G0D}WB0Je^mW)3j+GOW@ z%O61c2Y&;U_tIq$z~l$wk{yED08u~rbRqw&Q*&VYYAKpKiPu6|%$N;+c3aIx{%LLb z>Y?Qy5Os%`T>=rXm=bu)&`f`?`D`9ArepqAuTqf%W1{0a;q->4KbKqF@18=p$s{0< zbhnr&6urC7UrO$1F5@_vKIFq$3;PS7ACU%!$5HX8tu|Qr*zaZ!7(_C^UsZb&9XV;e z2pL>nU$-?aI;Z9FtWMphGQwo$V495en(dgAZp1Rl#LeibHRet=5?s*3@zE-CMgCT` zb}MP9ZB#z5k*LCGRoRM3STyt7rtY*3QHKEv=}*wwZd(Y>EctY@JsnClVyqct)-=@A z)bv@ZRc0CI+&lwtFoJv5>_ESJws9uwz=cm(;Av&%JX>5qT=vlH`HET1Cv-&01+?XQ zU0bi=N>E4T+|?5`bB+0ITO4MAj)un8;o;;_p3V0<6)$84ZSC!v7m z{@)D)fOdfEsqk#UNYZUBhObLZcnrhj(B}||ckX3s9M4UX zQMoHDL_rnb&P#Su-TrmOL*9nb(=xJs4Vkbp30sk`ABr9$ zkvYG)+CO{chV~^9%JMeLIEANERpt&*!x1p^Na*gce^`QDXG|OSD$9FS*hM()szl_O zQH$*Z3U!RfX2*aELd$0K{*f;AICSRZBCZ8^tppLP9*-La-^)HAuf6vWs3?r}e-9+x zTE|%-C4G8W9?=2e@kCnWEUZ_G?-IjL#nq&JJ|0@DY>PV!2z~Y0bq~XtC+Yk6aVaMy z->dfE!Lo$^YO+3nA$c*W3P#VZ6a$spx}%*t*~^$ya{xDhdKpSU?cET+!b)h}e#2_s z6!(hpC`=R${sm!4nq4w9YxIDkBjhd&#@uCgC!bt1TO&OAy543Rwrl=VO-(Cmj=j6y zwrppX8b8|OkeiSiT7GS3Z+*5_in9!p&ChXW-&|7C_7=O{92}}|fpz+Ieqa`G!4!7_ ze_jl;Mp5#H+85OLe?WO)|0|xwpQV`4R08STB;2dGzxXtKQT;u=q zR2Gq%05ZYELgs8Q3*ZE|hcoUV>b&XRbx`(34V>!mT8 z@_tnaZprk(Z-1c;%FAW&C{bj1Z&!EUzW=JAWAY9>Oe=VOC``K0h}@yls}B~*+(B*G z$9i%E@C=YEygtVpI23%ffJVW;+fe1KLlR0yQML~jH}C8kmJRSwRD4!FKu5rLWNq9H z_ww>RejzJFn|{s^DE4i#X0s$dv;GrSZ9vk!hL}dsNx5f) zMwi_Se=c`^VeMkuFmm_h%Majm+Vtr{D9Bzi8iN6j$ljjB4g?`OQVjY*p9s}#vq9Ar zv&QxX^ElUsT9w&}*;D-ErM1(VKKPZ?OU$f=pE#~-f)?}pu9f@ltGZ37>Y4$)pRRYY z1kz9T3X3)I|3|2QukE7#7YhJ#oux}uJqOQ|odnQUuPP-3y}(K!`lqLdrGH4Q&?``z z+syxD0-z}%ZDs(5K~?W14GpE=Lnfsa=JE;5&$lFZT+t`XkByCmqp8y9$y_{8)p+@0~L`q5j!>%V( zg7W+CCV>Cao6u={0>bmpq6!s=*gKGG!iuFw0gWPc;k{LA=DD=%fE z)ltMFWGcaQjPdX2Cu=S)ysjj{^n>^)O#fKfFfbQ;O1@lc@Jk->M0^lb`V%@t%$}5U zM!wYR-=8S_nk?QgPpWu(N8b9+8-MZlceXL*S?Aa`) zTf2w!6%3q4h}T-M{`G)c>n{^_XZG|utCS+CAD@?PZxVgti>KAU0)XV1M|<;AA5+># z$`F(`(rog7)d*N?edJHlA|j|@TffzKUB1P(+8UG(a<3}b46sYxc=Z`wF5P*Qa;uXcD-!hyGGeY$f?t(GZ`+h8 z&kG);7L)vX^ONt3M4i~{J=wZ*EoQ(Tf|UxO+9llOy*+(EqoqGqMgS$y^J?OIclQLB zbb>RlAKU%*!<|nHdwWI&ic)*NGiTYCCv|D)71RUIZevQea8%m%PTp}_Y)5tyNnyfN zYJaChV9HFtcSQnfnPy@x<3OW8>py!;dv0W*<0^J`cIA)tdGtRTrQ{$ss6hJXXS<}N zY7d)dwXWE(|5VKtuNX6G0?JO2P=7|M#BJ?l+(JuApwTMy3r<@&i?$fs`%}5sdtS;Q zIP_ftQc}_4WrZS}hi!r{>r4wW>kdmf!_UkSu6|-jn?#q5$k) zPa=t!juFam5NLsm;R=2s++~(8fKyjirWLCC79t)-GM+1iQWj6{0kmeRGAY5VR|est z-p`${uVFJPwO`-g*+|Rp4jDoXuQDlDY?ZNAwi;S-5S#&I2?7`{LDs>4mMe|$T|g;X z4P8K=U?qrOATaIDyw@^tsk)dJK*u7k3$TTp#9F~+2uOl*nkhJ)7NCZm11)NQR%GOt z5Xc8?t_k8p{ez&bL74*d4-5U^;tpr2j3VCd*6bfIA4D-_D>VW__=!i%T8SzH#I2W3 zyIWfsKouHa^I=w-0h1!|oQQzEZ3l3!0F;ot81RsQ`k4%rXVA13E9@W&94M4Q9Y9w= zCHM$fF#KwMHa4t~MTmKnkdT1y-f^OowXudnlZGelmzRZ6@a`k>x<5wv83F`Ncf zf$F1$fuOyi7W3kHMWK(JP!HVD;^HDyWC&gAA-Q-HD7yi!EY65)cwI8BkYul58HEe!0SEl7joYl@B2Qi-!KgN zA60ZiP*8~#gR?R>e;e#Lzaw`8p!$hf2MN+t-&|kX20)?E6U(6wZdf7+KaS7wJ|!+)uJ;;~x2DaYVNM%vomx^3#i>CcQ^$u6Jo`#|BP*g}=H%+DVV`$4A?py~ z0ZvR{vpi2ko&-sp3wx>2hh2cV>X9{6173-F^F5_uGY4DhIGfr-@#{Wdp!r7Gpy2vF z4-FBusJ5%Lauk9uaZeEM(Y}PZwFMd z>3r6p5(_K|>EqNXCXh5I1R7h7;zkofO@{Q90;vv|VuuG@1GN2bR|vjyTQ`Buwf7~u z^59~fM=?BL2gL{^2|tb=<*P?iz3T5vbv1TFw5)lEJZ36Q?xLLnajE!W0tz_BC2-_) z|AqrlRzcwzgvhPYW6V6A_eR(K1p$YkK*5=0Z$8a`ArWaj^S|3mM}FrN%nl;VH>Ch zJa`+%=w6=)m!(|sfR7^Bg?;IiA8_tGxhQ_UsDL$t(kx$QGe`jHWR^qZ6r({EK>y=j zyT|qvA*&Zq0=q4+L?-l&f&Qd;-rW)TGVu0_>7E!Z4U!A^$Bd=0EVRv;AHFu{HyF|w zqbHo`i!brZi`Q%?$DASuiFbPz;s{L^jz|~Vs67tpOVhe!c8kx_aYw6Cb-q}-*LBQh zRL8LvpRe$Ng@%E;KgyD|Tx4!z)I>fa$daA?@FYRXtzh;Q00lTomRt(= zW z@63|XM;$)Z(JIBr*$357yGfMH{%V5wQh__hf&vZ)f5*;^Gw!Dv6%I<#^rmPUkh-E| z9bGiTR|`pM2|urqJUO*E>0ArLcv14l0%QIS`x3D6|)DMkMh*K_%^}6z5VyTC1KqVRIIl;F|Y*pD*1KUHCD^(mew4S z#U11255{nwt@ONvGGh^M!VKD!L4RpqvxzHj;oUsjWfsfhBqO{y?PIpeagVL9E_;}G zc(+N`{Xei1);Y~l>I+?_R5m~rdO1yXAF#q>c~F8koNX-KWn=w$5!Gn0_ttTNk^gg8 zAMpQ`zm=Kt(;IHRLMC?>bOQst{6CVZ)IoWoR>!RB-_X5TkQ+C7Y3_YC>#LwJVxXhD z*J9Jod20org=(}ngA1Wx!pzk?5MLR}%FwCRPYL?j)1w$ePi3Sah)Xu1cx=co7{>$~B_(B2+Tdr+W# zbb2cEtY-V{$JgY=8(+;R-szkb9TbO3klWw3vI$iC^_+2c3@txaT|VBvEp4qj zB9)UL4$iy|I;NpVJ15usS8-X(cgJXwlde8L@s4nF7xVd)80HwYCiVf|1vDyxYpwnd zP@1ycLGCxyRYW%q*6xSWX}1pJShU~Z#C?a8=b`?BMukpE0$&Oq+^1!D zJRX}m65y9fg_5D1qkzx!D+E#T#Jyl9Wo`otf(JtB!)EzgsN>Sh1$4z{kkfqe^QSf{ z^H^y#F>7$-3D_&P!gEge#$V;;(ivlH7#;0H&AEjuE~8=j0S`KcayT@(%<4YRqbOKf zE|;I$_AHpZc2H7K(5*D~1_T*rAzj^l!SeX%$nBG?6qIZf4OUZH+;)B&U+9mRKOQ15 z@SJC+kLN&Caj7>sksIyI3>i!`k^z3b31?AV`vuAZF$H{qmtgqR5HN20Mve%OY8wS6Ysuw&ow!db5b%w4#{){KW+jDpXB>V*K zz}qypI*LH>E)Z~{T&9ekfnJj5!~Gi(1IOFbiQg<}9^ifL&{h|J-nQ&Q1?iZ_O48p7 zeg}NIPc>fST7CH5z9anV7j-37`Be%6K09gvjR{yqy`VM%hA7QV-w}i%U!p)KJp=O2 zVDHf?6b{XQv48@lHT4({hU+aCYgD1%p>8yTT#U1MUv+QFtBofQAJRp+Lk$d^k$xnK zi6~?tjB^`aLd}Wuh>zBrY<>ju6~l*9E!{2U%L6;k$!{KaDaXj-2}6qm-5cX=#lssj@v&}9_Q!fIe`nRxh*@`;Z_*bJ#Si; zs^rf2F{tkDt0m6&8ysytA>w4*4Wt49s zC1nd8$?7G2LTL0N6DC=Q3K3UWDx)z@4$i-5)w8mpZz?{g#O?41fRT`J-_U6OmP%J2 z98J3bhL~@^oy5^dX=s+=pPil3GTHzAl!#Zokr?WQNC~2)i#$MDAI#cPQ;ktad-BoE z{p~4If7CVB=g=BnLC2&_knqV!fl4Y zawznhhv0aX##)r5IYaS6`-|iN7QqAE0f-A5d`?Oye#2Y?s2Gcry5af>2?^1yiO;le zP_wh!fFeX#icM-8%pkxlD-&qZLQ4*Kv0UG_x5K$US~McO39)AcU(O*ixuHJ)`gSTd zIvOF2hcyb*DwI>X=0LCg?AbG#v?~Zmf41>DTqn358n=Ihl8biF)l?950;CE+2NQqu zP_OEtl&1wn{`ZI?Xaf6aV9dcG*bBCH;Qva2B5PiTC^Mz#o-ZP5UAst4?o`+vhZ zlfK@`DeMp6BXp`NfVApTR3)UQllgJmO8;;*^JCZ4^_hX@P zgY0((9D}QrV3-Gs9Eh}EA3el*1WujFL#DU1aIbP2V~-n@Xcf{zcw4d+XftDic^J<& z@?UHsRNim}i&H_WeD2*x-|DN6#$NVF^s%1WZvU%CSF{E(WG(&4%pt{R=3 z1V>#1^mn|mPgd+KNWV*K0ooG0VvHG+(%L%>r-FO^#V1UdTY-q4Yfy(1MDwmg8lSM~ z-w*#p!=&!#O(6|TCg>HpoA#wYnlzk384TXMyla|zefh$oW|1q@0s=EoQx&7CQD3P;pPKbKzDI%$`TyRxzX8`4AnNxeC0jrf z&D!yR^2UvPoEEGue_2`78e}s9-+e)P!fIvEt4FKg-XhTq3Q?rs4+nHVG#`yK_AN;f zE+KeR2o*?MK(oyb7XlD%9xKWWDCZ{CKM$M@KRI~A(FdYUOO(mNl03MW!|QQzahb%_ zG~FZv-a#Z1U^a``k46hH!y0dx<#0L`J{J>q-ykSt2eBtS7tOTdGq|s{zO_7)6#N1q z0`fO7ydlG|bPG-{xHFw5E3*PFu6acCZvoj*|LQSBJu`wn?Fw**V(&1VfQwbK_IP6` zm1U%*!JeLfLvA?ZkrlXxl2Tit-)2I|yl-K-AMAoVM5c@IzyTJYUUcz2Ow7gu6yg+DO@deVVZV4Zbp0PvLQoG8o-?du|J53L^*DlAH)*l? zv%j+CSTY5i>_RYWrMESlmbdM(AzbB;S~Y33_yIh)_Y17}(Xu663KvDLK4-i4H@UDL zqVkuxu?>pWIv&LhrRHzu9YS;C0eWELSA!XMo*tv=mB!8F;=0wxr5rBJHvumGiMHXh z9S@LFRig3O@ecf9a@Zpj5pi*EewXZc&4w|>B!EI7_UlksrLDMA@RLkZBhYYLEEsS( z*H+g|;$hyy$s}WodK{!^>_TT$!B=e7fCU9{VU``TgKyB?ANd?_xf|KV8u0`ldhGP@ z|7Yk<2~~`1jH0R)F`azT*I0zmx6{1EV)u?btum2a4JizhPXZcI`K`QEAlG)*3b)fK!0SuVhO7=+1{WRF z+VrCj3kEJ=_R(TCN%-RHFx!-WWc}e|5^r;kcF9}3)4R$a!5$;~d}y6=eB{vqL}tjd zr3gbtl*zCaZ)H2`}dxLQ=gVck$cRb zn?+W--tD;Ac1MHkTot4nQLH62K9?c}d2#~;MHJ-N%C_tmK=t*@D-Sw z=yRZA?2uPD*Id-$bAe-TvZhXR+>fa#g_=_B&XTrzl)SoO<;-&|25Dl9Lm83l!z(}y z>-rHic=~Q$dz7UV!1DamDi6nA#O55TyQMF;@gdWaXkOaHBw_-5Hn!Q`UEZ$Lie7Pf zBKEotAMlc^ZK!-%(j-Zn=|MCO&}ln zD<>aj#@+e-H5{$u7p9V=6oLH8zFlICQOS;mI)aA5QF%lfln8bDX){Fv?oOLLHN!dt zb?IBH7Rcgk6xL0DosjdsvG2@%T|mEsfi}}}O-qZXB#_E zF%}GSVv$8>ci^E1DeGQEF2tnVxn1ps5qwb&*faUVbar#P|VKqn_i>T-# zAyy%;Q9Tf7E9~`VCgZ<7gVvq4wzjD+eo)qs zh?t9*5n}(`U+e&kdwiE>CvHrFR6qOOiC}9`7(Nej-fbR%oo9LU*TcBfY}nMbrVG5VokR@^9e| zP$W_W4gB!r|vZqp{=RoBrq$KlkuO;<85 zQHIwPH!3Q*@(L#olF{Uw(`_@iUHqZ-#hNS**v^cHXHytM9kB;N{7e+I_TirNN5(YJ zzP|SO!OW3qyrAcwwDZ4bt=1iQ{#|w168@rWc`#fJONLKw zIR2{yZgOHN_8?>wv?&kthGe~$408JlR{*W|;Ku|smsj(xIWkCBbyoMBbhQ5d{Tqr! zBe)K=7-21g$}<9Q8tS0!LwG(3Mm4sTJE}Nd3z#o9mN+z6IL-kQ+cX0fpwAXIV~-J# z4PW##xn-fmIZ65nG$56C*uv9*`t+0;>xkNau>ihovx#WVE!PS#y1=11n#b1-hR3VMi*O@IJK`AS%r`;A>T2a8N!4*G%5 z{Bz`Ry8KT-eMZJl(mnotP^l2vkjsWpY8}%SW#nn<+krK~L(%4VbnA9zFtp)md`oD| zC>vcsxQqyw>=bz4-EHwIpqaTY*gw%G!UjHEsPmG?u)meQ&=Nu%w5C5!lPv)I1Y~F8 z@i(AK`4G`H2=s=^f~V@ZXkMc$-#8uT7%j&jsyNju;8xy3rm!VeR)dQ;2S=;3ok7s- zmka6l!gmrb2R6I4O}r(vxgQhnU2E^ff5cW|X7nhXRM19Zw!wbvwx2sRQL9+*D`Xn) zHpCBh+(42SW@g|$Qahox(U*e5!@ooRZAW3qt>vw*F=9UB|~= z6+(N(ABl37$C!Bk3h&q`ptere(7oMM=*sY&Bc=y^Hj8j_GXK&hlJH6St z{eL6KV`wO|7lBX}wi=?y^@W{PMkeJ!HXw!81Hw#$sa!ZWF0ZJA7pP-=$vR`AqnIv~ zgif{?IU7Cfp4wWBzvX+=a$C!zKA`?X&`!W)>bshsYeq-*TKZKPDGeBjw$&9BA7+~J zHWH^&Y+fq2c2Q&R+jz4g*NcL0k%8XDfIvm z)%rmR5LQH74h&E7lb4kh7A3v^_@lQ}MuL})6V(E_`K<8+;%UFBRxvS1tC_%s+*O+f zo|4Sy0u_tB`H;@2ITdN9pROA1D6i#XDWQDR0oeuT>7Jx#sZpxof|E)zk+>{EJ+$ieVmaLi-Hhanwe$>uQuWd6FZb+X%2xmD3{d&sPt! zZn!n~>Cw^Amu2J)-vv=oIL6ePKFQsc11JuzCD1jgNz;<3FmJ4WLWE96 zLoa49$Gw6G$?L5DjZ+nXpY2NV6hMiDP}`280Y*g9DxgQ85CGI-+SQ5Q@B@Gcx;Pwj z@3OBkH4Q(6U;u}Vp9gGrpw)#_7ZC*R@0pY7^t7WW@9+6ON*ft~COkB&@<0NG17T+7 zt-(m4W5kE=6YwY?e`7^@MWA^F$^<5T_`uCKt=B8(<#i63xd;Iej3aX+8HC+PACe(p zpHOvO<@);HuF@-z(Euq&nCg`g;tS-3oMY((FoQS3`vckLb;tk}2Xd?ZN7QkJcF|CX ziTnnXY_P?Qn!FC+3$e7YI39v8@e~xb&`Pp8dwd`NtELG>S7aka=mow$3D!HyE@O3g z%Gwa>0w^r>=Mb0Fej>wT2eT|5{38-5m92-#=0DhKeSRw?y8)P4edK0EjCu zKfg?;B=1`|*JHQ};PQ~8DqUd+!reMd-oj3O+v2uf`J2-9pl`QXVdlM48n-$ZvjVJ= zEf}OxkVytJ3+{Sumw{peOyi7yVky3J=VJgRua}L+ZUrzB?NdAr{b8}A7`J~UOxb`d z#Zd}IWhC*Lc1%GaSiuvm^2f=T0Y}Ml0m6w}=AM!97QIe^ zy(5tRapg1t13f`4vN!ty|0W9OYe*Mcn^^|fVz$~+0iqW9$OjAF|9=1|Yw~)CvjsV_ zm#QjGDcW3ROyM#}D!Lwy0o_?T%G4uPdi}c+Y^0-=-eobK8uWuPh?`w+E7lUNhD)@V z5eXv1O&WWg{|_~qs>4Oq0>3_h=bfj}N>rLQ&%kH)S{Cuzrz5-WD&vhYvk!4c&O&(u z;QjY#=5L#vgvIBa@dJT;ePsBPaAa5)o$slr`%cpQ4yDuk+F~#i9dAys!zIl20O*NN zf9)M7F)xjFV?dX_Sc5xv_x<6STYaz}On?=(-JE|k{v0wuL?G$|4QK!Js0yFP{pBt> zV<=1jGA3LwmA><2l#hHME+V2><8?bo6H4f4CSVP~v3~Dv>)fNErEDQb%BV|7AL~!v z%EoK)*dh&60bL%zEk!6_te~s(=Ax>Dp8j;o@&$m;;W~(3pi-bfIO`BbWfT?Jy4ic| z&1doV(Xn^Q2K^a&T9biHR{;eo&&JRx2v_b;dcuYP0PhpTTN<`)+EHY88}-Kqk*edJ zRD-#)JK7igD7%kjRp#BpE+TQ_sXbL;qGSUiBtfC8Sap|c%GPERF{O}07@7RB7pw?z z;bCLIC>1zCiSao}TM_dugs7O5lj`9O zLRl1HVZ{>tYZ%fx2!Dgn!bO2TyvOy}8%#D8wC~)Lkgajn>6#!c2e$XX^_T)%osfZB zW)yKuhC;MH8}v^2#)?*G4W=Np>e|NaK+B2Y(PVb#jWEhGU%6vJn}PH47nnO3#_d^j z@Mg&c+;c@e;+8xWLu0PoOqvh-Ag2_7ZLE+qXl%MrN7%){N){O){NBr-MzcWiCGbTr zsMwzpps5118Fgj@$){`aW$|cL#+xxCezk?PHRcX;#$>pSirA5`qhF~9nA7m4#YrOl zL~guhbR8w8+Jgf3#JaFTzd{zrMm>lQ(=*WG=4ZGGq`nA1E15=gm}(b5#7J3J67eVn}4 zr@dl=AvfnWf3pfp-~@NF2jastE}JS&krz0l)kRPzW1uywA(J`)j_Kk%UaZ-%d9Pg7 zO30F7yh*|=6K`AHRc>>f2!)9})(VNAYPjjvI#p2&W$x+Jm(wbVNJLA5R;3sjWC?hA z%wp;Gdt3#NjZ827L(AIdHi085WD5KXF^{|Pi%7nch_<_Du%fR=vw{Ach@|J75YHfL z!H#tOWNWhI8ACOte66p4EY00I=tVMx0}!qgkIEQt0`hf(bH;Fig(UNd?yU=T149TQ zsN~XGA=a3JT50ox>1-XY_1>lHI9_B5`MENCjaWt9VC%@m=u|eO{;ESomysxKQi8gC zPn+2)xhMWhKjyg-MHKM|=1rF-F9OO9P_F)0G|buE;|czdCuotVKJ`7;dZ4gk%ikZX2{>JNdSTo@$3F7D!7$R5Lp> zC*WO^1bKxOQfH5@^0U_+i5;-6Ge31?DipXRA*#jRaZtZ#y9p1*@dlK3)^v)2@XRYs@_YfM z(mU!60%s_q^Z6d|bLY?1-ZO`X(^cZYCXQDI+^^@G6a@R%sE@!v+-p#OBH!}j|pKz|X1-H{H zl~nhi{D$ad4K5w_C^GH)WZ)?O(t(3%o@%*FzmAccFW0qI98Yj*^4%dGH33EZ3(WY4 zaW$q9_laS|D7Wby57VteobZGqRwIxA%KglQ3UJ<{B zdXU9@sBu*jLk%n1=((!vryen8?6PD>|4$mXGkt~#M#H}gtWq|e7MrhECqwz>4bhaC=__2A0=5MS# z7UWS^aO_qkP$VOK3vdulYnOHc%mR}y*X4P3i zMyf;D=akl^JYAk_HF6cXJ_E5&$S}fSDo8L7*LWpVo)Z_1v`9e0}03~^}W}LKChBEj$ZgL7NFWq%4xWun!jMB zOW}iK)B?&%FK)OwQYaLh<#qIPy$U zPMV6kjeR8+_4wI9<*w6r?weIb0J>(%eqxYLatYw26M4)cPGkBfG%{km$aNs~BQjQc z+cjA{wjND1;TM^*UCM|dtI)>3&gDqm1Mro-{g3MGE&E2t4v17){pF4-q3YPN+`c+s z@i390Qm~exgbux@?&EhMhv8H{F6tdITMSGki=mR*;2e3I$`kOvK)I}_S0Iv z^jN>~9e1W}YbbW43y}O(Lgb!#j;{wiq*G`u<5s10yZYD>-Z;+WwNV(a!e!W~#9ym4 zl7uqA#rmUY1mRY&sGnAc`VhjDrUa(85WyV$jId$VF0)6sKodCt7Va1xa)A0Qtl|onID?J zUMzD~dGVvx+0d>rdZku7&K#S#2NbKts9kCC<_B26QDuG%uoaHmn7h(tu$&TsUI6Q-ZI+EmtgB-Tx~Ky(cf3!eT(jc!*qMPjjV!X>;kGhs(tY1-0pUd zTA#Epgm9V=S?^~ehwQ=uFJh7H!e{N3=0PsLCEsF*a#Q$D6SR(xy~Tj&?4LRoR2q#r z;Ayqoh2dm`4at*#K)P6ux62`KdGeWISL%59V4h0mPBufa+>#SOKF{N{l!#u`a%SK@A(8R4vDzuTO1>ii|@KJ zQB!hLmkzS>@=JpqqN6kNwyMuW&B`!S1>2Dx-?)YQf?AK|P5#BU0F_#8nOYeT#WO!1 z1q(3H77+jL0wwiW^}?C9Qb_*0K&F^?G}Ym}s_!@AGan-W?pkpZW~Ff<4t3o1x!&{% zN0iy@Uuoe$nd`|ZYV8q9cz*NsNjCmymYgK~DBR|`U1S+`EpFpvs%tp1^cF zvm?iu+?3>}NpJ5{Nep1TWao8OCNEkM8c1)&S4BStpploW-8=98mwPXte@n36by&cj z1CDxL=g2wp5ZVV>_QS0|zt1Ga!^~lD#*2OSr3aGYThvZO#yFsjT8al`h0qA>2jtzZ z0ZB(Vc8F3P%_1_9{-$_~;@iNA81KoXR7*@Z=!Gn_yWTB>6#E|47@0O^in_v=?S1?$ zbRALmjlg($TJ-DJ2h(^%Tu>Vi!I°?%Rp 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�%N%v=`6i<*)M14eE9I{fn!o( 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%0DTv$1=^01nC$s$oLc^w*Kb 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 Ac>n+a literal 0 HcmV?d00001 diff --git a/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/screenshot-tab-a-before.png b/libs/@hashintel/brunch-agent/docs/evidence/implementations/fe-1575-outer-browser-witness-2026-09-04-r2/screenshot-tab-a-before.png new file mode 100644 index 0000000000000000000000000000000000000000..082e16eb0becfae7a07011f3a2a2671c6d13991c GIT binary patch literal 88123 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

Jx#T$tyEhz)g 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 Date: Fri, 4 Sep 2026 11:40:25 +0200 Subject: [PATCH 13/13] M7+ resteering planning --- ...nce-and-tooling-decision-log-2026-09-04.md | 93 +++++ ...y-lineage-independent-review-2026-09-04.md | 392 ++++++++++++++++++ ...venance-by-lineage-mini-spec-2026-09-04.md | 135 ++++++ 3 files changed, 620 insertions(+) create mode 100644 libs/@hashintel/brunch-agent/docs/evidence/design/provenance-and-tooling-decision-log-2026-09-04.md create mode 100644 libs/@hashintel/brunch-agent/docs/evidence/design/provenance-by-lineage-independent-review-2026-09-04.md create mode 100644 libs/@hashintel/brunch-agent/docs/evidence/design/provenance-by-lineage-mini-spec-2026-09-04.md diff --git a/libs/@hashintel/brunch-agent/docs/evidence/design/provenance-and-tooling-decision-log-2026-09-04.md b/libs/@hashintel/brunch-agent/docs/evidence/design/provenance-and-tooling-decision-log-2026-09-04.md new file mode 100644 index 00000000000..7638119b3cb --- /dev/null +++ b/libs/@hashintel/brunch-agent/docs/evidence/design/provenance-and-tooling-decision-log-2026-09-04.md @@ -0,0 +1,93 @@ +# Provenance, workpiece, and tooling decision log — 2026-09-04 + +> Design evidence, not execution authority. Compiled on 2026-09-04 from the owner conversation that reviewed the Mission 6 tie-off and the Mission 7 departure point. Every terrain claim below was checked against the checked-out code or the installed Flue 2.0.3 types during that conversation; each entry names what was inspected. Owner-settled items are policy accepted in conversation and must still be promoted into mission authority at the named cut before implementation. Recommendations are the agent's and remain open until the owner accepts them. The projection of this log into a reviewable design is [`provenance-by-lineage-mini-spec-2026-09-04.md`](provenance-by-lineage-mini-spec-2026-09-04.md). + +Legend: **Settled** = owner accepted in conversation. **Recommended** = agent recommendation, not yet accepted. **Open** = fog; a probe is named. + +## A. Mission 6 tie-off + +**A1. Mission 6 deterministic layers are closed; the outer witness was blocked by an environment fault, not a product defect.** Settled as observation. Inspected: `docs/evidence/implementations/fe-1575-resumable-workpiece-petrinaut.md`; the shell's `ANTHROPIC_API_KEY` was the five-character placeholder `dummy`, which explains the recorded HTTP 401. Consequence: the outer two-tab witness, the cold-reader adjudication, and the product-manager demo remain open; the two human gates depend on the outer rerun because the model-produced revision does not yet exist. The Mission 6 builder is performing the rerun in a parallel session (untracked `fe-1575-outer-browser-witness-2026-09-04-r2/` observed in the worktree). + +**A2. Mission 6 stacks on unmerged Mission 5.** Observation. `gt log short` shows `ln/fe-1574-direct-voice-flue` beneath this branch; GitHub PR 9528 is open awaiting review; Mission 5's human Voice witness is unrun per its evidence README. No PR exists yet for FE-1575. Consequence: Mission 6 cannot merge before Mission 5, and its close report needs a PR. + +**A3. The prepared fixture's "Current Petrinaut correspondence" section is fixture-rigging.** Settled. Inspected: `prepared-crew-reservation-fixture.ts` versus `plugin-sdcpn/src/skills/sdcpn-modelling/templates/workpiece.md`; no template heading or skill directive produces such a section. Consequence: the Mission 6 fixture is a viability proof of transport, mutation, and resume, and must not be promoted into the provenance pair. The close report must say so. + +**A4. The fenced-block workpiece source is a Mission 6 contract that Mission 7 will change.** Settled. The Mission 6 close report names the move from fenced `runbook-ir` blocks to an `update_workpiece` tool as a carried change so nobody treats latest-block selection as settled. Mission 6's implementation is not retrofitted mid-tie-off. + +## B. Terrain: what exists between conversation, workpiece, and net + +**B1. Flue history to workpiece revision: exists and is tested.** Inspected: `packages/core/src/workpiece.ts`. The resolver selects the tagged prepared signal or the latest assistant `runbook-ir` block, identified by source message id plus SHA-256. + +**B2. Flue history to capture store: exists as a stub that re-indexes user utterances.** Inspected: `apps/brunch-agent/src/capture/apply-sweep.ts`, `packages/core/src/evidence/capture-store.ts`, `session-log.ts`. One envelope per user entry, excerpt equals the whole utterance, payload `{}`; excerpts resolve to a pointer of session id plus entry ordinal by substring search over an archived copy of history; the store adds an owner key, dedup, and idempotent retry. Everything but the owner key duplicates what Flue history already carries, under a second identity scheme. The store is a JSON file beside the sqlite database (`db-path.ts`). + +**B3. Capture store to workpiece: does not exist.** Inspected: the workpiece template asks for "exact expert wording" as prose beside each claim and never names capture ids, message ids, or ordinals; Markdown has no passage identity. Settled: this is the central unresolved design tension, and it has been deferred as "later" without being stated in the spine. + +**B4. Workpiece to net: one prose sentence in the fixture; no derivation record anywhere.** Inspected: fixture and template as in A3. Settled: a hand-authored derivation fixture, as the Mission 7 draft proposes, is useless and rejected. + +**B5. Workpiece visibility: the workpiece is a black box during a conversation.** Inspected: the `runbook-ir` block streams as a fenced code block inside the assistant message; the only current view is the Mission 6 fixture banner's collapsed `

` element (`prepared-fixture-banner.tsx`). No pane, revision list, or diff exists. + +**B6. Retained persona runs contain no revision series.** Inspected: every run under `docs/evidence/evaluations/` has at most one `runbook-ir` block; `vestera-runbook-headless` emits once at the end; Mission 4 v2 runs stopped before substance. Consequence: the model's revision cadence is unmeasured. + +**B7. Petrinaut elements have no metadata slot; the file wrapper has only `title` and `meta.generator`.** Inspected: `petrinaut-core/src/schemas/entity-schemas.ts` (strict objects), `file-format/types.ts`. + +**B8. Flue offers four typed ways to put something in the canonical log.** Inspected: `@flue/runtime` and `@flue/sdk` 2.0.3 `.d.mts`. Tool call records (input, output, call id; surfaced as tool parts on the assistant message with `turnId` and `submissionId`); `useDataWriter` data parts on the current response; `usePersistentState` `state_write` records, atomic with the tool batch, server-side only, not in `history()`; and signals via external `dispatch()` or `ctx.append` in finish hooks, surfaced as system-role messages with `tagName` and string attributes. There is no arbitrary custom entry and no tool-context `append`. + +**B9. The construction tool schema carrier is still the one Mission 3 falsified.** Inspected: `plugin-sdcpn/src/tools/petrinaut-construction.ts` declares input as `v.looseObject({})` with a `rawTransform` that re-parses against Petrinaut's Zod schema, and pastes the canonical JSON Schema into the description text. Flue accepts Valibot only (`ToolInputSchema = v.GenericSchema`), converts via `@valibot/to-json-schema`, and rejects other Standard Schema vendors by checking `~standard.vendor === "valibot"`. The provider therefore sees an object with no fields. Flat `addArc` can survive on the description; nested `addType.elements` failed nine of nine in Mission 3. The spine already recorded "Flue Standard Schema support or a mechanical shape-preserving conversion" as the accepted next move; neither has been done. + +**B10. Mounted tools today.** Inspected: `chat-agent/agent.ts`, `plugin-sdcpn/src/flue.ts`, `core/src/flue.ts`, `core/src/client-tools.ts`, website `local-storage-demo/`, persona `client-tool-hosts.ts`. Server: `ping`, Flue's `activate_skill`, `readPetrinautDoc` (browser-deferred, all SDCPN conversations), six construction tools (headless mode only), two fixture tools (Mission 6 mode only). Core owns no model-facing tool by stated rule. Client: the Petrinaut panel client-tool host; an `ask` interactive tool and `sweep` result handling that no mounted server tool ever produces; the Voice bridge, which is a transport rather than a tool; persona hosts `none`, `mock`, `real-headless`. The stock Petrinaut assistant exposes about fifty canonical tools. + +## C. Design decisions + +**C1. Provenance is recovered from lineage in the canonical log, not stored in a typed IR, a capture store, or a hand-authored derivation.** Settled in principle. Rationale: the typed comprehensive IR chased a receding horizon and degraded model performance; the structural swing left no seam; both treated provenance as a property of the domain model when it is a property of who changed what, in response to what, when. Every such moment is already recorded in Flue history once workpiece revisions and net mutations are tool calls. + +**C2. The honest shape of a why answer is one creating call, one workpiece passage, one introducing revision, then either a quoted line or a short turn range.** Settled. The owner's correction: tool calls do not occur every turn and workpiece revisions do not occur every turn, so ranges enter at exactly one hop, the last. The verbatim quote check narrows a range to a line where the model quoted the expert. Elements changed several times show introducing and last-changing calls separately. + +**C3. The why tool returns structured ranges; the assistant interprets.** Settled. The user asking "why" implies an assistant interpretation anyway, so the tool never authors prose and never invents a link. It must accept multiple element ids and return potentially several ranges per element. + +**C4. Workpiece updates are tool calls, not fenced blocks in assistant text.** Settled. Tool: `update_workpiece`, input one Markdown string, `durable: true`, validates and hashes, writes the current-revision pointer with `usePersistentState` inside the same tool batch, returns revision and hash. Core owns the tool; plugins own the template. Rationale: structural revision identity (call id), write-time validation, agent access to its own current revision without model echo, lineage shared with mutation calls through `turnId`, and a clean UI split. Caveats recorded: token cost is unchanged and a structured-patch input is the later absorber; a model may call a tool less readily than it emits text, so cadence must be measured either way. + +**C5. The generic lookup is a core `query_workpiece` tool; the element lookup is plugin-owned.** Settled for the split, name provisional. Core knows revisions and history, not Petri nets; it takes a revision pointer or passage locator and returns turn ranges with user text. Plugin-sdcpn owns a `locate_elements`-style lookup because only it knows which calls are mutations and where ids sit in inputs. + +**C6. Net revisions join to workpiece revisions through the client-tool result, not through Petrinaut metadata.** Recommended. The browser returns the post-mutation document hash inside the client-tool result (Mission 6 already computes it for the settled manifest). A document hash no tool result explains is honestly "changed outside the conversation." A file-level pointer in Petrinaut `meta` is deferred until Mission 11 has a real consumer for a self-describing export. + +**C7. The workpiece becomes a visible, revisioned document in its own pane.** Settled. Chat projects `update_workpiece` parts out of assistant messages, leaving a one-line marker; the pane shows current revision, revision list, and diff, driven from Flue history through the Mission 5 transport. Rationale: the chat pane is too small for artifacts; a why answer resolves to a passage the reviewer must be able to see; per-turn emission for the pane is the same behaviour that gives blame its grain. Projection lives in the app or transport layer, not the Petrinaut library. + +**C8. The capture store and sweep earn no place in Mission 7.** Recommended. Flue history already carries message ids and exact text. Owner-key enforcement on evidence reads can be a check at answer time. The store re-enters only if verification strains under compaction or ownership. + +**C9. The `ask` and `sweep` client handling is retired from code.** Settled. Surfaces: the two names in core `client-tools.ts` and the suspended ask contract behind them; the website's ask interactive tool and its test; the sweep filter in the panel transport and the sweep output module; the Voice references in `canonical-speech.ts` and `interview-coverage.ts`. Archived mission records remain the design reference. Vehicle: a subtraction commit under Mission 7 authority. + +**C10. Petrinaut mutation tools are wired into ordinary conversation now, and admission is by evidence rather than by an inherited six-tool subset.** Settled as policy. The owner's judgement: continuing to defer tool wiring is a strategic mistake; the six were an unexamined side-quest set; the skill teaches concepts but not tool use. Terrain supports it: the subset lacks every `update*` and `remove*`, `getNetCompilationErrors`, `addScenario`, `applyAutoLayout`, metrics, subnets, and differential equations. Parity with the stock modeller is still not the goal. Mission 6's live constraint that construction tools stay out of ordinary conversations must be amended at the Mission 7 cut, not in the Mission 6 tie-off. + +**C11. The schema carrier must be fixed before tools are admitted.** Recommended as the first act of the next cut. Options: a mechanical JSON Schema to Valibot interpreter for the subset Petrinaut uses (local, reversible, satisfies "mechanically derived"), or upstream Flue Standard Schema support. Petrinaut's canonical tool descriptions were written for the stock assistant and become useful field-level guidance once the carrier carries fields. + +**C12. The skill must add construction posture, not just concepts.** Settled in principle. Read the definition first, mutate in small steps, check compilation errors, record each decision in Construction notes, call `update_workpiece` before and after construction. + +**C13. Mission 7's release note narrows to the honest framing.** Settled. "Ask why about any element and see the workpiece passage, who prepared it, and the exact conversation line it rests on, or an explicit refusal." Rejected: inventing a longer conversation to make "what the expert actually said" true for prepared elements. + +**C14. Mission 7 names local deployment posture; remote durability returns to Mission 8.** Settled. The owner reports the Postgres persistence move is slow and unresolved for local versus remote; it will not exist for Mission 7, so the sequence lines up with the original numbering. + +**C15. The workpiece passage-identity question is decided by probe, not in a draft.** Recommended. Candidates: heading path (readable, breaks on rename), Markdown anchors (stable, changes the surface), companion manifest (clean Markdown, second-artifact drift). Probe: prepare references for the elements of one real pair, revise one non-semantic line, observe which scheme survives. + +## D. Real honest fixtures through persona interviews + +**D1. Real conversations and real workpieces replace prepared fixtures as the provenance pair.** Settled. The Mission 6 fixture stays a viability proof. Multiple persona runs can proceed in parallel; six cases already exist under `evaluations/cases/`. + +**D2. Persistence during a run is the Flue store; retention is the harness's per-run evidence directory.** Observation. The harness's `--brunch-evidence-dir` already refreshes a canonical `snapshot.json` plus deterministic projections on every settled read. With `update_workpiece`, revisions become tool parts in that snapshot and the harness's workpiece recovery must read tool parts instead of fenced blocks. + +**D3. How a retained real conversation becomes a live fixture is the first fog item of the persona programme.** Open. Options: keep the genuine conversation live in a durable store shipped with the demo; restore retained genuine records into a fresh store through Flue's storage adapter (records are genuine, only relocated, but the adapter's record types are private and the routing doc warns against consuming them); or replay the materialized snapshot as prepared signals, which turns genuine history into a prepared projection and would make the why route fixture-only. Probe: whether Flue 2.0.3 exposes or tolerates a conversation export and restore at the storage boundary. + +**D4. Stop rule: a turn cap as budget plus a Brunch-side completion signal; ledger coverage grades afterwards.** Recommended. Today the turn budget lives only in the launch prompt and the persona is told never to end the interview. Proposed: cap per run (larger than the 6–10 used so far, cost accepted), stop early when Brunch itself declares construction handoff or delivery in its status section, and grade coverage against the hidden oracle ledger after the run rather than using it to stop. + +**D5. Runs go to construction, because the fixture must contain lineage.** Recommended. Sequencing follows: carrier fix and tool admission and `update_workpiece` land before construction runs. An elicitation-only campaign can run earlier to measure revision cadence. + +## E. Consequences for the planning record + +**E1.** State the provenance tension in the spine as an open design decision with C1 as the current hypothesis, the typed IR and hand-authored derivation as rejected with reasons, revision cadence as the named strain, and the visible workpiece as the precondition. + +**E2.** Re-cut the Mission 7 draft: drop the capture-store chain and Mission 2 inherited closure; make the carrier fix, orphan retirement, `update_workpiece`, the workpiece pane, tool admission and teaching, and the persona programme the mission's body; make the why route the last step over real lineage; name local posture. + +**E3.** Adjust the Mission 9 and 10 drafts: they inherit the seam from lineage (revision id equals call id, passage identity per C15, element id, document hash per C6) and no longer assume a derivation fixture or prebuilt pair. + +**E4.** Mission 6 close report: record A3 and A4 plainly, plus the credential cause in A1. + +**E5.** Decision-integrity: every Settled item here is an owner decision expressed in conversation. It becomes authority only when written into the cut `MISSION.md` for Mission 7; this log and the mini spec are neither authority nor a substitute for it. diff --git a/libs/@hashintel/brunch-agent/docs/evidence/design/provenance-by-lineage-independent-review-2026-09-04.md b/libs/@hashintel/brunch-agent/docs/evidence/design/provenance-by-lineage-independent-review-2026-09-04.md new file mode 100644 index 00000000000..c96ae7fc06e --- /dev/null +++ b/libs/@hashintel/brunch-agent/docs/evidence/design/provenance-by-lineage-independent-review-2026-09-04.md @@ -0,0 +1,392 @@ +# Independent review of provenance-by-lineage replanning — 2026-09-04 + +> Review evidence, not execution authority. This document evaluates [`provenance-and-tooling-decision-log-2026-09-04.md`](provenance-and-tooling-decision-log-2026-09-04.md) and [`provenance-by-lineage-mini-spec-2026-09-04.md`](provenance-by-lineage-mini-spec-2026-09-04.md) against the checked-out Brunch and Petrinaut code, the installed Flue 2.0.3 documentation and types, the current future mission record, and three independent adversarial reviews. It identifies factual corrections, semantic gaps, and strategic blind spots. It changes no owner-settled policy and authorizes no implementation. + +## Executive verdict + +The replanning is directionally strong. Making the workpiece visible, making revisions first-class tool calls, refusing to turn the capture store into semantic IR, repairing the provider schema carrier before trusting construction, and deriving audit information from the canonical conversation record are all sound moves. + +The central claim is nevertheless overstated. The proposed mechanism establishes **temporal audit lineage**, not yet **motivational or causal provenance**. It can show which workpiece revision was current when an assistant requested a mutation and which conversation context preceded that revision. It cannot deterministically establish that a particular workpiece passage motivated a particular element. Passage selection, element-effect attribution, actor identity, and durable exact evidence each require information or contracts that the described lineage does not contain. + +The defensible near-term claim is: + +> Show the logged assistant mutation request, its later browser outcome, the workpiece revision temporally current for that request, and the intervening authorized conversation context, with explicit warnings where motivation, causal derivation, actor attribution, or exact historical evidence is not established. + +Anything stronger requires reopening C1–C3, C5, C6, C8, C10, C13, and C15 before Mission 7 authority is cut. The proposed Mission 7 also absorbs the central automatic-construction advance currently assigned to Mission 9 and is too large to remain a bounded explainability mission without an explicit recut. + +## Critical semantic gaps + +### 1. “Latest workpiece before mutation” is correlation, not causation + +The decisive unsupported traversal is: + +```text +element id + → mutation call + → latest update_workpiece at or before that call + → the passage in that revision +``` + +The conversation log contains no deterministic relation from a mutation to the passage that motivated it. A workpiece can contain many claims; one call can realize several claims; several mutations can be made while the same multi-topic workpiece is current; and a mutation can arise from formalism constraints, model inference, an external source, or a mistake. A post-construction workpiece update may contain the actual rationale but is excluded by the backward-selection rule. + +The proposed `locate_elements` returns mutation calls and the workpiece revision current at each. The proposed `query_workpiece` begins from a passage locator. No mechanism produces that locator from the mutation. Therefore the mini spec's statement that “every hop is a lookup in the canonical log; nothing is stored elsewhere and nothing is inferred” is false as written: selecting the relevant passage necessarily requires semantic inference or an explicit relation. + +This is not repaired merely by sharing a `turnId`. Shared temporal correlation still does not establish motivation, and the current client-tool result does not in fact share the mutation request's turn, as described below. + +**Required decision:** choose explicitly between: + +1. **Temporal-lineage claim:** report the workpiece revision current for the mutation and a broader conversation range, without saying that one passage motivated the element; or +2. **Small creation-time association:** carry a revision identifier and one or more passage locators with the mutation request or with a thin construction-operation envelope. + +A small creation-time relation is not the comprehensive typed IR previously rejected, and it differs materially from a retrospective hand-authored derivation fixture. If neither is acceptable, the system must return a broader range or refuse rather than invent a point passage. + +### 2. Passage identity and blame are prerequisites, not downstream fog + +The intent promises one workpiece passage, the revision that introduced it, and blame across revisions while passage identity remains undecided. Heading paths fail under rename or movement; exact text fails under edits; ordinary line blame fails under reformatting; anchors remain stable only if their lifecycle is defined; and a companion manifest can drift from the Markdown. + +The proposed C15 probe changes one non-semantic line. That is too weak to establish the promised semantics. It does not test: + +- heading rename or movement; +- passage split or merge; +- paraphrase that preserves meaning; +- deletion and reintroduction; +- a passage accumulating evidence from several non-adjacent periods; +- duplicate quotations or repeated headings; or +- correction, qualification, contextual coexistence, and conflict. + +For split, merge, paraphrase, and reintroduction there may be no unique mechanically discoverable “introducing revision” without explicit successor/predecessor semantics. + +**Required decision:** either define durable passage identifiers and their edit lifecycle before promising blame, or narrow the first claim to revision-local text and refuse cross-revision “introduced by” answers. The passage-identity probe should cover rename, move, paraphrase, split, merge, deletion, and reintroduction, not only a non-semantic line edit. + +### 3. User-turn ranges are not attribution and do not establish “who prepared it” + +The range between two workpiece revisions can contain unrelated statements and can omit older evidence reused in the new revision. A verbatim match proves string occurrence, not endorsement, origin, authority, or causation. A user may quote another person, reject the quoted proposition, or repeat wording supplied by the assistant. Non-verbatim synthesis, declared defaults, formalism constraints, assumptions, external sources, and construction-opened losses require distinct treatment. + +The proposed answer also collapses several different actors: + +- the assistant that authored the workpiece revision; +- the expert whose evidence supports a claim; +- the person who requested construction; +- the browser principal that applied the mutation; +- a later reviewer; and +- the owner or authority that permits canonical change. + +A Flue `role: "user"` is not sufficient actor identity. The release note's promise to show “who prepared it” is therefore unsupported by the described records. + +**Required contract:** represent and report workpiece author, source/evidence actor, mutation actor, requesting principal, and authorization context separately. Conversation ranges may be supporting context; they are not, by themselves, authorship or authority. + +### 4. Element IDs in tool inputs do not establish actual mutation effects + +Seeing an element ID in a mutation input does not prove that the call created or changed that element. Calls can fail, no-op, apply against stale state, affect several entities, create derived entities, delete an entity, replace or recreate an ID, or be successfully applied while their result delivery is lost. Commands such as layout can affect many elements without identifying them individually in the input. + +The current `clientToolHistoryFrom` projection treats results as opaque correlated outputs. It does not establish canonical effect semantics or reconcile conflicting and repeated results. + +**Minimum settled mutation evidence:** + +- mutation call or operation identity; +- target document identity or incarnation; +- expected base document hash; +- applied, no-op, failed, stale, or unknown outcome; +- confirmed post-document hash; +- exact created, updated, deleted, and derived element IDs, or retained canonical pre/post definitions from which those effects are mechanically derived; and +- one authoritative result per call with duplicate-result rules. + +Without this, the honest statement is “the assistant attempted this mutation,” not “this call created this element.” Deleted and recreated elements also need explicit lifecycle semantics; “creating call and last-changing call” is not sufficient when identity can be retired and reused. + +### 5. The browser mutation and workpiece update do not share one atomic boundary + +`update_workpiece` would be a server-side Flue tool. Its `usePersistentState` setter can commit atomically with that server tool's unit of work. Petrinaut mutation executes later in the browser and its result returns as a separate `client-tool-result` system dispatch. The workpiece update and the browser mutation therefore do not share durability or a transaction. + +A workpiece update can settle while a browser mutation fails, times out, applies against stale state, or is manually superseded. A browser mutation can apply while its result is lost. Two tabs or two conversations can target the same document. A later result can arrive after another mutation or hand edit. + +Atomicity across these boundaries is not necessarily required, but observable incomplete states and deterministic reconciliation are. The design should model an operation protocol rather than imply a shared batch: + +```text +mutation requested(callId, documentId, baseDocumentHash, workpieceRevision, intended scope) + → browser outcome(applied | no-op | failed | stale, postDocumentHash, effects) + → reconciled | incomplete | unknown +``` + +This protocol must define retry identity, duplicate delivery, stale-base refusal, lost-result behavior, and what provenance is safe to report for an incomplete or unknown operation. + +### 6. A post-document hash is not an adequate join + +A whole-document SHA-256 is a content fingerprint, not a mutation lineage record. It does not identify the pre-state, the transition, the actor, or the affected elements. Identical hashes can recur after revert and reapply. A hand edit followed by a logged mutation can yield a post-hash that appears “explained” by the tool result even though the resulting document includes an outside-conversation change. Serialization changes or a missing client-tool result can produce the opposite false classification. + +Consequently, “a document hash that no tool result explains is changed outside the conversation” is too strong. The safe classification is “not attributable from the recorded transitions.” Reliable attribution needs at least document identity, expected base hash, serialized operation order, result hash, operation ID, and confirmed effects. + +After an unexplained transition, the system should refuse provenance for the affected state—or for the entire document when no trustworthy diff can isolate the effects—and begin a new explicitly imported external revision if lineage is to continue. + +## Critical durability and access gaps + +### 7. Flue's supported history projection does not preserve exact lineage across compaction + +The design conflates Flue's append-only canonical storage with the public `history()` projection. Flue's underlying `ConversationStreamStore` is an ordered append-only canonical record, but its record types are not the supported application read surface. Brunch reads `createFlueClient(...).history()`, which returns a materialized conversation snapshot. + +Flue 2.0.3 explicitly compacts older messages into a summary while retaining only recent history verbatim. After compaction, the supported materialized history may no longer contain: + +- exact old user lines; +- old `update_workpiece` inputs; +- old mutation tool parts and results; +- the full workpiece revision series; or +- the exact text needed for quote verification. + +Brunch's current Flue history reader consumes only `snapshot.messages`; it has no supported access to the private pre-compaction records. This breaks the exact-line answer, workpiece revision pane, passage blame, and mutation lookup at once. + +C8 therefore understates the re-entry condition for independent retention. Compaction is already a known behavior, not merely hypothetical future strain. + +**Required decision:** either scope Mission 7 explicitly to uncompacted local conversations and visibly refuse once required evidence has compacted, or retain an immutable, authorized, compaction-independent lineage projection before compaction. That projection need not resurrect the current one-envelope-per-user-utterance capture design, but some stable retained evidence is required for the longer Mission 9 and Mission 10 story. + +Retention, export, audit, revocation, and migration are additional reasons a canonical operational conversation store may not be sufficient as the product's evidentiary archive. + +### 8. `query_workpiece` and `locate_elements` have no specified executable history-access boundary + +The ownership split is conceptually plausible but omits the runtime boundary. Inside a Flue agent there is no history hook. The supported read path is `createFlueClient(...).history()`, which requires a host-resolved conversation URL and transport. The current Brunch architecture deliberately places this absorption in the binding and app layer. + +Therefore “core knows revisions and history” is not currently true as an executable capability. A core server tool cannot silently self-HTTP without host composition, and a plugin-owned server tool cannot inspect Flue history without acquiring a substrate dependency or an injected history service. + +**Recommended boundary:** + +- core owns pure formalism-independent workpiece revision and query semantics; +- plugin-sdcpn owns interpretation of Petrinaut mutation names, inputs, outputs, and element effects; +- the binding/app owns authorized acquisition of the Flue materialized history or retained lineage projection; and +- the app composes the model-facing query tool from those capabilities. + +Whether there is one composed why tool or two model-facing tools should follow the minimum useful product interaction; package ownership does not require exposing package seams to the model. + +### 9. The proposed persistent-state pointer does not give the model the current workpiece + +The proposed state contains only `{ callId, sha256, revision }`. It contains no Markdown, and `usePersistentState` values are server-side; they are not automatically shown to the model. The statement that “the next render reads the current pointer without the model echoing it” does not explain how the model obtains the current workpiece content. + +Reading the content back from `history()` reintroduces the unavailable-history and compaction problems. A pointer alone also cannot validate or recover the current document after old tool parts disappear from the materialized projection. + +**Required mechanism:** persist the current Markdown with the pointer, or provide a retrieval capability backed by a compaction-independent store. The design must also distinguish generic core validation from plugin-specific validation. Core can check non-empty Markdown and generic size/integrity constraints, but it cannot validate conformance to the SDCPN workpiece template without plugin participation. + +### 10. Authorization, disclosure, retention, and untrusted-history handling are absent + +Returning coarse ranges “with the user text” can expose unrelated material and supplies old conversation content to the model as untrusted input. Answer-time equality with one owner key is insufficient for: + +- a second authorized reviewer; +- partial disclosure; +- revocation; +- restored fixtures; +- cross-conversation document access; +- a document whose owner changes; +- sensitive or deleted evidence; and +- later Mission 10 authority distinctions. + +The lineage must bind principal or actor identity, conversation identity or incarnation, document identity, and authorization context. Restoring or relocating a fixture must preserve those identities or explicitly establish replacements. Reads must fail without leaking the existence or content of unauthorized evidence. + +Retrieved conversation text should be treated as untrusted evidence rather than fresh instructions. The why operation should return only the smallest authorized range necessary for the answer and preserve a clear boundary between quoted evidence and model-authored interpretation. + +## Factual corrections to the mini spec and decision log + +### 11. The depicted client-tool turn topology is incorrect + +The mini spec depicts a user message, assistant response, mutation request, and mutation result as sharing one `turnId`. In current Flue history: + +- user messages commonly carry a `submissionId` but no `turnId`; +- the assistant mutation request carries the model turn's `turnId`; +- the construction tool's immediate Flue output is only `{ awaiting: "client" }` and terminates that response; +- the browser's actual output arrives later in a separate `client-tool-result` system dispatch under another submission; and +- the assistant continuation has a new model turn. + +Correlation is by `toolCallId`, plus submission and record order where needed—not by assigning the same `turnId` to the original user message and later browser result. Conversation-range resolution must join user deliveries, assistant turns, client-result signals, and continuations through their actual submission/order semantics. + +The retained Mission 6 witness also shows cumulative client-tool-result signals that repeat earlier call IDs. The lineage reader must deduplicate and reconcile by call ID rather than treating every signal occurrence as a new result. + +### 12. Current browser mutation results do not contain `documentSha256` + +The current construction tool settles server-side with `{ awaiting: "client" }`. The retained Mission 6 `addArc` browser result contains title, detail, target, and `applied`, but no document hash. Mission 6 computes the document hash separately in its settled manifest. + +Accordingly, the sentence “the browser returns the post-mutation document SHA-256 inside each client-tool result” describes proposed work, not observed current behavior. The browser result contract, its caller, and the production routing must be changed and tested before C6 exists. + +### 13. `usePersistentState` cannot be called inside the tool's `run` + +Flue hooks must be called while the agent function renders. The implementable pattern is: + +1. call `usePersistentState` during agent render; +2. capture the returned setter in the tool closure; and +3. invoke that setter from the tool callback, where `toolCallId` is available in the tool context. + +The mechanism table's pseudocode is therefore technically wrong or materially ambiguous. It should describe a render-time hook and tool closure, including how the revision number is computed with updater semantics and how the returned revision is kept consistent with the buffered state write. + +### 14. The Petrinaut file-wrapper description is imprecise + +The versioned Petrinaut file wrapper carries more than `title` and `meta.generator`: it also includes `version`, the SDCPN document arrays, and optional generator-version metadata. Runtime entity schemas use strict objects in important places, but the file import schemas are not uniformly strict. + +The narrower conclusion remains sound: there is no currently supported provenance metadata slot on individual elements, and no established file-level provenance field. The documents should state that directly rather than claiming that the wrapper has only two fields or that every relevant file-level object is strict. + +### 15. “Durable tool” does not make the browser side effect exactly once + +`durable: true` can protect the server-side tool attempt and its recorded Flue state effects. It does not make an external browser mutation exactly once. The browser can apply a mutation and lose its result; a retry can encounter changed state; signal admission can be deduplicated while the external side effect has already happened more than once. + +The durability statement must be scoped to the server workpiece tool. Browser mutation idempotency, base-state checking, and unknown outcomes require their own contract. + +## Strategic gaps in the mission sequence + +### 16. The proposed Mission 7 absorbs Mission 9's central product advance + +The recut Mission 7 now includes: + +- provider schema-carrier repair; +- broad ordinary-conversation mutation-tool admission; +- construction teaching; +- `update_workpiece` and persistent revision mechanics; +- a workpiece revision/diff pane; +- retirement of old client-tool surfaces; +- several real persona interviews through construction; +- production of a real constructed net; and +- the final why route over that lineage. + +Mission 9's current release note is that Brunch constructs a recognizable net region itself. If Mission 7's real persona run constructs the provenance pair, that advance has already been crossed. M7 becomes a large multi-front construction, UI, evaluation, persistence, and explainability mission whose user value arrives last, while M9 later repeats the same terrain under a different completion bar. + +**Required recut:** choose explicitly between: + +1. consolidate the real construction and explanation advance, then give the following mission projection breadth, repeat/change behavior, and readiness closure; or +2. make the visible revisioned workpiece a smaller precursor mission, followed by one mission that constructs and explains a real bounded region. + +At minimum, carrier repair plus one canonical production-path mutation should be an early go/no-go tracer before committing to the pane, persona campaign, and whole-net coverage. + +### 17. M7 is not bounded around one coherent visible advance + +Even if one branch may contain several tracer bullets, the proposed M7 has too many independent failure fronts: schema conversion, model tool selection, workpiece cadence, history access, passage identity, browser mutation effects, new UI, fixture restoration, persona quality, and reviewer usefulness. Several can invalidate the architecture after substantial unrelated implementation has landed. + +The first working line should answer the disputed semantic question with the least mechanism: one genuine conversation, at least two distinguishable workpiece passages, at least two mutations, one failed or no-op mutation, one correction, and one hand edit. If the why resolver cannot distinguish those cases without guessing, the architecture should stop before whole-net breadth. + +### 18. Fixture restoration is unresolved but lies on the critical path + +The mini spec accurately marks a `???` between a genuine persona run and a live demo fixture. Keeping a dev store, importing private Flue records, and replaying a materialized snapshot each make a different product claim. Replaying signals creates a prepared projection rather than preserving the original live lineage. + +Running several paid persona construction campaigns before proving that one minimal genuine conversation can be exported or retained, relocated, reopened, authorized, and queried risks producing evidence that cannot power the demo. + +**Recommended order:** run the export/restore/reopen probe on one tiny genuine conversation before the broader persona programme. Record whether the product fixture is a retained live store, a supported relocation of genuine records, or an honestly labelled prepared projection. + +### 19. Broad canonical-tool admission contradicts the stated restraint + +The mini spec says to admit Petrinaut's canonical mutation, query, and command tools by default and scope down only after observed misbehavior, while saying stock-modeller parity remains a non-goal. That is parity-first admission in practice. It also conflicts with the current Mission 9 record's rejection of broad tool parity and risks a large provider tool-definition cost, selection ambiguity, inappropriate commands, and a much larger failure surface before any scenario requires metrics, subnets, differential equations, scenarios, removals, and layout together. + +Rejecting the inherited arbitrary six-tool subset does not require admitting everything. Replace it with a **scenario-derived canonical subset**, mechanically generated from Petrinaut's authority, and expand it when the selected scenario or observed failure requires another mutation class. Measure schema size, prompt-cache effects, tool-selection behavior, latency, correction behavior, and provider errors before making a broad bundle the ordinary default. + +### 20. The completion criterion remains underdefined + +“Any element” and “consequential element” lack a mechanical inventory rule. The old M7 draft at least required a frozen element inventory and explicit supported or unsupported dispositions. That obligation should survive the mechanism change. + +Before a run is graded, freeze: + +- the selected document and workpiece revisions; +- the element inventory; +- the rule distinguishing consequential elements from presentation-only artifacts; +- expected supported, partially supported, externally changed, and refused dispositions; and +- what happens to deleted or recreated elements. + +Without this, whole-net completion can be gamed by excluding difficult elements after the fact. + +### 21. Migration and rollback are missing + +The plan changes persisted workpiece representation from fenced assistant text to tool parts and state, changes ordinary-conversation tool admission, removes `ask` and `sweep` handling, and changes the lineage expected by future missions. Existing conversations and retained runs contain only the old representation. Rollback after new state records and new tool calls is unspecified. + +A migration matrix should cover: + +- old history with new code; +- new history with rolled-back code; +- conversations containing both fenced and tool revisions; +- mixed-version browser and server; +- Mission 6 fixture mode; +- retained evidence restoration; and +- tool-manifest rollback. + +Given the prototype posture, a permanent compatibility layer is not warranted, but the transition crosses persisted data and separately deployed browser/server boundaries. An additive introduction with a bounded dual-read period may therefore be the least safe mechanism. The bridge should have an explicit removal gate. + +### 22. Deployment ordering is inconsistent + +C14 moves remote durability back to Mission 8, but current Mission 9 and Mission 10 drafts still require deployed or replacement-safe inherited state. Historical Mission 8 stopped before remote deployment, and no new executable M8 is yet scheduled. This leaves later missions either blocked on an unscheduled dependency or tempted to silently weaken “deployed.” + +Choose explicitly between: + +- scheduling a real Mission 8 persistence/deployment mission before the first remote claim; or +- making M9 and M10 explicitly local-product missions and naming a pre-M11 remote release gate. + +“Locally run panel,” “locally verified application image,” and “remote replacement-safe service” must remain distinct claims. + +### 23. Consumer discovery may be too late + +Deferring self-describing export and optimization-consumer discovery until Mission 11 risks choosing an M9 region and M10 correction that do not exercise the scenario, parameter, metric, executable, or behavioral semantics Chris and Yannis actually need. Mission 11 could then become an unexpectedly large rebuild rather than a handoff. + +Do lightweight, non-binding consumer discovery before selecting the M9 region: one optimization question, minimum scenario and parameter semantics, expected execution boundary, required outputs, and minimum credibility checks. Keep implementation in M11, but use the real consumer to select a representative proving case and decide whether file-level provenance is load-bearing earlier. + +### 24. Semantic and behavioral proof is too visual until the optimization handoff + +A visually plausible, parser-valid SDCPN can still have incorrect enabling, resource conservation, timing, scenarios, or stochastic behavior. Human semantic review is necessary but insufficient for operational behavior. + +When selecting the first meaningful generated region, require at least one executable discriminator derived from the workpiece—for example resource reservation and release, reachability, token conservation, or one scenario outcome—and carry it unchanged through the reviewer-revision mission. This need not become broad simulation coverage; it should be the cheapest check capable of catching a plausible but behaviorally wrong projection. + +## Items that should be reopened before Mission 7 authority + +### Reopen C1–C3: lineage and the honest why answer + +Decide whether the product promises temporal audit context or causal provenance. If causal provenance remains the intent, identify the smallest explicit mutation-to-passage relation and separate authorship, evidence, rationale, and authority. + +### Reopen C5: lookup ownership and execution + +Keep semantic package ownership, but assign supported Flue history acquisition, authorization, and tool composition to the binding/app boundary. Decide whether the model needs two tools or one composed why operation based on interaction quality rather than package topology. + +### Reopen C6: hash-only net/workpiece join + +Replace the post-hash-only proposal with a transition and effect contract, or narrow the claim to unattributed state correlation. + +### Reopen C8: excluding capture or another retained evidence projection + +Known Flue compaction already threatens exact evidence and revision recovery. Decide the uncompacted limitation or the minimal compaction-independent retention mechanism before promising exact historical lines. + +### Reopen C10: full-bundle default admission + +Retire the inherited arbitrary six, but choose a scenario-derived canonical subset and expand from observed need rather than mounting near-parity by default. + +### Reopen C13: release wording + +“Who prepared it” and “the exact conversation line it rests on” exceed the represented identity and causality. Narrow the release note until actor identity, evidence retention, and causal association are established. + +### Reopen C15: passage identity + +Treat passage identity as a prerequisite to point-passage provenance and blame. Strengthen the probe to semantic edits, or defer blame and report only revision-local text. + +### Reopen D1, D3, and D5: real fixtures and construction sequencing + +Prove one genuine conversation can become an authorized live fixture before the persona campaign, and resolve whether construction in M7 intentionally consumes M9's visible advance. + +## Recommended next sequence + +1. **Adjudicate the product claim.** Decide causal provenance versus temporal audit lineage and amend the release wording accordingly. +2. **Build one adversarial tracer on paper or in the smallest executable harness.** Use one conversation with two workpiece passages, two mutations, one failed or no-op mutation, one correction, and one hand edit. Require deterministic answers or explicit refusals. +3. **Correct the Flue topology model.** Represent user delivery, assistant mutation request, later client-result signal, continuation, duplicate result delivery, and server-state writes using their real identities. +4. **Define the minimum mutation transition/effect record.** Include document identity, base state, outcome, post state, affected elements, and unknown-result behavior. +5. **Force compaction.** Verify which exact user text, workpiece revisions, and tool records remain available through the supported public surface; choose an explicit limitation or retained projection. +6. **Export or retain and reopen the tracer conversation.** Exercise authorization and why resolution after relocation or restart before launching paid persona breadth. +7. **Probe passage identity under semantic edits.** Include rename, move, paraphrase, split, merge, deletion, and reintroduction. +8. **Repair the provider schema carrier for the smallest scenario-derived mutation subset.** Prove one real nested call before broad admission. +9. **Re-cut the mission topology from the observed results.** Explicitly resolve the M7/M9 overlap, deployment order, migration boundary, and consumer-driven proving scenario. +10. **Only then run the broader persona construction campaign.** Freeze the consequential-element inventory and behavioral oracle before grading. + +## Evidence consulted + +- [`provenance-and-tooling-decision-log-2026-09-04.md`](provenance-and-tooling-decision-log-2026-09-04.md) +- [`provenance-by-lineage-mini-spec-2026-09-04.md`](provenance-by-lineage-mini-spec-2026-09-04.md) +- [`../../../MISSION.next.md`](../../../MISSION.next.md) +- [`../../mission-drafts/7-capture-backed-review.md`](../../mission-drafts/7-capture-backed-review.md) +- [`../../mission-drafts/9-traceable-projection.md`](../../mission-drafts/9-traceable-projection.md) +- [`../../mission-drafts/10-bounded-reviewer-revision.md`](../../mission-drafts/10-bounded-reviewer-revision.md) +- [`../../specs/petrinaut-batched-construction-tools.md`](../../specs/petrinaut-batched-construction-tools.md) +- [`../../../packages/core/src/workpiece.ts`](../../../packages/core/src/workpiece.ts) +- [`../../../packages/plugin-sdcpn/src/flue.ts`](../../../packages/plugin-sdcpn/src/flue.ts) +- [`../../../packages/plugin-sdcpn/src/tools/petrinaut-construction.ts`](../../../packages/plugin-sdcpn/src/tools/petrinaut-construction.ts) +- [`../../../packages/binding-flue/src/history-reader.ts`](../../../packages/binding-flue/src/history-reader.ts) +- [`../../../packages/transport-aisdk/src/client-tool-history.ts`](../../../packages/transport-aisdk/src/client-tool-history.ts) +- [`../../../../../../apps/brunch-agent/src/agents/chat-agent/agent.ts`](../../../../../../apps/brunch-agent/src/agents/chat-agent/agent.ts) +- [`../implementations/fe-1575-outer-browser-witness-2026-09-04-r2/witness.md`](../implementations/fe-1575-outer-browser-witness-2026-09-04-r2/witness.md) +- Installed Flue 2.0.3 documentation for agent hooks, public conversation history, compaction, streaming, and conversation persistence under `node_modules/@flue/runtime/docs/` and `node_modules/@flue/sdk/docs/` +- Petrinaut canonical AI, action, entity, and file-format schemas under `libs/@hashintel/petrinaut-core/src/` + +## Review disposition + +The design should not be discarded. Its useful core is a first-class revisioned workpiece plus mutation-call audit history. The correction is to stop calling temporal adjacency a complete provenance relation, then add only the smallest identities, effects, retention, and authorization contracts that the real why answer requires. The mission sequence should be recut after those disputed seams are probed, not before. diff --git a/libs/@hashintel/brunch-agent/docs/evidence/design/provenance-by-lineage-mini-spec-2026-09-04.md b/libs/@hashintel/brunch-agent/docs/evidence/design/provenance-by-lineage-mini-spec-2026-09-04.md new file mode 100644 index 00000000000..259beb1dc6e --- /dev/null +++ b/libs/@hashintel/brunch-agent/docs/evidence/design/provenance-by-lineage-mini-spec-2026-09-04.md @@ -0,0 +1,135 @@ +# Provenance by lineage — mini spec for review, 2026-09-04 + +> Design evidence, not execution authority. This document projects the [decision log of 2026-09-04](provenance-and-tooling-decision-log-2026-09-04.md) into one reviewable statement of intent, design, and consequences for the Brunch mission spine. It is written for an independent reviewer who has not seen the originating conversation. Entry references such as C4 point into the log. Nothing here may be implemented until it is re-evaluated and cut into a live `MISSION.md`; the intended vehicle is the Mission 7 cut. + +## 1. Intent + +Brunch must be able to say, for any consequential element of a Petri net it helped build, where that element came from: the workpiece passage that motivated it, the revision that introduced the passage, and the conversation turns behind that revision, or an honest refusal. It must do this without a comprehensive typed domain model, without a second conversation log, and without anyone hand-authoring links. + +Two earlier approaches failed in opposite directions. A comprehensive typed intermediate representation tried to make provenance a property of the domain model; the typology receded as it grew and the model worked worse with it. The structural Markdown workpiece that replaced it is legible and cheap but has no seam to either the conversation or the net, and provenance was deferred as "later" without the tension being named in the planning record (B3). + +The resolving observation: provenance is not a domain fact. It is who changed what, in response to what, when. Three actors know a link at the moment it is created, and each moment is already recorded in Flue's append-only canonical log once the artifacts they produce are tool calls (C1). + +## 2. The lineage model + +```text +turn N: user says X (user message, turnId T) + └─ assistant response (assistant message, turnId T) + ├─ text + ├─ tool call update_workpiece { markdown } revision R, identity = call id + ├─ tool result { revision, sha256 } + ├─ tool call addArc { ... } net mutation, same turnId + └─ tool result { ..., documentSha256 } net revision, same turnId + state_write workpiece = { callId, sha256, revision } same batch, same durability +``` + +Resolution walks backwards from an element and is a point at every hop but the last: + +```text +element id + → mutation call that created it, and calls that changed it point(s) + → latest update_workpiece at or before that call point + → the passage in that revision point + → blame: the revision that introduced the passage point + → user turns between that revision and the previous one RANGE + └─ narrowed to one line where the passage quotes the expert verbatim +``` + +The honest why answer is therefore: one creating call, one workpiece passage, one introducing revision, and then either a quoted line or a short turn range (C2). The range is where workpiece cadence is coarser than turn cadence. Elements changed several times report introducing and last-changing calls separately. Every hop is a lookup in the canonical log; nothing is stored elsewhere and nothing is inferred. + +What the model does: it calls the tools and interprets structured ranges in prose. What it may not do: author a link, reread the transcript as provenance, or explain an element the tools mark unsupported (C3). + +## 3. Mechanisms + +### 3.1 `update_workpiece` (core, server-side) — C4 + +| Aspect | Decision | +| --- | --- | +| Input | one Markdown string, the full current workpiece | +| Run | validate non-empty and well-formed; SHA-256; `usePersistentState('workpiece', { callId, sha256, revision })`; return `{ revision, sha256 }` | +| Durability | `durable: true`, so an interrupted call replays rather than settling unknown | +| Ownership | core owns the tool because the mechanism is formalism-independent; plugins own the template | +| Replaces | the fenced `runbook-ir` block in assistant text; the prepared-signal route stays for test-authored revision zero | + +Why a tool rather than a fenced block: the revision identity is a call id instead of a regex over prose; the tool can refuse a truncated document; the next render reads the current pointer without the model echoing it; mutations and revisions share `turnId`; the UI can project the part into its own pane. Costs acknowledged: the full document still crosses the wire each revision, and a model may call a tool less readily than it emits text. A structured-patch input is the later absorber for token cost; cadence must be measured for either shape (B6). + +### 3.2 `query_workpiece` (core) and `locate_elements` (plugin-sdcpn) — C5 + +`query_workpiece` takes a revision pointer or a passage locator and returns the turn ranges behind it with the user text, plus verbatim-quote matches where the passage quotes. `locate_elements` takes element ids and returns, per id, the mutation calls with their turn ids and document hashes, and the workpiece revision current at each. The split follows knowledge: core knows revisions and history; only the plugin knows which calls are mutations and where ids sit in inputs. Names are provisional. + +### 3.3 Net revision identity through the client-tool result — C6 + +The browser returns the post-mutation document SHA-256 inside each client-tool result. Mission 6 already computes this hash for its settled manifest. A document hash that no tool result explains is reported as "changed outside the conversation." Petrinaut's schema is not extended: elements are strict objects with no metadata slot and the file wrapper carries only `title` and a generator (B7). A file-level provenance pointer in `meta` is deferred until Mission 11 has a consumer for a self-describing export. + +### 3.4 The visible workpiece — C7 + +The chat rendering projects `update_workpiece` parts out of assistant messages and leaves a one-line "workpiece updated" marker. A pane in the Petrinaut Brunch panel shows the current revision, the revision list, and a diff between any two, all derived from Flue history through the Mission 5 transport. The why answer renders into the same pane because it resolves to a passage the reviewer must see. This projection lives in the app or transport layer, not in the Petrinaut library. The pane is the surface every later provenance and revision mission assumes and none has built; it is also the product-manager-visible advance in its own right. + +### 3.5 Schema carrier repair — B9, C11 + +Precondition for admitting any tool beyond the flat ones. Flue accepts Valibot schemas only and rejects other Standard Schema vendors; the construction factory therefore declares an empty loose object and pastes Petrinaut's JSON Schema into the description. Fix by a mechanical JSON Schema to Valibot interpreter covering the subset Petrinaut uses (objects, strings, numbers, enums, arrays, nullable, optional, unions), or by upstream Flue Standard Schema support. The local interpreter is derived rather than hand-copied and is reversible if upstream support arrives. + +### 3.6 Tool admission and teaching — C10, C12 + +Petrinaut's canonical mutation, query, and command tools are admitted to ordinary SDCPN conversations, mechanically from Petrinaut's AI tool bundle, and scoped down only from observed misbehaviour. The inherited six-tool subset is retired as a product surface. The skill gains construction posture: read the definition first, mutate in small steps, check compilation errors, record decisions in Construction notes, call `update_workpiece` before and after construction. Parity with the stock modeller remains a non-goal; the change is the direction of the default. + +### 3.7 Subtraction — C8, C9 + +Retired from code under Mission 7 authority: the `ask` and `sweep` names in core, the suspended ask contract, the website ask interactive tool and test, the sweep filter and output module in the panel transport, and the two Voice references. The capture store and sweep are not consumed by Mission 7; the store re-enters only if answer-time verification strains under compaction or ownership. + +## 4. Tool inventory after this design + +| Tool | Owner | Executes | Status | +| --- | --- | --- | --- | +| `ping` | app | server | keep, diagnostic | +| `activate_skill` | Flue | server | keep | +| `readPetrinautDoc` | plugin-sdcpn | browser | keep | +| Petrinaut canonical bundle | plugin-sdcpn, derived | browser | admit to ordinary conversation after 3.5 | +| `update_workpiece` | core | server | new | +| `query_workpiece` | core | server | new | +| `locate_elements` | plugin-sdcpn | server | new | +| `ask`, `sweep` client handling | core, website | browser | retire | +| six-tool and two-tool subsets | plugin-sdcpn | browser | retire as product surfaces; Mission 6 fixture mode stays until Mission 6 archives | + +## 5. Real honest fixtures — D1 to D5 + +The provenance pair is a real conversation with a real revisioned workpiece and a real constructed net, produced by persona interviews against the production agent. The Mission 6 prepared fixture remains a viability proof and is not promoted (A3). + +```text +persona run (Pi harness, production ChatAgent, real-headless host) + → Flue store holds the genuine conversation, revisions, mutations + → harness retains snapshot.json + projections per settled read + → grade coverage against the hidden oracle ledger afterwards + → ??? → live fixture the demo opens (D3, open) +``` + +Settled: run several cases in parallel; six cases exist. Recommended: a turn cap larger than the 6–10 used so far as budget, early stop when Brunch itself declares construction handoff or delivery, ledger coverage as the post-hoc grade rather than the stop rule (D4); runs go to construction so the fixture contains lineage, which sequences the carrier fix and tool admission before the construction campaign, with an earlier elicitation-only campaign to measure revision cadence (D5). + +Open: how a retained genuine conversation becomes a live fixture in a fresh store. Keeping the dev store as shipped data, restoring genuine records through Flue's storage adapter, and replaying the snapshot as prepared signals each have a named cost in D3; the first probe is whether Flue 2.0.3 tolerates export and restore at its storage boundary. + +## 6. What this changes in the mission spine + +1. **Name the tension.** The spine states provenance-by-lineage as the current hypothesis, the typed IR and hand-authored derivation as rejected with reasons, revision cadence as the named strain, and the visible workpiece as the precondition (E1). +2. **Re-cut Mission 7.** Body: carrier fix, orphan retirement, `update_workpiece`, workpiece pane, tool admission and teaching, persona programme to construction. Last step: the why route over real lineage. Release note narrowed to the honest framing (C13). Local posture; remote durability to Mission 8 (C14). Capture-store chain and Mission 2 inherited closure dropped (E2). +3. **Adjust Missions 9 and 10.** They inherit the seam from lineage: revision id equals call id, passage identity per the probe in C15, stable element ids, document hash per C6. They no longer assume a derivation fixture or a prebuilt pair (E3). +4. **Mission 6 close report.** Record the fixture-rigging admission, the carried fenced-block-to-tool change, and the credential cause of the blocked witness (E4). +5. **Authority.** Every settled item is an owner decision expressed in conversation. It becomes authority only when written into the cut Mission 7 `MISSION.md`, with Mission 6's construction-tool constraint amended there and not in the Mission 6 tie-off (E5). + +## 7. Fog-line + +- Revision cadence: whether the model calls `update_workpiece` often enough for blame to have grain; unmeasured (B6). +- Passage identity: heading path, Markdown anchor, or companion manifest; decided by the probe in C15. +- Carrier repair route: local interpreter versus upstream Flue support (3.5). +- Fixture materialization from a genuine conversation (D3). +- Token cost of full-document emission on long interviews, and when a structured patch earns its place. +- Which canonical tools misbehave at the provider boundary once the carrier carries fields; only observed failure scopes admission down. +- Whether the why answer over a real pair is useful to a reviewer, not merely correct; a human judges, per the Mission 7 draft's existing risk row. + +## 8. Questions for the independent reviewer + +1. Is provenance-by-lineage a sufficient answer to the stated intent, or does it smuggle an assumption the log did not check? +2. Is the tool split in 3.2 the right ownership boundary, or should one tool serve both lookups? +3. Is returning the document hash in the client-tool result an adequate join between net and workpiece revisions, given hand edits in Petrinaut? +4. Does anything in sections 3 and 4 reintroduce a mechanism the spine's rejected-mechanisms list has already refused? +5. Is the persona programme's stop rule and fixture-materialization plan honest about what a "real" fixture is? +6. Which settled items should be re-opened before they enter the Mission 7 authority, and why?