Skip to content

FE-762: Petrinaut-format JSON export of the compiled net#157

Open
kostandinang wants to merge 1 commit into
ka/fe-761-petri-petrinaut-semanticsfrom
ka/fe-762-petri-blueprint-export
Open

FE-762: Petrinaut-format JSON export of the compiled net#157
kostandinang wants to merge 1 commit into
ka/fe-761-petri-petrinaut-semanticsfrom
ka/fe-762-petri-blueprint-export

Conversation

@kostandinang
Copy link
Copy Markdown
Contributor

@kostandinang kostandinang commented May 27, 2026

Summary

  • New module petrinaut-export.ts — pure serializer serializeBlueprint(blueprint, { runId, tokenIdFn? }) → PetrinautNet converting the (FE-761 Petri-net-faithful) NetBlueprint into Petrinaut's expected JSON shape.
  • Cook writes <runDir>/net.json on every run so the Petrinaut team can render the compiled topology and pressure-test the integration.
  • Token shape { id: <UUID>, ...payload } per the cross-team-agreed format; envelope carries schemaVersion 0.1.0 for forward-compatibility.

Context

  • Second sub-issue of the Petrinaut integration sub-track (parent FE-760). Pairs with FE-763 (event stream); together they give Petrinaut everything it needs to visualize a live cook run.
  • Stacks on FE-761 (Petri-net semantic alignment). The blueprint already exposes the topology in a serializer-friendly shape — places + transitions + initialTokens — so this is a thin export layer rather than a substrate refactor.
  • The Petrinaut team is unblocked: they were waiting on a sample net.json for fixtures/txt/ to begin their side of the work.

What changed

  • New src/orchestrator/src/petrinaut-export.ts: pure serializer.
    • Types: PetrinautNet { schemaVersion, runId, places, transitions, initialMarking }, PetrinautPlace { id, label }, PetrinautTransition { id, label, lane, kind, actor, guard, inputs, outputs }, PetrinautToken { id, sliceId?, epicId?, retryCount?, reworkCount? }, PetrinautMarking { place, tokens[] }.
    • Places: full internal IDs preserved as id; short visual label strips the slice:<id>: / epic:<id>: prefix.
    • Transitions: inputs come from TransitionSkeleton.inputs; outputs from enumerateCandidateOutputs (so the full reachable output set is visible to Petrinaut, including the FE-761 Slice 4 dispatch → running:* arcs).
    • Initial marking: tokens grouped by place, each assigned a fresh UUID; semantic payload fields (sliceId, epicId, retryCount, reworkCount) preserved when present.
  • engine.ts: when input.runDir is present, writes the serialized net to <runDir>/net.json after compileTopology() returns. Library callers and tests that omit runDir are unaffected.
  • cook-cli.ts: passes the existing runDir through to the orchestrator.
  • types.ts: OrchestratorInput gains optional runDir field.

Verification

  • 10 new tests in petrinaut-export.test.ts: envelope (schemaVersion, runId), places (label-stripping), transitions (arc shape, contract metadata), initial marking (tokens grouped, UUIDs distinct, payload preserved), JSON round-trip, golden counts pinned per fixture (simplePlan: 22 places, 19 transitions, 5 places hold initial tokens; depPlan: 42 places, 37 transitions, 8 places).
  • All 125 orchestrator tests pass; full npm run verify (check + test + build) green.
  • Outer-loop integration smoke (real Petrinaut loader round-trip on fixtures/txt/) deferred to cross-team validation once the loader is available.

Out of scope

  • Runtime event stream — initial markings event + transition-firing events (FE-763).
  • Sync transport — wire net.json and event stream to a live Petrinaut session (FE-764).
  • Final JSON envelope wire format per Petrinaut's loader — v1 is a sensible best-guess; expect cross-team revisions once Petrinaut publishes their schema reference.
  • Discrete-type system for semantic IDs (string vs uuid) — pending Petrinaut's H-6518 / H-6519.

Traceability

  • Linear FE-762 (parent FE-760); pairs with FE-763 and feeds FE-764; H-6518 / H-6519 (Petrinaut discrete types).
  • Frontier petri-blueprint-export in memory/PLAN.md; stacks on FE-761.

@kostandinang kostandinang changed the title FE-762: Petrinaut JSON export of the compiled NetBlueprint FE-762: Petrinaut-format JSON export of the compiled net May 27, 2026
@kostandinang kostandinang force-pushed the ka/fe-762-petri-blueprint-export branch from dc53d4c to f6356f7 Compare May 27, 2026 23:16
@kostandinang kostandinang marked this pull request as ready for review May 27, 2026 23:17
@cursor
Copy link
Copy Markdown

cursor Bot commented May 27, 2026

PR Summary

Low Risk
Additive optional filesystem write after compile; no changes to Petri net firing or cook execution semantics.

Overview
Adds a Petrinaut JSON export of the compiled Petri net so cook runs can ship topology to the visualization team.

A new pure serializeBlueprint maps NetBlueprint to PetrinautNet (schemaVersion 0.1.0, runId, places with short labels, transitions with full input/output arcs via enumerateCandidateOutputs, and initial marking with per-token UUIDs and semantic payload fields). When OrchestratorInput.runDir is set, the engine writes <runDir>/net.json immediately after compileTopology; cook-cli now passes the existing run directory. Callers without runDir behave as before.

Tests cover envelope, labeling, transition metadata, marking grouping, JSON round-trip, and golden topology counts for fixture plans.

Reviewed by Cursor Bugbot for commit ff3504c. Bugbot is set up for automated code reviews on this repo. Configure here.

@augmentcode
Copy link
Copy Markdown

augmentcode Bot commented May 27, 2026

🤖 Augment PR Summary

Summary: This PR adds a Petrinaut-compatible JSON export for the compiled Petri net so runs can be visualized/validated by the Petrinaut team.

Changes:

  • Introduces petrinaut-export.ts with serializeBlueprint() to convert a NetBlueprint into a PetrinautNet envelope (schemaVersion, runId, places, transitions, initialMarking).
  • Derives transition outputs via enumerateCandidateOutputs to expose the full reachable arc set.
  • Adds a deterministic token-id hook for tests; production uses UUIDs.
  • Extends OrchestratorInput with optional runDir.
  • Updates the engine to write <runDir>/net.json after compileTopology() when runDir is provided.
  • Threads runDir through the cook CLI into the orchestrator.
  • Adds comprehensive Vitest coverage for envelope fields, label stripping, arc shape/metadata, marking/token behavior, and golden counts per fixture.

Technical Notes: The export is designed as a pure serializer (no I/O); file output is owned by the runtime engine path when running via CLI.

🤖 Was this summary useful? React with 👍 or 👎

Copy link
Copy Markdown

@augmentcode augmentcode Bot left a comment

Choose a reason for hiding this comment

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

Review completed. 1 suggestion posted.

Fix All in Augment

Comment augment review to trigger a new review at any time.

// Skipped when runDir is absent (library callers / tests).
if (input.runDir) {
const net = serializeBlueprint(blueprint, { runId: input.runId ?? 'unknown' });
writeFileSync(join(input.runDir, 'net.json'), `${JSON.stringify(net, null, 2)}\n`);
Copy link
Copy Markdown

@augmentcode augmentcode Bot May 27, 2026

Choose a reason for hiding this comment

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

src/orchestrator/src/engine.ts:38 — Because the writeFileSync is inside the main try, any failure to write net.json (missing/unwritable runDir, permissions, disk issues) will halt the entire cook run even though compilation succeeded. If this is intended as best-effort integration output, it may be worth ensuring export failures don’t change the run’s success/failure semantics.

Severity: medium

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

Serializes a (refactored, Petri-net-faithful) NetBlueprint into Petrinaut's
expected JSON format and writes it to <runDir>/net.json on every cook run,
so the Petrinaut team can render the compiled topology and pressure-test
the integration end-to-end.

What landed:
- New module src/orchestrator/src/petrinaut-export.ts: pure serializer
  serializeBlueprint(blueprint, { runId, tokenIdFn? }) -> PetrinautNet.
- New types: PetrinautNet { schemaVersion, runId, places, transitions,
  initialMarking }, PetrinautPlace { id, label }, PetrinautTransition
  { id, label, lane, kind, actor, guard, inputs, outputs }, PetrinautToken
  { id: <UUID>, sliceId?, epicId?, retryCount?, reworkCount? },
  PetrinautMarking { place, tokens[] }.
- engine.ts: when input.runDir is present, writes the serialized net
  to <runDir>/net.json after compileTopology() returns. Library callers
  that omit runDir (tests) are unaffected.
- cook-cli.ts: passes the existing runDir through to the orchestrator.
- types.ts: OrchestratorInput gains optional runDir field.

Cross-team payload shape (2026-05-26 alignment):
- Token shape is { id: <UUID>, ...payload }. UUIDs generated at
  serialization time. (Token UUID lifecycle across consume->emit is a
  FE-763 open coordination item; v1 generates fresh per token.)
- schemaVersion '0.1.0' on the envelope for forward-compat.
- Place label strips slice:<id>: / epic:<id>: prefix for short visual
  names; full internal id preserved as place.id.

Open coordination items (tracked on FE-762):
- exact JSON envelope per Petrinaut's loader (pending team)
- string vs uuid discrete type for semantic IDs (pending H-6518/H-6519)
- place naming convention (full ids vs short labels) — v1 emits both

Tests: 10 new tests in petrinaut-export.test.ts (envelope, places,
transitions, initial marking, round-trip, golden counts pinned for
simplePlan and depPlan). All 125 orchestrator tests pass; npm run fix /
check / build all green.

Co-authored-by: Amp <amp@ampcode.com>
@kostandinang kostandinang force-pushed the ka/fe-761-petri-petrinaut-semantics branch from e4be997 to 94351f0 Compare May 27, 2026 23:21
@kostandinang kostandinang force-pushed the ka/fe-762-petri-blueprint-export branch from f6356f7 to ff3504c Compare May 27, 2026 23:21
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.

1 participant