gk v0.3.5 · graph engineering kit

GraphKit

Define agent workflows as graph-shaped YAML. One CLI compiles them to native execution on five targets — Claude Code, Cursor, OpenCode, Codex and Pi. Every run lands in a ledger; failed runs resume where they stopped. No custom runtime, no daemon — the host's own primitives do the work.

Get started View on GitHub
curl -fsSL https://github.com/thanhNt16/graph-kit/releases/latest/download/gk-darwin-arm64.tar.gz | sudo tar -xz -C /usr/local/bin
11
Topologies
5
Targets
13
Skills (claude)
8
Agents
575
Tests
Quick Start

Install — Release Tarball or Source

Easiest: every push to main publishes a patch release with prebuilt binaries. Or clone and build from source (not on npm yet). Requires Bun (source build) and at least one supported host — Claude Code, Cursor, OpenCode, Codex or Pi.

1. Release tarball (recommended)
# macOS Apple Silicon curl -fsSL https://github.com/thanhNt16/graph-kit/releases/latest/download/gk-darwin-arm64.tar.gz \ | sudo tar -xz -C /usr/local/bin # Linux x64 curl -fsSL https://github.com/thanhNt16/graph-kit/releases/latest/download/gk-linux-x64.tar.gz \ | sudo tar -xz -C /usr/local/bin gk --version # verify — then `gk init` in your project
2. Or: clone & build from source
# Clone the repo git clone https://github.com/thanhNt16/graph-kit.git cd graph-kit # Install deps + build bun install bun run build # → dist/index.js (executable, with shebang) # Run the full gate to verify bun run ci:local # → typecheck + lint + build + 542 tests + cbm:parity
2a. Install globally (npm link)
# From the repo root: npm link # If you have a conflicting 'gk' alias unalias gk 2>/dev/null # Verify — should show GraphKit help: gk --help gk graph topologies --json
2b. Or: standalone binary
# Build a standalone binary (no runtime needed): bun run build:bin # → dist/gk (self-contained) # Install to your PATH: cp dist/gk /usr/local/bin/gk chmod +x /usr/local/bin/gk # Verify: gk --help gk graph topologies --json
3. Install the kit + use it
# Install the kit into your project (agents, skills, hooks, rules): cd /path/to/your-project gk init # → .claude/ (default target) gk init --target cursor # → .cursor/ gk init --target opencode # → .opencode/ (TS plugin hooks) gk init --target codex # → .codex/ (TOML agents + AGENTS.md rules) gk init --target pi # → .omp/ (OMP extension + prompt fragments) # Or scaffold a new project from scratch: gk new --dir my-project gk new --dir my-project --target opencode # Graph lifecycle — sessions replace the single graph.yaml: gk template materialize audit-pr --params '{"task":"the auth module"}' --use # → .graphkit/graphs/2026-08-27-audit-pr.yaml, sets active gk graph list # session table, * marks the active graph gk graph switch 2026-08-27-audit-pr # flip the active pointer gk validate # validates the active session graph (agent binding checked) gk compile .graphkit/graphs/<id>.yaml # → .claude/workflows/{name}.workflow.js # Inside a session, skills auto-discover from the active kit's skills directory: # /gk-init-graph /gk-validate /gk-template /gk-execute
Three Ways In

Author, Run, Remember

✍️ Author

Write graph.yaml — pick from 11 proven topologies, bind agents per node, tier models, declare evidence gates. Compile or dispatch directly.

Browse topologies →

⚡ Run

Every dispatch lands in the run ledger — status, evidence, advisor events. Failed run? gk run resume replays checkpoints and re-runs only what's pending.

See the ledger →

🧠 Remember

Consolidate ledgers into project memory — patterns, failure recurrence, ranked suggestions. The kit gets sharper about your repo over time.

How memory works →
Architecture

Three Layers, Clean Boundary

gk CLI validates, compiles, and — new in 0.2 — bridges. The host executes. The kit template connects them. No custom state machine: the host's native primitives own the runtime.

Layer 1 — Kit Template
📦 kits/<target>/ installed into the host directory
Installed by gk init --target <id>.claude/, .cursor/, .opencode/, .codex/ or .omp/. Agents, skills, hooks, rules, schemas, topology templates — in the target host's native format.
8 agents (every host)·13 skills (claude) · 11 (others)·4 hooks·3 rules·11 templates
Layer 2 — gk CLI
⚙️ Compiler + Installer + Bridge
Validates graph YAML against schemas + topology contracts. Compiles to self-contained .workflow.js. Bridges to CBM MCP for indexing & code-graph queries. Never invokes a model.
gk initgk validategk compilegk graph index|search|trace|query
Layer 3 — Host Runtime
▶️ Workflow Tool  /  Native Subagents
Two execution paths. /gk:run is Claude Code only — its Workflow tool runs the compiled .workflow.js via agent(), parallel(), pipeline(). /gk:execute works on all five hosts, dispatching through each one's native mechanism: Task-tool subagents (Claude Code, Cursor, OpenCode), spawn-prompt protocol (Codex), or the gk-subagent extension's headless child processes (Pi).
Execution Paths 0.2

Compile-and-Run, or Dispatch Directly

Same graph, two execution paths. /gk:run is the opaque high-scale path inside Claude Code — the only host with a Workflow tool. /gk:execute is the transparent path on all five targets: you watch each subagent spawn, debug failures interactively, and skip compilation entirely. Each host dispatches through its own native mechanism (see the five-host table below).

/gk:run/gk:execute
HostClaude Code onlyAll five targets
Compile stepRequired (gk compile)Not needed — reads waves
VisibilityOpaque background jobFull — every agent visible
DebuggingHardInteractive, adaptive
Best for100+ node graphs<20 node graphs
SpeedSame — parallel within waves
Run Ledger & Project Memory 0.3

Every Run Recorded, Every Failure Mined

Two persistent subsystems turn execution history into an asset. The run ledger records every dispatch to .graphkit/runs/<run-id>/ — per-node status, rounds, evidence, advisor events. The pattern compiler mines those ledgers plus project memory into reusable patterns and ranked suggestions. No daemon, no database: plain files written by the host's execute skill and read by the CLI.

gk run start
run id → .graphkit/runs/<run-id>/
gk run node
per-node status + evidence + round
gk run end
terminal verdict — all nodes terminal
gk memory consolidate
ledgers + memory → patterns
gk suggest
ranked suggestions · --dismiss
ledger lifecycle
# Start a run from the active graph: gk run start # → run id + .graphkit/runs/<run-id>/ # The host's execute skill records each dispatch: gk run node <run-id> scouter --status passed --evidence '{"attack_surface":"..."}' gk run node <run-id> fixer --status failed --round 2 gk run status <run-id> # per-node table, counts, advisor_events gk run end <run-id> --status failed # terminal verdict # Mine history into patterns + suggestions: gk memory consolidate --runs 20 # → .graphkit/memory/patterns/ + suggestions/ gk suggest # ranked, with rationale gk suggest --dismiss <id> # keep the file, hide from ranking
PATTERN FAMILIES

Consolidation derives five families from real runs: node-sequence (which nodes follow which), evidence-cooccurrence (which evidence keys travel together), failure-recurrence (which nodes fail repeatedly), graph-reuse (which graphs get re-run), and advisor-repeat (0.3.2 — repeated escalations → "raise tier / loosen stop_when" suggestion).

COMPOUNDS

Recall widened to subfolders with .links.json neighbors below direct hits. The dream graph template proposes memory consolidations as reviewable diffs in .graphkit/inbox/. The waves payload now carries hooks (on_node_complete) and on_graph_complete commands verbatim to every host.

Checkpoint Resume 0.3.5

Failed Runs Resume Where They Stopped

A failed or interrupted run is not a restart. gk run resume <run-id> reconciles the ledger against the recorded graph — a node counts as satisfied only if its last trace line passed and every declared evidence key exists on disk — then derives a pending-only session graph: dependents of failures reopen, satisfied upstreams drop out, and their evidence reattaches to pending nodes as refs. The derived graph is validated against the same structural rules the compiler enforces (fan-out targets, loop membership, required evidence, eval-gate dependencies) before anything is written, activated as the session graph, and run as a child carrying resumes: provenance — visible in gk run status as the full chain.

reconcile
passed ∩ evidence-on-disk → satisfied
derive
pending-only graph · evidence → refs
validate
compile rules, fail-fast, nothing written
activate + start
session graph on · child run · resumes:
checkpoint resume
# A run failed mid-flight: gk run resume <run-id> # derive pending-only graph + start child run gk run resume <run-id> --dry-run # preview reconciliation, write nothing gk run resume <run-id> --from-node scan # redo scan + dependents gk run status # resumes_chain: [child, parent, …] # Graph edited since the run started? Refused: RESUME_GRAPH_DRIFT — commit the change and start fresh, or --force consciously.
Advisor Escalation & Fan-Out 0.3.2

Failing Nodes Ask for Help; Briefs Size the Fleet

Two per-node primitives close the biggest gaps in pure-wave execution. Advisor escalation: a looping node on a failed-round streak calls a read-only advisor at a stronger tier, gets its guidance appended to the objective, and retries at its original tier — capped and audited, never adding rounds. Fan-out: fleet size is decided at runtime by data, not by the author — an upstream node emits briefs, the fan-out node dispatches one parallel subagent per brief behind an in-node barrier.

failed round streak ≥ after_failed_rounds read-only advisor (fable) ## Advisor guidance re-dispatch at original tier
graph.yaml
nodes: fixer: agent: code-reviewer model: haiku objective: Fix the failing tests. loop: enabled: true stop_when: evidence found max_rounds: 4 advisor: # fires on a failed-round streak model: fable after_failed_rounds: 1 max_calls: 2 research: agent: Software Architect model: sonnet fan_out: # fleet size from upstream evidence briefs_from: briefs template: "Investigate: {brief.title} — {brief.body}"
audit trail
# Agents simulate escalation while iterating on graphs: gk run node <run-id> fixer --status failed --round 2 \ --advisor-fired 2 --streak 2 # → advisor.jsonl gk run status <run-id> # → { nodes: {...}, advisor_events: 1 } # Consolidation surfaces repeated escalations: gk memory consolidate # → advisor-repeat pattern → suggestion: # "raise model tier / loosen stop_when" # (action: review-failure) # Fan-out contract: # upstream evidence briefs = [{id,title,body}] # [] → zero briefs, round passes # missing/malformed → failed round (advisor-eligible)
542
Tests Pass
0
Failures
+24
New Tests
5/5
Kits Dispatch Advisors
0
New Deps
tsc ✓
Typecheck
Visualization 0.3.2

archify Replaces the Local Viewer

/gk:visualize now authors a typed archify IR — wave index → column, model tier → lane — validates it at showcase quality with a 5-cycle cap, and delivers a self-contained .graphkit/diagrams/{name}.html plus its .archify.json source. archify is skill-layer only: probed per host, installed once with consent, SVG fallback when unavailable. The local interactive viewer is deleted (see the historical section below); ASCII, SVG, and Excalidraw modes unchanged.

CBM Bridge 0.2

Code-Graph Queries Without a Graph DB

gk owns no graph database. It bridges to codebase-memory-mcp (CBM) — a live MCP server with an LSP-backed indexer (11 languages), SQLite + Cypher, and Leiden community detection. Four gk graph subcommands wrap CBM's tools so topology agents can look up code structure mid-run.

gk graph <cmd> stdio JSON-RPC CBM MCP server SQLite + LSP + Cypher ranked hits
Five subcommands
# Index a repo into the CBM graph: gk graph index /path/to/repo --mode fast # Natural-language code search (BM25 + semantic): gk graph search "graph validation" # Routed question — classify, then search/trace/query/snippet: gk graph ask "Who calls validateGraph in production?" # Caller/callee trace, 3-hop: gk graph trace validateGraph # Raw Cypher against the graph: gk graph query "MATCH (f:Function) RETURN f.name LIMIT 5" # JSON envelope on every call: # { "status":"ok", "data":{...} } | { "status":"fail", "error":{...} }
FAITHFUL CONTRACT

Return shapes mirror CBM's live output exactly — captured from the running server, not invented. Versioned at CBM_CONTRACT_VERSION = "2".

search → {total, search_mode, results:[{ name, qualified_name, label, file_path, start_line, rank}], has_more} trace → {function, direction, callers:[...], callees:[...]} query → {columns:string[], rows:unknown[][], total}
WHY BRIDGE, NOT BUILD

0.2 originally aimed to ship a native TS indexer (≈4.3k LOC) to beat CBM + grep. Evidence killed it: a tree-sitter-only indexer (no cross-file LSP) produced 4,477 edges vs CBM's 43,589 — a 9.7× deficit. CBM was already live and hitting all five target metrics on graph-kit. So ~400 LOC of bridge replaced 4.3k LOC of re-implementation.

# Parity harness — gate in ci:local (bun run cbm:parity) # decision rule: gk-CLI latency ≤ 1.5× CBM-direct CBM direct 63.2ms · CBM-via-MCP 525.6ms · gk CLI 17.5ms → c/a = 0.28× PASS
Graph Topologies

Eleven Canonical Shapes

Seven base topologies, plus custom for arbitrary DAGs and three flow presets (sdd, superpowers, research-and-build) built on it. They compose — a diamond's fan-out can embed an adversarial-verification subgraph, or wrap the whole thing in a memory-augmented layer.

Diamond
fan-out → reduce → synthesize
Split work to N parallel workers, reduce with deterministic code, synthesize with one high-tier agent.
→ code review · research · migration
Classify-and-Act
route 1 → 1 handler
Classifier inspects input, routes to exactly one handler. Fallback for unmatched inputs.
→ triage · routing · escalation
Adversarial Verification
produce → refute → adjudicate
Producer emits items. Independent refuters with fresh context challenge each. Survivors pass threshold.
→ security audit · fact-check
Loop Until Done
scout → work → dedup → repeat
stop when dry
Scout discovers work, workers process, dedup against seen. Loop until K consecutive empty rounds.
→ discovery · bug sweep
Generate-and-Filter
generate N → keep best K
Multiple generators propose candidates. Rubric scores in one deterministic pass. Keep top-K.
→ naming · ideation · design
Tournament
pairwise elimination
Candidates compete in pairwise judged rounds. One champion emerges.
→ ranking · eval scoring
Memory-Augmented
wrapper: any topology + curator
curatorwraps diamond inside
Wraps any base topology. A Memory Curator agent interleaves at cadence — extract, consolidate, expire, inject-or-null.
→ long-running graphs · cross-run memory
Custom
arbitrary DAG via depend_on
Define any shape. depend_on controls order — empty deps run now, shared deps run parallel, multiple deps form a barrier.
→ any shape you define
SDD flow
spec → design → dev → review
Spec-driven development. Brainstorm → plan → parallel workers → review → test. Custom-topology preset.
→ subagent-driven feature dev
Superpowers flow
brainstorm → plan → execute loop
verify · loop
Brainstorm → plan → workers → verify, looping until the goal holds. Matches the superpowers skill cycle.
→ brainstorm/plan/execute
Research-and-Build flow
scout → research → build
buildreview
Research-first features. Scout → research → compare → build → review. Decisions grounded before code.
→ research-first features
Per-Node Binding

Model Tiering, Tools, Loops, Constraints

Every node carries its own configuration. The scouter runs at opus for deep analysis. The verifier runs at haiku for cheap checks. Workers get their own tools, refs, and internal loops. Agent names must resolve to a file in the active kit's agents directory — validation fails otherwise.

graph.yaml
nodes: scouter: agent: Software Architect model: opus objective: Map attack surfaces tools: [Read, Glob, Grep] refs: - path: docs/owasp.md purpose: checklist depend_on: [] loop: enabled: true stop_when: evidence found max_rounds: 3 constraints: - no_write: true evidence: [attack_surface]
compiled .workflow.js
// Generated by gk compile // Self-contained: zero kit imports export const meta = { name: "security-audit", }; export function createDiamondWorkflow(config) { const { nodes } = config; return async (context) => { const scout = await context.agent( nodes.scouter.objective, { model: "opus", tools: nodes.scouter.tools, }); const results = await context.parallel( items.map(item => () => context.agent(..., { model: "sonnet", }))); return synthesize(results); }; }
Five Hosts, One CLI 0.2

Same CLI, Five Targets

Pass --target <id> to install the host-flavored kit — the same eight agents in each host's native format. The gk CLI is identical across targets — validate, graph new/ascii/svg/waves, memory, run ledger all work the same (pure CLI). The kit differs per host.

install for any host
# Into an existing project: gk init --target cursor gk init --target opencode gk init --target codex gk init --target pi # Or scaffold fresh: gk new --dir my-project --target codex # Map abstract tiers to host models: gk models opencode set --map opus=anthropic/claude-opus-4.5 # stored in .graphkit/models.opencode.json
ClaudeCursorOpenCodeCodexPi
Rules.claude/rules/*.md.cursor/rules/*.mdcAGENTS.mdAGENTS.md rules sectionAGENTS.md
Agents.claude/agents/*.md.cursor/agents/*.md.opencode/agent/*.md.codex/agents/*.toml.omp/agents/ fragments
Skills13 · .claude/skills/11 · .cursor/skills/11 · .opencode/skills/11 · .codex/skills/11 · .omp/skills/
Hookssettings.json + *.cjshooks.json + *.cjsTS plugin gk.tsnone — AGENTS.md rules.omp extension handlers
Execution/gk:run + /gk:execute/gk:execute/gk:execute/gk:execute/skill:gk-execute via OMP

Agent formats stay host-native: markdown frontmatter for Claude/Cursor/OpenCode; Codex TOML (name, description, developer_instructions, model, sandbox_mode); Pi prompt fragments installed under .omp/ for OMP. Dispatch paths: Claude Code / Cursor / OpenCode spawn Task-tool subagents wave by wave (parallel within a wave); Codex uses a spawn-prompt protocol against custom TOML agents — the wave barrier is instruction-enforced, not tool-enforced (documented limitation); Pi dispatches through OMP via the gk_dispatch_agent extension, running headless omp -p child processes (requires omp on your PATH). Skills gk-compile/gk-run remain Claude-only; non-Claude targets execute graph.yaml directly through gk-execute.

Dogfooded, Not Mocked

Every graph below actually executed in this repository via /gk:execute — the features shipped on this page (viewer interactivity, CLI hardening, this very report's positioning pass) were built by these graphs. Each card links its graph.yaml.

gk-social-improve PASSED
custom · 12 nodes · 6 waves · 2026-08-19

Sonnet research fleet (Reddit/X/HN sweep, docs audit, product-gap probe, competitive scan) → fable consolidation + plan → 3 parallel sonnet executors → fable review (1 critical found) → fix loop → acceptance gate. Shipped the CLI fail-loudly contract and docs honesty batch.

gk-social-improve graph
viewer-interactivity-upgrade PASSED
custom · 10 nodes · 6 waves · 2026-08-18

Built this viewer's interactive edges, drag re-routing, and a11y drawer. The review wave caught what every executor self-review missed: drag deltas compounding across mousemove events (~30× overshoot) — runtime-reproduced by the fable reviewer, fixed with regression tests.

viewer-interactivity-upgrade graph
gk-improve-tournament PASSED
tournament · 11 nodes · 3 waves · 2026-08-18

Six sonnet fleet sweeps → four optimization-lens candidates → fable-judged pairwise elimination. Champion measured −29% tokens on the frozen benchmark; the judge also falsified one fleet proposal that regressed accuracy — adversarial checking working as designed.

gk-improve-tournament graph
gk-autoresearch PARTIAL → −52%
custom · 11 nodes · 7 waves · 2026-08-15

Self-improvement loop: parallel web research → plan → benchmark harness build → routing experiment. Three rounds took gk's code-graph recall from 124,414 → 59,309 tokens (−52.4%) with wrong-hits 12 → 5, measured on a frozen replay benchmark.

gk-autoresearch graph

The Full Lifecycle

Inside a session, the kit's skills walk the user from blank canvas to verified run — 13 shipped for Claude Code (including gk-compile and gk-run), 11 for every other target. /gk:execute is new in 0.2 (cyan border).

/gk-init-graph
Generate graph.yaml
/gk-brainstorm
Refine nodes + tiers
/gk-visualize
ASCII / SVG render
/gk-validate
Gate-check
/gk-compile
YAML → .workflow.js
/gk-run
Workflow tool run
/gk-execute
Dispatch subagents
/gk-eval
MERGE/BLOCK gate
/gk-recall
Recall + reinforce
/gk-evidence
Results report
/gk-status
Run state

Engineering Team

Seven agents from agency-agents, plus the Memory Curator. Each declares a model tier, graph roles, and evidence keys.

🏛️
Software Architect
scouter · planner · synthesizer
opus
👁️
Code Reviewer
worker · verifier · gk graph search/trace
sonnet
🧪
QA Engineer
verifier · worker
haiku
📊
Data Engineer
worker · scouter · gk graph query
sonnet
🎨
UI/UX Researcher
worker · synthesizer
sonnet
🔧
Agents Orchestrator
scouter · synthesizer
opus
📝
Document Generator
synthesizer · worker
sonnet
🧠
Memory Curator
curator · injector · gk memory recall/trace
opus

CBM Bridge — Five Metrics Proven

The 0.2 bridge was exercised end-to-end by a 15-node gk-evolve custom-topology graph. A verifier node looped until all five success metrics held. Final: all pass, three with documented caveats.

MetricTarget
M1 — indexing speed≤ CBM, ≥10k nodes/secPASS · delegation
M2 — indexing qualitynode_yield ≤ 1.10, edge kinds + complexityPASS
M3 — API paritycontract mirrors live CBM outputPASS
M4 — retrievalgk CLI ≤ 1.5× CBM-directPASS · 0.28×
M5 — recall > grepRecall@10 ≥ 0.95, ≥10× vs grepPASS · CBM 4/5 vs grep 0/5
461
Tests Pass
0
Failures
1545
Expect Calls
60
Test Files
5/5
Metrics
0
Lint Errors

Autoresearch — The Kit Improved Itself

Three rounds of the Karpathy-style loop: freeze a benchmark, mutate one axis, keep measured wins, reset the rest. Round 1 failed honestly (the instrument bypassed the product code — diagnosed, not papered over). Rounds 2–3 shipped the corrections.

Frozen 20-question task-replayMetric (lower = better)Wrong
grep/glob reference2,9360
gk baseline — raw search_graph124,41412
+ question-kind routing (gk graph ask)63,1155
+ tournament payload trims59,309 · −52.4%5
MEMORY LAYER — MEASURED

A 6-agent research fleet + fable judge found the ACT-R decay shipped in 0.2 was a store-wide time bomb (no reinforcement → uniform ~day-10 expiry). Fixed with a closed loop: gk memory recall retrieves (keyword×salience + validity/supersede filters) and reinforces survivors; gk memory touch bumps use; gk memory trace decays with a JSONL audit trail; bun run eval:memory reports hit_rate 1 / 0 validity violations / 14 malformed entries counted as expected.

Two adversarial catches along the way: the fleet's deadcode trim was measured regressive before it shipped, and CBM search_graph was measured to return 0 hits over markdown-only projects — gk-recall's semantic step had always been dead weight and was replaced with the measured retriever.

Durable Memory, Strict Boundaries

Memory capture remains GraphKit's markdown store, with additive OKF-compatible provenance fields: generated, recorded_at, status, and sources. This is deliberately not an OKF conformance claim; existing GraphKit fields stay authoritative and unknown fields survive rewrites. See the current OKF specification.

Capture identity
basename + content hash of source and body
Re-capture
same content → idempotent skip
Changed content
new file; old entry superseded, never overwritten
Recall
keyword × salience, validity and supersede filters
Trace
ACT-R decay; expired entries retained for audit
READER CONTRACT

Malformed memory entries are dropped and counted in malformed. A missing memory directory is empty. Other filesystem failures return MEMORY_DIR_UNREADABLE and fail instead of silently erasing recall.

Memory-augmented workflows share one terminal contract: the curator's final non-empty line is exactly INJECTION: <reminder> or INJECTION: null. A non-null reminder is prepended to the next action dispatch; malformed output becomes null and never blocks the action node.

CONFIG + PARITY

Cadence counts completed action-node executions, not curator calls. recall_topk, expire_policy: manual, and null_intervention_allowed are honored from graph configuration.

Curator contract parity is tested across Claude Code, Cursor, OpenCode, Codex, and pi. Codex uses sandbox_mode = "workspace-write" for persistence.

461
Tests Pass
0
Failures
1.0
Eval Hit Rate
14/14
Malformed Expected
0
Validity Violations
tsc ✓
Typecheck

These are deterministic fixture and behavior checks, not benchmark-superiority claims. The @0xwast3 memory-engineering article is third-party validation only. Its status: conflicted field and three-month capture criterion are follow-up scope, not shipped behavior.

The Kit Ran Its Own Flow — Viewer Interactivity Upgrade

The superpowers preset was extended with a research fan-out and executed via /gk:execute: 3 parallel sonnet researchers → fable consolidation + plan (function-ownership map keeps parallel executors collision-free) → 3 sonnet executors with self-review loops → fable final review → sonnet fix loop → fable acceptance gate with a live smoke test. 10 nodes, 6 waves, one hotfix, zero commits until the gate passed.

Historical note — the local interactive viewer this section documents was removed in v0.3.2 in favor of archify-rendered diagrams; see Visualization above.

ShippedDetail
Edges are first-classinvisible wide hit-target paths make edges hoverable/selectable; dragging a node re-routes incident edges live (incremental deltas, no dagre re-run); Shift+click traces a route (BFS routeIds)
Drawer & keyboardreal SSE focus-restore (the 0.2 fix was a no-op — capture now happens before blur), drawer role="dialog" with focus trap/return, arrow-key nav skipping filtered nodes, coherent Escape
Launch opspinned port 4800 (GK_VIEWER_PORT), port-busy probe +1…+9 then ephemeral, opt-in Chrome via GK_VIEWER_BROWSER=chrome — default still just prints the keyed URL
Kit upgradesgk init now overwrites stale kit files on upgrade (skills refresh) while preserving user .gk.json; --force remains the wipe path
REVIEW LOOP — EARNED ITS KEEP

Executor self-reviews caught 3 bugs pre-review (inverted drag endpoints, dropped Esc-clears-selection, dual-stack test bind). The fable gate still found 1 critical the tests masked: drag re-routing compounded mousemove deltas — one 40px move vs two 20px moves diverged, ~30× overshoot over a 60-event drag — because every test simulated exactly one mousemove. The reviewer runtime-reproduced it, the sonnet fixer shipped incremental deltas plus a two-moves-equal-one-move regression test, and 2 majors (stale .route ribbons, Shift+click popping the drawer) fell the same way. Acceptance re-proved every plan checkbox independently, including a live key-gated smoke on the pinned port.

461
Tests Pass
0
Failures
+22
New Tests
5/5
Bundle Parity
0
New Deps
tsc ✓
Typecheck

Graph Runtime Primitives — Session Store, Loop Groups, Template Gallery

Three core runtime features landed to unlock multi-session workflows and iterative refinement without a custom runtime engine:

ShippedDetail
Session Graph StoreImmutable timestamped session graphs under .graphkit/graphs/YYYY-MM-DD-<slug>.yaml with collision suffixing (-2, -3) and an active pointer at .graphkit/active. Managed via gk graph list|switch|show. Root graph.yaml fallback preserved.
Loop Groups & Hybrid StopTop-level loops: directive repeats contiguous wave spans. Hybrid stop hierarchy: deterministic gate_evidence check first, LLM-judged stop_when fallback, max_rounds hard bound. Enforced via schema + compiler wave-span closure.
Template Gallery & Materializegk template materialize <name> [--params] [--use] resolves project-local ⇒ user-global ⇒ bundled gallery. Ships 4 bundled templates (audit-pr, refactor-module, bench-eval, doc-sweep).
552
Tests Pass
0
Failures
+91
New Tests
4
Gallery Templates
0
New Deps
tsc ✓
Typecheck

Try the New Runtime Features

Step-by-step verification flows for the three features shipped in v0.2.25:

Flow 1: Materialize Gallery Template & Manage Session Graphs
# 1. Initialize host kit in your workspace: gk init --target pi # or claude / cursor / opencode / codex # 2. List bundled gallery templates (audit-pr, refactor-module, bench-eval, doc-sweep): gk template list # 3. Materialize a session graph with parameter substitution: gk template materialize audit-pr --params '{"task":"auth module"}' --use # → creates .graphkit/graphs/YYYY-MM-DD-audit-pr.yaml and sets .graphkit/active # 4. Manage graph sessions: gk graph list # shows session IDs, timestamps, and active indicator gk graph show # prints YAML of the active graph gk validate # validates the active session graph # 5. Collision safety — same-day runs auto-suffix: gk template materialize audit-pr --params '{"task":"payments"}' --use # → auto-suffixes to YYYY-MM-DD-audit-pr-2.yaml gk graph switch YYYY-MM-DD-audit-pr # switch back anytime
Flow 2: Multi-Node Loop Groups & Contiguity Validation
# Declare multi-node loops across contiguous waves with hybrid stop: cat << 'EOF' > loop-demo.yaml apiVersion: graphkit.dev/v2 kind: Graph metadata: name: loop-demo topology: custom nodes: scout: agent: code-reviewer objective: Scout anomalies. depend_on: [] evidence: [findings] fix: agent: software-architect objective: Fix found issues. depend_on: [scout] evidence: [patch] loops: - id: review-fix-cycle nodes: [scout, fix] max_rounds: 3 gate_evidence: [findings] evidence: required_keys: [patch] EOF gk validate loop-demo.yaml # → passes (contiguous waves, declared evidence)

The Part of the Stack Every Other Tool Makes You Run Itself

gk is a graph-engineering compiler kit, not a "multi-agent framework." Where CrewAI/AutoGen/ADK ship a runtime that invokes models and owns the execution loop, gk declares the graph, gates it at validate, and compiles it to a deterministic .workflow.js the host already runs — with zero models orchestrating. gk never invokes a model; coordination is compiled from graph.yaml, not delegated to an LLM, which is where other stacks' empirically measured flakiness lives (CrewAI: a 34% non-deterministic failure rate over 3 weeks on identical inputs vs 4% under explicit orchestration — per 2025–26 dev-shop retrospectives). The term "graph engineering" is the field's own label for this rung (Simmons, "We Are Entering the Graph Engineering Phase"): the craft of what happens between context windows.

Budgets are the safety story. Every production postmortem independently converges on caps — hard turn/token/¤ ceilings, fail-closed defaults, checkpointed edges. gk's limits, constraints, and loop max_rounds are that blast-radius control (Edgeless Lab — the $50-night swarm; TURION — "hard budgets, always"). What you leave runnable will eventually run; gk makes the bound explicit and auditable.

Per-node binding kills the state-schema tax. The LangGraph scorecard's cost center is designing a typed state schema — 2–4 weeks per modest graph (Orange ITS review), "most of the time goes to state schema" (Kalvium). gk binds model, tools, skills, refs, loop, constraints per node; there is no shared schema to hand-write. Agent names must resolve to a real file in the active kit's agents directory — validation fails otherwise.

Verification is the field's #1 unmet demand — a partial answer today, not a claim it's solved. Users want a separate verifier; a model must not certify its own work (langgraph #7209; antfarm README). gk's answer is two existing primitives — the adversarial-verification topology (produce → refute → adjudicate) and the evidence gate's required_keys (a node only passes if it produced what its graph declared). That is a partial answer: there is no first-class recompute/verify-gate primitive, and no runtime telemetry. Verification is a direction gk has started, not a solved claim.

Host-native = subscription-safe. gk rides each host's supported first-party harness — Claude Code Workflow / native subagents, Cursor, OpenCode, Codex, or Pi — instead of a third-party orchestration layer — the exact harnesses Anthropic keeps first-class in the subscription, unlike third-party bridges now billed extra (The Verge; TechCrunch). No runtime tax: gk ships no Python/TS runtime, no dependency graph.

Roadmap — Next Up

Five consolidated candidates, cross-validated by four parallel research passes (competitive scan, user-pain mining, repo-internal deferrals, adjacent-standards bridges). Ranked by value × fit with the compiler thesis ÷ effort. S1 checkpoint resume shipped in 0.3.5 — gk run resume replays the ledger, derives a pending-only graph, and starts a provenance-linked child run.

S1 · SHIPPED 0.3.5
gk run resume — checkpoint replay ✓

Reconciles .graphkit/runs/<id>/ against the recorded graph (passed + evidence-on-disk), derives a pending-only session graph where satisfied evidence becomes refs, validates it against the compiler's structural rules, and starts a child run carrying resumes: provenance. Drift-guarded by sha256.

S2 · TABLE-STAKES
Human-approval wave gate

approval: wave pauses dispatch before write-capable waves via host-native permission hooks — the production make-or-break primitive (OpenAI needs_approval, Mastra suspend(), Flowise human-input node). Implementable wholly in compiler + host skills.

S3 · BRIDGE
OTel export — gk run export --otlp

Serialize run ledgers into OpenTelemetry GenAI-convention spans — waves, nodes, advisor events, durations — ingestible by Datadog/Jaeger/Langfuse. Fills the admitted "no runtime telemetry" gap with a pure compiler-side bridge, zero daemon (the CBM play, repeated).

M1 · RELIABILITY STORY
gk bench — golden-run harness

N runs of a graph; evidence-gate pass-rate and cost matrix per per-node model tier, diffed against a golden baseline run. The deterministic "which tier passes at what cost" answer competitors' eval harnesses approximate with LLM judges.

M2 · OWN BACKLOG
CBM retrieval routing + shaping

Route intents to search_graph/trace_path/query_graph, thread result limits, unify the four bespoke subcommand bodies — idea-backlog calls it the "largest single lever"; program.md scores retrieval accuracy as 96.5% of the remaining gap.

M3 · SAFETY STORY
gk lint — static cost estimation

Compile-time estimate: nodes × loop rounds × fan-out breadth × tier pricing, calibrated by ledger duration_ms; warnings for unbounded patterns. Budgets-as-blast-radius made checkable before anything runs.

Parking lot from the same consolidation: typed seam contracts on edges (JSON-Schema evidence validation), worktree snapshots for atomic replay, advisor tier-swap escalation (spec'd non-goal), gk graph history ledger join, deterministic predicate routing, MCP-registry tool resolution.