Interview mode for human nodes (mode: interview). Runtimes extract questions from upstream agent output and present each as an individual form field with optional suggested answers. New fields: questions_key, answers_key.
DIP127: lint warning for invalid human node mode values.
DIP128: lint warning when interview mode has a meaningless default value.
DIP129: lint warning when interview mode has conflicting choice-style labeled edges.
Integration guide updated with interview mode implementation guidance and recommended answer JSON schema.
api_design.dip example updated to use interview mode for Q&A collection.
interview_loop.dip example: reusable interview subgraph with iterative Q&A. Parameterized by topic and focus areas. LLM generates questions with suggested options, human answers via interview mode, assessor loops until requirements are clear. Grade A, ~$0.92/run.
3 blog posts: Multi-line Prompts Without Escaping (deep dive), Conditional Edges (tutorial), Cost Estimation (tutorial). Hub-and-spokes model with cross-links.
Auto-deploy: CI now deploys site/ to GitHub Pages on successful main builds.
Fixed
--version / -version flags now work (previously failed with "flag provided but not defined").
Formatter idempotency: subgraph param values with quotes (e.g., "API design") were double-quoted on each format pass. Parser now strips surrounding quotes from param values.
code_health_check.dip example: self-contained pipeline that audits a Go repo. Gathers context with shell tools, runs vet/staticcheck/tests in parallel, three-model independent review, synthesized report with quality gate and retry loop. 5 test scenarios. Grade A, ~$1/run.
Single-source nav: site/_layout/nav.html is the one source of truth. scripts/sync-nav.sh propagates it to all 16 pages with correct prefixes and active states. Pre-commit hook runs it automatically. No more editing nav in 16 files.
scripts/gen-changelog-html.sh emits a placeholder nav that sync-nav.sh fills.
just install and just build now inject commit hash and build timestamp via ldflags. dippin version shows dev (commit: abc1234, built: 2026-03-27T18:45:10Z) instead of dev (commit: none, built: unknown).
Two-tier navigation across all site pages. Top row: Docs, Playground, Blog, GitHub. Bottom row: CLI, Language, Testing, Validation, Analysis, Architecture, Editors, Changelog. Mobile collapses to hamburger with divider-separated groups.
Fixed
Mobile nav menu no longer renders as unstyled text on desktop (missing display: none).
Blog index only shows the 5 published posts — removed 20 dead links to unwritten articles.
Playground content no longer overlaps the nav bar (padding adjusted for two-tier height).
Playground now has the floating dots background matching all other pages.
Homepage "See all 25 posts" corrected to "All posts".
Blog section with 25 planned post cards and topic filtering (Guides, Tutorials, Deep Dives, Reference).
5 blog posts published: Getting Started, Scenario Testing, Migrating from DOT, CI Integration, Editor Setup. Edited for voice, clarity, and inline links.
Homepage "From the Blog" section featuring 3 latest posts below the fold.
SEO meta tags on all 12 site pages: Open Graph, Twitter Cards, descriptions, canonical URLs. Pages render rich previews when shared.
Blog ideas doc (docs/blog-ideas.md) with 25 post synopses, coverage plans, and approach notes.
DIP126 lint rule: subgraph ref: file validation — warns when referenced workflow file does not exist on disk.
dippin watch command: file watcher that re-runs lint on .dip changes with 200ms debounce. Uses fsnotify.
dippin test --coverage flag: edge coverage summary showing which workflow edges were/weren't traversed by test scenarios.
Tree-sitter grammar scaffolding in editors/tree-sitter-dippin/ — grammar.js, external scanner for indentation, highlight queries, and test corpus. Enables proper syntax highlighting in Neovim, Helix, and Zed.
WASM playground at site/playground.html — browser-based editor with live parse, lint, and format via WebAssembly. Build with just wasm.
gemini-3.1-pro-preview-customtools added to model catalog and pricing tables.
35 diagnostic codes total (was 34).
Fixed
CI failures: golangci-lint errcheck on f.Close(), funlen on buildLintExplanations (split into 4 functions), misspell false positive in DIP118 example.
Migration parity: consensus_task_parity.dip and semport_thematic.dip model names now match DOT originals (gemini-3.1-pro-preview-customtools).
Changed
validator/lint_tool_cmd.go split with //go:build !wasm / wasm tags — bash -n syntax check and exec.LookPath binary check are no-ops in WASM.
validator/lint_subgraph.go similarly gated for WASM (no os.Stat).
Site mobile CSS improvements: table overflow handling, code word-break, install-cmd sizing.
Site nav updated with Playground link across all pages.
Documentation
All references updated from 34→35 codes, DIP101–DIP125→DIP101–DIP126 across README, CLAUDE.md, docs/, and site/.
docs/validation.md — full entry for DIP126.
docs/cli.md — watch command section, test --coverage flag.
preferred_label now works on human gates — scenario key preferred_label (or per-node Gate.preferred_label) matches against edge labels (case-insensitive substring). Previously silently ignored on freeform gates.
prompt: blocks now parse on human nodes — HumanConfig gained a Prompt field. Multiline prompt blocks work the same as on agent nodes. Formatter round-trips correctly.
Tool auto-defaults no longer mask fallback edges — empty-string scenario values ("Node.tool_stdout": "") now suppress the auto-seeded success default, allowing unconditional fallback edges to fire.
Added
immediately_after test assertion — assert adjacency in the execution path: "immediately_after": {"NodeX": "NodeY"} checks that NodeY is the very next node after NodeX.
branch field for targeted parallel testing — "branch": ["WorkerA"] limits which parallel fan-out branches are simulated. Without it, all branches are walked (new default).
Simulator walks all parallel branches — parallel fan-out now visits all targets, not just the first. Matches real runtime behavior.
Example test suites — .test.json files for vulnerability_analyzer, consensus_task, code_quality_sweep, and sprint_exec (20 tests across 4 workflows).
Test coverage at 95.7% — up from 85.6%. Six packages at 100%.
just cover now excludes untestable files (main.go, cmd_lsp.go) from coverage reports.
Documentation
docs/testing.md — added Caveats section (not_visited fragility with loop-breaking), Clearing Defaults section (empty-string technique), immediately_after field documentation.
Graph truncation on pipelines with restart edges — buildAdjacency() included restart (back) edges, creating cycles that prevented Kahn's algorithm from assigning layers to downstream nodes. All nodes are now rendered. Affects both full and compact modes.
Simulator infinite loop on tool-gated loops — pipelines with when ctx.tool_stdout not contains all-done loops would spin to the 500-step limit. New MaxNodeVisits option forces the loop-exit edge after N visits. The test runner sets this to 3 by default.
Per-node scenario injection in dippin test — NodeName.key=value scenarios now work reliably because the loop-breaking fix allows the simulation to reach the target node.
Testrunner accepts empty/invalid schemas silently — LoadTestFile now rejects .test.json files with zero tests.
dippin test — scenario test runner for workflow assertions. Define .test.json files alongside .dip workflows with expected status, visited/not-visited nodes, and path ordering. Supports --verbose flag for path tracing and JSON output for CI integration.
New package:testrunner/ — loads .test.json suites, runs each case through the simulator with injected scenario values, checks assertions against results.
New doc:docs/testing.md — documents the .test.json format and test runner usage.
DIP121 lint rule: condition references variable not produced by source node's IO.Writes. Skips when writes are empty (advisory) or variable is a reserved runtime key (ctx.outcome, ctx.status, ctx.internal.*, graph.*, params.*).
DIP122 lint rule: condition tests value not declared in source tool's ToolConfig.Outputs. Only fires for tool nodes with explicitly declared outputs.
dippin explain <DIPxxx> — rich explanations for all 34 diagnostic codes. Shows trigger conditions, fix guidance, and example snippets. Supports text and JSON output.
dippin unused <file> — detects dead-branch nodes (reachable from start but no path to exit) and estimates wasted cost per run. Reuses coverage.Analyze() sink detection + cost.Analyze() for cost enrichment.
DIP101 suppressed for mixed routing — when a source node has both unconditional and conditional outgoing edges, the conditional branches are intentional routing. DIP101 no longer fires on their destinations. Covers all four reported patterns: compound inequality conditions, exhaustive set + fallback, mixed unconditional/conditional, and labeled fallback edges.
DIP101/DIP102 exhaustive detection now recognizes any complete partition — if all conditional edges from a node test the same variable with equality (2+ values), the conditions are treated as exhaustive. No longer limited to hardcoded {success, fail} pairs. Handles done/more_questions, tasks_remain/all_done, and any custom value set.