Graft v1.2: From Code Generator to Execution Engine
What is Graft?
Graft is a graph-native language that compiles .gft files to Claude Code harness structures, eliminating token waste in multi-agent AI pipelines through typed schemas and edge transforms.
What v1.2 Adds
graft run — the command that turns Graft from a code generator into an execution engine:
graft run pipeline.gft --input '{"title": "crash on login", "description": "..."}'
Instead of compiling to .claude/ and letting humans orchestrate, graft run compiles AND executes the pipeline by spawning Claude Code subagents automatically.
Runtime Architecture
The runtime is a tree-walking interpreter over FlowNode[] from the compiled AST:
- Parallel execution via
Promise.allSettled(notPromise.all) - Foreach iteration with
max_iterationscap - Edge transforms as pure TypeScript functions (~80 lines, no jq dependency)
- File-based data passing via
.graft/session/node_outputs/ - Mock spawner injection via
SpawnerFnfor testing
Additional CLI options:
--dry-run— simulate execution without spawning real Claude subprocesses--verbose— print detailed execution progress--timeout <seconds>— configurable subprocess timeout (default 5 minutes)--work-dir <dir>— specify working directory
The Forced Dissenter's Most Productive Self-Rebuttal
A4-Specialist scored 8/10 confidence (highest) and became the forced dissenter. The self-rebuttal was the most productive part of the debate:
1. generateAgent() Reuse
A4 proposed reusing the existing generateAgent() function for runtime prompts. Then argued against their own proposal:
"The function produces markdown with YAML frontmatter and
===NODE_COMPLETE===sentinels designed for manual Claude Code mode. The runtime needs a plain prompt that says 'output JSON only.' These are fundamentally different output contracts."
All 4 agents agreed after this self-rebuttal. A separate buildPrompt() was created for runtime.
2. ExecutionContext Class
A4 proposed academic-style state threading with a typed context class. Self-rebutted: "plain Map<string, unknown> suffices."
3. Full Failure Strategies
A4 proposed implementing retry/fallback/skip strategies. Self-rebutted: "adds ~80 lines of untestable-without-real-CLI code." Deferred — the code is structured so they can be added later.
A3-Skeptic's Two Showstoppers
stdin.end() Required After Spawn
Without calling stdin.end() immediately after spawning the Claude CLI subprocess, it hangs forever waiting for input. No timeout can save you — the process simply never terminates. This is a fundamental Node.js child process behavior that A3 caught before any code was written.
Promise.allSettled, Not Promise.all
For parallel execution, Promise.all rejects on the first failure and silently discards successful branch results. If three branches succeed and one fails, you lose all three results. Promise.allSettled collects all outcomes — successes and failures — so partial results are preserved.
Stats
| Metric | Value | |--------|-------| | New source lines | ~400 | | New tests | 36 (171 total) | | Agent calls | ~14 | | New ratchet decisions | 12 (70 total) | | Dependencies added | 0 |
Try It
git clone https://github.com/JSLEEKR/graft.git
cd graft && npm install && npm run build
node dist/index.js run examples/hello.gft --input '{"title":"test"}' --dry-run
Built with Claude Opus 4.6 via Claude Code. April 2026.