Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 102 additions & 0 deletions .agents/skills/feature-close/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
---
name: feature-close
description: "Retire a finished or abandoned feature — write its context/history.md row, git mv its document to context/archive/, and sweep every reference to its old path for review. Explicit invocation only — run this when the user types /feature-close. Do NOT match on 'we're done with X', 'close this out', or general wrap-up requests."
---

# /feature-close

Owns the **Tier 2 → retired** transition. Nothing else in this workflow archives a plan —
`/feature-implement` detects that a feature is finished and *names* this command; it never does the work.

Read [`context/workflow.md`](../../../context/workflow.md) for the tier model.

## Usage

```
/feature-close # retire the active feature as shipped
/feature-close "<name>" # retire a named feature as shipped
/feature-close "<name>" --dropped "<why>" # retire one that will not be built
```

**Resolving the target:** with no argument, the entry marked `active`. With a name, resolve it against
`context/roadmap.md` — **any entry holding a plan is a valid target**, not just an active one. An abandoned
plan is a droppable state.

## Mode 1 — `shipped`

### Refuse first

Check both before touching anything, and refuse if either fails:

1. **Every phase in the ledger is `done`.** If not, list the ones that are not, and stop. Do not offer to
mark them.
2. **No open `P0` or `P1` in `context/findings.md` is tied to this feature.** If there is, quote it and
stop.

A refusal here is the workflow working, not a problem to route around. If the user overrides after being
told, say plainly what is being overridden, then proceed.

### Then, as one reviewed change

1. **Move the entry into history.** Remove it from `context/roadmap.md` entirely, and append one row to
`context/history.md`: date, name, outcome `shipped`, a one-line why, and a link into `context/archive/`.
One line. That file **indexes** depth, it does not duplicate it — the reasoning stays in the archived
plan.
2. **`git mv` the plan** from `context/plans/` to `context/archive/`. Use `git mv`, not `mv` — the file's
history is the record of how the feature was actually built.
3. **Rewrite the document's header to point at the history row.** In the moved document, replace
whatever the header claimed before with:

```markdown
Retired — its outcome and date are in [`../history.md`](../history.md).
```

Add a note if its §-references are cited from source comments. **Do not stamp the outcome and date
into the document.** `history.md` owns them, and a copy in the header is a second place to maintain.
Replacing the old header is what stops a stale status surviving the move.
4. **Sweep every reference to its old path**, and **show the sweep for review before committing.**

### The sweep

Plan documents get cited by path from root-level entry points, from other `context/` files, from skills,
and from inside `context/standards/`. An unattended `git mv` breaks all of them silently.

```bash
grep -rn "<old-path>\|<OLD-FILENAME>" --include='*.md' . | grep -v node_modules
```

- **Rewrite links, minding depth.** `context/plans/` and `context/archive/` are the same distance from the
root, so a `../../` link *inside* the moved document still resolves — but a link *to* it from elsewhere
changes. Verify, don't assume.
- **Leave §-number citations alone.** Source comments cite plan sections without a path
(`// SMART-CROP-PLAN.md §7.3`). Those survive the move untouched and must not be "helpfully" rewritten
into paths that will rot.
- **Show the full list of edits before committing.** That review is why this is an explicit command rather
than a side-effect.

### Finally

Move every **closed** finding tied to this feature out of `context/findings.md` and into the archived plan's
own log. `findings.md` must not grow for the life of the project.

## Mode 2 — `--dropped`

For an entry that will not be built. **There is no ledger check in this mode** — unfinished phases are
expected.

1. Append a `context/history.md` row with outcome `dropped` (or `superseded by <name>`) and **the reason
the user gave**, verbatim in substance, not softened. That row is what stops the idea being re-proposed,
so a vague reason makes it worthless.
2. Remove the entry from `context/roadmap.md`.
3. **If the entry never had a document, stop here.** If it had one — a draft in `context/drafts/` or a plan
in `context/plans/` — `git mv` it to `context/archive/`, repoint its header at the `history.md` row (no
stamped outcome, same rule as Mode 1), and sweep.

## Rules

- **Never delete a plan document.** Archiving keeps the reasoning; deleting throws away the record of a
decision someone will otherwise re-litigate.
- **Never leave `roadmap.md` and `history.md` inconsistent.** An entry is in exactly one of them.
- **Never commit the sweep unreviewed.**
- **Never mark a phase `done` to get past the refusal.** If phases are unfinished, the feature is
unfinished.
142 changes: 142 additions & 0 deletions .agents/skills/feature-implement/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
---
name: feature-implement
description: "Activate a planned feature in context/roadmap.md and run the next phase of its plan through implementation, verification and review, updating that plan's status ledger. Explicit invocation only — run this when the user types /feature-implement. Do NOT match on 'implement X', 'build this', 'let's code it', or any general request to write code."
---

# /feature-implement

Owns the transition from *has a plan* to *being worked*, **and** the phases within it. One invocation runs
**one phase**: pick it, do it, gate it, close out its ledger row.

Read [`context/workflow.md`](../../../context/workflow.md) for the tier model, the one-active-feature rule
and the gate contract. This skill cites those rather than restating them.

## Usage

```
/feature-implement # resolve or choose a feature, then run the next phase
/feature-implement "<name>" # a named feature
```

## 1. Resolve the feature

Read `context/roadmap.md`.

- **One entry is `active`** → that is the feature. Skip to step 3.
- **None active** → rank the entries whose **Doc** points into `context/plans/` and **ask which to
activate**, using your runtime's question mechanism if it has one. Rank by: open questions resolved →
dependencies shipped (a `history.md` row under it) → smaller first.
- **No entry has a plan** → say so and name `/feature-plan`. Do not plan one here.
- **A name was given** → resolve it against `roadmap.md`. It must have a plan; if it does not, name
`/feature-plan`.

**Never execute anything out of `context/drafts/`.** A draft has no ledger and is not a plan, however
detailed it looks.

## 2. The approval checkpoint — before setting the marker

This is the step that used to be structural: `/feature-plan` stopped and you typed a second command. It is
explicit here now, or it is lost.

1. **Surface the plan's §8 Open questions and require an acknowledgement.** Do not proceed on silence.
2. **Re-check that the files the plan cites still exist.** A plan drafted a month ago against a
since-changed tree is a state that can now exist and could not before. Name anything that has moved.
3. **Check the one-active-feature rule** in [`context/workflow.md`](../../../context/workflow.md). If
another entry holds the slot, stop and name it.
4. Set the marker to `active`. One token, one place — do not move the entry, add a section, or write a
summary line anywhere.

## 3. Pick the phase

Read the plan's status ledger. Take the **lowest-numbered phase that is not `done` and whose `Depends on`
entries are all `done`.**

**State which phase you picked, and why, in one line, before doing anything else.**

If it is already `in progress`, **read its Note and resume from there — do not restart it.**

## 4. Check `context/findings.md`

An open `P0` or `P1` tied to this phase **is** the work. Fix it before starting anything new.

## 5. Stop on disagreement

If the ledger's claim contradicts the repo — a phase marked `done` whose **Files:** do not exist, or work
plainly in the tree under a phase marked `not started` — **say so and stop.** Never silently re-do or skip
a phase on a stale ledger.

## 6. Do the work

Read the phase's §6.2 sub-section: its scope, its **Files:**, and what `done` means for it.

Delegate to a coder per [`context/executors.md`](../../../context/executors.md) if one is configured;
otherwise implement in-host. The coder's system prompt is
[`context/roles/coder.md`](../../../context/roles/coder.md).

The brief **cites paths, it does not paste files.** Point at `context/standards/README.md` and say to load
per its conditional table; point at `context/stack.md` and the phase's own section. Anything that can read
this repository can open them, and a brief that inlines them is a brief that goes stale.

Describe **what** needs to happen, never **how** to code it. Scope each delegated task to specific files.

## 7. Gate 1 — verification

Per the gate contract in [`context/workflow.md`](../../../context/workflow.md): read
[`context/verify.md`](../../../context/verify.md) and run its sections in order — Lint → Typecheck → Build →
Test.

**Never carry a copy of these commands here and never invent one.** A missing section is skipped and said
so, never faked. Exit 0 is the verdict regardless of summary text. If `verify.md` does not exist or has no
filled-in section, stop and say so. Docs-only changes run Lint plus a read of the diff.

A failure is the verdict — go to step 9 with the failing output verbatim as the feedback.

## 8. Gate 2 — review

Dispatch per [`context/executors.md`](../../../context/executors.md). With no independent reviewer
configured, review the diff yourself against the plan's review expectations and the standards — weaker, and
**say which one you ran.**

Require concrete evidence — file paths, command output — for every verdict, and a `P0`–`P3` severity on
every blocking finding.

- `PASS` or `PASS WITH NOTES` → the phase's work is done; go to step 10.
- `FAIL` → **write it to [`context/findings.md`](../../../context/findings.md) first, then** go to step 9.

**Write the finding before the loopback, not after it.** A verdict that lives only in this session's
transcript evaporates when the conversation ends — including a `P0` the cap never got to.

## 9. Loopback

Cap: **two loops per gate, per phase.**

Under the cap: re-brief with the prior implementation and the validator's feedback **verbatim — do not
summarise or paraphrase it** — plus the instruction to address only the failing items, refactor nothing
that passes, and expand no scope. Then re-run the same gate.

At the cap: **write a finding** (`P1` for a Gate 1 cap-out — a phase whose verification cannot pass is
blocked by definition), then escalate to the user with the current state and the last feedback.
**Escalating is not a substitute for recording.**

## 10. Close out the ledger row

In the same commit as the work:

- **All of the phase's scope landed and both gates passed** → `done`.
- **Some landed** → stays `in progress`, Note rewritten to name exactly what remains.
- **A gate hit its cap, or something external blocks it** → `blocked`, with the blocker in the Note.

**Never mark `done` on a coder's self-report** — the gate output is the evidence. **Refuse `done` while an
open `P0` or `P1` is tied to this phase**; leave it `in progress` and name the finding.

## 11. Report

- What changed, and which files.
- Gate 1 output, and Gate 2's verdict.
- Loopback counts, if any.
- Findings written or closed, by id.
- The phase's new ledger status, and which phase is next.

**When every phase is `done`, say so and name `/feature-close`.** Do not move files, stamp headers or sweep
references — that is a tier boundary, and crossing it is an explicit command the user runs, not a
side-effect of the last phase finishing.
138 changes: 138 additions & 0 deletions .agents/skills/feature-plan/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
---
name: feature-plan
description: "Promote one item from the Tier-1 backlog in context/roadmap.md into a Tier-2 plan document under context/plans/, then stop without implementing. Explicit invocation only — run this when the user types /feature-plan. Do NOT match on 'plan out X', 'how should we build X', or any general planning or design request."
---

# /feature-plan

Turns one roadmap entry into a plan document, then **stops**. It never implements anything and never marks
a phase `done` — every phase in a new plan is `not started`.

**Planning is not activation.** Several features may hold plans at once; there is no "a feature is already
active" refusal here. That is what makes planning ahead possible. Activation is `--activate` or
`/feature-implement`, and both are subject to the one-active-feature rule in
[`context/workflow.md`](../../../context/workflow.md).

## Usage

```
/feature-plan # rank the pending entries and ask which to plan
/feature-plan "<name>" # plan a named entry
/feature-plan "<name>" --activate # plan it, and mark it active
```

**Nothing needs to be looked up first.** This command resolves its own starting point.

## Steps

### 1. Pick the entry

Read `context/roadmap.md`.

**With a name:** take that entry. If none matches, say which names exist and stop.

**With no argument:** rank the `pending` entries and **ask which to plan**, using your runtime's question
mechanism if it has one, or a plain numbered question if it does not. Writing a plan is a commitment and
takes real work to produce; silently taking the top entry makes that decision on the user's behalf, badly,
whenever the backlog order is stale.

**Ranking**, in priority order:

1. **Has a draft** — the entry's **Doc** names a document in `context/drafts/`. Half-researched is better
and cheaper. This dominates: an entry with real notes beats a one-line entry almost regardless.
2. **Unblocked by what just shipped** — it builds on something with a `context/history.md` row, so the
ground under it is settled rather than hypothetical.
3. **Smaller first** — `small`, then `medium`, then `large`. A plan that can be executed beats one that
gets admired.
4. **Backlog order** — ties break by position in the file.

Offer the top four, **best first**, each with a one-line reason drawn from the ranking — say *why* it is
ranked there, not just what it is. Leave room for the user to name something else.

Special cases, where asking is noise rather than help:

- **Exactly one `pending` entry** — state it and proceed. A one-option question is not a choice.
- **No `pending` entries** — say the backlog is empty and name `/roadmap "some idea"`. Do not invent one.

**State which entry you picked and why, in one line, before doing anything else.**

### 2. Already planned? Start a conversation, not a refusal

If the entry's **Doc** already points into `context/plans/`, say so, show the plan, and ask whether to
iterate on it.

- **Every phase `not started`** → iterate freely.
- **Any phase `in progress`, `blocked` or `done`** → **warn first, and get an answer before writing.**
Rewriting a plan under work that already happened is the "ledger disagrees with the repo" hazard arriving
by a new route. Name which phases have moved.

### 3. Decide the document

The plan ends up at `context/plans/<NAME>-PLAN.md`, where `<NAME>` is the entry's kebab-case name
upper-cased.

- **If the entry's **Doc** names a draft in `context/drafts/`**, `git mv` it to that path and build the
plan on top of its content. Use `git mv`, not `mv`. Do not create a second file and do not leave the
draft behind — a draft and a plan for the same feature is two documents disagreeing about one thing.
- **Otherwise** copy `context/plan-template.md` to that path. Copy it verbatim; it is a bare skeleton with
nothing to strip. [`context/plan-template.notes.md`](../../../context/plan-template.notes.md) says what
goes in each section.

**The draft is the most valuable input you have** — material the user gathered deliberately, often from
somewhere you cannot reach. Carry its specifics forward; do not summarise them away, and do not silently
drop a fact because you could not verify it. Mark it as an open question instead.

### 4. Research and draft

Delegate the research and the draft to a planner subagent **if your runtime provides one**; otherwise do it
inline. Either way the brief is the same, and the output contract is the template's section list, not a
planner's own default shape:

- The roadmap entry verbatim, and the full content of its draft if there was one.
- **The full section list from `context/plan-template.md`, stated as required output**, in order, with the
ledger's exact column set. A general-purpose planner will otherwise emit implementation-steps-and-
acceptance-criteria — a per-phase artifact, not a plan — and you will throw it away.
- Pointers to `context/stack.md`, `context/standards/README.md` (load per its conditional table) and
`context/verify.md`. Cite the paths; do not paste the files in. Anything reading this repo can open them.
- **Cite file paths and command output for every claim about the current codebase.** Anything unverified is
an open question, not an assertion.
- Phases are **commit-sized units with checkable outcomes**, each with a real `Depends on` value and a
**Files:** line naming every path it touches. That line is what makes reconciliation a check rather than
a judgement call.

### 5. Write the document

Fill in the template's shape. Then:

- Date it and point its header at the roadmap entry.
- **No `**Status:**` header.** Feature status lives in `roadmap.md`, phase status in the ledger. A document
that claims its own status is a copy that goes stale.
- Fill in **§8 Open questions** honestly. An honest gap is worth more than an invented decision.
- Every phase is `not started`.

### 6. Update the roadmap entry

Repoint the entry's **Doc** field at the new `plans/` path. If you `git mv`d a draft, that same edit is
what fixes the now-dead `drafts/` link, so do it together.

**Leave the marker alone unless `--activate` was given.** `pending` with a `plans/` document is the correct
state for a planned-but-not-started feature.

**With `--activate`:** check the one-active-feature rule in
[`context/workflow.md`](../../../context/workflow.md) first. If another entry holds the slot, **write the
plan, skip the activation, and name the feature that holds it.** The plan is valuable and harmless on its
own; discarding it over a marker would undo the point of the split.

### 7. Report and stop

State the document path, the phase count, and the open questions. Then say plainly that **what you produced
is a reviewable skeleton plus open questions, not a finished plan of record** — the value is the structure
and the research. Name the next step: the user reviews and edits the plan, and `/feature-implement` runs it
once they are satisfied.

## Rules

- **Never implement anything.** Not "just the first phase", not "a quick scaffold".
- **Never mark a phase `done`**, and never mark a phase anything other than `not started`.
- **Never write outside `context/`.** No source files, no config.
- Do not fold the draft's content into `context/roadmap.md`. Tier 1 stays high-level.
Loading
Loading