Skip to content

Add the tracker layer (tickets, deps, states, API), real agent-spawn adapter, and JS workflow authoring - #2

Merged
frgmt0 merged 2 commits into
mainfrom
claude/service-primitive-impl-1qctvx
Jul 13, 2026
Merged

Add the tracker layer (tickets, deps, states, API), real agent-spawn adapter, and JS workflow authoring#2
frgmt0 merged 2 commits into
mainfrom
claude/service-primitive-impl-1qctvx

Conversation

@frgmt0

@frgmt0 frgmt0 commented Jul 13, 2026

Copy link
Copy Markdown
Owner

Follow-up to #1, addressing the review feedback point by point: #1 shipped "a reference impl of the dispatcher/execution layer, not the tracker layer" — no ticket entity, no cross-task deps, no todo/review/done state model, no server or API (read-only CLI), an unimplemented agent-spawn adapter, and no CI. This PR adds all of it, so the repo can serve as the Plane replacement, not just the per-task engine — plus JS-scripted workflow authoring.

What's new

  • Ticket entity + tasks.json registry (§1.5) — the #N / #N.x tree with one-level children, needs cross-task dependencies (acyclic by construction: needs may only reference existing tickets), and a local, locked + versioned registry (advisory lock, version counter, atomic tmp+rename writes).
  • Cross-ticket DAG promotionblockedBy → promote on done: tickets with unmet needs sit in backlog burning zero tokens; when the last need completes they promote to todo and (if autoStaff) open their run in the background. Missed promotions are re-derived on recovery.
  • The eight-value state model (§1.1)backlog / todo / design / design_review / in_progress / in_review / done / cancelled, projected live from the run record on every event, via a per-ticket state_map (node → column, the doc's "each board carries a state_map"); node-kind defaults otherwise (gates → in_review, parks a human owns → in_review with the reason on the ticket). The INT design flow's map ships as a preset.
  • HTTP API (dependency-free node:http) — file/board/status, staff, nudge, human-gate verdicts, pause/resume (with grants), cancel, plus event-log and journal reads; 400/404/409 error mapping; the server owns the engine tick cadence.
  • CLI is no longer read-onlyserve boots the full stack (tracker + git worktrees + process workers); board / file / ticket / staff / nudge / gate / pause / resume / cancel drive the API.
  • Real agent-spawn adapter — the piece that was "literally unimplemented": spawns an actual worker process per seat inside its git worktree, writes the §6.4 stage manifest + brief into .beckett/, and speaks a line-JSON driver protocol (readiness handshake with real observed branch/sha, turns, file changes, checkpoints, done-signal; nudges over stdin; abort = WIP commit + SIGTERM; a silent process exit synthesizes finished and rides the engine's alarm/retry ladder).
  • JS workflow authoring — workflows as code, not just config: a fluent flow().worker().gate().fanout().join().budget().build() builder, plus flow scripts (.js/.mjs/.cjs default-exporting (ctx) => flow) that compute the shape for the task at hand (see examples/flows/adaptive.flow.mjs: hotfix → one-pass, "areas:" in the body → computed fanout arms, criteria count → effort). Scripts may also export hooks — a scripted concierge with operator authority (auto-approve gates, auto-grant a visit on park, file follow-up tickets), run off the event path, reloaded from the stored script path on recovery, errors journalled never fatal. Everything a script returns goes through the full linter, so scripting controls shape and management without loosening the bounded-execution guarantees.
  • CI — GitHub Actions: typecheck, full test suite, and the §7 simulated deployments on every push/PR.

Testing (166 tests, all green — 41 new)

  • Tracker: ref allocation and tree shape, needs validation (unknown/cancelled refused), promotion with single/multiple/autoStaff:false needs, filing-time lint refusal, registry versioning, recovery with missed promotions.
  • State projection: todo → in_progress → in_review → done across the reviewed lifecycle; design/design_review via the INT state_map; parks surface as in_review with reasons; cancel mid-run.
  • Real workers: an actual node child process handshakes against real git state, writes and commits real output, and completes the run — end to end, including under the tracker; crash → silent-exit alarm → retry → park; refusal path; stdin nudges; protocol-boundary fuzzing (coerceWorkerEvent).
  • API: the full lifecycle driven over the wire on an ephemeral port, including a human gate verdict and dependency promotion.
  • Authoring: builder composition + refusals, script loading (async/CJS/error paths), one script producing different shapes per ticket, hook policies (auto-approve, auto-grant, follow-up filing, error journalling), hook reload across recovery.

Also smoke-tested the assembled stack manually: run-of-show serve over a fresh repo, file via CLI → auto-staffed → real worker process committed its output in the task worktree → ticket done on the board.

Not done here: npm publishing (needs registry credentials and a go-ahead).

🤖 Generated with Claude Code

https://claude.ai/code/session_01A3DUAdiNuM62Q6TVAyj7rv

claude added 2 commits July 13, 2026 14:12
…al workers

Addresses the review of the first PR ("reference impl of the dispatcher/
execution layer, not the tracker layer") — the pieces needed to serve as a
Plane replacement rather than just a per-task engine:

- Ticket entity + tasks.json registry (§1.5): the #N / #N.x tree, needs
  cross-task dependencies (acyclic by construction), locked + versioned
  local registry with atomic writes
- Cross-ticket DAG promotion: blockedBy -> promote on done; unmet needs sit
  in backlog, promotion staffs autoStaff tickets in the background, missed
  promotions are re-derived on recovery
- The eight-value state model (§1.1): backlog/todo/design/design_review/
  in_progress/in_review/done/cancelled, projected live from the run record
  via a per-ticket state_map (INT map shipped as a preset), with park
  reasons surfaced on the ticket
- HTTP API (node:http, dependency-free): file/board/status, staff, nudge,
  gate verdicts, pause/resume/cancel, events/journal reads; 400/404/409
  error mapping; owns the engine tick cadence
- CLI is no longer read-only: serve boots the full stack (tracker + git
  worktrees + process workers); board/file/ticket/staff/nudge/gate/pause/
  resume/cancel drive the API
- Real agent-spawn adapter: spawns an actual worker process per seat in its
  git worktree, writes the stage manifest + brief into .beckett/, speaks a
  line-JSON driver protocol (ready handshake, turns, file changes,
  checkpoints, done-signal), nudges over stdin, abort = WIP commit +
  SIGTERM, silent exits synthesize finished and ride the alarm/retry ladder
- CI: GitHub Actions (typecheck, tests, simulated deployments)
- 26 new tests (151 total): tracker semantics, promotion, projection,
  registry versioning, real-child-process end to end (incl. under the
  tracker), full API lifecycle over the wire

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A3DUAdiNuM62Q6TVAyj7rv
Workflows can now be authored with JavaScript instead of (or alongside)
JSON, so the shape is computed for the task at hand rather than one rigid
structure for every ticket:

- FlowBuilder: fluent flow().worker().gate().fanout().join().budget()
  .build() API; build() runs the full linter so an unbounded or malformed
  graph never leaves the builder
- Flow scripts: a .js/.mjs/.cjs file default-exports (ctx) => flow, where
  ctx carries the ticket (title/body/criteria), the builder, and the
  presets; supports async scripts, wrapped returns ({flow, stateMap,
  hooks}), module-level exports, and CJS interop; results are linted and
  frozen exactly like hand-written specs
- Hooks: an onEvent export acts as a scripted concierge with operator
  authority (nudge, pause/resume with grants, gate verdicts, cancel, file
  follow-up tickets); runs serialised off the event path; errors are
  journalled, never fatal; reloaded from the stored script path on recovery
- Wiring: Ticket.flowScript + filing via the tracker, HTTP API and CLI
  (--flow-script); examples/flows/adaptive.flow.mjs demonstrates per-task
  shapes (hotfix -> one-pass, "areas:" -> computed fanout arms, criteria
  count -> effort) plus an auto-extend-once park policy
- 15 new tests (166 total): builder composition/refusals, script loading
  (async, cjs, error paths), per-task shape divergence through the tracker,
  hook policies (auto-approve gate, auto-grant on park, follow-up filing,
  error journalling), and hook reload across recovery

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A3DUAdiNuM62Q6TVAyj7rv
@frgmt0 frgmt0 changed the title Add the tracker layer: tickets, cross-task deps, state model, HTTP API, real agent-spawn adapter Add the tracker layer (tickets, deps, states, API), real agent-spawn adapter, and JS workflow authoring Jul 13, 2026
@frgmt0
frgmt0 marked this pull request as ready for review July 13, 2026 14:33
@frgmt0
frgmt0 merged commit 13a581c into main Jul 13, 2026
1 check passed
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