Skip to content

feat: add start/end node markers (v0.3) - #15

Merged
handlename merged 11 commits into
mainfrom
feature/stant-end-nodes
May 17, 2026
Merged

feat: add start/end node markers (v0.3)#15
handlename merged 11 commits into
mainfrom
feature/stant-end-nodes

Conversation

@handlename

Copy link
Copy Markdown
Owner

Why this change

Existing workflows require deleting and re-adding nodes when debugging a partial flow, since the entry point was implicit ("the node with no incoming edges"). This forces destructive edits and makes restoring the workflow tedious.

v0.3 introduces explicit start/end markers as Canvas text nodes:

  • runestone:start marks the entry point. Moving its outgoing edge re-routes the workflow without deleting any nodes.
  • runestone:end (optional, zero or more) halts the workflow gracefully when reached — useful for stopping execution at a checkpoint during debugging.

Approach

  • Markers are payloadless text nodes identified by literal runestone:start / runestone:end content (no frontmatter, no body). Chosen over file-node markers to keep them lightweight and visually distinct from runnable nodes.
  • The implicit "no incoming edges = start" rule is removed entirely. This is a breaking change — accepted because the plugin is still in beta and the partial-execution UX gains outweigh the migration cost.
  • end semantics chosen as halt-workflow (graceful): reaching any end stops new scheduling, but in-flight exec/script nodes complete naturally so their output remains in the Log Panel.
  • Internal representation uses a discriminated union WorkflowNode | MarkerNode exposed via isMarkerNode / isWorkflowNode type guards. Markers are excluded from ExecutionState.entries (no payload to track) and visualized via a dedicated CanvasVisualizer.updateMarkerNode path.
  • Marker color lifecycle: start (running 5 → success 4 on completion); end reached → success 4; end unreached → skip 0.

Migration

Existing workflows must add a runestone:start text node connected to the original entry point. The bundled example workflows (vault.example/workflows/*) have been migrated, and the now-redundant start.md exec nodes (whose only purpose was to be the implicit start) have been removed.

See MIGRATION.md for the full migration guide.

Acceptance criteria

All criteria from the spec are covered by tests:

  • A1–A7: validator rules (start count, edge constraints, end validation)
  • B1–B4: text-node marker parsing
  • C1–C7: executor behavior (start propagation, end halt, args independence, parallel start)
  • D1–D5: visualizer marker color path (dedicated unit tests omitted; DOM-mock cost prohibitive — behavior validated manually against the example workflows)

npm test: 183/183 passing. npm run build and npm run lint clean.

Review notes

  • The biggest design call is graceful halt on end-reach: in-flight nodes complete instead of being killed. This avoids child_process.kill() complexity and the inability to cancel AsyncFunction cleanly. Worth a sanity check.
  • validator.ts was rewritten — the template-reference check now targets start-adjacent successors (instead of the start node itself, since markers have no body).
  • The MarkerNode discriminated union ripples through several files (parser, builder, validator, executor, execution-state, run-canvas). The fan-out is deliberate; the type guards keep the WorkflowNode-specific code paths cleanly narrowed.

handlename and others added 10 commits May 17, 2026 18:56
Add start Node and end Node definitions as payloadless text-node markers
(`runestone:start` / `runestone:end`). Update Workflow Node, Start Node,
Partial Execution, Pre-Execution Validation, and Node Status entries to
reflect the new explicit-marker model. Adds End Node section under
Workflow Graph.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Document the v0.3 breaking change where start nodes become explicit
text-node markers, and introduce the optional end node for graceful
workflow halt. Includes Before/After Canvas examples and the visualizer
color mapping.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add start and end node sections to the Node Types reference. Update
the workflow creation steps to require the `runestone:start` marker,
and link to MIGRATION.md for users upgrading from v0.2.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add REQ-NODE-005 (start) and REQ-NODE-006 (end). Update REQ-GRAPH-001
to admit text-node parsing, REQ-GRAPH-002 for the explicit start marker,
and add REQ-GRAPH-007 for end markers. Update REQ-VALID-001 with the
new pre-execution rules and REQ-UI-001 / REQ-UI-002 with marker
visualization and log-panel exclusion.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Expand the Domain concepts table to cover all six node types and add
the marker-specific execution rules. Update agent guidelines to point
new node types at runners (for runnable types) and the
MarkerNode/isMarkerNode contract (for start/end).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add MarkerNode type and isMarkerNode / isWorkflowNode type guards.
ParsedGraph.nodes becomes a union of WorkflowNode | MarkerNode so the
graph layer can carry payloadless start/end markers alongside file-backed
workflow nodes.

Parser exposes parseTextMarker(text) which recognizes the literal
`runestone:start` / `runestone:end` (whitespace-trimmed, case-sensitive).
Builder includes text-node markers in the workflow graph.

Tests cover the B1-B4 acceptance criteria for marker parsing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace the implicit "node with no incoming edges = start" rule with
explicit marker-based validation: exactly one start marker, end markers
have incoming >= 1 and no outgoing, template syntax checks now target
the start-adjacent successors.

Executor adds an early-return guard for MarkerNodes:
- start: emit start-begin, schedule successors with empty input, then
  emit start-end after promises settle.
- end: emit end-reached and set the `halted` flag so no new nodes are
  scheduled. In-flight nodes complete naturally (graceful halt).
Args collection and skip propagation use isWorkflowNode guards so
markers do not contaminate runner dispatch.

ExecutionState filters out MarkerNodes so they never reach the log
panel. run-canvas wires the new onMarkerStateChange callback to color
mappings.

Tests cover A1-A7 (validation) and C1-C7 (execution) acceptance criteria.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add CanvasVisualizer.updateMarkerNode(nodeId, color) which paints the
Canvas node color directly without consulting ExecutionState.entries.
Marker nodes are excluded from entries (they have no payload, no
duration, no status lifecycle), so the standard updateNode path skips
them. This dedicated method is wired from the executor's
onMarkerStateChange callback (D1-D5 acceptance criteria).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add a `runestone:start` text node to para-note.canvas and
args-exec-example.canvas, with an outgoing edge to the original entry
point (start.md) in each workflow. Per MIGRATION.md v0.3, the implicit
"no incoming edges" start rule is replaced by explicit text-node markers.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
With the v0.3 `runestone:start` text-node marker, the previously-required
`start.md` exec node (which was just a no-op `echo '{}'`) is redundant.
Connect the start marker directly to the first real workflow node and
delete the start.md file.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The two `const results = await executeWorkflow(...)` sites only inspect
callback side effects (statusChanges / executed arrays) and never read
the returned results. Remove the unused bindings to clear the lingering
no-unused-vars warnings.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@handlename
handlename merged commit 7b0073e into main May 17, 2026
4 checks passed
@handlename
handlename deleted the feature/stant-end-nodes branch May 17, 2026 11:24
@handlename handlename mentioned this pull request May 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant