Sections
On this page
- Two modes, one explicit choice
- Three policies, not three values of one field
- A feature in spec-first mode
- A task in strict mode
- Neither a patch nor a skip button
- The format: OpenSpec as the industry standard
- A ratchet: making it worse is forbidden, living with the old state is not
- OpenSpec entity mapping
- Exchanging the openspec/ directory
- MCP tools
- Who benefits from strict mode
- Next
Documentation that keeps pace with the code
Strict mode: a task closes only with an applied document revision or an explicit reason why none was needed.
Strict mode ties work completion to documentation. An agent cannot silently close a task: it must either apply a spec revision or record a meaningful reason why the spec was unaffected.
Two modes, one explicit choice
The mode is stored on the project and written to .flownix during initialization, so the agent knows the rule before its first status change. It can be switched from the web app or from an agent while a project is being connected.
Standard
Work closes through the normal workflow with no mandatory link to a specification.
Best for: Prototypes, personal projects, and teams with an external documentation process.
Strict
Closing a task or plan requires an applied doc delta or an explicit no-impact conclusion.
Best for: APIs, regulated products, and teams that treat documentation as a contract.
Spec-first
Strict mode plus the reverse order of work: no task can be created under a feature until a human accepts its document.
Best for: Teams that work a decision out before building it, rather than describing it afterwards.
Three policies, not three values of one field
There are three fields, and they answer different questions. They can be set independently, but spec_first only means anything together with the other two — the server refuses to enable it without them.
| Policy | The question it answers | What turning it on does |
|---|---|---|
spec_mode: strict | Must a task close with a spec? | done requires an applied delta or a declared no-impact. |
require_proposal_approval | Did a human look before work started? | An unapproved delta blocks in_progress and cannot be applied. |
spec_first | In what order does the work happen? | A delta is born a draft; no task is created under a feature until its document is approved. |
You switch them in the project header — a panel with three toggles. The panel knows about the
dependency between them: enabling spec_first sends all three settings in one request and says
beforehand what will be enabled along with it, and it will not let you remove a prerequisite while it
is on. Changing policies requires an organization admin.
A feature in spec-first mode
- The agent creates the feature — that is the change, and its
contentcarries the proposal. propose_doc_deltaproduces a draft: it stands in no review queue and asks nobody anything.- The agent and the human work the document out —
update_doc_deltawith the full body, as many times as it takes. Rejected decisions stay as comments on the feature. submit_doc_delta— and the agent stops. Now the delta is addressed to a human.- The human approves or rejects. On a rejection the same delta is reworked, and the rejected revision stays readable in the round history.
- Only after approval does the agent cut tasks — from the document that was accepted.
Creating a task earlier is refused with spec_first_not_approved. The refusal names the feature, the state of its deltas, and both ways out: drive the document to approval, or declare that no described behaviour changes.
A task in strict mode
- The agent reads
spec_modefrom.flownixand opens the current documentation. - It performs the work and decides whether a documented contract or behaviour changed.
- If it changed, the agent proposes the document's complete next state and applies the revision.
- If it did not, the agent records a concrete reason with
declare_no_spec_impact. - The server verifies the evidence before it accepts the
donestatus.
Neither a patch nor a skip button
The spec changed
A delta contains the complete document. That makes optimistic locking reliable, keeps history readable, and prevents apply from replacing preserved sections with a fragment.
The spec did not change
No-impact is an auditable conclusion with a meaningful reason, not an automatic gate bypass. The server rejects short placeholders.
The format: OpenSpec as the industry standard
A Flownix spec is not free-form Markdown. Documents are written in the OpenSpec format, an open standard for spec-driven development: an agent writes specs by the same rules in every project, the server can check their structure, and a project exchanges specs with the outside world without losing meaning.
# Auth
## Purpose
Authentication and session management.
## Requirements
### Requirement: Token issuance
The system SHALL issue a JWT upon successful login.
#### Scenario: Valid credentials
- GIVEN a user with valid credentials
- WHEN the user submits the login form
- THEN a JWT is returnedOne requirement is one observable behaviour with one RFC 2119 keyword (SHALL, MUST, SHOULD, MAY) in uppercase. Every requirement carries at least one scenario: a requirement nobody can check is a wish, not a contract. How it is built — the queue, the library, the table schema — belongs in the plan, not the spec.
The validate_spec tool checks a saved document by slug, or raw text saved nowhere yet, and answers with what to fix. It changes nothing, so you can call it before creating a node for the spec at all.
A ratchet: making it worse is forbidden, living with the old state is not
Strict mode holds the quality of a spec, not merely the fact that it was edited. The rule is single: a delta is rejected when it introduces issues the previous version of the document did not have. Issues inherited from the previous version come back as warnings and block nothing.
That is what keeps switching strict mode on from breaking an existing project. Every document written before it is free-form, and straight validation would mean no task in the project can be closed until somebody rewrites all the documentation by hand. Instead the format tightens through ordinary edits.
OpenSpec entity mapping
| OpenSpec | Flownix |
|---|---|
openspec/specs/<domain>/spec.md | doc node, spec_domain is the directory name |
### Requirement: / #### Scenario: | sections inside the doc node body |
delta spec (## ADDED/MODIFIED/REMOVED Requirements) | a doc_revisions row (full body) plus computed operations |
changes/<name>/proposal.md | a feature node |
changes/<name>/design.md | a plan node |
changes/<name>/tasks.md | task nodes under the plan |
openspec archive | apply_doc_delta plus closing the node |
openspec validate --strict | validate_spec plus the spec_mode=strict gate |
Exchanging the openspec/ directory
A project exports to an openspec/ tree and imports back from one — including a repository built by the OpenSpec tool itself.
export_openspecreturns a list of files:specs/<domain>/spec.mdper document,changes/<slug>/per open feature,changes/archive/<date>-<slug>/per closed one. The agent writes them to disk with its own tools — the MCP server runs over HTTP and never reaches your repository.import_openspectakes the same tree back. It is idempotent by document domain and by thechanges/<name>directory: importing an unchanged tree again creates no duplicates and proposes no empty deltas, so it is safe to call after everypull.
Reversibility is proven by a test rather than declared: import(export(project)) into an empty project reproduces the canonical render of every spec, the same branch composition and the same delta states.
MCP tools
Fourteen operations cover policy discovery and updates, the revision lifecycle including the draft, format checking, exchanging the openspec/ tree, and an honest no-impact path.
| Tool | Purpose |
|---|---|
get_project_policy | Read the project mode and its completion requirement. |
set_project_policy | Turn strict mode on or off — during project onboarding in flownix-init, for example. |
propose_doc_delta | Propose a document's complete next state from a task or plan. |
list_doc_deltas | Inspect proposed, applied, and discarded revisions; filter by review_status to find your own drafts. |
get_doc_delta | Read one revision in full, together with its review round history. |
update_doc_delta | Edit a draft or rejected revision in place — with the full document body. |
submit_doc_delta | Send a draft to review: the only draft → pending transition. |
apply_doc_delta | Apply a revision if the document version has not changed. |
approve_doc_delta / reject_doc_delta | The human decision on a proposal; refused from an agent session. |
discard_doc_delta | Discard a proposed revision while keeping it in history. |
declare_no_spec_impact | Explicitly explain why the work did not change documented behaviour. |
validate_spec | Check a spec against the format — by document slug or by raw body; changes nothing. |
export_openspec | Export the project as an openspec/ tree to write into the repository. |
import_openspec | Import an openspec/ tree back into the project; idempotent. |
Who benefits from strict mode
Contractual APIs
Response schemas and integration promises change in the same cycle as the implementation.
Multiple AI agents
The next agent receives the current specification instead of reconstructing intent from commits.
Audit and compliance
Every document change is linked to its source, version, reason, and application time.
Next
- Closing a task in strict mode — what is required on the way out
- Spec-first mode — the order of work when the document is accepted first
- The skill system — which skill leads the work under which policy