Skip to content

release: v7.0.0 (in progress)#92

Merged
mellonis merged 51 commits into
masterfrom
v7
Jun 3, 2026
Merged

release: v7.0.0 (in progress)#92
mellonis merged 51 commits into
masterfrom
v7

Conversation

@mellonis

@mellonis mellonis commented May 21, 2026

Copy link
Copy Markdown
Owner

Draft. Integration PR for the v7 release line. Stays draft while v7 alphas iterate; flipped to ready when stable v7.0.0 is cut.

Summary

v7 is the composition-representation overhaul on top of engine v7's wrapper/Mermaid changes. Three alphas shipped so far on the v7 branch:

Closes (held until this PR lands, since v7-branch merges don't auto-close)

Still pending before flipping to ready

  • Engine v7.0.0 stable ships upstream. Engine is currently at 7.0.0-alpha.3; post-machine-js's peer-dep range will widen to ^7.0.0 at that point.
  • Peer-dep widening in packages/machine/package.json: ^7.0.0-alpha.3^7.0.0.
  • CHANGELOG entry for stable [7.0.0] - YYYY-MM-DD summarizing the cumulative v7 changes and migration notes. Should note that Extend defineProperty lockdown to intermediate engine-graph states (continuations, hoppers, group wrappers) #72 is deferred to v7.1 (see below).
  • Scan README and docs for any (in progress) / alpha-specific markers and clean them up.
  • Lerna version bump 7.0.0-alpha.47.0.0 on a final release commit.

Deferred to v7.1

Release flow when ready

  1. Convert this PR from draft to ready.
  2. Merge (squash NOT recommended — preserves the alpha trajectory in master history).
  3. From master: npx lerna publish from-package --yes (publishes @post-machine-js/machine@7.0.0 to the latest dist-tag).
  4. gh release create v7.0.0 --target master --title v7.0.0 --notes-file … (stable, NOT prerelease).

Test plan

  • All v7 alphas merged on the v7 branch with their own per-PR CI green.
  • 315/315 tests pass on v7 HEAD; coverage 100/100/100/100; lint + typecheck clean.
  • One final pre-release smoke after version bump.
  • Engine v7.0.0 stable consumed (peer-dep verification).

Closes (auto-close on merge to master)

Closes #82, #83, #85, #86, #87, #97, #101

(v7-branch merges did NOT auto-close these issues — the close keywords need to be on the merge-to-master PR.)

mellonis added 16 commits May 21, 2026 02:03
Adopts engine v7 (alpha.1) across @post-machine-js/machine:

- Rename consumer-side uses of `withOverrodeHaltState` to
  `withOverriddenHaltState` (closes #82).
- Switch wrapper composite shape from `"A>B"` to `"A(B)"` in
  tests, README, naming-convention table, and the `Path` validator's
  rejection message (closes #83).
- Adopt engine #138/#139 toMermaid emission overhaul: new edge-label
  vocabulary (`['x']`/`[B]`/`[*]`/`[K]`/`[E]` reads/writes, bracketed
  movements `[L]`/`[R]`/`[S]`), `idle -. enter .->` sentinel for the
  initial state, `subgraph w_N["halt frame"]` block for wrapper
  composites in place of single composite-named entry nodes. Pulled
  in because engine alpha.1 bundles all four upstream changes
  atomically; no separate post-side issue tracked this adoption.

Engine devDep bumped to `^7.0.0-alpha.1` (root + packages/machine).
Peer-dep widening and CHANGELOG entry intentionally deferred to the
eventual `v7-0-0-alpha-1` bump PR per the v7 release-PR checklist.

Quality gates: build clean, 267/267 tests, lint clean, typecheck
clean, coverage 100/100/100/100.
…tive

- Remove the hand-drawn stylized Mermaid blocks from Quick Start and
  Subroutines sections; the engine-emit blocks (previously hidden in
  `<details>`) are now the single diagrams per section, mirroring the
  upstream engine README's convention.
- Add upstream tracking references next to the diagram quirks readers
  will notice: `c_N` orphan + `onHalt` anchor on `s_N`
  (turing-machine-js#173), and the subroutine-body-visually-outside-
  the-frame question (turing-machine-js#174). The runtime divergence
  on `s6 → s0` is now called out explicitly in the reading guide
  rather than gestured at.
- Adjust intro prose for both sections to reflect the single-diagram
  shape.
Combines the pending v7 adoption work (rename + paren naming + Mermaid
emit) with engine alpha.2's emit-shape changes (#174 callable-subtree)
into a single alpha.2 release. post-machine-js skips its own v7-alpha.1
since engine alpha.1 was superseded before any post-side adoption
shipped.

Engine bump:
- devDep `@turing-machine-js/machine` ^7.0.0-alpha.1 → ^7.0.0-alpha.2
- peerDep `@turing-machine-js/machine` ^6.4.0 → ^7.0.0-alpha.2

Code adoption (was prepared against alpha.1, now reconciled to alpha.2):
- consumer-side identifier rename `withOverrodeHaltState` →
  `withOverriddenHaltState` (#82, engine #149)
- wrapper composite shape parser/formatter `>` → `(…)` (#83, engine #148)

Engine alpha.2 emit deltas (no separate post-side issue):
- README's `toMermaid` block regenerated for the callable-subtree shape:
  wrapper is now a `[[bare(continuation)]]` call site OUTSIDE the
  subgraph; the bare hopper + body live INSIDE
  `subgraph w_N["callable subtree of NAME"]`. Bold `==> "call"` from
  wrapper to bare; dotted `-. "return" .->` back to wrapper. The
  retired `-. onHalt .->` is gone.
- Body's halt-bound transition now retargets to the frame's halt marker
  `cN` instead of the real `s0`.
- `summarizePostMachine().stateCount` is +1 per call site (wrapper and
  bare are separate nodes now). The README's "Structural summary"
  example shifts from `6 1 1` to `7 1 1`; matching test assertion
  updated.

Version bump via lerna:
- @post-machine-js/machine: 6.4.0 → 7.0.0-alpha.2

CHANGELOG entry under `[7.0.0-alpha.2] - 2026-05-21` covers #82, #83,
engine #174 adoption, peer-dep widening, and migration notes for
consumers.

Verification:
- npm test — 267/267 pass
- npm run lint — clean
- npm run typecheck — clean
- npm run test:coverage — 100/100/100/100 (above hard floor)
- npm publish --dry-run --tag next — clean
Renames the section header  →  and lists the
three engine v7 changes that drove this release (#149, #148, #174).
Fixes the dangling anchor link earlier in the file. Existing v5/v6
notes preserved as 'previously applied, still apply on v7'.
…on-marker cleanup

Three doc improvements stacked on top of the alpha.2 release:

1. **Structural summary section gains side-by-side diagrams.** The
   inline-vs-subroutine comparison previously logged only the abstract
   `4 0 0` / `7 1 1` numbers. Two <details> blocks now show the engine
   emit for each machine, with prose pointing at the three extra nodes
   (wrapper, hopper bare, continuation) that drive the +3 stateCount
   delta. Readers SEE the trade-off, not just hear about it.

2. **Visualization section actually visualizes now.** The section was
   called "Visualization" but contained no Mermaid block — just a
   `console.log(mermaid.split('\n')[0])` and a stale cross-reference to
   a nonexistent `<details>` in Quick Start. Inlined the actual engine
   emit for the example machine. Updated the outdated
   #138/#139 reference to #174 with the bytewise-stable claim.

3. **Header-level (v6.1.0+) version markers stripped.** Headers like
   `## MachineState shape (v6.1.0+)` were useful during v6.x but lose
   meaning under v7-alpha.2's peer-dep range (`^7.0.0-alpha.2`). The
   CHANGELOG is the authoritative history. Inline history-context
   mentions (e.g., "stable as of v6.1.0; was experimental __onPause")
   are preserved — those explain API migrations and stay useful.

4. **Fixed broken anchor links** left by version-marker removal:
   `#machinestate-shape-v620` → `#machinestate-shape`,
   `#path-based-resolver-v630` → `#path-based-resolver`,
   `#breakpoints-v630` → `#breakpoints`.

Tests added: the Structural summary test now also asserts the salient
Mermaid shape features for both machines (no subgraph / no `[[…]]`
wrapper on inline; `callable subtree of walkToBlank` subgraph + call /
return arrows + retired-onHalt on withSubroutine).

Verification: 267/267 tests pass, 100/100/100/100 coverage, lint clean.
chore(release): 7.0.0-alpha.2 — engine alpha.2 adoption (closes #82, #83)
…truction case (#85)

PostMachine used to create a "hopper" State per subroutine — a stub that
wrapped a `Reference` to the subroutine's first instruction, providing
the forward-declaration anchor `withOverriddenHaltState` needs at the
moment `call(...)` is processed. For the common case this indirection
is dead weight.

This commit drops the hopper for subroutines that:
  - don't participate in any cycle (Tarjan's SCC on the local call graph)
  - have a non-degenerate body (first instruction isn't `stop`)
  - have a non-wrapper first instruction (not a leading group `[…]` or
    leading `call(…)`)

The hopper is retained otherwise:
  - cyclic subs need the forward-declaration anchor (mutual recursion
    `foo → bar → foo` continues to work via hoppers)
  - degenerate `{ 1: stop }` would wrap haltState directly, which the
    engine can't dispatch from
  - leading group/call would get unwrapped by engine #176's nested-wohs
    collapse, losing the inner wrapping's continuation

Observable changes for hopper-dropped subs:
  - composite wrapper name: `foo(continuation)` → `foo::1(continuation)`
  - `summarizePostMachine().stateCount`: −1 per call site
  - `toMermaid` subgraph label: `"callable subtree of foo"` →
    `"callable subtree of foo::1"`
  - `onStep` callbacks: −1 per subroutine entry (the hopper used to fire
    its own `[*] → body₁` transition as a distinct step)

New files:
- packages/machine/src/callGraph.ts — Tarjan's SCC over local subroutine
  call graphs; identifies cyclic subs and emits a reverse-topological
  build order so acyclic subs' callees are built before their callers
- packages/machine/test/callGraph.spec.ts — unit tests for the analyzer

Changed:
- packages/machine/src/commands.ts — `call()` producers are tagged in a
  WeakMap so the analyzer can read each producer's target subroutine
  name without invoking it
- packages/machine/src/classes/PostMachine.ts — analyzes local call
  graph; creates hoppers ONLY for cyclic subs; processes subroutines in
  reverse-topological order; installs first-instruction State directly
  for hopper-dropped acyclic subs (with the safe-to-wrap fallback for
  haltState / wrapper first-instructions)

Tests updated:
- examples.spec.ts: Subroutines Mermaid emit + Structural summary counts
- machine-state.spec.ts: arrivalPath test uses 2-instruction body
- machine.spec.ts: call/sub-subroutines step counts (−1 per dropped hopper)
- naming.spec.ts: composite names + body state names per new convention

Docs:
- packages/machine/README.md — Structural summary section's Mermaid
  block regenerated; narrative + counts reflect the new emit. Trailing
  caveat lists the four hopper-retained cases.
- packages/machine/CHANGELOG.md — [7.0.0-alpha.3] entry with full
  migration walkthrough

Version bump:
- @post-machine-js/machine: 7.0.0-alpha.2 → 7.0.0-alpha.3
- Engine peer-dep unchanged: `^7.0.0-alpha.2`

Verification:
- npm test — 276/276 pass
- npm run lint — clean
- npm run typecheck — clean
- npm run test:coverage — 100/100/100/100
- npm publish --dry-run --tag next — clean

Closes #85.
feat(PostMachine): drop subroutine hopper for acyclic plain-first-instruction case (#85)
Adopts the spec-file storage convention from `mellonis/turing-machine-js`:
`*.spec.ts` co-located next to the source file it tests, instead of
batched in a separate `test/` directory. Matches the engine repo so
contributors moving between the two see one consistent layout.

File moves (all via `git mv` to preserve history):

  packages/machine/test/breakpoints.spec.ts        →  src/breakpoints.spec.ts
  packages/machine/test/callGraph.spec.ts          →  src/callGraph.spec.ts
  packages/machine/test/lockdown.spec.ts           →  src/lockdown.spec.ts
  packages/machine/test/path.spec.ts               →  src/path.spec.ts
  packages/machine/test/v3.spec.ts                 →  src/v3.spec.ts
  packages/machine/test/helpers.ts                 →  src/classes/PostMachine.test-helpers.ts
  packages/machine/test/machine.spec.ts            →  src/classes/PostMachine.spec.ts
  packages/machine/test/machine-state.spec.ts      →  src/classes/PostMachine.machine-state.spec.ts
  packages/machine/test/naming.spec.ts             →  src/classes/PostMachine.naming.spec.ts
  packages/machine/test/custom-alphabet.spec.ts    →  src/classes/PostMachine.custom-alphabet.spec.ts
  packages/machine/test/state-at.spec.ts           →  src/classes/PostMachine.state-at.spec.ts
  packages/machine/test/debugger.spec.ts           →  src/classes/PostMachine.debugger.spec.ts
  packages/machine/test/examples.spec.ts           →  src/classes/PostMachine.examples.spec.ts

Files staying in test/:
- `test/examples.spec.ts` (root README example tests — cross-package
  scope, kept at root like the engine's `test/round-trip.spec.ts`).

Naming convention:
- Top-level source modules: `<base>.spec.ts` next to `<base>.ts`
  (e.g. `breakpoints.ts` + `breakpoints.spec.ts`).
- Classes with multiple test concerns: `<ClassName>.<suffix>.spec.ts`
  (e.g. `PostMachine.naming.spec.ts`, `PostMachine.debugger.spec.ts`).
  Matches the engine's `State.spec.ts` + `State.debug.spec.ts` pattern.

Other changes:
- `vitest.config.ts` include glob updated from `packages/*/test/**` to
  `packages/*/src/**/*.spec.ts`. Root `test/**/*.spec.ts` retained.
- `packages/machine/test/tsconfig.json` removed (was used to type-check
  the now-removed test/ directory; the main src `tsconfig.json` already
  includes spec files for type-checking, and `tsconfig.build.json`
  already excludes `**/*.spec.ts` from the published build).
- `CLAUDE.md` updated to describe the new convention.
- Imports updated from `'../src/X'` to either `'./X'` or `'../X'`
  depending on the spec file's new depth.
- `helpers.ts` → `PostMachine.test-helpers.ts`, placed next to its
  two consumers (`PostMachine.spec.ts`, `PostMachine.custom-alphabet.spec.ts`).

Verification:
- npm test — 278/278 pass
- npm run lint — clean
- npm run typecheck — clean
- npm run test:coverage — 100/100/100/100

No code change. Pure file-organization refactor.
chore: co-locate spec files with their source (match engine-repo convention)
Two PostMachine conventions were mentioned in prose but lacked the
visual treatment that makes them concrete. Both now have collapsed
<details> blocks alongside the existing Commands section, with matching
test assertions in `PostMachine.examples.spec.ts`.

### noop in the graph (fall-through + unconditional jump)

Two diagrams:

1. **Fall-through chain** — `{ 10: mark, 20: noop, 30: mark, 40: stop }`
   emits 3 reachable states. noop's signature `[*] → [K]/[S]` (read
   anything, keep cell, stay) is structurally distinguishable from the
   surrounding marks' `[*] → ['*']/[S]`.

2. **`noop(40)` as unconditional jump** — only the source instruction
   `10` appears; `20` and `30` are unreachable and silently dropped by
   `toGraph`. The trailing `40: stop` also elides (see below). Net
   diagram: a single state pointing directly at halt.

### Trailing stop doesn't get its own node

`{ 10: mark, 20: stop }` emits ONE state (`s1["10"]`), not two —
`stop` is a halt routing convention, not a State. Inline note covers
the asymmetry that `pm.stateAt({ instructionIndex: 20 })` still
resolves (to the canonical haltState singleton) even though the graph
doesn't render a node for index 20.

### Tests

Three new tests in `PostMachine.examples.spec.ts` under a new `Commands`
describe block, mirroring the README structure:

- `noop in a chain produces a single [K]/[S] state` — pins noop's emit
  signature alongside the surrounding marks
- `noop(40) jumps directly; unreachable instructions are dropped` —
  verifies the unconditional-jump emit + the drop-unreachable behavior
- `{ 10: mark, 20: stop } emits one state, not two` + companion test
  that `pm.stateAt` for the trailing-stop index resolves to haltState

Shape-based assertions (`expect(mermaid).toContain('["10"]')`,
regex on transition labels) — IDs aren't pinned, since the global
State.#id counter isn't stable across test ordering.

Verification:
- npm test — 282/282 pass (279 prior + 3 new)
- npm run lint — clean
- npm run typecheck — clean
- npm run test:coverage — 100/100/100/100

Closes #87.
docs(README): add diagrams for noop and trailing-stop behaviors (#87)
- `$tag(...tags, command)` inline decorator wraps a command with one or
  more tags; rejects groups and bare-`$tag` misuse with helpful messages.
- `pm.tag` / `pm.untag` / `pm.tagsOf` / `pm.findByTag` registry methods
  resolve paths and forward to engine `state.tag(...) / .untag(...) /
  .tags` — PostMachine doesn't maintain its own tag storage.
- Auto-tag policy: each program/subroutine entry point is tagged at
  construction — top-level entry → `'main'`, subroutine entry → sub name.
  Halt-resolving entries (`stop`) are skipped so the tag doesn't leak via
  the globally-shared `haltState` singleton.
- README gets a new `## Tags` section + updated example diagrams +
  rewritten Subroutines prose (was stale since alpha.3's hopper-drop).
- Bumps to 7.0.0-alpha.4. Engine peer dep unchanged (`^7.0.0-alpha.3`).
Verifies the README's recommended workaround for the group-rejection
case — wrap each group member individually with `$tag(...)`. Pins
tagsOf for inner paths, the outer wrapper carrying only auto-tag
`'main'`, and findByTag returning the group-inner path object.
Splits the Inline `$tag` decorator section into two named subsections,
each with code AND a Mermaid diagram:

- Wrapping a single command — the existing example, now with a diagram
  that illustrates tag composition (s1 carries both `tag_hot` from the
  inline `$tag` and `tag_main` from the auto-tag, rendered comma-
  separated in the label with two `class` directives).
- Per-member in a group — new example showing the recommended
  workaround for the group-rejection case, with the diagram showing
  per-member tags landing inside the group's callable subtree.

Both diagrams were probed from actual engine output, not handwritten.
feat: state tags + auto-tag policy (#86)
mellonis added 6 commits May 23, 2026 13:10
Engine `@turing-machine-js/machine` shipped 7.0.0-alpha.4 today with
two upstream bug fixes that post-machine-js inherits transparently:

- toMermaid HTML-entity-escapes user content in labels — fixes the
  edge-label parse error when an alphabet contains literal `"`, `<`,
  `>`, etc. (engine #194). Post-side `toMermaid(machine.initialState,
  machine.tapeBlock)` benefits immediately without code changes.
- runStepByStep halt stack scoped to the call rather than the
  TuringMachine instance — fixes a memory leak / ghost-iteration when
  the same machine is reused across consecutive runStepByStep calls
  (engine #196). Post-side runStepByStep inherits the fix.

Engine alpha.4 also adds State.collectStates (engine #195) and
extracts toGraph/fromGraph to a sibling module (engine #180), but
neither affects post-machine-js — the public State.toGraph /
State.fromGraph statics still exist as delegates, and collectStates
is an additive helper post doesn't currently surface to consumers.

Updates:
- packages/machine/package.json — peer dep AND devDep widened.
- package.json (workspace root) — devDep widened so the locally-
  installed engine matches what the published peer dep requires.
- package-lock.json — refreshed via `npm install`.
- packages/machine/CHANGELOG.md — alpha.4 entry updated:
  - Date 2026-05-21 → 2026-05-23 (publish moves to today).
  - Engine peer-dep line spells out the from→to range and lists
    engine alpha.4's transparent fixes (#194 / #196).

Tests: 315/315 still pass against engine 7.0.0-alpha.4.
chore: widen engine peer dep to ^7.0.0-alpha.4
Engine 7.0.0-alpha.5 (turing-machine-js#207) collapses `haltState.debug`
to a boolean and rejects object-shaped writes at the engine setter. The
prior `installHaltLockdown` was funneling the (now-defunct) per-side
DebugConfig through `withLockdownEscape`; with the boolean shape there's
nothing to mediate, and the "per-PostMachine routing" benefit was
syntactic only since haltState is a process-global singleton.

- Drop `installHaltLockdown` from `lockdown.ts` and its module-load call
  in `src/index.ts`. State-side lockdown is unaffected.
- Rewrite `PostMachine.#refreshHaltDebug` to write the boolean directly
  (no escape needed); the per-BP filter shape stays in `#breakpoints`
  for arrival-path filtering in the `onPause` wrapper.
- Tests: `lockdown.spec.ts` + `breakpoints.spec.ts` swap the
  lockdown-error assertions for the engine's boolean-only error.
  `PostMachine.spec.ts` adds a `stripMatchedTransition` helper to keep
  cross-machine onStep equality semantic — engine #205 leaks
  process-global stateIds into `MachineState.matchedTransition.id`.
- README + CLAUDE.md: rewrite Subtlety 6 + lockdown.ts blurb;
  README's halt-BP block documents the relaxed direct-write surface
  and the registry-bypass caveat.
- Refresh lockfile to engine 7.0.0-alpha.5 (the existing
  `^7.0.0-alpha.4` range already accepts it via semver-prerelease).

Peer-dep widen + CHANGELOG entry deferred to the v7 release PR per the
v7 trajectory checklist.
The comment justifying the `if (state.isHalt) continue;` skip in the
`installStateLockdown` loop still referenced the module-load halt
lockdown that was dropped earlier in this PR. The skip is still correct,
but for a different reason: haltState is a process-global singleton, and
installing a per-instance lockdown on it would block other PostMachine
instances and turing-only consumers from writing it.
PR-description archaeology ("was X before / dropped because Y") belongs
in the commit message and PR body, not in source. Each comment now
explains only what a reader of the current code needs to know.
feat: drop module-load haltState lockdown (engine #207)
mellonis added 20 commits May 25, 2026 19:10
…accessor through wrap (#97)

Engine v7 moved breakpoint detection into DebugSession and reshaped the
pause descriptor to `m.pause: {side, cause}` (was `m.debugBreak:
{before?, after?, cause}`). PostDebugSession adoption:

- #shouldFire reads `raw.pause.cause` (was `raw.debugBreak?.cause`);
  param typed `EnginePausedMachineState`.
- New `PostPausedMachineState = MachineState & {pause}` for the post
  `pause` listener; the pause wire-up carries `raw.pause` onto the
  post-wrapped state.
- debugger spec asserts `s.pause.{side,cause}`.

Critical fix: PostMachine.runStepByStep's #wrapMachineState previously
spread `{...raw}`, which silently dropped the engine's non-enumerable
MACHINE_STATE_INTERNAL accessor. The engine's DebugSession reads that
accessor (matched symbol + halt-imminence) to do detection — so once
detection moved out of the generator, post's pause events stopped
firing entirely. The Symbol is package-private (can't re-attach), so we
now mutate `raw` in place (a fresh per-iter object) to add arrivalPath /
candidatePaths while preserving the accessor.

315 tests pass.
adopt(post): engine v7.0.0-alpha.6 DebugSession reshape (#97)
Rewrite the PostMachine method table, MachineState-shape, and Breakpoints
sections for the run() (sync) / debugRun() / runStepByStep() split adopted
from engine #102, fix a dangling ToC anchor, and drop the now-pointless
await on the synchronous run() across both READMEs and the specs.
…ecycle)

#100 shipped PostDebugSession without coverage for its step controls and
lifecycle methods; v7-targeted PRs skip CI, so the gap only surfaced on the
v7 -> master integration PR (#92), whose build fails the 100/100/100/100
floor. Cover stepIn/stepOver/stepOut, external pause()/stop(), setRunInterval,
off() (incl. the unregistered-listener no-op), the halt-breakpoint #shouldFire
path, and the step/halt listener-dispatch bodies.
…resh

docs(claude): refresh v7 engine-adoption notes for post alphas 3-6
The "Nodes" reading-guide bullet claimed wrappers always sit OUTSIDE
their callable subtree's subgraph. Engine v7 fix (turing-machine-js#223)
moves framed wrappers — those whose continuation chain participates in
a caller's frame — INSIDE the owner frame's subgraph with the same
[[…]] shape. Split the prose into top-level vs framed cases.
docs(machine): hedge wrapper-placement prose for framed wrappers
Advance to the next numbered Post instruction in the current scope.
Position-independent: skips sub-step transitions inside groups
(50.1 → 50.2) and descents into called scopes (call('foo') → foo::1)
because those aren't numbered instructions in the current scope.

Two rules cover the full semantics:
1. Advance until click-time (scope, instructionIndex) pair changes;
   sub-step transitions and sub-scope descents stay silent.
2. If there's no next numbered instruction in the current scope
   (you hit stop or fall through the end), the natural engine
   continuation fires — return to caller's continuation if inside
   a call/group, halt if at top level.

Internally drives the engine via repeated stepIn; filters the
resulting step-cause pauses via path comparison. Breakpoints
mid-advance interrupt normally and consume the stepInstruction intent.

Closes #101.
feat(debug): PostDebugSession.stepInstruction() (7.0.0-alpha.7, #101)
CI on the v7→master integration PR caught two issues in alpha.7's
stepInstruction implementation:

1. Nested calls (foo calls bar from inside foo): the helper's
   scope-name comparison surfaced at bar::2 instead of running through
   bar's body to land at foo::3. Cause: arrivalPath.scope is the
   immediate callee (not the full stack), so 'sibling scope at same
   depth' (bar from foo's POV) was misclassified as 'different
   instruction.'

2. PostDebugSession.ts coverage dropped to 97.5% (lines 251, 258
   uncovered) — branches that exercise non-empty click.scope weren't
   reached by the existing tests.

Fix: classify scope changes by length relative to click, using Post's
call stack discipline (returns always go through ancestor scopes):
- cur.length > click.length → deeper, keep stepping
- cur.length < click.length → shallower, surface (returned past click)
- equal length: scope-content match → sub-step / land by index;
  scope-content differ → sibling callee at same depth, keep stepping

New tests cover both nested-call (foo→bar→foo::3) and mid-group
(10.2→10.3→20) cases, exercising the previously uncovered branches.

Existing 'inside callee at last' test simplified to use foo: {1: stop}
(single-instruction subroutine) so the test reflects the helper's
shallower-scope detection path.
…lpha.8

Engine alpha.8 (TapeSnapshot + tapeViewport move, #227) shipped on npm
next today. Bump post's peer-dep widening for alpha.7 to track the
latest engine alpha at ship time. Updates: package.json peer dep,
package-lock.json, CHANGELOG entry, CLAUDE.md narrative + #stillIn-
ClickTimeInstruction algorithm description.
fix(debug): stepInstruction nested-calls + 100% coverage
devDep bumps (all patch/minor):
- vitest + @vitest/coverage-v8 4.1.5 → 4.1.8
- rollup 4.60.3 → 4.61.0
- eslint 10.3.0 → 10.4.1
- typescript-eslint 8.59.2 → 8.60.1
- @types/node 25.6.2 → 25.9.1

`npm audit fix` clears 6 dev-only vulns (3 moderate / 3 high) under
nx/lerna toolchain — no production-runtime exposure.

Verified locally: build, test (332/332), lint, typecheck, coverage
100/100/100/100 floor held.

Preparation for the v7.0.0 stable cut on PR #92.
mellonis added 2 commits June 3, 2026 06:11
chore(deps): bump root devDeps + npm audit fix for v7.0.0 cut
Stable v7 release. Bumps @post-machine-js/machine from 7.0.0-alpha.7 to
7.0.0. CHANGELOG entry consolidates the v7 trajectory across alphas 2-7
(adoption of engine v7 composition overhaul + debug-surface reshape,
instruction-derived state names + arrivalPath, path-based tag registry,
stepInstruction).

Peer dep @turing-machine-js/machine stays at ^7.0.0-alpha.8 in this
commit — widening to ^7.0.0 lands in a follow-up commit on this branch
after engine 7.0.0 publishes to npm.
mellonis added 2 commits June 3, 2026 15:39
….0.0

Engine v7.0.0 stable is now on npm (latest dist-tag); widening the peer-dep
range from the alpha pin to the stable caret. Mirrors widening in root
dependencies and packages/machine peer + dev deps.

Verified locally: build, test (332/332), lint, typecheck, coverage
100/100/100/100, publish dry-run confirms @post-machine-js/machine@7.0.0
publishes with tag latest.
release: v7.0.0 (waiting on engine publish)
@mellonis mellonis marked this pull request as ready for review June 3, 2026 12:41
@mellonis mellonis merged commit 9fc95b8 into master Jun 3, 2026
4 checks passed
@mellonis mellonis deleted the v7 branch June 3, 2026 12:43
@github-project-automation github-project-automation Bot moved this from Ready to Done in @mellonis's machines Jun 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment