Skip to content
Back to skills

Add Feature Specification

ASecurity

Single writer of about.md — reads the brainstorm intent file, extracts the objective and the closed decisions without asking, and asks only what is still open. Loaded by /add-new.

  • 9 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 29, 2026
developmentgodatabasefrontendbackend

Security analysis

A100/100

Scanned September 29, 2026

npx -y skills add brabos-ai/code-addiction --skill add--feature-specification --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Add Feature Specification?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Add  Feature Specification
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/brabos-ai-add-feature-specification/badge)](https://www.skillsdirectory.com/skills/brabos-ai-add-feature-specification)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: add--feature-specification
description: Single writer of about.md — reads the brainstorm intent file, extracts the objective and the closed decisions without asking, and asks only what is still open. Loaded by /add-new.
---

# Feature Specification

<!-- uses:
- skill: add--doc-schemas
- command: /add-new
- mention: /add-brainstorm
- mention: add--feature-discovery
- mention: /add-plan
-->

**The single writer of `about.md`.** `/add-new` loads it, whether the user ran `/add-new` by hand or
`/add-brainstorm` handed off to it on an automatic delivery. Both arrive at the same command, so both
produce the same document from the same rules.

**Principle:** Document WHAT and WHY, not HOW.

## When to Use

- Writing or completing `about.md`.
- Requirements changed, or scope expanded, and the document must follow.

### When NOT to Use

- Technical analysis of the codebase — that is `add--feature-discovery`.
- Technical implementation planning — that is `/add-plan`, which writes `plan.md`.
- Allocating a feature id, creating its directory, running the schema gate or dispatching a reviewer.
  **All four are orchestration and belong to the command that loaded this skill**, never here. A skill
  that allocates an id behaves differently depending on who called it, which is the one thing a single
  writer exists to prevent.

---

## Phase 1: Check State

Read `docs/features/[FEATURE_ID]/about.md`.

| State | Action |
|---|---|
| Does not exist / empty | Phase 2 |
| Partially filled | Phase 2, for the missing sections only |
| Complete | Phase 2 decides whether anything changed |

## Phase 2: Read the Intent File, Then Ask Only What It Left Open

**The calling command resolves the intent file and hands it over.** It is
`docs/brainstorm/YYYY-MM-DDTHHMMSS-<slug>-intent.md`, written by `/add-brainstorm`, and its shape is
the `brainstorm-intent` schema in `{{skill:add--doc-schemas/SKILL.md}}`.

### 2.1 Extract, do not re-ask

**`## Objective` first.** Copy the intent file's `## Objective` into `about.md`'s `## Objective`
verbatim, without asking. Every other section is written against it: a Scope item that cannot be traced
to it is scope this feature is not for, and the plan reviewer fails the plan on exactly that.

```
IF THE INTENT FILE CARRIES `## Objective`:
  ⛔ DO NOT: Re-word, narrow or "clarify" it on the way in — a better sentence is a different objective
  ✅ DO: Copy it byte for byte

IF THERE IS NO INTENT FILE, OR IT CARRIES NO `## Objective`:
  ⛔ DO NOT: Ask the user "what is your objective?" and wait
  ✅ DO: Draft one or two sentences from what the user already said — what will be true when this is
         done that is not true today — ask them to correct it, and mark it
         `[from conversation, no brainstorm]`
```

```
IF A DECISION APPEARS UNDER `## Decided` IN THE INTENT FILE:
  ⛔ DO NOT: Put it to the user again, in any form
  ⛔ DO NOT: Re-derive it, re-word it as a confirmation question, or offer alternatives to it
  ✅ DO: Carry it into about.md as a settled decision, with the rationale the file gave it
```

**This prohibition is the reason this skill exists.** A question already answered, asked again, is
what made the old questionnaire feel like an interrogation about things the user had just decided.

`## Prior art` fills the document's account of what already exists. `/add-brainstorm` STEP 1 already
ran the INDEX and GRAPH steps that produced it, so nothing here runs them again for an entry the file
already names.

### 2.2 What to ask

| `## Open` reads | Ask |
|---|---|
| The literal `None` | Nothing. Go to 2.3 |
| One or more bullets | Those items, and only those — one question per turn |
| The section is absent, empty, or the file is missing | The full set of questions this skill would ask with no input at all |

⛔ **A `## Open` section that is present but empty is read as absent.** A missing signal means "not
closed", never "closed". Falling the wrong way here produces a document built from decisions nobody
made.

**Every question carries a concrete recommendation** — which option this skill would take and why,
drawn from the codebase and from what the intent file already settled. Ask through the provider's
structured-question tool where the `structuredQuestions` capability says one exists; otherwise present
an option table with the recommendation marked.

### 2.3 The confirmation screen

**With nothing left open, the user still sees what is about to be written — once, in one screen.**

It restates the decisions being carried into `about.md` and stops, so an extraction error can be
corrected. It is not a questionnaire and must not become one: it asks for a correction, not for
answers.

⛔ **The approval never scales away, only the interrogation does.** The calling command owns the
`[STOP]` around this screen.

### 2.4 The three-fact test — how much document this work needs

Run it when the intent file names no `path:`, or when there is no intent file. Three facts:

1. **Intent gaps** — is there a decision a builder would have to guess?
2. **Irreversible actions** — a migration, a data deletion, a public contract change, an external
   integration?
3. **Footprint** — more than a handful of files, or an area no delivered feature has touched?

**Clean on all three takes the light path: a compact `about.md` and no decomposition.** Any flag takes
the full one. The ratchet is one-way — the classification may rise mid-run and never falls.

⛔ **This skill owns the test; the calling command applies its result.** The classification is
authoring input. What the command does with it — whether it dispatches discovery agents, whether it
runs a reviewer — is orchestration, and neither side restates the other's half.

## Phase 3: Write the Document

**Load the `feature` schema from `{{skill:add--doc-schemas/SKILL.md}}` and write against it.**

```
IF ABOUT TO WRITE THE DOCUMENT:
  ⛔ DO NOT: Carry a template in this skill, or reconstruct one from memory
  ✅ DO: Load the schema and follow its sections, depth floors and hard bans
```

⛔ **The schema is the single owner of that shape.** A template kept here drifts from it, and the
drift is invisible until the two disagree — at which point the validation gate rejects a document this
skill told someone to write.

Write extractively: requirements, not implementation. **`add--doc-schemas` owns the update discipline**
under its Cache Documental rule — follow it rather than a copy kept here.

### 3.1 `## Relations`, `## Observations` and `tags:`

**These are mandatory sections of the `feature` schema, so this skill writes them every time.** A rule
kept in the calling command would drift from the schema this skill writes against.

The calling command hands over whatever it has — a `past-features.md` Related Features table, a
`RELATED_WORK` set, a `discovery.md` naming prerequisites, and the intent file’s `## Prior art`.
A light path may supply only the last. Write from what arrived.

| Material in hand | Becomes |
|---|---|
| A prerequisite this feature cannot ship without | `- depends_on [[<id>]] — <the one-line reason given>` |
| The parent epic, when this `about.md` is a subfeature | `- part_of [[<parent id>]]` |
| Any other related feature | Leave it out. `related:` already carries it, and an untyped edge is not this skill’s to invent |

```
IF NO PREREQUISITE AND NO PARENT EPIC ARRIVED:
  ⛔ DO NOT: Ask the user which feature this one depends on
  ⛔ DO NOT: Invent a `depends_on` from the conversation
  ✅ DO: Write `## Relations` carrying the single word `None`
```

⛔ **`add--doc-schemas` owns the rule that nobody is asked**, in its Relations & Observations section.
What is specific here is the provenance: every edge comes from material the caller handed over, never
from a question.

Write `tags:` from the domains the confirmed decisions settled — bare lowercase words. Write
`## Observations` from the same material: measurements and constraints no other section holds. Empty
is valid.

**A required layer is never excluded.** A new route needs a backend; a new field needs a database; a
feature the user must see needs a frontend. Excluding a layer the feature cannot work without
produces a document that reads complete and specifies something unusable.

## Phase 4: Persist

Write the file. **The validation gate is the calling command's**, and it runs after this skill
returns — see When NOT to Use.

---

## Checklist

- [ ] `## Objective` copied verbatim from the intent file, or drafted, corrected and marked
- [ ] Intent file read, and every `## Decided` item carried in without being re-asked
- [ ] Only `## Open` items were put to the user
- [ ] Every question asked carried a concrete recommendation
- [ ] The confirmation screen was shown, and the user's corrections applied
- [ ] `about.md` written against the `feature` schema, with no template invented here
- [ ] Problem, users and value stated
- [ ] Requirements and business rules carry ids
- [ ] No required layer excluded
- [ ] Scope states what is included AND what is not
- [ ] Decisions carry their rejected alternative
- [ ] `## Relations` written from material handed over, or carrying `None`
- [ ] `## Observations` and `tags:` written from the same material
- [ ] No HOW mixed into the WHAT — technical analysis belongs to `add--feature-discovery`

## Common Rationalizations (BLOCKED)

| Excuse | Reality |
|--------|---------|
| "I'll confirm the decided items just to be safe" | That is the interrogation this skill removed. They were decided |
| "`## Open` is empty, so everything is closed" | Empty is absent. Absent means not closed — ask the full set |
| "I'll keep a small template here for speed" | It drifts from the schema, and the gate rejects what this skill told someone to write |
| "The command didn't say which path, I'll assume light" | Run the three-fact test. An assumption is not a measurement |
| "I'll allocate the id since I'm already writing the file" | Orchestration. The command owns it, and a skill that does it behaves differently per caller |

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.