Skip to content

feat(supervise): first-class continuity on graph edges — fresh | resume | steer, all ledgered - #725

Merged
drewstone merged 2 commits into
mainfrom
feat/graph-continuity
Aug 3, 2026
Merged

feat(supervise): first-class continuity on graph edges — fresh | resume | steer, all ledgered#725
drewstone merged 2 commits into
mainfrom
feat/graph-continuity

Conversation

@drewstone

Copy link
Copy Markdown
Contributor

Owner directive from #694: fresh respawns, session RESUMES, and live steers must all be expressible as plain data. This ships the axis.

  • Delegates edges declare continuity: 'fresh' | 'resume' (per-spawn override on the tool); every ledger row and journal edge event stamps the effective mode — fresh/resume on spawns, steer on steer legs and analyzes deliveries. Zero ambiguity about how any hop continued.
  • Resume: a new live worker on the same node whose executor receives resume: { ofWorker, sequence } and owns session re-attachment; spend continuous in the one conserved pool; caps count resumes like spawns. Refused loud: no prior settled worker, prior still live (that's steer — the error says so), riding a semantic key, unresumable seams (workerFromBackend fails loud rather than ledger a resume that never happened — post-audit hardening). Resume after a FAILED prior is deliberately allowed (the seam decides salvageability) — tested and stated.
  • examples/graphs/shot-loop-resumed.ts: the VB resumed-shot loop as pure data — shots stamp fresh/resume/resume, lineage chain proven at the seam.
  • Back-compat: continuity-free graphs byte-identical (audit probe chore: agent-runtime 0.5.5 — unify agent-eval / agent-knowledge dep tree #6: all 10 new tests FAIL against old src — they test the feature, not tautologies).

Adversarially audited SHIP: lineage plumbing, dedup-distinctness, stamp integrity, refusals, and spend arithmetic all micro-revert-falsified; racing resumes proven safe (zero async gap).

0.127.0 + CHANGELOG. Suite 2364; typecheck/lint/build/docs/version-gate green.

…sals — fresh | resume | steer as ledgered data

A delegates edge accepts continuity: 'fresh' | 'resume' (edge default;
spawn_agent takes a per-call override). A resume traversal targets a node
whose prior worker has SETTLED: the kernel spawns a NEW live worker bound
to the same node whose spawn context carries resume: { ofWorker, sequence }
(WorkerResumeContext) — the executor seam owns the session re-attachment;
the kernel keeps identity, ordering, ledger truth, and spend continuity in
the one conserved pool. Traversal caps count resumes exactly like fresh
spawns.

Fail-loud refusals at the tool: resume-no-prior (explicit resume with no
settled prior; the DECLARED edge default instead degrades to fresh on the
node's first spawn), resume-while-live (steer is the live-worker channel,
the error says so), resume-with-key (keys are run-once, resume runs again).
Resume lineage is process-local — the same boundary as the analyst-run
marker — and stated where it lives.

EdgeTraversal and the journal 'edge' event gain
continuity: 'fresh' | 'resume' | 'steer' — spawns stamp their effective
mode, every mid-run delivery into a live recipient (driver steer legs,
every analyzes delivery) stamps 'steer'. validateGraph refuses nonsense
values and analyzes edges carrying the field.

Threaded as continuityByProfile through SuperviseOptions →
SupervisorAgentDeps → DriverAgentOptions / serveCoordinationMcp →
CoordinationToolsOptions; runGraph derives it from delegates edges. Kernel
exports ContinuityMode, WorkerResumeContext, TraversalContinuity.

New example examples/graphs/shot-loop-resumed.ts (the VB shot shape as
data: shot 1 fresh, shots 2-3 resume the prior settled session), proven
offline in tests/examples/graph-topologies.test.ts; kernel continuity
suite in tests/kernel/graph.test.ts. Edges without continuity behave
byte-identically to before. Bump 0.127.0.
… pin resume-after-failed-prior policy

A backend seam with no session re-attachment accepting a resume spawn
would ledger continuity:'resume' over a brand-new session — a stamp
asserting something that never happened. Refuse loud; session-resuming
makeWorkerAgent seams are the resume consumers. Failed-prior resume is
deliberately allowed (the seam decides salvageability) — now tested and
stated.

@tangletools tangletools left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✅ Auto-approved drewstone PR — d2986340

This PR was opened by the trusted drewstone account.
The full PR reviewer audit still runs separately and will publish findings if it detects issues.

tangletools · auto-approval · reason: drewstone_author · 2026-08-03T19:43:21Z

@tangletools tangletools left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Value Audit — sound

Verdict sound
Concerns 2 (1 low, 1 weak-concern)
Heuristic 0.0s
Duplication 0.0s
Interrogation 140.3s (2 bridge agents)
Total 140.3s

💰 Value — sound

Adds node-level session continuity (fresh|resume|steer) as plain data on graph edges — a clean new axis that the three existing primitives (process-resume, key, steer) genuinely don't cover, built on the existing makeWorkerAgent seam and edge ledger.

  • What it does: A delegates edge (or per-call spawn_agent arg) may declare continuity: 'resume'. On any spawn after the node's first, the kernel resolves the node's most recent SETTLED worker (by profile.name = node id), mints a NEW live worker, and hands its executor seam WorkerSpawnContext.resume = { ofWorker, sequence } — the lineage the seam uses to re-attach the backend session. The kernel keeps identity, or
  • Goals it achieves: Make 'fresh respawn vs session resume vs live steer' expressible as ONE FIELD on a graph edge, so a resumed shot-loop (shot 1 settles failed → shot 2 continues shot 1's session context, spend continuous in one pool) is data, not a hand-rolled driver loop. Secondary: eliminate ledger ambiguity — every hop now states how it continued, so 'did traversal 2 continue traversal 1's session or start fresh
  • Assessment: Sound and in-grain. The change fills a real gap: I checked the three adjacent primitives and none covers 'spawn a NEW worker that continues a SETTLED prior worker's session'. Scope.resume/ResumedWork (types.ts:711) is PROCESS-crash recovery — it re-adopts settled work without spawning; key/SpawnOpts.key (types.ts:503) is idempotency — a completed key returns its cached result WITHOUT re-running; s
  • Better / existing approach: none — this is the right approach. Searched for an existing mechanism to extend: Scope.resume (types.ts:711) is process-level crash recovery, a different concept; SpawnOpts.key (types.ts:503) is run-once idempotency, structurally incompatible (extending key to mean 'run again with lineage' would break its exactly-once guarantee); steer (types.ts:644 Scope.send) targets LIVE workers, not settled on
  • Model: opencode/zai-coding-plan/glm-5.2
  • Bridge attempts: 2
  • Bridge warning: opencode/kimi-for-coding/k2p7: opencode: opencode error

🎯 Usefulness — sound

A coherent, fully-threaded continuity axis (fresh/resume/steer) that extends the edge-ledger and fail-closed spawn patterns in the codebase's grain, with comprehensive refusals and correct back-compat — no equivalent reinvented, no materially better approach.

  • Integration: Fully reachable. continuityByProfile is plumbed through runGraph → supervise → supervisorAgent (both arms) → driverAgent → serveCoordinationMcp → createCoordinationTools (verified at graph.ts:718-721,933; supervise.ts:1587,1668; supervisor-agent.ts:509,592; coordination-driver.ts:367; coordination-mcp.ts:156). The per-call continuity arg is a live MCP tool parameter (coordination.ts:1796-1810),
  • Fit with existing patterns: Excellent. Extends the established edge-ledger observability contract (continuity is a new column on EdgeTraversal/graph.ts:142-167 and the journal edge event/types.ts:939-944) and the established fail-closed spawn-resolution discipline (resolves before assignment/budget, coordination.ts:1862-1872). Does NOT compete with the key idempotency mechanism (explicitly refused resume-with-key) or steer
  • Real-world viability: Holds up. Refusals cover every realistic misuse and are tested (graph.test.ts: resume-no-prior, resume-while-live, resume-with-key, resume-after-failed-prior, nonsense value on edge, continuity-on-analyzes-edge). Racing resumes are safe: resolveContinuity is synchronous, reads the live view + ledger, and hands off to scope.spawn with no await gap (coordination.ts:1114-1167, 1884-1888). latestSettl
  • Model: opencode/zai-coding-plan/glm-5.2
  • Bridge attempts: 1

🔎 Heuristic Signals

🟡 Cruft: console debug added examples/graphs/shared.ts

  • console.log(

🎯 Usefulness Audit

🟡 'resume' is overloaded between continuity-resume and durable Scope.resume [ergonomics] ``

The word 'resume' now names two distinct concepts at two layers: continuity 'resume' (WorkerResumeContext / spawnContext.resume — per-node session re-attachment WITHIN one process) and the pre-existing durable Scope.resume (ResumedWork / scope.resume — cross-process restart from a journal). Both are surfaced on adjacent surfaces (a single spawn context could in principle carry both spawnContext.resume AND come from a scope.resume path). They are documented as distinct and operate at different la


What this audit checks

It judges the change on its merits — not whether it was tasked out in an issue. Unticketed, fast-moving work is fine; the question is whether the change is good and whether a better or existing approach should be used instead.

Pass What it asks
Heuristic Vague title? Whitespace-only or cruft-bearing diff? (content signals only)
Duplication Do added function/class names already exist elsewhere in the repo?
Value Audit What does it do? What goal does it achieve? Is it good? Better architecture or already-exists?
Usefulness Audit Does it integrate and fit? Will it hold up in real use and actually get used?

Findings are concerns, not blocks — the human reviewer decides what to do with them.

value-audit · 20260803T194758Z

@drewstone
drewstone merged commit 74ca0b9 into main Aug 3, 2026
4 checks passed
@drewstone
drewstone deleted the feat/graph-continuity branch August 3, 2026 19:48
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