Skip to content

FE-819: Orchestrator <> Petrinaut integration improvements#176

Merged
kostandinang merged 7 commits into
mainfrom
ka/fe-819-orchestrator-petrinaut-integration-improvements
Jun 9, 2026
Merged

FE-819: Orchestrator <> Petrinaut integration improvements#176
kostandinang merged 7 commits into
mainfrom
ka/fe-819-orchestrator-petrinaut-integration-improvements

Conversation

@kostandinang

@kostandinang kostandinang commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

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

  • Plain-graph wire contract — Petrinaut narrowed its definition route to a .strict() schema (plain places/transitions/arcs). NetDefinition / projectNetDefinition slimmed to match, dropping types and all SDCPN-only fields that would otherwise be rejected; backed by an in-repo schema mirror + a compile-time drift pin.
  • Arc-scoped delta firings — every transition_firing carries 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. initialState is 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.)
  • Run-state legibility — leading status frame, terminal carries { state, reason }, halts re-emit a status-suffixed title; synthetic run:completed / run:halted places + a run:finish firing surface the outcome on the flat canvas. Presentation-only.
  • Mechanical lane projection--petrinaut-lanes=mechanical hides the semantic lane for a smaller demo graph; execution unchanged (frames restrict to surviving nodes).
  • Launcher--petrinaut-base-url--petrinaut-url (full route, no alias); link is {PETRINAUT_URL}?runId=…&sse=…; .env is 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 initialState rather than treating output as a whole frame.

Verification

npm run verify passes (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

kostandinang commented Jun 5, 2026

Copy link
Copy Markdown
Contributor Author

@kostandinang kostandinang changed the title FE-819: Complete cook CLI help with all Petrinaut flags FE-819: Orchestrator <> Petrinaut integration improvements Jun 5, 2026
@kostandinang kostandinang force-pushed the ka/fe-819-orchestrator-petrinaut-integration-improvements branch from 5014e0f to 37f7e8c Compare June 8, 2026 11:26
@kostandinang kostandinang marked this pull request as ready for review June 8, 2026 11:29
@cursor

cursor Bot commented Jun 8, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Changes the external Petrinaut wire contract and launcher URL/env resolution on a demo-critical path; risk is mitigated by broad oracles and schema mirrors but still needs cross-team staging verification.

Overview
Hardens the brunch cook → Petrinaut live SSE seam (FE-819): export/reducer, stream bus, cook CLI, and docs/oracles stay aligned so the Bristol demo view does not drift from what Petrinaut actually consumes.

Wire contract — Streamed definition is now a plain-graph shape (id/name + arcs only), validated against an in-repo mirror of Petrinaut’s .strict() schema; SDCPN-only fields and types are dropped. Markings are count-only; each transition_firing carries arc-scoped consume/produce deltas (A99 — not full cumulative markings), with a single full initialState for the consumer to fold onto.

Run legibility — Connections lead with a status frame; terminal carries { state, reason? }; halts can re-emit a title-suffixed definition. Synthetic run:completed / run:halted places plus a run:finish firing make terminal outcomes visible on the canvas (presentation-only).

CLI / launcher--petrinaut-base-url / PETRINAUT_BASE_URL--petrinaut-url / PETRINAUT_URL (full route path); launcher is {url}?runId&sse (no mode). Shared loadLocalEnvFile with shell-wins over .env. New --petrinaut-lanes=both|mechanical projects a smaller mechanical-only graph for export/stream while execution still runs the full net.

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.

Comment thread src/orchestrator/src/petrinaut-stream-export.ts Outdated
Comment thread src/orchestrator/src/petrinaut-stream-export.ts
@kostandinang kostandinang force-pushed the ka/fe-815-orchestrator-demo-fixtures branch from 5568b87 to 78ab259 Compare June 8, 2026 17:26
Base automatically changed from ka/fe-815-orchestrator-demo-fixtures to main June 8, 2026 22:06
kostandinang and others added 6 commits June 9, 2026 00:18
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>
@kostandinang kostandinang force-pushed the ka/fe-819-orchestrator-petrinaut-integration-improvements branch from 4ad88ee to 3ee3064 Compare June 8, 2026 22:21

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ 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.

Comment thread src/orchestrator/src/engine-contract.test.ts
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)
@kostandinang kostandinang added this pull request to the merge queue Jun 9, 2026
Merged via the queue into main with commit 5742f65 Jun 9, 2026
9 checks passed
@kostandinang kostandinang deleted the ka/fe-819-orchestrator-petrinaut-integration-improvements branch June 9, 2026 14:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants