AGENT SKILL

new

Start a dossier wave from a goal sentence; the sole entrypoint. Invoke when the user says "ds:new" or "start a dossier", or when work meets the start rule — more than one session, more than 5 files, or an operator step.

License 许可
ISC
最近更新
2026-11-13
Stars
★ 3
Forks
0

01 前言 Front Matter

name
new
description
Start a dossier wave from a goal sentence; the sole entrypoint. Invoke when the user says "ds:new" or "start a dossier", or when work meets the start rule — more than one session, more than 5 files, or an operator step.
argument-hint
"<goal sentence>" | <slug>

03 SKILL.md 正文

ds:new — start a wave

Creates .scratchpad/dossier/<YYYY-MM-DD>-<slug>/DOSSIER.md per ${CLAUDE_PLUGIN_ROOT}/FORMAT.md, then asks the operator for goal, scope and repos.

Inputs

  • "<goal sentence>" from $ARGUMENTS — the normal start. Run ds:grill "<goal sentence>" first, then come back with the slug it confirms; step 1.5 consumes its draft. Skip the grill only when the goal is one line with no open decision, and derive the slug from it.
  • <slug> (kebab-case, ≤30 chars) — the start after a grill, or for a backfill. Empty → ask for the goal sentence.
  • Date defaults to today (date +%Y-%m-%d). Override by prompt when backfilling historical work.

Steps

0. Helpers

§S lines append via "${CLAUDE_PLUGIN_ROOT}"/cli/ds s-append <dir> "<event>" (FORMAT.md §15) — pass the text after the timestamp, which the script prepends; ds new-finish (step 5) writes the DONE line. The initial scaffold is a full Write (new file).

1. Validate slug + path

  • Slug matches ^[a-z0-9][a-z0-9-]{0,29}$. Anything else is refused with an explanation.
  • Run "${CLAUDE_PLUGIN_ROOT}"/cli/ds root and compute dir=<root>/.scratchpad/dossier/<date>-<slug>/ from the path it prints. Every .scratchpad/ path below is under that root. In a linked worktree with no ledger yet, the root is the primary checkout, so removing the worktree cannot delete the ledger.
  • Collision check: dir exists or .scratchpad/dossier/_archive/<date>-<slug>/ exists (a same-day close+reopen) → ask the operator to bump to <slug>-2, <slug>-3, etc. Checking _archive/ too avoids two INDEX rows keyed to one slug (Vm.1).
  • Ignore check: in a git work tree, git -C <root> check-ignore -q .scratchpad/ exiting 1 means the ledger will show as untracked and a git add -A would commit it; any exit other than 0 or 1 means the check could not run, so say that. Carry the result into the step-6 report with the per-clone fix — append .scratchpad/ to the file git -C <root> rev-parse --git-path info/exclude names — and leave the choice to the operator; some repos track .scratchpad/ on purpose.

1.5. Grill gate (conditional)

Fires only when a grill artifact exists for this slug, so trivial ds:new runs are untouched. <slug> is the RESOLVED slug from step 1 (post-collision-bump; a bumped <slug>-2 starts without <slug>'s grill):

"${CLAUDE_PLUGIN_ROOT}"/cli/ds assert-grill .scratchpad "<slug>"

The helper discovers the newest .grill/<date>-<slug>.md by slug — grill's own date may be days older than today (multi-day --resume, pending-external waits) and the gate still finds it. Route on the exact exit code:

exit meaning action
0 complete (path printed) consume its ## Draft §G/§C in step 2 — do NOT re-ask; after the step-3 Write lands, stamp via ds assert-grill --consume .scratchpad "<slug>" "<date>-<slug>" (atomic tmp+mv per Vm.8; refuses a double-consume)
1 no artifact proceed normally — grill is never required; step 2's clarify lever recommends it
2, 3 artifact incomplete / unconfirmed REFUSE scaffold; point at ds:grill --resume <slug> (or delete the artifact to abandon)
4 artifact already consumed proceed normally; recommend a fresh ds:grill "<goal sentence>" — a consumed grill never feeds twice
69, 70 cli/ds did not run (69: no Node.js 22.18+; 70: internal error) REFUSE scaffold; report the stderr line

A new slug does not bypass an open grill. When this session left a grill under another slug incomplete or unconfirmed, refuse the scaffold and point at ds:grill --resume <that slug>, unless the operator abandons it.

2. Gather inputs (operator-interactive)

Ask one block at a time, tersely, no preamble:

  1. §G goal — one-line outcome, then up to 5 scope bullets (IN / NOT IN).
  2. §C constraints — locked decisions, stack notes. Bullets, ≤10.
  3. §X repos — each repo this dossier touches, as <org>/<name> or an absolute path. Operator-provided; no git-remote magic.
  4. Initial §T tasks — ask for T1..Tn now; an empty answer leaves §T empty. Give a row who=H only after the agent tried to prove it in a scratch fixture (a throwaway directory, an isolated tmux socket, a disposable session) and could not. A re-check that waits on a date gets its own row with a T<n>+<k>d need, so ds close --carry carries it; a row that joins it to work done now holds the wave open until the date.

A wide refactor is sequenced expand–contract. One mechanical change whose blast radius breaks many call sites at once (rename a column, retype a shared symbol) cannot land green as one task. Expand first: add the new form beside the old. Then migrate the call sites in batches, one task each, each needs the expand. Contract last: delete the old form in a task that needs every batch.

Clarify before freezing (the highest-value lever): an underspecified §G or §C decision — ambiguous scope, an unstated choice, more than one plausible approach — gets its resolving question NOW, before §T is authored. A vague goal yields vague tasks, and one or two sharp questions here beat a wrong build. More than a couple of open questions → recommend ds:grill <slug> (full interrogation protocol, artifact-gated). "Just go" → record the assumption as a §C bullet so it stays auditable.

§I, §V, §B, §S and §Z grow during the build; the scaffold leaves them empty.

2.5. Resolve pins (proactive verify)

From the stack named in §C plus the repos in §X, derive a pin-spec list and resolve current versions once (shared 24h cache, offline-safe):

"${CLAUDE_PLUGIN_ROOT}"/cli/ds resolve-pins eol:<slug>... <ecosystem>:<pkg>...
  • eol: results → §C bullets (current stable / EOL note).
  • A version, SHA or deprecation claim in §C that no spec covers → dossier:verify checks it against a primary source.
  • package results → the §I "Pinned deps" table (FORMAT.md §6).
  • Map the libs actually named to specs (e.g. "Go backend + React UI" → eol:go npm:react npm:react-dom go:<module>). The model does the stack→spec mapping; do not blind-parse §C prose into specs.
  • {"offline": true} / latest: null, or exit 69 (no Node.js 22.18+) / 70 (internal error) → record the pin as offline and proceed; the scaffold continues either way.
  • go:<module> without a /vN suffix names the v0/v1 path, so the resolver walks /v2 through /v12 and answers from the highest that resolves — pin the module path in src, not the one you asked for. A warning on the object means a probe went unanswered: the version is a floor, not the ceiling.

These fold into the single atomic step-3 Write — no extra commit, no TDD cycle.

2.6. Subtraction pass (ungrilled wave only)

Runs when step 1.5 exited 1 or 4 — no grill fed this wave, so no set audit or subtraction pass has seen it — and whetstone is installed. Spawn the subtraction pass (whetstone doubt-pass, "Subtraction pass": its template, its model rule) on the draft §G, §C and §T as the artifact, with §G as the contract. One cycle. Show each cut to the operator and ask which to take; a cut never edits a §C bullet the operator gave without that answer. Hold the SUBTRACT: line and append it to §S after step 3 as ds:new — subtract=<verdict>. Without whetstone, skip it and say so in the step-6 report.

2.7. Write the contract

The repo decides the home. .dossier/ exists → the repo opted into tracked contracts: write .dossier/<date>-<slug>.md and commit it before the first task — citable as evidence, outliving the wave. Otherwise write <wave-dir>/CONTRACT.md beside the ledger and price that home out loud: untracked wherever .scratchpad/ is gitignored (the assumed setup), archived with the wave, citable by nobody, and its criteria run as shell from a file no diff ever showed a reviewer — where a tracked contract's criteria appear in the commit that added them. Name the opt-in (mkdir .dossier, track it) so the choice stays the operator's. Never create .dossier/ yourself — a tracked directory appearing in a repo that did not ask for one is the artifact rule this split exists to respect.

Either way the content is FORMAT.md §2.5's — consumer, reached-via, budget, an optional milestone (the cutover row, when rows run after it), and a ## done-when table whose every row is a command with an expected exit code. ds:converge and the UserPromptSubmit hook resolve both homes, tracked first.

consumer is the field that asks whether the work reaches anyone, and the one nobody writes unprompted. Ask for it plainly: who runs this, and by what path does it get to them? A wave once hardened a checker through three review rounds while no consumer could execute it, and no step in this skill had ever asked. ds:converge refuses a contract whose consumer row is missing or empty (CONVERGE: PARSE, exit 2), so a contract written without the answer fails its first run.

A criterion that cannot be written as a command is a criterion nobody can check. Turn it into one, or drop it and say what was dropped.

A done-when command reads source and repo state only. It does not read a deployed target, a pushed remote, or anything that waits on an operator step. A runtime rewrite or an operator delay then fails the check. Put pushes, deploys and reloads in who=H rows. ds close --carry carries them as after: rows.

A §T row marked route=delegate adds the done-when row `<plugin>/cli/ds delegation-check <dossier-dir>` with exit 0 guard (it passes before any row is built), so ds:converge checks each delegated row's review and rebuild lines.

In the tracked home, commit the contract after the step-3.7 sign-off and before the first task — the UserPromptSubmit hook counts budget from the commit that added the contract.

3. Scaffold DOSSIER.md

Compute fields:

title = <slug>
header_line = `<date>` · `live`

Write the file at <dir>/DOSSIER.md per FORMAT.md §2 section order:

# <slug>

`<date>` · `live`

## Goal

<goal-from-step-2>

Scope:
<scope-bullets>

## Constraints

<constraint-bullets>

## Interfaces

_(empty — populate when first contract lands)_

## Invariants

| id | invariant | check |
|----|-----------|-------|

## Tasks

| id | state | who | task | needs | cite | verify |
|----|-------|-----|------|-------|------|--------|
<initial-tasks-if-provided>

## Bugs

| id | bug | root cause | invariant added | fix cite |
|----|-----|------------|-----------------|----------|

## Repos

| repo | branch | ahead | tag | pushed | notes |
|------|--------|-------|-----|--------|-------|
<repo-rows-from-step-2-with-placeholders>

## Status

<!-- Each entry is its own paragraph (blank lines before AND after). Per FORMAT.md §11. -->

<YYYY-MM-DD HH:MM:SS> ds:new — created slug=<slug>

## Closeout

_(empty — written by ds:close)_

Write <dir>/DOSSIER.md directly: the file is new, and step 3.5 catches a partial write.

3.5. Assert scaffold completeness

Before touching INDEX or §S, confirm the write landed intact:

"${CLAUDE_PLUGIN_ROOT}"/cli/ds assert-scaffold "<dir>"

It exits 1 naming any missing §-section (or the title line) — deterministic, so nobody eyeballs the Write output. On failure step 5 waits: report the missing sections, re-run the step-3 Write to repair, then re-assert. Mirrors the post-move assertion ds:close runs via ds archive-move. Exit 69 (no Node.js 22.18+) or 70 (internal error) means the assertion did not run: report its stderr line and stop before step 5.

3.6. Baseline the contract

A row that passes before the work cannot judge the work. Run every row once, now:

"${CLAUDE_PLUGIN_ROOT}"/cli/ds converge --baseline <contract-path>

BASELINE: OK (exit 0) appends ds:converge — baseline OK … to §S; then go to step 3.7. BASELINE: FAIL <ids> (exit 1) appends ds:converge — baseline FAIL <ids> to §S (nothing is written when no live wave owns the contract) and names each row that passed or did not run (exit 124, 126 or 127), or each guard row that failed: rewrite the row so it fails until the work lands (a script the wave has not written yet: test -f tools/x.ts && node tools/x.ts), or, for a row that must stay green throughout (a full CI run), end its expect cell with guard (exit 0 guard), then rerun. Which row is a guard is model-judgment; the baseline line lists every guard so the operator sees them. CONVERGE: PARSE (exit 2) is a contract to fix first.

3.7. Sign off the design

The sign-off judges the design before any build, from a notes file and the lines it cites, so it reads nothing else. One design covers one slice. This step signs off the wave's first slice. ds:build step 5.7 signs off each later slice before its build.

  1. Write the first slice's design to <root>/.scratchpad/tmp/<date>-<slug>/design-notes.md: the goal in the operator's words, each claim about current code with its path:N cite, a ## done-when table in the contract's shape (a row that must stay green ends its expect cell with guard), and one REMOVES: <name> line per skill, file or command the wave deletes or renames.

  2. Run the computed checks until they pass:

    "${CLAUDE_PLUGIN_ROOT}"/cli/ds design-check <notes> <repo>
    

    DESIGN: OK (exit 0) writes <notes minus .md>-evidence.md with every cited line. DESIGN: FAIL <n> (exit 1) names each cite that does not resolve, each check that passes today or did not run, and each file that names a REMOVES: item and is not in the notes: fix the notes and run it again. DESIGN: PARSE (exit 2) is a notes file to fix first.

  3. With evidence in the session's agent list, spawn one evidence agent with the notes path, the evidence path, the repo path and the findings path below. It runs its own checks, then spawns signoff, and returns the signoff reply. Otherwise, with signoff in the list, spawn one signoff agent. The plugin ships neither: they are the operator's own agents (ADAPTERS.md). A signoff agent may have no read tool, so put the full text of the notes file and the evidence file in its mission. Name a separate findings file for either agent, <root>/.scratchpad/tmp/<date>-<slug>/signoff-findings.md. Read the findings from that file, or from the reply when the file is empty (an evidence agent that stops early writes its findings in the reply). There is one line per finding: block: or note:, then missing: <what>, at <file:line or section> or evidence missing: <fact>, at <file:line>. A block: finding makes the build wrong or unsafe; every other finding is a note:. The reply ends with SIGNOFF: PASS when no line is block:, else SIGNOFF: CHANGES. Without either agent, the verdict is skipped-absent.

  4. Append §S ds:new signoff=<PASS|CHANGES|skipped-absent> notes=<notes>, where <notes> is the design notes path from item 1, never the findings file: ds:build hands it to the builder and the reviewer as the design. Put each note: line in the step-6 report as a follow-up. On CHANGES, fix each block: line once, re-run item 2 (ds design-check), and ask for one re-check; a second CHANGES goes to the operator with both lists.

Then commit the contract (tracked home). Whether the sign-off is sound is model-judgment; that the line exists is code: step 5 exits 1 without it.

4. Initial §X refresh

For each repo row added in step 2, run:

"${CLAUDE_PLUGIN_ROOT}"/cli/ds x-refresh <dir> <repo-label> <repo-path>

When it refuses with not a git repo, the row keeps its placeholders plus the note _(repo not found — verify path)_.

5. Finish

"${CLAUDE_PLUGIN_ROOT}"/cli/ds new-finish <dir>

It exits 1 naming the missing line when §S has no ds:new signoff= line: run step 3.7. Otherwise it regenerates .scratchpad/INDEX.md, appends ds:new — DONE slug=<slug> dir=<dir> to §S, prints the ds handoff lines and exits 0.

6. Report

ds:new <slug> → .scratchpad/dossier/<date>-<slug>/DOSSIER.md
§X: <N> repos seeded
follow-ups: <each sign-off note: line, or none>
next:
<each handoff line step 5 printed, verbatim>

Add .scratchpad/ is not gitignored here plus the fix when step 1's ignore check fired.

Idempotency

<dir>/DOSSIER.md already exists → refuse; the operator picks a new slug or opens the existing one via ds:status.

<dir> exists with DOSSIER.md missing (a rare crash mid-scaffold) → recreate it, preserving any §S entries from the partial run.

Cite

  • FORMAT.md §2 (section order), §2.5 (wave contract), §10 (§X format), §11 (§S format), §17 (Vm rules)

04 同仓库更多 Skills

raisedadead
raisedadead/claude-code-plugins

suite-review

Run the monthly evidence review of this repo's plugin skills. Count each skill's opportunities and uses with the census, read what happened where a skill was not used, put each skill in one bucket, act, and write the actions as predictions with a check date. Use when the operator says "suite review" or "monthly review", or when the suite-review line on LATER.md is due.

★ 3
raisedadead
raisedadead/claude-code-plugins

tiger-style

Check the column budget of the lines a change adds, and read that change against the TIGER_STYLE shape rules a script cannot judge. Use when the user asks about line length or column limits, to check code shape, what the column check flagged, or why a commit was blocked on a column budget.

★ 3
raisedadead
raisedadead/claude-code-plugins

tdd-cycle

Drive one vertical slice of behaviour red-green-refactor, seam agreed before the first test. Use when the user asks to add a feature, fix a bug, write code test-first, says "TDD this", "red green refactor", or "write a failing test first". Inside a live dossier:build covenant, invoke dossier:build instead — it composes this skill's run-slice command as its RED/GREEN proof.

★ 3
raisedadead
raisedadead/claude-code-plugins

prototype

Build a throwaway prototype to answer a design question. Use when the user wants to sanity-check whether a state model or logic feels right, or explore what a UI should look like.

★ 3
raisedadead
raisedadead/claude-code-plugins

doubt-pass

Adversarial doubt cycle on a plan or design before any code exists — distinct from post-hoc code review. Use when the user asks to doubt this, stress-test a design before building it, poke holes in a plan, find the flaw in an approach, or before committing to a non-trivial architecture or design decision.

★ 3
raisedadead
raisedadead/claude-code-plugins

diagnose

Diagnose a hard bug or a performance regression with a feedback loop first, then ranked hypotheses, instrumentation and a regression test. Use when the user says diagnose or debug this, or reports something broken, throwing, failing or slow.

★ 3