Skip to content

Capability: spec-workflow

The core loop: a work item is specified as a chain of artifacts — optional brainstorm, then a Kiro-style 3-phase spec plus a testing plan — each iterated with the human feedback its approval gate records, locked by that gate, then executed end-to-end with minimal intervention.

What it is

The product-development-lifecycle workflow the-loop runs on every work item, exposed as the /the-loop:work-on superset command and granular per-step commands (brainstorm, new-requirement, create-ticket, create-design, create-tasks-plan, execute-tasks, finish-tasks, work-status).

Current behaviour

  • Every work item SHALL have a ticket; nothing is worked without one.
  • A work item's spec SHALL live in docs/specs/<id>/ — the loop's fixed convention; the CLI's own routing.graph.specDir defaults to it, and an operator whose instance drives repositories laid out differently sets that key or passes --spec-dir (issue-352) — as the artifact chain brainstorm.md (optional) → requirements.md|bugfix.md → design.md → testing-plan.md → tasks.md, plus evidence/ — the record each gate leaves, and the committed proof once verification has run.
  • Every tree of checked-in knowledge the loop maintains SHALL sit at its conventional place, not a configured one: specs at docs/specs/<id>/, capability docs at docs/capabilities/ and learnings at docs/learnings/ (the index learnings.md, one learning-<nnn>.md each, topics/), all repo-relative (issue-224, decision-082 placed the learnings inside the documentation tree; issue-352 removed the workflow keys that had let a project move the three). The learnings deliberately sit inside the documentation tree, so a repository that publishes docs/ publishes its learnings with it; the git-ignored write-gate queue (.the-loop/learnings-pending/) is harness state and stays out of it.
  • requirements.md and bugfix.md SHALL be two accepted names for the same phase-1 artifact, not two artifacts. Either clears the requirements-definition gate, held to the identical standard; both present blocks, because two phase-1 artifacts in one folder have no defined source of truth (decision-045). Both bundled templates carry the ## Requirements and ## Security considerations sections the gate requires, so the choice is about which shape fits the work — reproduction and root cause, or user stories — and never about which one will pass.
  • An artifact with an approval gate SHALL be iterated with the feedback that gate records and SHALL be locked by the gate itself (issue-281): on an authorized approval, lock-artifacts writes status: approved and the approver into the front matter. The session SHALL NOT set status: approved and SHALL NOT request an approval of its own — one gate, one human reply (the review per phase is always on and delivered by the gates; the workflow.requireHumanReviewPerPhase switch was removed in issue-352). An artifact with no gate (brainstorm.md, tasks.md) advances on shape alone. No downstream artifact is written against an upstream one whose gate has not yet approved it.
  • The spec chain SHALL live in the origin repository — the one the ticket was created in — however many repositories the work item touches, and each contributing repository SHALL get one pull request walking its own inner loop (issue-183, decision-069). A work item MAY declare those repositories with the-loop graph repos <id> --repository <owner>/<repo> … once the design and the task DAG say what the change spans, which records them in work-item-state.json and turns them into a gate at implementation rather than a note.
  • Where each artifact is iterated with humans SHALL be a durable, reviewable surface — never a terminal. For the outer loop the work item declares which, at phase-selection: the work item itself (the default — comments on the ticket, so an item whose code lands in other repositories opens no discussion-only PR) or a pull request in the origin repository (the outer-loop-on-pull-request box). Either way the artifact SHALL be a committed file linked from the ticket — the choice is the review surface, not whether the chain is checked in. A pull request's own loop SHALL always be iterated on that pull request, and a contribution SHALL NOT be asked the question at all (issue-199): it joins a work item somebody else is running, so its one artifact is iterated on that thread and its record carries no surface.
  • WHEN a work item starts as a fuzzy idea THEN the loop SHALL begin with a brainstorm.md root artifact (optional Phase 0) and convert it to requirements once its author says it has converged — the brainstorm has no approval gate and is never status: approved (issue-281).
  • The work item's phase SHALL be tracked on the ticket via labels (loop:<phase>, a fixed vocabulary since issue-352) through the state machine not-started → brainstorming (optional) → requirements-definition → design → test-planning → tasks-breakdown → implementation → verification → needs-review → complete, with the fine detail (current node, attempts, declared skips) in work-item-state.json.
  • tasks.md SHALL be a DAG of small verifiable tasks referencing requirements, each task's _Test:_ naming a row of testing-plan.md's matrix; checkmarks are kept current during implementation.
  • How the work item will be proved SHALL be planned, then executed as its own phase (testing-and-contracts, issue-163): test-planning authors testing-plan.md before the task DAG — and sits before design-approval, so one human gate approves and locks the design and the plan derived from it — and verification executes it after implementation and before the review chain, with results and committed evidence recorded in the same artifact. An activity that could not run is never ticked.
  • Security SHALL be a gated concern of each phase (a fixed rule, not a setting): requirements/bugfix carry a Security considerations threat-model-lite (untrusted actors, trust boundaries, abuse cases, fail-closed — "no new attack surface" is written and justified, never implied); design carries a Security design section enforcing every boundary; security-relevant tasks name the negative test proving the boundary holds.
  • Completion SHALL be gated by the ready-to-ship gate (green checks, threads resolved, evidence — summarised from the verification results, a passed security review — the built-in security-review skill when available, else the-loop's checklist — PR briefing, capability docs folded in) and the fixed risk tiers: tier 1–2 autonomous-complete, 3–4 human-approves-pr, 5 human-approves-spec-and-pr, inferred from the change (default 3) and raised by a fixed set of sensitive paths (schemas, .the-loop/**, .github/workflows/**, auth/secret/credential paths). An effective risk tier ≥ 4 SHALL wait for a named human security sign-off, and an unresolved security finding SHALL block completion at any tier. Tests are written alongside the implementation, always (a bug fix reproduces red first); there is no TDD mode to choose.
  • The loop SHALL read and honor the operator's custom instruction docs (config.customInstructions): every registered doc is read, in order, immediately after loading the config when work on an item starts (and re-read after a context clear). The structured config wins where both speak; no instruction doc can weaken the loop's gates (security, paper trail, reviews, autonomy) — such instructions are ignored and the conflict logged, fail-closed. A missing doc is handled per customInstructions.onMissing (default warn).
  • A registration SHALL be verifiable, not only honoured. WHEN the agent (or an operator) runs the-loop instructions --doc <entry>… --on-missing <policy> with the entries read from customInstructions (the CLI reads no harness config, issue-352) THEN the loop SHALL report every doc given, in the order given, with its resolved path and one of present / missing / unreadable / invalid; everything that is not present SHALL count as unresolved (invalid included), and --on-missing SHALL decide the exit code — error → 1, warn → 0 with a warning naming each one, ignore → 0. IF no doc is given THEN the report SHALL be empty and the exit code 0, because registering nothing is not an error. The report SHALL carry facts about each doc and never its contents (cli, issue-132).
  • The loop SHALL manage its context window by checkpoint-then-reset (a fixed rule since issue-352, config.contextManagement before it): a reset (clear or compact) is always preceded by a checkpoint — tasks.md checkmarks current, WIP committed, the phase label in sync. No prose checkpoint is written: the next step is the first unticked task and the pointer is work-item-state.json's (issue-365).
  • WHEN the phase advances across a locked artifact (most importantly tasks-breakdown → implementation) THEN the loop SHALL clear and derive the next phase's work from the checked-in artifacts, not the conversation.
  • WHEN a task in the DAG completes THEN the loop SHALL checkpoint and compact; mid-task only compaction is permitted, never clearing. Headless sessions reset by ending at the boundary and resuming fresh from the state file and the checkmarks.
  • The phase state machine SHALL be executable, not only described. Each phase above is a node in the shipped process graph, with entry/exit hook chains that decide when it is complete and declared edges that route on those decisions (process-graph, issue-109). The prose in reference/workflow.md and the graph in cli/the_loop/graph/pdlc.yaml describe the same loop; the graph is the one that runs. the-loop check <id> reports where a work item actually stands against its checked-in artifacts, and --recompute derives that verdict from the artifacts alone rather than trusting stored state.
  • A work item may be delivered by several PRs. WHEN more than one PR delivers a work item (a spec PR then an implementation PR, a stacked series, a follow-up after review, one PR per repository) THEN the loop SHALL label each of them for routing and list all of them in evidence/pull-requests.md, and finish-tasks SHALL require every listed PR to be merged or closed before the work item is marked complete — one PR merging is not the work item ending (issue-101).

Design

reference/workflow.md · reference/context.md · reference/instructions.md · reference/security.md · SKILL.md · architecture § the loop

History

Work itemWhat changedLinks
issue-368The work item's spec directory carries its pull requests (2026-09-15): work-item-state.json gained pullRequests[] — ref, repository, number, URL, inner-loop directory, upstream state and who recorded it — so a reviewer reads which pull requests deliver the item from the branch, and a second machine does not re-derive them from gh. It lost the session block in the same change: a harness conversation id is a handle to one machine and never belonged in a repositoryspec, decision-128, process-graph, issue
issue-365 (review)The multi-repo declaration moved off artifacts (2026-09-14) and onto a verb the agent calls, the-loop graph repos, writing work-item-state.json. It cannot be a phase-selection question: that gate runs before requirements, design and tasks exist, and which repositories a change spans is not knowable until they do — so it is declared at tasks-breakdown, bounded by shape and by the instance's own repositories, with the flags as the full set so a declaration can be corrected. The state file was renamed in the same roundspec, decision-127, process-graph, issue
issue-365The execution log was retired (2026-09-14): no template, no scaffolding, no log-entry hook at 47 node boundaries, no phase mirror and no prose checkpoint before a context reset — every fact in it was already in work-item-state.json, the loop:<phase> label, the commits and the harness's own transcript. What the log gated stayed: each review-chain node now reads one record of its own under evidence/, and the multi-repo repos declaration moved to work-item-state.json, declared by the agent once the task DAG exists. Existing logs are left where they are — history, read by nothingspec, decision-126, process-graph, issue
issue-352The harness config became the agent's alone (2026-09-12): ticketing, workflow.phases, workflow.phaseLabelPrefix, workflow.specApproach, workflow.requireHumanReviewPerPhase, localOrchestration, notifications, reviews.critics and graph left it (version 0.3.0); labels are loop:<phase>; the-loop instructions and the-loop scenarios take the registered docs and globs as flags the agent passes; the skill's Configuration section tells the harness what the file is for and what to hand the CLI. Nine more blocks left because they configured what is now the-loop's fixed rule: autonomy (tiers 1–2 autonomous-complete, 3–4 human-approves-pr, 5 human-approves-spec-and-pr, inferred from the change, fixed sensitive paths), security (considerations in every requirements, design enforces the boundaries, a security review at the ready-to-ship gate, tier 4+ human sign-off), tdd (standard, always), minimalism, tokenEconomy, selfImprovement (learnings always on, index under 200 lines, written at the third occurrence), contextManagement (clear at a phase boundary, compact after each task, never mid-task), userInteraction and externalTools. A fourth pass removed workflow (specDir, capabilitiesDir, learningsDir): docs/specs/<id>/, docs/capabilities/ and docs/learnings/ are the loop's convention, and an instance laid out differently sets the CLI's routing.graph.specDirspec, decision-123, issue
issue-281Approvals became gate-owned (2026-08-25): every artifact phase had been costing the human two approvals — one out-of-band to let the session set status: approved (demanded by locked: true on the producing node's exit), one at the graph's approval node, which discards pre-gate feedback — and tasks-breakdown demanded one with no gate at all. Producing nodes now gate shape only; a new lock-artifacts hook on requirements-approval, design-approval and the contribution loop's plan-approval writes status: approved plus the approvers as part of classifying the human's one reply; gate-less artifacts (brainstorm.md, tasks.md) advance with no human stop; and the skills/commands stopped re-implementing approvals in prosespec, process-graph, issue
issue-224The learnings tree moved under the documentation tree: docs/learnings instead of a hardcoded top-level learnings/, with the-loop's own tree moved there and the upgrade command presenting (never taking) the relocation (the workflow.learningsDir key this introduced left the harness config in issue-352; the location is now the convention)spec, decision-082, issue
issue-183The chain got a place: it lives in the repository the ticket was created in, one PR per contributing repository delivers it, and each work item declares at phase-selection whether the outer loop's artifacts are iterated on that repository's PR or on the work item itself (the default) — the inner loop deliberately not configurable. execution-log.md gained an optional repos: declaration that await-inner-loops gates onspec, decision-069, process-graph, issue
issue-163The chain gained testing-plan.md between design and tasks, and the state machine gained the test-planning and verification phases — how a work item is proved is now planned, gated and evidenced rather than assumedspec, decision-060, testing-and-contracts, issue
issue-124A bug's bugfix.md clears the phase-1 gate it always should have: the two documented names became alternatives for one artifact, both present blocks, and the bundled bugfix template gained the ## Requirements heading the gate asks forspec, decision-045, process-graph, issue
issue-109The phase state machine became executable: every phase is a node in the shipped process graph, with hook chains deciding completion and declared edges routing on the outcomespec, process-graph, decision-041, issue
issue-101The execution log tracks a list of the PRs delivering a work item; each is labelled for routing and all must be merged/closed before finish-tasks completes the itemspec, decision-039, issue
issue-132Custom instruction docs became verifiable: the-loop instructions reports which registered docs resolve and turns onMissing into an exit code, so a mistyped path is a signal rather than silencespec, decision-049, cli, issue
issue-59Added per-installation custom instruction docs the loop reads and honors (customInstructions config, onboarding group, precedence rules)spec, decision-029
issue-48Added checkpoint-then-reset context-window management (clear at phase boundaries, compact at task boundaries, contextManagement config)spec, decision-027
issue-47Security became a gated concern of every phase: threat-model-lite in requirements, Security design section, security-review gate item, risk-tiered human sign-off (config.security)spec, decision-026
issue-25Added the capability-docs fold-in as a ready-to-ship gate itemspec, decision-020
issue-18Design phase gained first-class UI/UX design artifactsspec, decision-018
issue-17Added the optional brainstorming phase and the iterate-until-locked rule as a first-class principlespec, decision-017
issue-1Established the 3-phase Kiro-style spec workflow, phase labels, granular commands and templates (v0)spec, decision-004, decision-011

Released under the MIT License.