Turn a vague product idea (a "sparkle") into a complete, grounded design through waves of select/multi-select questions - then orchestrate the build. Targets exactly which contexts/files the idea touches, scouts them before asking anything, converges the design across four perspectives (functional, UX, UI, performance/architecture), and executes via builder subagents in a worktree under Director review. Runs live in a memory vault (a linked Obsidian folder, or <repo>/.spark/ with the same sch...
Installs into .claude/skills of the current project.
Are you the author of Spark?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/xkazm04-spark)
---
name: spark
contexts: tracked
memory: vault
category: workflow
description: Turn a vague product idea (a "sparkle") into a complete, grounded design through waves of select/multi-select questions - then orchestrate the build. Targets exactly which contexts/files the idea touches, scouts them before asking anything, converges the design across four perspectives (functional, UX, UI, performance/architecture), and executes via builder subagents in a worktree under Director review. Runs live in a memory vault (a linked Obsidian folder, or <repo>/.spark/ with the same schema); every run ends with a self-improvement retro that sharpens the skill itself. Per-repo specifics - vault path, gates, context map, host rituals, repo law - come from the overlay at .claude/spark/config.md, and the loop runs on defaults without it. Invoke with `/spark <idea...>` or `/spark resume <slug> | status | reflect`.
argument-hint: "<idea...> | resume <slug> | status | reflect"
version: 1.7.2
model: sonnet
---
# Spark — sparkle in, fire out
> The operator's strength is *having* the idea; the model's strength is everything between the idea and the shipped commit: locating it in a large codebase, knowing what already exists, asking the few questions that actually matter, designing across perspectives the operator wouldn't pause on, and building without drift. `/spark` is that bridge. **One invocation = one idea, end to end: target → scout → design waves → brief → build → retro.** Multiple sparks run as parallel CLI sessions, isolated by worktrees and coordinated by whatever live-session ledger the repo keeps.
## Roles
- **Director (the main session).** Owns targeting, question design, the design brief, builder briefs, diff review, merge decisions, gates, vault writes, and the retro. Never delegates judgment.
- **Scouts (Explore subagents, read-only).** One per target context: current-state brief with `file:line` evidence. A surface only "exists" if it renders — trace mount points. **Not cheap by default:** since Claude Code 2.1.198 an Explore scout that names no model inherits the session's (capped at opus), so a Fable/Opus Director's fan-out runs on Opus. Set `model` per scout: `haiku` for an enumerate-the-sites brief (measured about 0.4x the Opus-inherited cost at equal anchor accuracy), the inherited model for a brief that asks for mount-point or consumer tracing (the small tier did not volunteer tracing; untested when asked).
- **Builders (strong subagents, one per work package).** Tight brief + acceptance criteria + file scope; work in the spark's worktree; return structured reports; return questions instead of guessing.
## Project overlay
This file is the **method** and is repo-agnostic. Everything a repo *is* — its vault, gates, context map, host rituals, conventions, taste — lives in an overlay the Director reads in Phase 0. **Resolution order, first hit wins per key:**
1. **`.claude/spark/config.md` in the consuming repo** (tracked, so it travels with the clone and survives the vault, which is not version-controlled). This is the home.
2. **`$VAULT/<vault_subdir>/config.md`** — where earlier versions scaffolded the config. If it exists and the repo overlay does not, say so and offer to move it; if the repo overlay exists and *points at* the vault file for a section, read that section from the vault. Never silently maintain two copies of the same section.
3. **Defaults** — every key below has one. **The loop runs with no overlay at all**; when it does, say in the opening sentence that defaults are in force and what was detected.
Overlay shape: YAML frontmatter for scalars, markdown `##` sections for lists and prose.
```yaml
---
product: "<product name>" # brief header [the repo directory name]
stack: "<one-line stack>" # brief header [detected from the manifest, else "unknown"]
vault: ["<abs vault root>", ...] # candidate roots, first existing wins [<repo>/.spark]
vault_subdir: Spark # namespace inside the vault; "" = the root [Spark]
context_map: context-map.json # the targeting source [context-map.json; absent -> see Phase 1]
base_branch: master # worktrees fork from / land on it [detected from origin/HEAD]
active_runs_ledger: "" # path of a live-sessions ledger if the repo keeps one [none]
locale_count: 1 # sizing multiplier for string-heavy work [1]
---
```
| Section | What it carries | Default when absent |
|---|---|---|
| `## Gates` | `always:`, `when <condition>:`, `builder:` — the exact commands, verbatim | **only** what `.ai/manifest.yaml` `capabilities` declares (typecheck / lint / test); else the manifest's script names; else `say which gate you could not find and run none` |
| `## Rituals` | host-specific commands to run at named phases (see below) | none — the loop runs without them |
| `## Repo law` | the convention digest pasted verbatim into every builder brief; out-of-scope walls; where the authoritative rules file is | "read the repo's CLAUDE.md / AGENTS.md first; reuse before building" |
| `## Wave defaults` | wave size, perspective checklist overrides | one AskUserQuestion call of up to 4 questions; the Phase-3 checklist |
| `## Question taste` | learned — what this operator wants **asked** vs **decided for them** | empty; built by the retro |
| `## Skill improvement log` | append-only, one dated line per retro finding | created on first wrap |
**`## Rituals`** is the portability seam: anything the *host* repo demands that the method itself does not need. Each entry names a phase and a command, and the Director runs it at that phase and nowhere else. Typical entries: registering/deregistering in a live-sessions ledger (Phase 0 / Phase 6), capturing an operator correction to a decision ledger (Phase 3, same turn as the correction), running a translation pipeline before commit (Phase 5). **If the overlay declares no ritual for a phase, that phase has no ritual** — never invent one, and never import another repo's.
## The vault
Resolve `VAULT` = first existing `vault` candidate, else `<repo>/.spark/` — **the same schema either way**, still an Obsidian-openable folder. Then use `$VAULT/<vault_subdir>/`:
```
Spark/
Spark.md # HOME: idea ledger table (slug - status - contexts - one-liner - last session),
# fire count (shipped), link to last session
config.md # OPTIONAL - the legacy overlay home; see Project overlay resolution order
ideas/<slug>.md # one per spark, cradle-to-grave (see schema)
sessions/<YYYY-MM-DD[-n]>.md # immutable run records, end with `next:` pointer
```
**Idea note** (`ideas/<slug>.md`) — the atom of the loop:
```markdown
---
slug: <kebab, stable> type: spark/idea
status: sparked | scouted | designing | designed | building | shipped | parked | dropped
contexts: [<context names>] groups: [<groups>]
sparked: <date> designed: <date|-> shipped: <date|-> commit: <sha|->
waves_used: <n> questions_asked: <n>
---
## Spark (the operator's words, near-verbatim - never paraphrase away intent)
## Targeting (contexts chosen + why; contexts considered and excluded + why)
## Scout digest (what exists today, file:line; what the idea collides with or can reuse)
## Design decisions (one line per answered question: Q -> chosen option -> implication.
## Include options REJECTED - they are memory for the next wave and next spark.)
## Design brief (the buildable contract - see Phase 4 schema)
## Build record (work packages, builder reports digest, review verdicts, gate results, SHAs)
## Retro (what the process got wrong/right on THIS idea - feeds the improvement log)
```
**Vault safety (non-negotiable):** the vault is not version-controlled and Obsidian file-recovery never sees agent writes. Never open-for-write a note you didn't create this session; session-note names collide — probe and suffix `-2`, `-3`. Re-read `Spark.md` immediately before every write; never patch from a stale Phase-0 copy. After any parallel phase, list the target dir and backfill missing notes from returned agent content.
## The loop
### Phase 0 — Recall & register
1. Read the overlay (§ Project overlay), resolve `VAULT`, read `Spark.md` (missing → scaffold the vault tree, and scaffold `.claude/spark/config.md` from what you **detected in THIS repo** — gates from its manifest/scripts, context map, ledger — never from another project's set).
**Promote recurring lessons before anything else.** Read the overlay's `## Skill improvement log`. A lesson that appears in two entries, or whose trap this repo has hit again, moves now into `## Gates` (a check to run, and when) or `## Repo law` (a constraint to obey). Those are the only overlay sections a builder brief carries: a lesson that lives only in the log never reaches the builder who repeats it.
2. Parse invocation: new idea text → new slug; `resume <slug>` → jump to the phase its `status` names; `status` → render the ledger table and stop; `reflect` → Phase 6 only.
3. Host rituals: run the overlay's Phase-0 `## Rituals` entries (typically a live-sessions ledger check + register — one bash invocation, since such a ledger is unsafe to edit-then-commit across concurrent sessions). Always run `git status` regardless: repos host parallel sessions, and foreign WIP is never swept into your commits. Scan the harness's auto-memory for veto signals.
4. **Fetch before you look at anything.** `git fetch` and report, in one line, how far the base is from its remote (`git rev-list --count <base>..origin/<base>`) and whether the checkout's gates are green *before* this spark touched them. Both are inherited state that will otherwise be discovered as your defect: a repo developed on two machines can be hundreds of commits behind, and a red gate on arrival is attributed to the builders who found it. If the base is behind, say which of the two you are designing against — the local base or the remote's — and prefer the remote's.
5. Record the spark verbatim in `ideas/<slug>.md` (`status: sparked`).
### Phase 1 — Target (evidence, not vibes)
1. Read the overlay's `context_map`. **If the repo has no context map**, target from the repo's **top-level source directories** plus the scout's own findings, and say plainly in `## Targeting` that the partition is provisional — a wrong target is then a scout finding, not a silent miss.
**Sizing rule when a map exists:** if two sources disagree about the partition (a committed export vs. the tool that owns it), say which you chose and why, and treat counts from the other as unusable for sizing.
2. Map the idea to **1-3 primary contexts** (where code changes land) and up to 3 **touched contexts** (integration points: stores, command/API surfaces, shared components, strings). Name them and the reasoning in `## Targeting` — including near-miss contexts you excluded, so a wrong targeting is diagnosable at retro.
3. If targeting is genuinely ambiguous (two plausible homes with different architectures), that is **wave-1 question #1** — never guess silently, never ask more than one targeting question.
### Phase 2 — Scout before asking
Launch one Explore scout per primary context (parallel, "very thorough"): what exists, what the idea overlaps/duplicates, reusable primitives (check the repo's shared-component catalog when the overlay's `## Repo law` names one), data model touchpoints, perf-relevant volumes, `file:line` evidence. Digest into `## Scout digest` (`status: scouted`). **When the target is a new or empty repo** (an extraction, a greenfield package), scout the repos the idea is extracted from or must integrate with, under the same evidence rules, and say so in `## Targeting`. **If scouts cannot be launched** (pool exhausted, tool unavailable), the Director scouts directly under the same evidence rules and says so in `## Scout digest` — never skip scouting, never retry a refused launch.
**Scout the remote's version of the target paths, not just the checkout's.** When Phase 0 found the base behind its remote, run `git log HEAD..origin/<base> -- <the target contexts' paths>` before the scouts report. A non-empty result means the thing you are about to design against has already been redesigned elsewhere: read those commits and treat what they changed as a wave-1 constraint. One command here replaces re-cutting a built, gate-green design after the sync.
**Read the governing registry subject BEFORE the waves, not after.** Resolve the target contexts' subjects through `.ai/registry-map.json` and read the golden path plus the techniques whose `use_when` matches the idea. A standard read here becomes a wave-1 constraint or a named deviation; read afterwards it is only a review comment. (The weekly-digest spark found that a documented whole-fleet period delta inverts at a 7-day window only because the time-windows subject was open before Q1.)
**Grounding rule: no question reaches the operator that the code could have answered.** "Should this be a new tab or extend X?" is only a valid question if the scout confirmed X exists, renders, and could host it.
**Liveness rule (every half is required):**
1. A surface only "exists" if it RENDERS — trace every surface to an actual mount point.
2. A FIELD only "exists" if some query the consumer actually calls POPULATES it. For every field the design depends on, the scout names the query that fills it and confirms the consumer calls that query, not a leaner projection of it.
3. For any DERIVED store the design moves or rebuilds, name the function that regenerates it — or state that none exists.
4. A TIMESTAMP only means what its name says if the row it sits on is APPENDED, not REWRITTEN. For any field the design reads as an event time, the scout states whether the table is append-only or re-created per snapshot, and names the writer. A `createdAt` on a snapshot-rewritten table answers "when did we last look", never "when did this start".
5. A MODULE only exists for a surface if that surface's RUNTIME can import it. For anything a screen might consume, the scout states the client/server boundary: a filesystem- or database-backed module is not available to a client component, however close it sits in the tree.
6. A POLICY only exists if something COMPUTES it. For every rule a doc or the brief declares (a privacy projection, a retention date, an eligibility condition), name the column, field or function that carries it. A policy with nowhere to live cannot fail a test, because it cannot exist.
Also required of every scout that maps shared render helpers or models: enumerate OTHER CONSUMERS of them, and **show the grep or command that produced the list** rather than asserting it — extension-site checklists are otherwise silently incomplete.
> Paid for in blood: a sibling loop shipped against a component with zero mount points, and a spark built a correct parser against a field the consumer's query returns blank by design. Same failure, one level apart.
### Phase 3 — Design waves (the heart)
Converge the design through **waves of AskUserQuestion** (each call = up to 4 questions; single-select for architecture forks, multiSelect for scope composition). **There is no wave cap** — a large feature legitimately takes a long dialog. The loop terminates on *clarity*, not on count: after every wave, re-run the completeness checklist below; iterate while any item is genuinely open, stop the moment none are. The discipline is per-question, not per-run: every question must be one whose answer changes the design — an unnecessary question is a flaw at any wave number, and ten necessary waves are not.
**Wave composition — questions are ordered by decision leverage, not by perspective:**
- **Wave 1 — shape:** the questions whose answers change everything downstream. Scope boundary (multiSelect: which of these 4-6 scouted capabilities is v1?), the one architecture fork, the primary user moment, targeting disambiguation if needed. **Order metaphor/shape questions before presentation questions** — a presentation answer given before the metaphor settled has to be re-asked.
- **Middle waves — perspectives sweep:** work through the perspectives *still genuinely open* after the shape settled: **functional** (edge behaviors, empty/error states), **UX** (entry point, flow, what the user sees while waiting), **UI** (which shared primitives, where it lives visually), **performance/architecture** (data volume, caching, sync vs background, engine impact). Deep ideas may need several waves inside one perspective — follow-up questions that only became possible after the previous answer are the sign the dialog is working, not drifting.
- **Final wave — residue:** whatever the checklist pass still marks open. If a wave's answers OPEN more items than they close for two consecutive waves, the spark is compound — propose splitting it into two ideas rather than continuing.
**Question craft rules:**
1. Every option is a real, scouted, buildable choice — description names the trade-off in one line. Put your recommendation first, marked "(Recommended)". **Write the condition into the option text**: when an option's risk is conditional, name the condition, so an override arrives with its mitigation already agreed.
2. **Decide, don't ask, when convention already answers:** the repo's own conventions (strings, tokens, shared components, error handling, loading UX — the overlay's `## Repo law`) are never questions. Consult `## Question taste` — it accumulates what this operator wants asked vs. decided for them. Operator "Other" answers and corrections are the strongest taste signal; when the overlay declares a Phase-3 correction-capture ritual, run it in the same turn as the correction.
3. **An answer may be a DOCTRINE rather than an option pick.** When the reply reframes the question, treat it as a course correction: re-scope, and re-scout if it created a new code question.
4. After each wave, write `## Design decisions` immediately (chosen AND rejected options) — a killed session must lose nothing.
5. **A mid-wave stop means the options were too narrow, not that the question was wrong.** When the operator interrupts a wave to clarify, widen the option set with what the interruption revealed before re-asking; the reframed answer is usually the best one the dialog produces.
6. **Two answers that contradict each other get a synthesis, not a re-ask.** When picks from different questions cannot both hold, propose the design that keeps both intents as one option and ask once.
7. **Completeness gate before leaving Phase 3** — the perspective checklist, answered either by operator choice, convention, or explicit Director decision (marked as such): functional scope, data model and persistence, command/API surface, UX flow plus all async/empty/error states, UI surfaces and shared-component reuse, strings/i18n plan, performance posture, failure modes, doc surfaces affected, out-of-scope list.
### Phase 4 — The brief & the go-gate
Write `## Design brief` in the idea note:
```markdown
### Summary (three sentences a PM would sign)
### Work packages (1-4, each ONE builder session: files touched, what changes,
acceptance criteria 3-6 checkable bullets, and the DOC SURFACE it owns -
where two packages document one feature, exactly one owns the file and
the others emit sections to scratch for the Director to merge)
### Data & API (schema/migrations, new commands/endpoints, generated types to regen)
### UX/UI spec (per-surface: states, components from the catalog, tokens, loading pattern)
### Strings (sections touched; the overlay's translation ritual, if any, runs before commit)
### Non-goals (explicitly rejected options from the waves)
### Risks
```
**Contract completeness:** when packages build in parallel against this brief, it must name every **wire-level identifier** — type names, field names, command/parameter names, enum string values, key formats — not just types and shapes. A renamed argument that the contract did not carry is the defect this rule exists for. Three more gaps recur between parallel packages, so the contract closes each explicitly:
- **Every new field or input names its producer AND its first consumer**, and that consumer sits inside some package's file scope. An input with a producer and no owned call site ships dead.
- **The absent-value convention is stated once** in `### Data & API` (omit the key, `null`, or `0`, and why), so two packages coding the same missing value do not drift.
- **A number a sibling package computes is derived from the contract or labelled "illustrative, not arithmetic".** A fixture figure that contradicts the formula is resolved three different ways by three builders.
**Compute the landing overlap before the gate, not at merge.** Intersect the brief's file list with the landing checkout's `git status --short` (and, for a fan-out that re-stamps or regenerates shared files, say so plainly: a clause re-stamp, a codegen pass and a regenerated index each touch files no work package names). A non-empty intersection means the merge is already blocked by someone else's uncommitted work, so the gate question names the landing path with the build — land later, open a PR, or have the operator commit first. "Build now" must not silently mean "build now, block at merge".
Gate with one AskUserQuestion: **Build now / Adjust (say what) / Park it** (`status: designed`). "Adjust" loops one targeted wave, not a restart. "Park" is a first-class success — a designed-but-parked idea is a shippable asset in the vault.
### Phase 5 — Fire (execution)
1. `git worktree add .claude/worktrees/spark-<slug> -b worktree-spark-<slug>` from `base_branch` — all multi-file work isolates. **Unless the overlay's `## Repo law` says the repo's gates cannot run in a worktree** (a dev-server lock, native dependencies, generated types bound to the main checkout): then build in the main checkout on `base_branch`, with builders on disjoint file scopes. Either way the repo's own parallel-safety law applies in full: stage per file, verify the staged set against your intent before every commit, never stash, never `git add -A`.
2. One builder per work package, sequential when packages share files, else parallel. **When a consumer package depends on a producer package's exports, the Director commits the wire types AND compilable stubs with the final signatures before the fan-out**, so the packages share no file and both typecheck alone (it has turned sequential packages into parallel ones in three projects; the runs are in `LESSONS.md`). Brief = the work package + the overlay's `## Repo law` digest + the `## Gates > builder` commands + "state the constraint and the evidence, and counter-propose rather than guess". **Assign a cross-cutting property (encryption, auth, audit) to the FIRST package that creates data subject to it**, never to a later one — otherwise the branch has a real intermediate state that violates it.
- **Write each brief to a scratch file and hand the builder its path.** A file can be amended after the Director reads more code, lets parallel builders be briefed in one turn, and survives a rate limit that kills a builder mid-flight: the resumed builder re-reads its own brief and files and loses nothing.
- **Never dispatch a package whose design depends on a question still open,** even when the package looks independent. Order the wave before the work it determines.
- **Parallel builders share nothing live.** Each UI builder gets its own port and kills it on exit, or verifies headless; a builder that writes app data uses a throwaway store or a scratch identity and reports what it wrote. Two builders on one browser or one dev server cross-contaminate, and one builder's fabricated test data is read into the next run.
3. Director reviews every diff against acceptance criteria (not vibes), runs the overlay's `## Gates`, fixes-or-bounces, commits atomically per package. **Run the repo-wide gates at the FIRST package commit, not at the end:** tree-wide ratchets and budgets (an import-graph budget, a literal-count ratchet, a route registry) bind every new module, and they are often red on arrival, so compare each against the spark's base commit rather than against zero. Found at the end, one spark's growth is indistinguishable from the tree's.
**A fix the Director orders from its own diagnosis carries its own falsification.** When the defect was read off an artifact (a transcript, a log, a screenshot), the brief names the case that provoked it and one neighbour that never triggered it; the builder measures both before and after; a fix that worsens the measured outcome is withdrawn and documented, not tuned. A diagnosis read off one artifact is a hypothesis, and the builder's measurement outranks it. Builder refusals backed by evidence are signal, not disobedience. Any Phase-5 ritual the overlay declares (a translation pipeline, a codegen regen) runs before the commit it belongs to, not at the end.
4. Doc-sync: update the doc surfaces the overlay maps for the touched areas, in the same session. If the repo has an automated doc-sync check, ask the scout in Phase 2 whether the target paths are covered by it at all — a check that never fires reads exactly like a check with nothing to say.
5. Merge to `base_branch` only when all gates are green; then remove the worktree + branch. Do not assume the main checkout is on `base_branch` or clean: rebase the spark branch onto the base inside the spark worktree, then `git checkout <base> && git merge --ff-only` there if the base is free. `status: shipped`, record SHA.
**An integration seam is smoke-tested on the built artifact before ship** (a client calling its server, a process calling a process): packages green in isolation, with fixtures on both sides, never cross the seam, so only the real build shows a missing CORS layer or a hardcoded port. **Visual and browser verification of UI polish stays an optional follow-up note, never a blocking phase** — record the surface and the selectors to drive in the idea note and in `Spark.md`, and ship.
### Phase 6 — Retro (the self-improving mechanism)
Before running the overlay's Phase-6 rituals, the Director audits **the process, not the product**, and writes `## Retro` + appends dated one-liners to the overlay's `## Skill improvement log`:
- **Targeting accuracy:** did the build touch contexts targeting missed, or skip ones it named?
- **Question efficiency:** which questions changed nothing downstream (should have been convention)? What did the operator answer via "Other" that the options should have contained? Mirror any correction's lesson into `## Question taste`.
- **Scout misses:** anything the builders discovered that the scout should have surfaced?
- **Execution friction:** gate failures, builder bounces, rework — and the upstream design decision that would have prevented each.
- **Skill edits:** if >=2 sessions' logs point at the same flaw, propose a concrete edit to THIS file — gated with the operator, never silent. A repo-specific lesson goes to the overlay, never to this file. **A repo-specific lesson seen for the second time is promoted in this retro** into `## Gates` or `## Repo law` (see Phase 0), not appended to the log a second time.
Wrap: session note with `next:` pointer, update `Spark.md` ledger, run the overlay's Phase-6 rituals (typically deregistering from the live-sessions ledger with the SHA).
## Invariants
- One spark per session by default; the vault + worktrees + whatever ledger the overlay names are what make many parallel sparks safe.
- The operator's verbatim spark text is sacred — design converges *toward* it; scope creep beyond it needs an explicit question.
- Waves are uncapped; clarity is the terminator. Each question must earn its place; the checklist decides when the dialog is done. Two consecutive waves that open more than they close → propose splitting the spark.
- Never mark shipped on a typecheck alone — the overlay's gates run, integration seams are smoke-tested on the built artifact, and UI work gets observed, not assumed.
- **Never paste one repo's overlay into this file.** A project copy that did so shadowed the shared copy unnoticed.
---
<!-- clause: knowledge-sync v2 - stamped by scripts/apply-skill-clauses.mjs from docs/skill-clauses/knowledge-sync.md; edit the template, then re-stamp -->
## Knowledge sync
This skill proposes and executes backlog items. Every item it proposes is judged against the standard this repo subscribes to, so a run moves the codebase toward the registry's golden paths and sends back what it learned - not toward a private notion of "better" that the next skill will undo.
**Subscription** - read once at the start of the run; degrade honestly, never invent a standard:
- `.ai/manifest.yaml` -> `registry.local` (default `../ai-registry`; `$AI_REGISTRY_DIR` wins) and `knowledge.domains` (the bundles this repo consumes - `software-engineering` for code, plus whatever else it declares). No registry declared -> skip this section and say `registry: none` in the run header.
- `.ai/registry-map.json` - the join between this repo's contexts and the bundle's subjects, with a per-pair state (`unknown` / `conformant` / `deviation` / `not-applicable`) that `/conform` fills in over time. Missing while `context-map.json` exists -> build it once, `node <registry>/scripts/build-registry-map.mjs --project <slug>`, and commit it: the map is the repo's subscription to the paths, and it is how a path improved for another project reaches this one. Missing both -> resolve through `<registry>/knowledge/<domain>/index.json` and say `registry: declared, unmapped`.
- The always-on rules `.claude/rules/ai-registry-*.md` carry the subject map. They orient; they do not replace the read below.
**Read before you propose.** For each context in scope, take its subjects from the map and read the golden path (`subjects[<slug>].file`, verbatim from the index - never a path built from a slug; bundles are nested) plus the techniques whose `use_when` matches what you are about to decide. Then every backlog item you emit names the technique it serves or violates - `standard: <subject>/<technique>` - or `standard: none` when nothing governs it. A pair the map already marks `deviation` is a pre-approved item with its fix described; a pair marked `conformant` is a regression guard on anything you change there. A deviation is a finding: never lower the standard to fit the code, and never present a technique's number as a rule - the technique carries the rule, the application carries the measurement.
**Log the read** - one line per context, append-only, to `.ai/consults.jsonl` in the task's MAIN checkout (never a disposable worktree), written before the run's first commit - pre-commit consult checks read it: `{"ts":"<ISO>","bundle":"<domain>","subjects":["<slug>"],"techniques":["<slug>"],"deviations":<n>}`, where `deviations` counts the items this run raised that a technique explicitly names. Bare slugs, never paths. The registry's `signals-collect.mjs` folds these into `signals/` as counts only; it is the only way the corpus learns which paths are load-bearing and which are decoration.
**Send back what a LANDED fix taught.** When a change you made and verified generalizes past this repo - a rule that would transplant to an unrelated team, a case where a technique's rule broke against real code, or a place this repo does it BETTER than the golden path - append one line to `.ai/registry-leads.jsonl`: `{"ts":"<ISO>","bundle":"<domain>","nearest":"<subject-slug or null>","kind":"technique|application|subject","claim":"<when X, do Y, because Z - one sentence>","because":"<what this run measured or broke and fixed>","confidence":"low|medium|high","from":"spark@<version>"}`. Earned only: it came from code you changed, not from a fix you proposed. A lead ORIGINATES a finding and never authorizes one - nothing here edits a bundle; the registry's `leads-collect.mjs` -> `librarian/inbox.md` -> `/intake` decides what survives. Say in the report that you filed one, and say plainly when you filed none. Verdicts on a pair's state belong to `/conform`: close by naming the contexts you touched so it can re-judge them.
<!-- /clause: knowledge-sync -->
<!-- clause: skill-reflection v6 - stamped by scripts/apply-skill-clauses.mjs from docs/skill-clauses/skill-reflection.md; edit the template, then re-stamp -->
## Skill Reflection
After the work, record only useful observations supported by this run. No lesson is
a valid result. Reflection inherits the task's authorization; it grants no additional
permission to edit another repository, send data, commit, or publish.
**Run log.** Unlike a lesson, this is written on every run that started work - failed and
aborted runs included; skip read-only info modes and runs cancelled before any work. Append
ONE line to `.ai/skill-runs.local.jsonl` at the root of the task's MAIN checkout: local,
gitignored run output inside the task's own repository, never a write into the registry.
A run that worked in a linked worktree logs in the main checkout that worktree belongs to
(`git rev-parse --git-common-dir`, minus `/.git`) - a disposable worktree takes the line
with it when it is removed. `log-run.mjs` resolves this on its own.
The registry pulls it later (`/librarian skills` on the same machine). When a registry
checkout is reachable (`registry.local` in `.ai/manifest.yaml`), prefer its writer, which
stamps project, device and version for you:
```sh
node <registry>/scripts/log-run.mjs --skill spark --outcome <o> --difficulty <1-5> \
--provider <claude|openai|xai|qwen|google|other> --model <your model id> [--effort <level>] \
[--tokens-est <n>] --result "<one sentence>" --comment "<self-reflection>"
```
Otherwise write the line yourself: `{"ts":"<ISO, UTC Z>","skill":"spark","outcome":…,
"difficulty":…,"provider":…,"model":…,"effort":…|null,"tokensEst":…|null,"result":…,"comment":…}`.
- `outcome`: `shipped` (the goal landed) / `partial` / `no-op` (ran correctly, nothing to
do) / `parked` (designed or staged, deliberately not landed) / `failed` / `aborted`.
- `difficulty` rates the task as this run met it: 1 trivial - mechanical; 2 routine - the
method as written; 3 demanding - real judgment calls or one detour; 4 hard - dead ends,
rework or an operator course-correction; 5 at the edge - partial or failed on the merits.
- `model`/`effort` as your harness states them (`null` effort when you cannot see it).
`tokensEst` is the drop in the harness's remaining-token counter since this skill was
invoked, or `null` (with `log-run.mjs`, omit `--tokens-est`); exact figures are measured
later from transcripts - never guess one.
- `result` is one line (max 240 chars). `comment` (max 2000) is the self-reflection a
reviewer reads: what worked, what the method made harder, where its instructions were
wrong, missing or ignored. No filesystem paths or email addresses.
- Never read run logs during a run. They are evidence ABOUT this skill for its reviewer;
an executor that reads its own diagnosis contaminates the next measurement.
**Project learning.** Only when this run produced an observation that would change how a
future run behaves. A run that went as the method describes writes nothing: an entry that
restates the procedure, records "no issues", or repeats the task is a defect, not a
deliverable. When there is such an observation and local edits are within scope, put one
dated line in the overlay this skill's `## Project overlay` section names, under
`## Skill improvement log`. **Write only into an overlay that already exists.** If the
project has none, put the observation in the response instead - creating a new tracked
file for a reflection is scope the task did not ask for, and a reader who never asked for
the skill has to review it. If the overlay is a structured config (YAML, TOML, JSON),
record the note as comments so the file keeps parsing, or use the response.
Use a supplied memory contract only when its destination and writes are authorized.
Keep project details out of the shared method.
**Method learning.** Identify the installation before editing anything. A local
`.ai/registry-installation.local.json` receipt can identify development versus release,
the registry revision, and selected skill versions. Verify any link's actual target;
do not assume a skill directory is a writable registry link.
- For a pinned release, marketplace cache, ordinary copy, or unknown installation,
keep a proposal in the project overlay or response. Do not edit the installed method
or silently relink it. Adoption and rollback are explicit installation operations.
- For a development link, edit the registry only when that checkout is already within
the accepted task scope. Otherwise report a proposal. Authorized changes belong in
the source checkout, followed by its gates; commit only when the task authorizes it.
- Record an actual lesson in `LESSONS.md` against the version **used**:
`## <version-used> - <YYYY-MM-DD> - <project-name>` and concise bullets. A proposal
must be labeled as such; structural checks are not evidence of field effectiveness.
- Applied skill changes require a version bump: patch for wording, minor for a step
refinement, major for method redesign. A lesson alone needs no bump. Shared stamped
clauses are edited in the registry's `docs/skill-clauses/` and regenerated with
`scripts/apply-skill-clauses.mjs`, never patched in individual installed skills.
**Domain learning.** Follow `## Knowledge sync` when present, within the same scope
and privacy boundaries. A method lesson and a domain knowledge lead are different
artifacts; do not fabricate either to fill a reflection quota.
<!-- /clause: skill-reflection -->