На этой странице
- Work a Change Spec-First
- Is this your skill?
- The procedure
- 1. Open the change
- 2. Find the document, do not invent one
- 3. Draft the delta
- 4. Work it out
- 5. Submit, then STOP
- 6. When it comes back rejected
- 7. Only now, cut the tasks
- 8. Execute
- When the feature changes no documented behaviour
- What not to do when the gate refuses you
- Checklist
spec-first-change
Use when the project has spec_first on and a change has to be worked out before any task exists — triggers on "plan a feature", "decompose this", "разбей на задачи", "заведи фичу" in a spec-first project, on the refusal spec_first_not_appro
Work a Change Spec-First
The order of work is reversed here, and that is the whole point: the document is written and accepted first, tasks are cut from it afterwards. Not "write the spec early" — the server refuses to create a task or plan under a feature whose delta is not approved.
Prerequisites: flownix-basics, flownix-write-spec. The OpenSpec format, validate_spec
and the approval gate are owned by flownix-write-spec and are not repeated here: the format
used to sit in five skills, and the copy people read is always the one that drifted.
Is this your skill?
get_project_policy({ project_id })spec_first: false → this skill is not yours. Use plan-feature, which is unchanged for such
projects. spec_first: true → everything below, and plan-feature hands decomposition to you.
The mode only exists together with spec_mode: strict and require_proposal_approval — the
server refuses to enable it otherwise. So in a spec-first project you already know two more
things: a task closes only with an applied delta or a declared no-impact, and only a human
approves anything.
The procedure
1. Open the change
create_node with kind feature. Its content is the proposal: why, what changes, what
the boundaries are, and which alternatives you rejected and why.
Create nothing else. No plan, no tasks — the server refuses them, and reaching that refusal
wastes the user's turn instead of doing the work. Bind the feature to its components right here
(flownix-basics), and set ticket_ref if an external ticket was named.
2. Find the document, do not invent one
rag_query for the behaviour, then list_docs / get_node. Change the document that already
covers the area. A second document about the same subject is worse than a stale one: the reader
finds one of them and never learns the other exists. create_doc_node only when nothing covers
it — bound to at least one component.
3. Draft the delta
propose_doc_delta, with this feature as source_node. In a spec-first project the delta
is born review_status: draft.
A draft asks nobody anything. Do not tell the user their approval is pending — it is not, and you would both be waiting for each other. It is your working copy of the document until you decide it is ready.
body is the FULL new document body, exactly as flownix-write-spec requires.
4. Work it out
update_doc_delta with the full body, as many times as it takes. Format issues come back in
spec_issues and do not block the edit — a draft is written in passes, and a requirement
whose scenario is not written yet is a normal intermediate state. The format is enforced at
submit.
Record every rejected decision as a [decision] comment on the feature, with the reason it
was rejected. This is not bookkeeping: what a team threw away is more valuable than what it
kept, because the next agent will otherwise propose exactly that again. The delta's round
history keeps the bodies; the comments keep the reasoning.
If the human is editing the draft in the web UI at the same time, reread it (get_doc_delta)
before your next update_doc_delta — you replace the body wholesale.
5. Submit, then STOP
submit_doc_delta({ revision_id })From this moment the delta is in the review queue, it holds the gates, and it can no longer be edited in place.
Then stop. Name the delta and the document, say in one or two lines what it changes, say
plainly that it needs their approval in the web UI, and wait. You cannot approve it:
approve_doc_delta refuses every agent session.
Do not fill the wait with adjacent work nobody asked for. "While we wait, I'll…" is how a session ends up with changes the user never reviewed and did not want.
6. When it comes back rejected
Read review_note. Fix the same delta with update_doc_delta — it returns to draft and
the rejected body stays readable in the round history. Then submit_doc_delta again.
Do not propose a new delta. A new row breaks the thread: the whole point of the round history is that "what we discarded and why" reads as one story.
7. Only now, cut the tasks
review_status: approved → decompose. Plan and tasks under the feature, each task self-contained,
each bound to components, each with set_references to the document.
Cut them from the accepted document, not from what you had in mind in step 1. If the document ended up describing something different from your original idea, the document wins — that is what the human approved.
8. Execute
execute-task as usual. apply_doc_delta goes together with closing the work, not before it.
When the feature changes no documented behaviour
A refactor, a rename, a dependency bump. declare_no_spec_impact on the feature unblocks
decomposition, and it wants a sentence naming what changes and why no described behaviour moves.
Two things about it:
- It does not cascade down. Each task under the feature still answers for its own spec when it closes.
- It is not the cheap way out. It is available, quick, and looks legitimate, which is exactly why reaching for it when the change does touch described behaviour turns this whole mode into paperwork. If you cannot write that sentence honestly, the change affects the spec.
What not to do when the gate refuses you
The refusal is FailedPrecondition prefixed spec_first_not_approved. It names the feature,
the state of its deltas, and the two calls that lift it. None of the following is a way around
it, and each looks like progress:
- creating the task under the epic or the project instead, to sidestep the feature;
- moving a task under the feature afterwards —
move_nodeis gated identically; declare_no_spec_impacton a feature that does change described behaviour;set_project_policyto turnspec_firstoff. Changing the project's policy to get around the project's policy is the failure, not the workaround. If the mode is genuinely wrong for this work, that is a conversation to have with the user, not a call to make.
Checklist
-
get_project_policyread;spec_firstis actually on. - Feature created with the proposal in
content, bound to components. Nothing else created. - Existing document found, not a second one invented.
- Delta proposed from the feature; it is a
draft, and the user was not told it awaits them. - Rejected decisions recorded as
[decision]comments on the feature. -
submit_doc_deltacalled, the user told what waits for them, and work stopped. - After a rejection: the same delta reworked, not a new one.
- Tasks cut only after
approved, and cut from the document that was approved.