FE-819: Orchestrator <> Petrinaut integration improvements#176
Conversation
5014e0f to
37f7e8c
Compare
PR SummaryMedium Risk Overview Wire contract — Streamed Run legibility — Connections lead with a CLI / launcher — Verification — Extensive unit/oracle tests (delta replay, schema strictness, bus replay-equivalence, lane projection, flag help completeness) and SPEC/PLAN updates. Reviewed by Cursor Bugbot for commit f6848f8. Bugbot is set up for automated code reviews on this repo. Configure here. |
5568b87 to
78ab259
Compare
The printHelp 'Cook flags' block had drifted: it omitted every flag parseCookArgs already accepts (--petrinaut-fold, --petrinaut-stream, --petrinaut-base-url, --no-petrinaut-open). List them all plus the PETRINAUT_BASE_URL / PORT env vars, and add a flag-completeness guard to the packaged --help test so the help can't silently drift again. Co-authored-by: Claude <noreply@anthropic.com>
… rename
Field-test-driven hardening of the cook -> Petrinaut live SSE stream:
- Full markings: transition_firing frames carry the complete cumulative
pre/post marking instead of single-place deltas (matches Petrinaut's
frame reader; pools/budgets visible every frame). Inverted
frame-replay oracle replaces the old delta-based oracle.
- Terminal-status fidelity: leading `status` frame per connection;
`terminal` frame carries { state, reason }; halts re-emit a
status-suffixed definition title. Additive over the existing wire.
- Structural run outcome: synthetic run:completed / run:halted places +
a run:finish firing at run end, so halts/completions show on
Petrinaut's flat canvas. Presentation-only; engine/contract unchanged.
- Launcher rename: --petrinaut-base-url / PETRINAUT_BASE_URL ->
--petrinaut-url / PETRINAUT_URL (no alias; full route incl. path).
Launcher URL is {PETRINAUT_URL}?runId=...&sse=... (mode dropped).
.env loading is now shell-wins so an inline prefix beats a stale .env.
Post-review hardening:
- Marking narrowed to count-only (Record<PlaceId, number>); dropped the
unused token-colour arm.
- Canonical TerminalEventKind shared across export/bus; single
loadLocalEnvFile (src/orchestrator/src/local-env.ts) shared by the
cook CLI and the backend.
Co-authored-by: Amp <amp@ampcode.com>
- SPEC: add count-only marking decision/invariant and the FE-819 stream-wire lexicon (run state, export/status/terminal frame, run-status place, synthetic run:finish, Petrinaut URL, launcher URL). - PLAN: mark Cards A-D landed, record post-review hardening, fix the stale loadLocalEnvShellWins reference, neutralize personal names. Co-authored-by: Amp <amp@ampcode.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Add a view-only lane projection orthogonal to fold: --petrinaut-lanes=mechanical (default both) hides the semantic lane for a smaller demo graph. New petrinaut-lane-projection.ts seam — projectBlueprintLanes drops semantic transitions + semantic-only places and rewrites return-done into a mechanical done-spec → completed bridge (dep-signal fan-out preserved); projectMarking / projectFiring restrict each streamed/exported frame to the surviving nodes. Execution is unchanged: the engine wires the full blueprint and emits the full marking, so restriction conserves tokens (the real run already consumed done-spec at the suppressed assess-semantic:dispatch) and the halt sink stays visible. Wired through engine, stream bus, and the static reducer (mode-gated); flag + help + types threaded. Reconciled SPEC §Lexicon (lane projection) + PLAN. Co-authored-by: Claude <noreply@anthropic.com>
Petrinaut's actual-mode Brunch route adopted a strict (.strict()) schema
accepting only plain graph data: places {id,name,x?,y?}, transitions
{id,name,inputArcs,outputArcs,x?,y?}, arcs {placeId,weight,type?}.
Brunch's previous SDCPN-laden definition frame (colorId, dynamics,
lambda/kernel, root `types`) would now be rejected, not ignored.
- Slim NetDefinition + projectNetDefinition to the plain-graph shape;
drop `types` and all SDCPN-only place/transition fields. Rename the
wire types SdcpnPlace/SdcpnTransition -> NetPlace/NetTransition
(they were never SDCPN-shaped on this path).
- Add petrinaut-brunch-contract-schema.ts: an in-repo mirror of
Petrinaut's brunchNetDefinitionSchema, used as the projection oracle
so a Petrinaut-side tightening fails a brunch test.
- Compile-time bridge: NetDefinition pinned assignable to the schema's
inferred output, catching TS-type/contract drift.
- Narrow ArcType to the producible 'standard'|'inhibitor'.
- SPEC: add D163-K (plain-graph wire definition), correct D162-K /
I127-K / `color fold` glossary (colour identity has no wire carrier).
Consequence: colour-fold slice identity is not expressible on this
interface; identity fold is the only meaningful stream fold until the
standardized protocol is owned in Petrinaut Core. Marking contract
(full markings, A99) untouched.
Co-authored-by: Claude <noreply@anthropic.com>
4ad88ee to
3ee3064
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 3ee3064. Configure here.
Petrinaut's TransitionFiring wire shape carried the full net marking on every firing (Card A frame-replay), listing places a transition isn't connected to. The Petrinaut team confirmed firings must be arc-scoped deltas — `input` the consumed tokens, `output` the new tokens to add — with Petrinaut folding each delta onto `initialState`. Revert eventToTransitionFiring / synthesizeRunStatusFiring to emit deltas (FE-764's original shape); delete the cumulative-fold apparatus (applyMarkingDelta + marking threading) from the static reducer and the live bus. Rewrite the frame-replay oracle as an arc-scoped delta oracle. Resolve SPEC A99 and update PLAN FE-819 Card A to record the reversal. Co-Authored-By: Claude <noreply@anthropic.com> 🤖 Generated with [Claude Code](https://claude.com/claude-code)


Summary
A series of improvements hardening the brunch ⇄ Petrinaut integration — the live SSE view a cook run drives on Petrinaut's read-only "actual/live" canvas (
brunch cook --petrinaut-stream). Each wire seam is locked behind an oracle so it can't regress silently. Read-only, one-way; no write-back.What Changed
definitionroute to a.strict()schema (plain places/transitions/arcs).NetDefinition/projectNetDefinitionslimmed to match, droppingtypesand all SDCPN-only fields that would otherwise be rejected; backed by an in-repo schema mirror + a compile-time drift pin.transition_firingcarries only the transition's consume/produce delta (input= tokens consumed from input-arc places,output= the new tokens to add to output-arc places), never places the transition isn't connected to.initialStateis the single full marking; Petrinaut reconstructs the running net state by folding each delta onto it. Count-only. (Reverses an earlier full-marking approach per the Petrinaut team's confirmation — SPEC A99.)statusframe,terminalcarries{ state, reason }, halts re-emit a status-suffixed title; syntheticrun:completed/run:haltedplaces + arun:finishfiring surface the outcome on the flat canvas. Presentation-only.--petrinaut-lanes=mechanicalhides the semantic lane for a smaller demo graph; execution unchanged (frames restrict to surviving nodes).--petrinaut-base-url→--petrinaut-url(full route, no alias); link is{PETRINAUT_URL}?runId=…&sse=…;.envis shell-wins. Help lists every flag.Consequence
Colour-fold slice identity has no carrier on this interface — identity fold is the only meaningful stream fold until the standardized protocol lands in Petrinaut Core. SPEC §Lexicon + decisions/invariants reconciled.
Open follow-up (A99 watch): re-verify on staging that delta firings don't regress the 2026-06-05 "pools/budgets empty mid-run" rendering — i.e. confirm Petrinaut folds deltas onto
initialStaterather than treatingoutputas a whole frame.Verification
npm run verifypasses (format/lint, full suite, build). Oracles: schema-mirror validation + compile-time pin (definition), arc-scoped delta oracle + replay-equivalence (markings), lane-projection tests, flag-completeness test (CLI).🤖 Generated with Claude Code