Files
Skills/docs/plans/2026-05-31-milestone-close-gate.md
T
Brummel 6723bd87dd docs: implementation plan for the milestone-close gate
Nine bite-sized tasks across eight files; pipeline.md as the single
source, fieldtester.md for the milestone carrier, then the referencing
skills and the vocabulary/profile layer, closing with a cross-file
verification sweep.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 12:13:24 +02:00

26 KiB

Milestone-close gate Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: Make audit unable to imply a milestone is finished — separate cycle (a pipeline round) from milestone (a tracker container closed only when complete ∧ functional), and add a milestone-wide fieldtest as the closing gate.

Architecture: Documentation/skill-file change across the plugin. The milestone-close gate is defined once in docs/pipeline.md; audit, fieldtest, boss reference it without restating it (single-source, matching the repo's recent carrier/handoff single-sourcing). The milestone fieldtest is a carrier-scope variant of the existing fieldtest skill — its carrier contract is extended in the authoritative agent file. The root conflation cycle ≡ milestone is corrected in README.md, templates/project-profile.yml, and docs/profile-schema.md.

Tech Stack: Markdown skill/agent files; YAML profile template. No code. "Tests" are grep assertions over file content and a YAML parse check — the observable verification this repo admits. Each task: a RED check that pins the current state, the edit(s), a GREEN check that confirms the new state, then a commit.

Spec: docs/specs/2026-05-31-milestone-close-gate-design.md

Scope note: The spec's edit list named seven files. This plan adds an eighth — fieldtest/agents/fieldtester.md — because the carrier contract the spec references (milestone_promise) lives there authoritatively; documenting the variant in fieldtest/SKILL.md without defining it in the agent file would be a dangling reference. Task 2 covers it.

Task order rationale: docs/pipeline.md first (it is the single source the others reference); then the fieldtester agent (single source of the carrier contract); then the referencing skills; then the vocabulary/profile layer; then a final cross-file verification sweep.


Task 1: docs/pipeline.md — the single-source gate definition

Files:

  • Modify: docs/pipeline.md (ASCII graph lines 10 & 15; new sections after the graph, before ## Phase descriptions)

  • Step 1: RED — confirm the conflated wording and the absence of the gate

Run:

cd ~/dev/skills
grep -n "\[cycle close\]\|--(clean)-+" docs/pipeline.md
grep -c "Milestone-close gate\|Cycle vs. milestone" docs/pipeline.md

Expected: the first grep prints the two ASCII lines ([cycle close] and --(clean)-+); the second prints 0 (neither new section exists yet).

  • Step 2: Relabel the cycle-close ASCII node

In docs/pipeline.md, replace:

       [cycle close]

with:

       [cycle close — a loop step, not a milestone close]
  • Step 3: Rename the audit clean edge to drift-clean

In docs/pipeline.md, replace:

                       --(clean)-+

with:

                       --(drift-clean)-+
  • Step 4: Add the two single-source sections

In docs/pipeline.md, immediately after the closing of the ASCII diagram (the line before ## Phase descriptions), insert:

## Cycle vs. milestone

These are two distinct axes, and conflating them is a bug.

- A **cycle** is one round in the pipeline graph above
  (`brainstorm → planner → implement → audit → [fieldtest]`).
  A cycle close is an internal loop step.
- A **milestone** is a tracker container (Gitea milestone,
  GitHub milestone, Linear project — whatever the project's
  tracker calls a long-running work scope). A milestone spans
  potentially many cycles and closes only when the work it
  promised is **complete and functional** (see the gate below).

`audit` runs at cycle close and proves *drift-clean* — the code
matches the design ledger. It is blind to whether the work is
*functional* from a downstream consumer's point of view; that is
what `fieldtest` measures. So no `audit` result closes a
milestone, and neither does a `/boss` done-state.

## Milestone-close gate

A milestone may be closed in the tracker only when **both** legs
hold:

1. **Complete** — every cycle filed under the milestone is
   `audit` drift-clean (or its drift explicitly ratified), and
   the milestone container has no open iterations / issues left.
2. **Functional** — the **milestone fieldtest** has run its
   curated end-to-end scenarios against the milestone's promise
   and its status roll-up is `clean`: every scenario
   demonstrably delivers what the milestone promised; no open
   `bug` findings; `friction` / `spec_gap` findings resolved or
   ratified into the design ledger.

The milestone fieldtest is the milestone-wide variant of the
`fieldtest` skill: the same fieldtester agent, a carrier scoped
to the milestone's promise rather than one cycle's surface. Its
scenarios are chosen top-down from what the milestone as a whole
promised, not assembled as the union of per-cycle axes.

A milestone whose entire scope is internal (no user-visible
surface) is exempt from the functional leg — the milestone
fieldtest is *not applicable* and the complete leg suffices.

This gate defines *when* a milestone is closeable. The actual
close stays a deliberate human / orchestrator act (`tea
milestone close`, or the tracker equivalent); no skill performs
it automatically.

  • Step 5: GREEN — confirm the rename and the new sections

Run:

cd ~/dev/skills
grep -n "a loop step, not a milestone close\|--(drift-clean)-+" docs/pipeline.md
grep -c "## Milestone-close gate" docs/pipeline.md
grep -c "## Cycle vs. milestone" docs/pipeline.md
grep -n "\-\-(clean)-+" docs/pipeline.md || echo "OK: no bare clean edge remains"

Expected: first grep prints both relabelled lines; the two grep -c print 1; the last prints OK: no bare clean edge remains.

  • Step 6: Commit
cd ~/dev/skills
git add docs/pipeline.md
git commit -m "docs(pipeline): single-source the milestone-close gate

Define the cycle/milestone distinction and the complete-and-functional
close gate once in pipeline.md; rename audit's cycle-close edge to
drift-clean so it no longer reads as a milestone close."

Task 2: fieldtest/agents/fieldtester.md — milestone-scope carrier variant

Files:

  • Modify: fieldtest/agents/fieldtester.md (Carrier contract section, after line 73)

  • Step 1: RED — confirm the carrier knows only the cycle scope

Run:

cd ~/dev/skills
grep -c "milestone_promise\|Milestone-scope variant" fieldtest/agents/fieldtester.md

Expected: 0 (no milestone carrier variant defined).

  • Step 2: Add the milestone-scope variant to the carrier contract

In fieldtest/agents/fieldtester.md, immediately after the line:

both are also empty, return `NEEDS_CONTEXT`.

(the last line of the empty-axis_hints fallback, before ## The Iron Law), insert:


### Milestone-scope variant

When dispatched as the **milestone fieldtest** — the closing
gate for a tracker milestone (see `../../docs/pipeline.md`
§ Milestone-close gate) — the carrier is scoped to the
milestone's promise rather than one cycle's surface:

| Field | Content |
|-------|---------|
| `milestone_id` | e.g. `milestone-7` |
| `milestone_promise` | the milestone's stated goal / acceptance from the tracker (and its spec, if one exists) — what the work as a whole promises to deliver |
| `commit_range` | `<milestone-start>..HEAD` |

In this mode, Phase 1 derives 2-4 **curated end-to-end
scenarios top-down from `milestone_promise`** — each scenario a
realistic downstream task that, run end to end, demonstrates the
milestone delivers what it promised. Do **not** assemble the
scenarios as the union of per-cycle axes; the per-cycle
fieldtests already covered axis-local surface. There is no
`axis_hints` fallback in this mode: if `milestone_promise` is
empty, infer it from the milestone's spec / tracker entry, and
if that is also empty, return `NEEDS_CONTEXT`.
  • Step 3: GREEN — confirm the variant exists and references the gate

Run:

cd ~/dev/skills
grep -n "### Milestone-scope variant" fieldtest/agents/fieldtester.md
grep -n "milestone_promise" fieldtest/agents/fieldtester.md
grep -n "docs/pipeline.md.*Milestone-close gate" fieldtest/agents/fieldtester.md

Expected: each grep prints at least one matching line.

  • Step 4: Commit
cd ~/dev/skills
git add fieldtest/agents/fieldtester.md
git commit -m "fieldtester: add milestone-scope carrier variant

Authoritative carrier contract for the milestone fieldtest: scoped to
milestone_promise, scenarios derived top-down rather than as a union of
per-cycle axes."

Task 3: fieldtest/SKILL.md — document the milestone fieldtest variant

Files:

  • Modify: fieldtest/SKILL.md (new section after the Overview ending at line 35, before ## When to Use / Skipping; Cross-references block)

  • Step 1: RED — confirm the skill documents only the per-cycle scope

Run:

cd ~/dev/skills
grep -c "milestone fieldtest\|Two scopes" fieldtest/SKILL.md

Expected: 0.

  • Step 2: Add a "Two scopes" section after the Overview

In fieldtest/SKILL.md, immediately before the line ## When to Use / Skipping, insert:

## Two scopes: per-cycle and milestone

`fieldtest` runs at two scopes, both using the same fieldtester
agent — the carrier picks the scope:

- **Per-cycle fieldtest** (the default this file otherwise
  describes): dispatched after a surface-touching cycle's audit,
  carrier scoped to that cycle (`cycle_id` / `cycle_scope`).
  Catches cycle-local friction early. Optional / orchestrator
  judgement, as below.
- **Milestone fieldtest**: the closing gate for a tracker
  milestone. Carrier scoped to the milestone's promise
  (`milestone_id` / `milestone_promise`); the fieldtester
  derives curated end-to-end scenarios top-down from that
  promise and proves the shipped implementation delivers it. Its
  green status roll-up is required before a surface-touching
  milestone may be closed.

Both carriers are defined authoritatively under **Carrier
contract** in `agents/fieldtester.md` (the milestone variant
under its **Milestone-scope variant** sub-heading). The gate the
milestone fieldtest feeds is defined once in
`../docs/pipeline.md` § Milestone-close gate — not restated
here. The milestone fieldtest is skippable on the same terms as
the per-cycle one, lifted to milestone level: a milestone whose
entire scope is internal (no user-visible surface) is exempt.

  • Step 3: Add a gate cross-reference to the Cross-references block

In fieldtest/SKILL.md, find the **Upstream gate:** bullet:

- **Upstream gate:** `../audit/SKILL.md` runs first;
  fieldtest comes after a clean (or ratified) audit.

Replace it with:

- **Upstream gate:** `../audit/SKILL.md` runs first;
  fieldtest comes after a clean (or ratified) audit.
- **Closing gate it feeds:** `../docs/pipeline.md`
  § Milestone-close gate — the milestone fieldtest's green
  roll-up is the functional leg of that gate.
  • Step 4: GREEN — confirm both additions

Run:

cd ~/dev/skills
grep -n "## Two scopes: per-cycle and milestone" fieldtest/SKILL.md
grep -n "Closing gate it feeds" fieldtest/SKILL.md

Expected: each grep prints one matching line.

  • Step 5: Commit
cd ~/dev/skills
git add fieldtest/SKILL.md
git commit -m "fieldtest: document the milestone fieldtest variant

Name the per-cycle vs milestone scopes; the milestone fieldtest feeds
the functional leg of the milestone-close gate (single-sourced in
pipeline.md)."

Task 4: audit/SKILL.md — drift-gate wording and the milestone red flag

Files:

  • Modify: audit/SKILL.md (Step 2 table line 74; carry-on path lines 107-110; Red Flags list)

  • Step 1: RED — confirm "Audit can close" and no milestone red flag

Run:

cd ~/dev/skills
grep -n "Audit can close" audit/SKILL.md
grep -c "milestone" audit/SKILL.md

Expected: first grep prints the Step 2 table line; the count is 0.

  • Step 2: Reword the green-exit row to a drift gate

In audit/SKILL.md, replace:

| `0` | Green | All metrics within tolerance vs. the script's baseline. Audit can close. |

with:

| `0` | Green | All metrics within tolerance vs. the script's baseline. The cycle's drift gate is clear (drift-clean, not a milestone close — see `../docs/pipeline.md` § Milestone-close gate). |
  • Step 3: Annotate the carry-on commit body as drift-clean

In audit/SKILL.md, replace:

- **carry-on path:** the audit-close commit body says
  `cycle <X> tidy (clean)` and ratifies whatever the
  regression check drove. Audit commits always exist at cycle
  close — they carry the architect findings, the regression
  numbers, and the resolution.

with:

- **carry-on path:** the audit-close commit body says
  `cycle <X> tidy (clean)` and ratifies whatever the
  regression check drove. Here `clean` means *drift-clean* —
  the cycle's code matches the ledger; it is **not** a milestone
  close, which additionally requires a green milestone fieldtest
  (see `../docs/pipeline.md` § Milestone-close gate). Audit
  commits always exist at cycle close — they carry the architect
  findings, the regression numbers, and the resolution.
  • Step 4: Add the milestone red flag

In audit/SKILL.md, in the ## Red Flags — STOP list, after the line:

- "We'll re-run after the holidays" without a dated backlog issue

add:

- Declaring a milestone closeable on the strength of an
  audit-clean while the milestone fieldtest has not run green —
  audit proves drift-clean, never functional (see
  `../docs/pipeline.md` § Milestone-close gate)
  • Step 5: GREEN — confirm all three edits

Run:

cd ~/dev/skills
grep -n "drift-clean, not a milestone close" audit/SKILL.md
grep -n "Here \`clean\` means \*drift-clean\*" audit/SKILL.md
grep -n "Declaring a milestone closeable" audit/SKILL.md
grep -n "Audit can close" audit/SKILL.md || echo "OK: stale wording gone"

Expected: the first three print a line each; the last prints OK: stale wording gone.

  • Step 6: Commit
cd ~/dev/skills
git add audit/SKILL.md
git commit -m "audit: clarify clean means drift-clean, not milestone close

Reword the green-exit row, annotate the carry-on commit body, and add a
red flag: an audit-clean never licenses closing a milestone — that needs
a green milestone fieldtest (gate in pipeline.md)."

Task 5: boss/SKILL.md — done-state references the gate

Files:

  • Modify: boss/SKILL.md (Done-state bullet, lines 120-121)

  • Step 1: RED — confirm done-state restates the formula locally

Run:

cd ~/dev/skills
grep -n "audit clean, fieldtest clean if applicable" boss/SKILL.md
grep -c "Milestone-close gate\|not an automatic milestone close" boss/SKILL.md

Expected: first grep prints the done-state line; the count is 0.

  • Step 2: Point done-state at the single-source gate

In boss/SKILL.md, replace:

- **Done-state** — queue is empty AND the cycle is fully
  ratified (audit clean, fieldtest clean if applicable). Go to
  Step 5.

with:

- **Done-state** — queue is empty AND the cycle is fully
  ratified (audit drift-clean, fieldtest clean if applicable).
  Go to Step 5. A `/boss` done-state means this run has nothing
  left to dispatch; it is **not** an automatic milestone close —
  closing a tracker milestone needs its end-to-end milestone
  fieldtest green and stays a deliberate manual act (see
  `../docs/pipeline.md` § Milestone-close gate).
  • Step 3: GREEN — confirm the reference

Run:

cd ~/dev/skills
grep -n "not an automatic milestone close" boss/SKILL.md
grep -n "docs/pipeline.md.*Milestone-close gate" boss/SKILL.md

Expected: each grep prints one matching line.

  • Step 4: Commit
cd ~/dev/skills
git add boss/SKILL.md
git commit -m "boss: done-state is not a milestone close

Reference the single-source gate; a /boss done-state means the queue is
empty, not that the tracker milestone may be closed."

Task 6: README.md — fix the root cycle≡milestone conflation

Files:

  • Modify: README.md (lines 30-32; the fieldtest table row line 26)

  • Step 1: RED — confirm the conflation and the bare "Optional" row

Run:

cd ~/dev/skills
grep -n "AILang calls a cycle a \*milestone\*" README.md
grep -n "surface-touching cycle | example fixtures" README.md

Expected: both grep print their respective lines.

  • Step 2: Rewrite the vocabulary paragraph to separate the axes

In README.md, replace:

Vocabulary is configurable. AILang calls a cycle a *milestone*
and a sub-cycle an *iteration*; your project may call them
*release* and *sprint*, or *epic* and *story*, or whatever fits.

with:

Vocabulary is configurable. A **cycle** is one round in the
pipeline graph; your project may call it a *release*, an *epic*,
or whatever fits, and its sub-unit (the default *iteration*) a
*sprint* or a *story*. A **milestone** is a distinct, higher
axis — a tracker container (Gitea/GitHub milestone, Linear
project) that spans potentially many cycles and closes only when
the work it promised is complete *and* functional (see
`docs/pipeline.md` § Milestone-close gate). A cycle close is a
loop step; it is never a milestone close.
  • Step 3: Nuance the fieldtest table row

In README.md, replace:

| `fieldtest` | Orchestrator-dispatched post-audit, surface-touching cycle | example fixtures + friction spec | Optional |

with:

| `fieldtest` | Orchestrator-dispatched post-audit | example fixtures + friction spec | Per-cycle optional; milestone fieldtest is the closing gate for a surface-touching milestone |
  • Step 4: GREEN — confirm the conflation is gone

Run:

cd ~/dev/skills
grep -n "calls a cycle a \*milestone\*" README.md || echo "OK: conflation removed"
grep -n "A \*\*milestone\*\* is a distinct, higher" README.md
grep -n "milestone fieldtest is the closing gate" README.md

Expected: first prints OK: conflation removed; the other two print a line each.

  • Step 5: Commit
cd ~/dev/skills
git add README.md
git commit -m "docs(readme): cycle is not a milestone

Separate the pipeline-round axis (cycle) from the tracker-container axis
(milestone); note the milestone fieldtest as the closing gate."

Task 7: templates/project-profile.yml — vocabulary and pipeline phase

Files:

  • Modify: templates/project-profile.yml (vocabulary block lines 40-43; pipeline block lines 66-74)

  • Step 1: RED — confirm the wrong comment and missing milestone slots

Run:

cd ~/dev/skills
grep -n "what a top-level work unit is called" templates/project-profile.yml
grep -c "milestone" templates/project-profile.yml

Expected: first grep prints the cycle: comment line; the count is 0.

  • Step 2: Fix the vocabulary block

In templates/project-profile.yml, replace:

vocabulary:
  cycle: cycle                            # what a top-level work unit is called
  subcycle: iteration                     # what a sub-unit is called
  ledger_entry: contract                  # what one design-ledger entry is called

with:

vocabulary:
  cycle: cycle                            # one round in the pipeline graph (NOT the top-level container)
  subcycle: iteration                     # a sub-unit of a cycle
  milestone: milestone                    # tracker container spanning many cycles; closes only when complete AND functional
  ledger_entry: contract                  # what one design-ledger entry is called
  • Step 3: Add the milestone-fieldtest phase to the pipeline block

In templates/project-profile.yml, replace:

  # fieldtest: { boss_only: true, when: surface_touch }

with:

  # fieldtest:           { boss_only: true, when: surface_touch }   # per-cycle usability test
  # milestone_fieldtest: { boss_only: true, when: surface_touch, gates_close: milestone }  # closing gate: end-to-end proof of the milestone's promise
  • Step 4: GREEN — confirm the slots and that the YAML still parses

Run:

cd ~/dev/skills
grep -n "milestone: milestone" templates/project-profile.yml
grep -n "milestone_fieldtest" templates/project-profile.yml
python3 -c "import yaml,sys; yaml.safe_load(open('templates/project-profile.yml')); print('YAML OK')"

Expected: first two grep print a line each; the python prints YAML OK (commented lines do not affect the parse, and the active vocabulary block stays valid).

  • Step 5: Commit
cd ~/dev/skills
git add templates/project-profile.yml
git commit -m "profile: add milestone vocabulary slot and milestone_fieldtest phase

Correct the cycle comment (a cycle is a pipeline round, not the
top-level container); add the milestone tracker-container slot and a
commented milestone_fieldtest phase that gates the milestone close."

Task 8: docs/profile-schema.md — schema doc for the new slots

Files:

  • Modify: docs/profile-schema.md (vocabulary table line 130; pipeline example lines 184-186; minimal-profile example line 213)

  • Step 1: RED — confirm the same conflation in the schema doc

Run:

cd ~/dev/skills
grep -n "What a top-level work unit is called" docs/profile-schema.md
grep -n "  cycle: milestone" docs/profile-schema.md
grep -c "milestone_fieldtest" docs/profile-schema.md

Expected: the first two grep print their lines (the table row and the minimal-profile example); the count is 0.

  • Step 2: Fix the vocabulary table row and add the milestone row

In docs/profile-schema.md, replace:

| `cycle`        | string | `cycle`        | What a top-level work unit is called. Examples: `milestone`, `release`, `epic`. |
| `subcycle`     | string | `iteration`    | What a sub-unit is called. Examples: `iteration`, `sprint`, `story`. |

with:

| `cycle`        | string | `cycle`        | One round in the pipeline graph (NOT the top-level container). Examples: `cycle`, `release`, `epic`. |
| `subcycle`     | string | `iteration`    | A sub-unit of a cycle. Examples: `iteration`, `sprint`, `story`. |
| `milestone`    | string | `milestone`    | Tracker container spanning many cycles; closes only when complete AND functional (see `pipeline.md` § Milestone-close gate). Examples: `milestone`, `epic`, `release`. |
  • Step 3: Fix the minimal-profile example so it stops equating cycle with milestone

In docs/profile-schema.md, replace:

vocabulary:
  cycle: milestone
  subcycle: iteration

with:

vocabulary:
  cycle: cycle
  subcycle: iteration
  • Step 4: Document the milestone-fieldtest phase in the pipeline section

In docs/profile-schema.md, in the ## pipeline fenced YAML example, replace:

  fieldtest:
    boss_only: true               # only orchestrator dispatches
    when: surface_touch           # condition tag (orchestrator judgement)

with:

  fieldtest:
    boss_only: true               # only orchestrator dispatches
    when: surface_touch           # condition tag (orchestrator judgement)
  milestone_fieldtest:
    boss_only: true
    when: surface_touch           # end-to-end proof of the milestone's promise
    gates_close: milestone        # its green roll-up is the functional leg of the milestone-close gate
  • Step 5: GREEN — confirm the schema doc is consistent

Run:

cd ~/dev/skills
grep -n "One round in the pipeline graph (NOT the top-level container)" docs/profile-schema.md
grep -n "| \`milestone\`    | string" docs/profile-schema.md
grep -n "gates_close: milestone" docs/profile-schema.md
grep -n "^  cycle: milestone" docs/profile-schema.md || echo "OK: minimal example no longer equates cycle with milestone"

Expected: the first three print a line each; the last prints the OK: message.

  • Step 6: Commit
cd ~/dev/skills
git add docs/profile-schema.md
git commit -m "docs(schema): document milestone slot and milestone_fieldtest phase

Correct the cycle vocabulary description, add the milestone container
slot, fix the minimal-profile example, and document the
milestone_fieldtest phase that gates the milestone close."

Task 9: Final cross-file verification sweep

Files: none modified — verification only.

  • Step 1: No file still equates cycle with milestone

Run:

cd ~/dev/skills
grep -rn "calls a cycle a \*milestone\*\|top-level work unit\|^  cycle: milestone" \
  README.md docs/ templates/ audit/ fieldtest/ boss/ \
  && echo "FAIL: stale conflation remains" || echo "OK: no conflation remains"

Expected: OK: no conflation remains.

  • Step 2: The gate is defined once and referenced, not restated

Run:

cd ~/dev/skills
echo "definition (expect exactly 1, in pipeline.md):"
grep -rln "^## Milestone-close gate" docs/ audit/ fieldtest/ boss/ README.md
echo "references (expect audit, fieldtest, boss, README, profile-schema):"
grep -rln "Milestone-close gate" docs/ audit/ fieldtest/ boss/ README.md

Expected: the definition list contains exactly docs/pipeline.md; the reference list additionally contains audit/SKILL.md, fieldtest/SKILL.md, boss/SKILL.md, README.md, docs/profile-schema.md.

  • Step 3: The milestone carrier is single-sourced in the agent file

Run:

cd ~/dev/skills
echo "carrier definition (expect fieldtester.md):"
grep -rln "### Milestone-scope variant" fieldtest/
echo "milestone_promise mentions:"
grep -rln "milestone_promise" fieldtest/

Expected: the variant heading appears only in fieldtest/agents/fieldtester.md; milestone_promise appears in both fieldtest/agents/fieldtester.md and fieldtest/SKILL.md (the skill references the field, the agent defines it).

  • Step 4: The profile template still parses

Run:

cd ~/dev/skills
python3 -c "import yaml; yaml.safe_load(open('templates/project-profile.yml')); print('YAML OK')"

Expected: YAML OK.

  • Step 5: No commit needed — this task only verifies. If any check fails, return to the owning task and fix before proceeding.

Notes for the executor

  • This repo commits directly on a working branch (milestone-close-gate); do not open PRs unless asked. main is sacrosanct — never reset/revert it.
  • All prose is English (repo rule: anything committed is English).
  • There is no build/test toolchain here; the grep/YAML checks above are the verification. Do not invent a test runner.
  • Single-source discipline is the spine of this change: if a check in Task 9 shows the gate defined in more than one place, the fix is to replace the duplicate with a reference to docs/pipeline.md, not to keep both.