Tech
Spec Harness in Depth: Packaging Long-Horizon Development into Verifiable Task Packages
Machine-translated from the Chinese original. Corrections welcome.TMT
What AI coding agents lack is not bandwidth for writing code — it is memory. A task that spans several sessions accumulates half-finished plans, already-falsified approaches, and acceptance criteria that get lost in chat history; restart the terminal and the context resets to zero. Spec Harness targets exactly this: a task-package workflow tool for AI coding agents that persists long-horizon changes as a recoverable, verifiable Development Record, governed by scope, evidence, and Git gates. It provides no model and makes no product decisions for you.
Its worldview in one sentence: when a coding task outlives one conversation, the missing tool is not a smarter model — it is a contract that everyone (including your future self) can read.
1. The core abstraction: the task package
All work lives in a .spec/specs/YYYY-MM-DD_slug/ directory with two core files: spec.md records scope, assumptions, and trade-offs (including a remarkable “falsified paths” section, more on that below), while tasks.md holds the task list. After closeout the whole package is archived under .spec/specs/archive/ — the archive directory is the project’s engineering log.
Every task must carry a two-line contract: boundary (which files this task may touch) and verify (how completion is proven). The verify is a read-only assertion that must exit 0 before the checkbox goes on. A real example from this blog’s archived 2026-10-26_blog-5f package, task T3:
Boundary delimits “what may change”; verify delimits “how completion is proven” — both lines present, or the task stays unchecked. This is not formalism: with multiple agents running in parallel, boundary is the guardrail between lanes (in our practice, global style files are mainline-only; lanes request new variables instead of reaching in). Verify separates “looks done” from “proven done” — a verbal “passed” never counts.
The most interesting section of spec.md is falsified paths: rejected proposals go into the archive together with the reason for rejection. Our blog-5f package records three — hero banner treatment (rejected by visual adjudication), a green heatmap (broke the grayscale skeleton), and shrinking the title from 27px to 22px (a hierarchy anchor; reduce weight, not size). Whoever wants to try again reads the file first and saves a round of budget.
2. The stage pipeline: five core commands and the gates they keep
Five core commands form one verifiable chain: goal → scope → tasks → verification → archive → commit → push. Gates stand between stages: run refuses while spec.md still has template placeholders; done requires every task to have boundary/verify, a fully green acceptance surface, and at least one non-placeholder piece of evidence (script output, test results); push merges only spec/-prefixed integration branches, never combines file changes with a commit, and forbids --no-verify.
A blocked task gets a ! marker and surfaces to the user — never a silent skip. Actionable issues found during check must be written back into the package and fixed in the same round; “to-dos” are not deliverables.
Interruption recovery is a designed norm — the most direct answer to “tasks outlive conversations”: re-run /spec:run at any moment and it resumes from the checked state in tasks.md, depending on no chat memory. Going further, /spec:autoplan runs interactive planning (clarify the goal, then framework, detail, and review passes; it stops when planning is ready — no auto-start), and /spec:autorun executes package by package, capped at 5 auto rounds by default (--max-rounds adjustable), resuming from the same step after a pause; the one-shot entry /spec:goal runs planning, execution, review, archiving, and the commit in a single pass.
The command surface totals 12 stage commands: the core profile installs the five core commands, and full adds the seven extensions — goal / autoplan / autorun / update / status / doctor / organize — where doctor self-checks and repairs the environment and organize audits structure. One easily-missed detail: installing only lays down files; it never auto-evaluates every task. If you want it to proactively ask “should this get a package?” before you start, wire the activation hooks once with install_activation_hooks.py --mode on. The criterion is delivery shape — an independent acceptance surface, actual implementers, a recoverable in-flight task; small fixes, read-only investigations, and one-off experiments just get done. It guards against “forgot to evaluate”, not against deliberate under-reporting — the documentation is refreshingly candid about this.
3. Multi-agent orchestration: one orchestrator, bounded helpers
Spec Harness is deliberately conservative about multi-agent work: the main session is the single orchestrator — routing, integration, acceptance, and the done/push gates never leave the mainline. Sidecar work (exploration, building, reviewing — context-independent slices) may be delegated, but only after a machine route decision (scripts/route_decision.py) and a written assignment contract: goal, scope, excluded areas, output, and verification method, all five present. An optional handoff.md covers cross-session boundaries — a generative snapshot header plus an append-only entry log, with required sections that adapt to solo / multi-person / agent / cluster collaboration modes.
Extension slots plug other team processes in: team-loop for team cycles and workflow-runner for workflow fan-out, each with its README protocol and tests. The source repo also ships four orchestration agent definitions: orchestrator, planner, reviewer, confirmer.
4. Installation: one installer, a dozen-plus hosts
Spec Harness is a Python 3.9+ standard-library implementation (PolyForm Noncommercial license), installed in three steps:
git clone https://github.com/MicTx/spec-harness.git /tmp/spec-harness
cd /tmp/spec-harness
git checkout v0.22.2
bash install.sh
The installer supports a dozen-plus hosts: Claude Code, Codex, Gemini CLI, Grok, OpenCode, OpenClaw, Hermes, Pi, ZCode, DeepSeek Harness, Devin, Cursor… auto-detecting installed hosts when unspecified. Install profiles come in core / full: core ships the five core stage commands plus Git hooks; full adds all 12 stage commands and the slots/agents extensions. We use INSTALL_HOSTS=pi bash install.sh on Pi — the /spec commands work right after installation.
5. Running on a real blog
This blog is a user. The archive directory holds a chain of packages — from the bare-clone build rework and mobile layout fixes to the SEO unblocking: blog-5f packed eight tasks on three lanes (two mesh terminals plus the mainline) running in parallel, every task’s verify a command-line assertion, page tasks wired to E2E — E2E_BASE=http://127.0.0.1:18924 node tests/e2e.mjs, all 34 passing. Packages relayed one after another; nineteen green commits landed in a single day.
Tools iterate, but the idea does not expire: write “what to do” as a contract, write “done” as evidence, archive the process as a log. Whether the collaborators are humans or agents, those three things are the foundation of long-horizon engineering.
评论区加载失败。