agent-spec: an intent compiler that turns requirements into verifiable task contracts
`agent-spec` is an AI-native BDD/spec verification tool for task execution.
At a glance
- What is it?
- agent-spec is a Rust CLI that compiles human intent into structured requirements, lowers them into Task Contracts under specs/, and mechanically verifies the implementation against those contracts. The interesting part is not the spec format; it is that every gate between intake and verification is deterministic and model-free.
- Who is it for?
- Adopt agent-spec if your team already writes requirements documents and wants a machine-checkable link between those clauses and the code an agent produces, and if you are willing to run the governance gates in CI. Do not adopt it if you want a tool that writes the spec for you: candidates are drafted by an agent and validated by the CLI, and the CLI never authors one, so an empty candidate list is a valid outcome that leaves the question free-form.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 17 days ago.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The problem: agents implement something, but nobody can prove it matches the request
The stated purpose is to compile human intent into verifiable Task Contracts and then mechanically verify the implementation against them. Intent arrives as PRDs, issues or conversations. Those are captured as structured requirements, which the project calls its intermediate representation. Requirements are then lowered into Task Contracts, which live as specs/*.spec.md files. Agents implement against the contract, and the machine checks whether the code satisfies it. The audience is teams already using coding agents on work that has a written specification behind it, where the failure mode is not a broken build but a build that passes while quietly implementing the wrong clause. The README frames the review loop as three steps: humans review the contract, agents implement against the contract, the machine verifies whether the code satisfies the contract. That is a narrower claim than general code review, and it is the claim the tooling is built around.
Two intermediate representations, kept deliberately separate
The architecture divides facts into Requirement IR and Code Graph IR. Requirement IR records what the system must do, and lives in accepted knowledge/requirements/*.md files as REQ-* clauses marked MUST, SHOULD or MAY. Code Graph IR records what the current program is, and is derived from language code-intelligence providers: the README names a Rust Atlas and an F1 adapter kit, with future F2 providers described as planned. The code graph is derived and rebuildable; accepted requirements remain the governed source of truth. An Intent-Code Linker binds REQ identifiers, work units and code symbols together, and requirements plan --gate validates the resulting REQ by work-unit by spec DAG with typed code bindings. This separation is the design decision that makes the rest coherent. If the code graph were authoritative, refactoring would silently rewrite the specification. Because it is derived, a stale graph is a rebuild problem rather than a governance problem. The README also notes that liveness is recomputed from verdicts and never stored, which avoids a second source of truth for the same fact.
Where the model is allowed to touch the pipeline
The README is explicit that AI participates only at the edges: drafting candidate requirements and implementing contracts. Every gate in between (lint-knowledge, graph, plan, lifecycle, trace) is deterministic and model-free. Human acceptance sits at both ends. Intake runs either through an agent-spec-intent-compiler skill, where an AI drafts Candidate Requirement Blocks and a human reviews and accepts them, or through agent-spec requirements import, which is deterministic and reads marked blocks or a YAML dialect. A Requirement Governance Gate moves items from proposed to accepted or rejected, and rejected items become historical and non-executable. This is a real constraint on what the tool can do. It will not resolve an ambiguous requirement by inference. It stops and asks. Three stages emit the same machine-readable envelope so an agent harness can render a choice rather than inventing a question: requirements questions for ambiguity found by a lint, knowledge questions <id> for a proposal's unresolved items or a decision's alternatives, and verify --emit-questions for scenarios the machine could not settle, with their evidence. Candidates are drafted by the agent and validated by the CLI, at most four, each with a label and a one-sentence description. The CLI never authors one, and an empty candidate list is a valid answer meaning the question stays free-form.
Getting it running: the commands the README names
The CLI is published on crates.io as agent-spec, and the README links docs.rs and a CI workflow at .github/workflows/contract-guard.yml. The artifact walk is documented as a single-direction flow: knowledge/proposals/ holds LEP-NNN entries asking whether to do something and why, producing ADR-NNN; knowledge/decisions/ holds the ADR ruling with alternatives; a governed requirement lands in knowledge/requirements/ as REQ-* with MUST clauses and scenarios; and specs/ holds task-* contracts that are executable and verifiable. The README states that knowledge/standards/operational/id-registry.md is the authority for which prefix lives where, and recommends scaffolding each artifact with agent-spec knowledge new <kind> <id> so the enum values, filename and exit pointer are correct the first time. Gate commands named in the material include lint-knowledge --gate, requirements graph --gate, requirements plan --gate, requirements work-units, requirements test-obligations, requirements worktrees, requirements questions, knowledge questions <id>, trace REQ-* --gate, verify --emit-questions, and agent-spec mcp, which is described as read-only knowledge serving. The lifecycle stage is listed as lint, then structural, then boundaries, then bound tests, with quality providers including clippy, rustfmt, deny and miri. I have not installed or run any of these; the list is what the README and the architecture diagram name.
The governance gate has teeth, but the orphan check is only a warning
lint-knowledge --gate enforces the artifact walk. A task contract with no satisfies: link raises orphan-spec at Warning severity. An ADR-* identifier placed under a requirement's Dependencies section raises dependency-kind-mismatch. An accepted proposal whose produced decision does not link back raises produces-link-integrity. The severity split matters when you wire this into CI: a warning does not fail a build by default, so a repository can accumulate task contracts with no traceable requirement unless the pipeline is configured to treat the warning as blocking. The README is candid about a migration cost here. The 1.3.0 migration used a shrink-only baseline for existing contracts, and that baseline is now retired and empty. Any non-empty .agent-spec/orphan-baseline.json is now an Error rather than an exemption. Teams that adopted before 1.3.0 and relied on the baseline to hold their orphan count steady will need to empty that file and fix the underlying links, not just the count. This is the sharpest upgrade edge visible in the supplied material.
Where agent-spec is the wrong tool
The pipeline assumes a specification exists or can be drafted and accepted. For exploratory work, throwaway scripts, or a codebase where the requirements live only in a maintainer's head, the intake stage has nothing to compile and the governance gate has nothing to accept. The refusal to let the model author requirements is a deliberate limit, and it means the tool cannot bootstrap a specification from code. It also means throughput is bounded by human review at two points: requirement acceptance on the way in and Contract Acceptance on the way out. A team that wants an agent to decide what the software should do will find the tool fighting them at every gate. The language coverage is another boundary. The README names Rust Atlas and an F1 adapter kit, with F2 providers described as future, so the code-intelligence side is not presented as language-neutral today. And the trace model has a specific property worth reading twice: when a human settles a scenario, the trace record carries the judgment's class and an evidence digest, never an identity, so approval binding stays with the external system that can actually attest it. If your compliance process expects agent-spec itself to record who approved what, it will not, by design.
How it differs from running a general test suite against agent output
The nearest conventional alternative is a plain test suite plus a linter: the agent writes code, tests exercise it, and a human reads the diff against the ticket. That approach verifies behavior, but it does not connect a specific requirement clause to the code that claims to satisfy it. agent-spec inserts a typed link at that point. Task Contracts carry satisfies: REQ-* along with Boundaries and Symbols, and requirements plan --gate validates the REQ by work-unit by spec DAG with typed code bindings. The trace step then classifies each requirement as honored, violated or unproven. The word unproven is the meaningful difference: a test suite that never exercises a clause looks the same as one that passes it, while a trace can report the clause as unproven. The cost is that you maintain the requirement artifacts, the contracts and the bindings. requirements test-obligations is described as spec-derived and code-independent, and requirements worktrees produces a parallel scheduling manifest, so the tooling does try to reduce the manual bookkeeping. But the artifacts are yours to keep current, and nothing in the supplied material suggests they regenerate themselves.
Licence and the maintenance surface you are taking on
The repository is MIT licensed, which permits commercial and closed-source use and modification provided the copyright notice and permission notice are retained. I am not a lawyer and this is not legal advice; check the LICENSE file in your own checkout. The maintenance cost visible in the material is not the Rust dependency tree, it is the artifact set. You are adopting knowledge/proposals/, knowledge/decisions/, knowledge/requirements/ and specs/ as directories that must stay internally consistent, with knowledge/standards/operational/id-registry.md as the authority for identifier prefixes. The release history shows three releases between July and August 2026: v1.1.0 on interop deepening, v1.2.0 on an evidence-aware Atlas, and v1.4.0 described as the enforcement release. The 1.3.0 migration retired the orphan baseline, which is the pattern to expect: each release can tighten a gate that previously tolerated drift. Budget for reading release notes before upgrading, and expect that a gate which passed on your current artifacts may fail on the next version. The agent-spec mcp server being read-only limits one class of risk, since an agent cannot use it to rewrite accepted requirements.
Editorial conclusion
Adopt agent-spec if your team already writes requirements documents and wants a machine-checkable link between those clauses and the code an agent produces, and if you are willing to run the governance gates in CI. Do not adopt it if you want a tool that writes the spec for you: candidates are drafted by an agent and validated by the CLI, and the CLI never authors one, so an empty candidate list is a valid outcome that leaves the question free-form. Before committing, verify three things in your own checkout: that lint-knowledge --gate passes on your existing knowledge/requirements files, that .agent-spec/orphan-baseline.json is empty or absent, and that your task contracts carry satisfies: links, because an orphan spec raises orphan-spec at Warning severity rather than blocking the build.
Community notes