English · 简体中文
Add To Your Repository · Quick Start · How To Use It · Shared Truth · Advanced Usage
specFlow makes AI-assisted development feel like engineering again: instead of letting requirements dissolve into chat logs, code diffs, and personal memory, it gives every module a current truth, a next truth, and a clear path from idea to verified change. Humans and agents can move fast together while the repository still knows what is true, what is changing, and what is ready to ship. It is not a rigid template, but a strong working skeleton you can adapt and sharpen for your own domain.
When the code moves fast, truth has to move slower.
Many AI-assisted projects eventually hit the same problems:
- the real requirement only exists in chat history
- different people understand the same feature differently
- code changed, but nobody can clearly say whether behavior is still correct
- each person or agent uses a different working style, so the process becomes hard to trust
specFlow solves that by making one thing explicit:
- the behavior source of truth should live in files
Then it adds a small command set around that truth, so design, planning, implementation, verification, and promotion do not drift apart.
Runtime-driven. Module-shaped. Spec-first.
specFlow is not a standalone runtime.
It is a governance layer that works together with an agentic runtime, such as:
CodexGemini CLIClaude Code
In plain language:
specFlowprovides the working rules- the runtime reads those rules and executes the work
specFlow is also module-oriented.
That means:
- the basic working target is a formal
module - Specs, planning, implementation, verification, and promotion are normally organized per module
Learn the shortest path first. Expand later.
If you are new, do not try to understand the whole system first.
Read in this order:
Add To Your RepositoryQuick StartHow You Actually Use ItThe Core ModelThe 3-Minute FlowWhen You Need Manual Control, only when you actually need it
That is enough to start using specFlow.
If later you want to understand how to customize the rules or use the deeper governance features, jump to Advanced Usage.
First place
specflow/in your repository. Then runinit.
For most teams, the default setup is enough:
- clone this repository somewhere else
- copy only the
specflow/directory into your project root - run
init
Shell example:
git clone https://github.com/Bingordinary/SpecFlow.git /tmp/SpecFlow
cp -R /tmp/SpecFlow/specflow ./specflowWindows PowerShell example:
git clone https://github.com/Bingordinary/SpecFlow.git $env:TEMP\SpecFlow
Copy-Item -Recurse -Force $env:TEMP\SpecFlow\specflow .\specflowIf you need a long-term upstream sync workflow, treat that as advanced maintenance and see tooling/README.md plus the repository history strategy you prefer.
Bootstrap the files, then let the runtime follow the flow.
After the specflow/ directory is in your repository, run this from the repository root:
<specflow-binary> initFor all command examples below, <specflow-binary> means the compiled executable that matches your platform under specflow/tooling/bin/.
See tooling/README.md for the exact filenames.
This installs the basic structure you need:
AGENTS.md,GEMINI.md,CLAUDE.mddocs/specs/- including module Specs, appendix files, and process-state files
.githooks/pre-commit- supporting files used by the workflow
One clarification:
initcreates the hook file under.githooks/pre-commit- Git will not automatically use that folder unless
core.hooksPathpoints to.githooks
If you want Git to actually use the installed hook, run:
git config core.hooksPath .githooksFrom this point on, a beginner usually does not need to start by memorizing commands.
If your runtime reads the installed instruction files, the normal day-one experience can be natural language:
- "Add rate limiting to the auth module."
- "This checkout behavior changed. Update the truth first, then implement it."
- "Check whether current code still matches the accepted truth."
The runtime should route that intent into the correct internal specFlow flow.
After init, you normally use specFlow in one of two ways:
- say what you want in natural language
- let the runtime route it into the right
specFlowstep - when you want exact control, use the matching command yourself
What makes this spec-driven is simple:
- the current accepted truth of one module lives in
docs/specs/modules/stable/s_{module}.md - the next truth being prepared lives in
docs/specs/modules/candidate/c_{module}.md
The main document you write is that module Spec file.
A formal module Spec should cover at least:
- module goal and boundary
- key terminology
- data structures and protocols
- state machine and main flow
- edge cases and error handling
- verifiability and acceptance criteria
If the module depends on shared truth or global constraints, the Spec also needs to record that alignment explicitly.
Read the three cases below as one rough story about the same module over time. This is intentionally simplified. The point is to show the lifecycle shape, not every exact rule.
flowchart LR
A["A. first version"] --> B["B. next version"]
B --> C["C. later alignment check"]
How to read this:
A. first versionis when the module is created for the first time.B. next versionis when that same module changes later.C. later alignment checkis when you want confidence that current code still matches the accepted truth.
One note before the story:
- if the module already existed before
specFlow, usespec_init:{module}once to capture its current accepted behavior as the first governedstable - after that, the module behaves like the story below
What you say:
- "Create a new module for search."
If you want exact control:
spec_new:module_search
-> write docs/specs/modules/candidate/c_module_search.md
-> cand_check:module_search
-> cand_plan:module_search
-> cand_impl:module_search
-> cand_verify:module_search
-> cand_promote:module_search
What those commands are doing:
spec_newcreates the firstcandidatefor the new module- then you or the runtime write the actual candidate content into
c_module_search.md cand_checkmakes sure that written candidate truth is closed enough to guide workcand_planturns that truth into an implementation plancand_implwrites code against that candidatecand_verifychecks whether the code matches the candidatecand_promoteturns the accepted candidate into the newstable
When you write the document content:
- right after
spec_new, the file exists but it still needs real content - this is where you write the first candidate design in
c_module_search.md - the minimum useful content is:
- what the module is for
- what inputs and outputs it owns
- what the main flow is
- what edge cases matter
- how you will know the result is correct
- only after that does
cand_checkhave something real to judge - if
cand_checksays the candidate is still incomplete, you keep editing the same candidate file until it is closed enough
What specFlow adds here:
- the new module does not begin as "just some new code"
- the repository gets a written first version of the module's behavior before implementation drifts
- later agents can see what the module was supposed to do, not just what happened to get coded first
What you say:
- "Update search so typo correction runs before ranking."
If you want exact control:
spec_fork:module_search
-> edit docs/specs/modules/candidate/c_module_search.md
-> cand_check:module_search
-> cand_plan:module_search
-> cand_impl:module_search
-> cand_verify:module_search
-> cand_promote:module_search
What those commands are doing:
spec_forkopens a newcandidatefrom the currentstable- then you or the runtime edit
c_module_search.mdto describe the next version cand_checkconfirms that edited next truth is clear enoughcand_plan,cand_impl, andcand_verifymove that next truth into code and verify itcand_promotemakes the next truth become the new acceptedstable
When you write the document content:
spec_forkgives you a starting point by deriving the candidate from the current stable truth- then you edit the candidate file to describe what changes in this round
- this is where you update things such as:
- changed protocol or field meaning
- changed main flow
- new validation or error behavior
- new acceptance criteria
cand_checkis the point where the system asks "is this updated candidate written clearly enough to drive the implementation round"- if the answer is no, you go back to the same candidate file and keep refining it
What specFlow adds here:
- it separates current accepted behavior from next behavior being prepared
- the repository does not have to guess after the fact whether the code change was a bug fix, a behavior change, or an unfinished idea
- another agent can read the current truth and the next truth directly instead of reconstructing intent from diffs and chat logs
What you say:
- "Check whether the search module still matches the accepted truth."
If you want exact control:
read docs/specs/modules/stable/s_module_search.md
-> stable_verify:module_search
If drift exists and you want to start the next change round:
spec_fork:module_search
-> edit docs/specs/modules/candidate/c_module_search.md
-> cand_check:module_search
What that command is doing:
- it checks the current implementation against the current accepted
stable - it does not start a new candidate round just because you asked for verification
- if drift exists, that drift must be handled before anyone claims stable alignment
What specFlow adds here:
- verification becomes an explicit repository action, not only a conversational judgment
- the project gets a clear answer to "still aligned" versus "drift exists"
- that makes it easier to trust the result later, especially when a different person or a different agent revisits the module
The beginner takeaway is simple:
- first version of a new module:
spec_new+ candidate chain - next version of an existing governed module:
spec_fork+ candidate chain - later alignment check:
stable_verify - historical module entering governance for the first time:
spec_init
You can still start in natural language. These command names are the exact handles behind that lifecycle.
One accepted truth. One next truth.
There are only two core states a beginner needs first:
stable: the behavior that the project currently treats as truecandidate: the next version of behavior that is being prepared
flowchart LR
A["A. stable"] --> B["B. open candidate"]
B --> C["C. candidate"]
C --> D["D. implement and verify"]
D --> E["E. promote"]
E --> A
How to read this:
A. stableis the currently accepted version.C. candidateis the next version being shaped.D. implement and verifyhappens around the candidate.E. promoteturns the accepted candidate into the new stable.
Learn the work pattern first. Learn the command names later.
If you only want the shortest useful model, remember this sequence:
- write or update the behavior truth
- make sure that truth is clear enough to guide work
- implement against that truth
- verify the code against that truth
- promote the verified next truth into the accepted version
flowchart LR
A["A. write truth"] --> B["B. close the truth enough to work"]
B --> C["C. implement"]
C --> D["D. verify"]
D --> E["E. promote"]
How to read this:
A. write truthmeans the behavior should become explicit in files first.B. close the truth enough to workmeans the repository should not rely on chat memory for key decisions.C. implementandD. verifyhappen against that written truth.E. promotemakes the accepted next version become the current baseline.
This is what specFlow is trying to protect.
The command system exists to make this sequence explicit and reviewable. But for a beginner, the sequence matters more than the exact command names.
Manual control matters only when:
- you want to drive the exact step yourself
- the runtime did not route your request the way you expected
- you are debugging governance state for a module
Most manual control starts from just three entry decisions:
| Situation | Use this command |
|---|---|
| bring an existing historical module into governance for the first time | spec_init:{module} |
| start a brand-new module | spec_new:{module} |
change a module that already has governed stable truth |
spec_fork:{module} |
After that, the normal candidate chain is:
cand_check -> cand_plan -> cand_impl -> cand_verify -> cand_promote
There is also one stable-side maintenance step:
stable_verify
Use stable_verify:{module} only when the module is currently on stable, but you need to check whether the code still matches that accepted truth.
If you want one compact picture:
flowchart LR
A["A. spec_init or spec_new or spec_fork"] --> B["B. cand_check"]
B --> C["C. cand_plan"]
C --> D["D. cand_impl"]
D --> E["E. cand_verify"]
E --> F["F. cand_promote"]
This is the explicit control surface. You only need it when natural-language routing is not enough.
docs/specs/_status.md is the project state index.
You normally look at it only when one of these is true:
- the project has many modules
- you are not sure which layer one module is currently on
- you want to know the default next step for that module
flowchart LR
A["A. not sure where one module currently stands"] --> B["B. read docs/specs/_status.md"]
B --> C["C. find Active Layer"]
C --> D["D. find Next Command"]
How to read this:
B. read docs/specs/_status.mdtells you the current recorded state.C. find Active Layertells you whether the module is currently onstableorcandidate.D. find Next Commandtells you the default next legal step.
In normal use, _status.md is for reading state, not for manual scratch edits.
Most work should stay module-local for as long as possible.
There are three different places truth can live:
- the module main spec
- the module appendix
- cross-module shared truth
flowchart LR
A["A. module main spec"] --> B["B. module appendix"]
B --> C["C. shared natural-language intent"]
C --> D["D. shared_ops request"]
How to read this:
A. module main specis the main home for one module's behavior.B. module appendixis still one module's truth, just expanded out of the main file.D. shared_ops requestis where you enter when the truth is no longer only about one module.
Use this rule:
- first appearance stays in the current module
- do not extract something into shared just because it may be reused later
- move into shared only when multiple modules really depend on the same truth
shared_ops:{natural-language request} is the only user-facing entry for shared governance.
Use it when you want to:
- design shared truth from the start
- extract already-written module truth into a shared contract
- bind a module to an existing shared contract
- change shared topology such as split, merge, rename, or retire
- check which modules are affected after a shared-contract change
The important idea is simple:
- you describe the shared intent
- the runtime chooses the internal shared flow
- if the route is unsafe or ambiguous, it must stop at a checkpoint instead of guessing
Once basic usage makes sense, this is the section that helps you understand the whole system and adapt it to your own project.
The advanced part is mainly about four things:
- understanding the document structure
- knowing which files you should customize
- adding project-local standards
- knowing which governance flows exist beyond the standard module commands
At a high level, the repository splits into four layers:
flowchart TD
A["A. tooling"] --> B["B. bootstrap and maintenance"]
C["C. templates root"] --> D["D. files installed into the host project"]
E["E. framework docs"] --> F["F. baseline governance rules and command docs"]
G["G. host project docs and entry files"] --> H["H. your project-specific truth and standards"]
How to read this:
A. toolinginstalls, checks, and upgrades the paradigm.C. templates rootis the material copied into the target repository.E. framework docsis the baseline rule system ofspecFlowitself.G. host project docs and entry filesis where your project expresses its own truth and standards.
The safe beginner rule is:
- change project-owned files first
- change framework files only when you intentionally want to evolve the paradigm itself
Most teams mainly customize:
docs/specs/**docs/project_standards/**- the project-owned parts of
AGENTS.md,GEMINI.md, andCLAUDE.md
specFlow allows a project to add its own local standards on top of the framework baseline.
These standards live in:
docs/project_standards/docs/project_standards/_registry.md
One important rule:
- a standard file is not active just because it exists
- it becomes active only after it is registered in
_registry.md
In normal use, you usually do not need to build these files by hand. The simplest path is to ask the agent in plain language.
The tooling surface is useful, but it is not the first thing a beginner needs to learn.
The most common maintenance commands are:
initdoctorupgrade
See tooling/README.md for the full tooling surface.
Besides the standard module commands, specFlow also has advanced flows.
Two you should know exist are:
spec_flow_reviewshared_ops:{natural-language request}
Use spec_flow_review when you want to review the governance system itself rather than move one business module forward.
Its default scope now covers both the governance baseline documents and the governance tooling implementation under specflow/tooling/.
If you want to deeply understand or redesign the system, read in this order:
framework/docs/agent_guidelines/spec_policy.mdframework/docs/agent_guidelines/command_policy.mdframework/docs/agent_guidelines/git_policy.mdframework/docs/agent_guidelines/shared_ops.mdframework/docs/agent_guidelines/spec_flow_review.md- the command docs under
framework/docs/agent_guidelines/commands/ - the installed project-side files under
docs/
specFlow has two ownership modes:
frameworkspecFlowowns the file shapeupgrademay refresh it
project- your repository owns it after bootstrap
upgrademust not overwrite an existing project-owned file
This matters because specFlow is meant to be adapted, not to control the entire repository forever.
Files like AGENTS.md, GEMINI.md, and CLAUDE.md use a managed block model, so the host project can keep its own instructions outside the specFlow block.
specFlow is probably too heavy if:
- your project is very small
- your team does not want formal behavior truth in files
- you do not need
stableandcandidate - you do not need humans and AI to follow one shared operating model
