Skip to content

release: current-revision DAG view + node-output file refs - #276

Merged
LeXwDeX merged 5 commits into
mainfrom
dev
Aug 15, 2026
Merged

release: current-revision DAG view + node-output file refs#276
LeXwDeX merged 5 commits into
mainfrom
dev

Conversation

@LeXwDeX

@LeXwDeX LeXwDeX commented Aug 15, 2026

Copy link
Copy Markdown
Owner

Summary

Promote to main for the next official release. One train merged on dev since v1.0.14 (#274):

feat(dag): current-revision view and node-output file refs (PR #275, implements the settled ledger in workflows/dag-engine-optimization.md):

  • Graph-revision view semantics: workflows carry graph_rev; replan/extend supersedes the replaced segment and the view (status output, httpapi nodes, TUI summaries, fail counts) renders exactly the current revision — historical replaced segments including their old failures are hidden; live current-rev failures (token/API/cap unreachable) stay visible and counted; terminal aggregation no longer counts superseded failures (the old rebuild bug re-seeded replaced nodes as required-unsatisfied and failed workflows); a current-rev tail failure still fails the workflow visibly. Durable rows, event sourcing, completed outputs, and engine replan semantics unchanged — audit stays agent-reachable by id, TUI zero entry. Legacy workflows render byte-identical (migration defaults, pinned).
  • Node-output file references: a node final reply that is a single existing absolute file path is captured as {content_ref, size, sha256, summary} at submit time (anomalies fall back to inline, never fail the node); the result action returns the pointer + summary; inline and output_schema payloads unchanged; report writes under .opencode/workflow-reports/ auto-ensure an append-only .gitignore entry.

Dev validation

Release plan

On merge: dispatch release-fork from main (official). Release notes carry the two feature groups above.

…ation.md)

Red-first probes A-p1..A-p5 for the v1.0.15 graph-revision view ledger
(workflows/dag-engine-optimization.md, Train A). View-layer semantics only:
durable data untouched, replan/cancel engine unchanged.

RED on the unmodified engine (documented failing assertions):
- A-p1/A-p3: replaced failed+cancelled nodes still counted in current-rev
  summaries (nodeCount 8 vs 6) and re-seeded as required-unsatisfied on
  rebuild — the wake-up bug chain this train breaks.
- A-p5(a): wake digest failure attribution still names superseded replaced
  failures.
- A-p1 status seam: workflow status action surfaces superseded rows.

PINS (green before and after): A-p2 current-rev genuine failure visibility,
A-p4 legacy no-rev rendering, A-p5(b) reopen wake wash by status.
…revision (dag-engine-optimization.md)

Train A implementation for the v1.0.15 rev-view ledger
(workflows/dag-engine-optimization.md): durable data untouched, engine
replan/cancel semantics unchanged — view-layer wash only. Root cause of the
wake-up bug: replaced segment rows (cancelled via replan; terminal failures
the fragment bypassed) re-seeded as required-unsatisfied on every runtime
rebuild, welding workflows to failure despite the new path succeeding.

Mechanism (evidence M1 design, red-first probes landed in d33d4f4):
- workflow.graph_rev (audit counter) + workflow_node.superseded (view
  predicate); migration defaults graph_rev=1 / superseded=false keep every
  legacy workflow rendering exactly as v1.0.14 (A-p4).
- Projector marks superseded on NodeCancelled (+ explicit cancel, U1) and on
  the new optional WorkflowReplanned.superseded list; graph_rev bumps once
  per replanning event (leg order guards the double-bump).
- Dag._replan publishes the supersede list: terminal-FAILED rows at replan
  time are the segment the new revision replaces.
- DagStore.getCurrentNodes + summary SQL filter; switched view/aggregation
  seams: loop rebuild/recovery/checkCompletion/wake attribution, step-mode
  readiness, workflow status action, TUI dag.nodes route.
- Engine reads stay unfiltered on purpose: _replan plan input, terminate
  cleanup, review gate/extend, spawnReady input mapping (completed old-rev
  outputs survive for A1/A2), result store, recovery reconcile.

No HTTP response-shape change => no SDK regen; TUI renders the filtered
server seams verbatim (zero client changes, server-side aggregation
invariant). Mutation re-proof: four targeted mutations each red the probes;
A-p2 pin green throughout. Gates: opencode/core/tui/schema typecheck, core
migration --check, root lint 4849<=4850, dag suites green (opencode 725,
core dag 94).
…ization.md)

Train B probes for the v1.0.15 node-output file-reference ledger
(B1-B4). RED on the unmodified engine (5 fail / 8 pass): B-p1(a) and
B-p1(a2) fail because non-schema nodes never write captured_output
(no submit-time absolute-path detection); B-p3 fails because the
workflow result action pages the raw output string and never surfaces
content_ref/path/summary; B-p4(a)/(b) fail because nothing touches
the project .gitignore on first write into the report area. Guard and
pin probes are green before and must stay green after: nonexistent /
empty / directory / prose-embedded paths stay inline (B-p1 guards),
output_schema payloads containing a path string stay inline JSON
(B-p2 dual-track pin), the legacy paged result read is unchanged
(B-p3 pin), and refs outside the report area never touch .gitignore
(B-p4(c)).

The run's evidence.md was absent from the worktree, the config
workflow repo, and the opencode data dir at train start — the probe
contract is derived from the settled ledger in
workflows/dag-engine-optimization.md; the report area convention is
.opencode/workflow-reports/ (no better-fit existing .opencode/
directory; naming mirrors .opencode/workflow-drafts/).
…gine-optimization.md)

Train B implementation for the v1.0.15 node-output file-reference
ledger B1-B4 (red-first probes landed in a1dbaf8; all 13 probes +
6 post-feature units green).

Mechanism (dual track, B1):
- B2 submit-time detection — new runtime/output-ref.ts. When a
  non-schema node's final reply IS one absolute path (single token,
  no prose) and the file exists as a non-empty regular file, capture
  {kind: file_ref, content_ref, path, size, sha256, summary} into the
  existing captured_output column — the same durable seam submit_result
  writes and NodeStarted resets. Any anomaly (relative path, missing /
  empty file, directory, prose around the path, fs error) keeps the
  exact legacy inline settlement; the capture is audit metadata and
  never fails the node. Integrity receipt: sha256 + size at submit
  time; summary is the first ~200 chars captured at submit time so it
  stays stable even if the file drifts later.
- B3 result action — a captured file ref reads as a durable pointer
  (content_ref + summary + path + size + sha256, truncated:false,
  no cursor); the parent agent fetches content itself with the read
  tool. Inline outputs and output_schema payloads keep the paged read
  byte-identical — no migration, no shape change for them. The node
  output column stays the raw path string, so input mapping and wake
  digests behave exactly as before.
- output_schema nodes are untouched (B1): detection runs only in the
  free-text completion branch; schema settlement keeps inline JSON
  even when a payload field contains a path (B-p2 pin).
- B4 report-area gitignore — first capture into
  <directory>/.opencode/workflow-reports/ appends the area entry to
  <directory>/.gitignore (append-only via appendFile, idempotent,
  skips when the entry or a covering .opencode/ rule exists, best-
  effort). Cross-worktree refs never touch a project gitignore. The
  report area convention is .opencode/workflow-reports/ — no
  better-fit existing .opencode/ directory; naming mirrors the
  existing .opencode/workflow-drafts/ area.

No HTTP response-shape change => no SDK regen; TUI untouched
(result view is tool-served, captured_output is not a TUI surface).
Crash window between capture and NodeCompleted persists: recovery
completes such a node with undefined output while the result seam
still serves the durable ref.

Mutation re-proof (each reverted, then restored): capture-wiring
removal reds B-p1(a)/(a2)+B-p4(a)/(b); result-branch removal reds
B-p3 alone; gitignore-call removal reds B-p4(a)/(b) alone with
B-p1 still green.

Gates: packages/opencode bun typecheck + bun test test/dag test/goal
test/project = 744 pass/0 fail/1 skip (62 files). packages/core bun
typecheck + bun run migration --check (no schema changes) + license-
scope check + bun test test/dag = 94 pass/0 fail. packages/tui bun
typecheck + bun test = 244 tests/0 fail. packages/schema typecheck +
16 tests/0 fail. ROOT bun run lint = 4849 warnings (unchanged from
baseline), 0 errors.
feat(dag): current-revision view and node-output file refs (v1.0.15 ledger)
@LeXwDeX
LeXwDeX merged commit bfe30f9 into main Aug 15, 2026
15 checks 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.

1 participant