feat: add start/end node markers (v0.3) - #15
Merged
Conversation
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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:startmarks 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
runestone:start/runestone:endcontent (no frontmatter, no body). Chosen over file-node markers to keep them lightweight and visually distinct from runnable nodes.endsemantics chosen as halt-workflow (graceful): reaching any end stops new scheduling, but in-flightexec/scriptnodes complete naturally so their output remains in the Log Panel.WorkflowNode | MarkerNodeexposed viaisMarkerNode/isWorkflowNodetype guards. Markers are excluded fromExecutionState.entries(no payload to track) and visualized via a dedicatedCanvasVisualizer.updateMarkerNodepath.5→ success4on completion); end reached → success4; end unreached → skip0.Migration
Existing workflows must add a
runestone:starttext node connected to the original entry point. The bundled example workflows (vault.example/workflows/*) have been migrated, and the now-redundantstart.mdexec 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:
npm test: 183/183 passing.npm run buildandnpm run lintclean.Review notes
child_process.kill()complexity and the inability to cancelAsyncFunctioncleanly. Worth a sanity check.validator.tswas rewritten — the template-reference check now targets start-adjacent successors (instead of the start node itself, since markers have no body).MarkerNodediscriminated 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.