verification-setup
Interviews the owner, one topic at a time, and writes `.claude/rules/verification.md` — the environments, resource capacity, refresh/deploy commands, test identities, tooling, known gaps, and coverage
Files3
View on GitHubSKILL.mdpackages/skills/verification-setup/SKILL.md
GitHubverification-setup
.claude/rules/verification.md is owner-governed: infrastructure policy, not something a
model should guess at. This skill is the only way it gets written or changed — running it
IS the owner's approval, so there is no separate confirmation step once the interview is
done.
When it applies
- A new project, right after
/init-projectcopies the template unfilled. - A readout —
/implement-trd,/verify-build, or a phase gate — that named this skill becausecheck-verification-unfilledfound a missing section. - A
/verify-build --fixrun recorded a need against the file (/refine-verificationnames such needs in its diagnosis; it never records or edits anything there). - Any time the owner wants to change what the file says, filled or not.
Inputs
| Input | Where it comes from |
|---|---|
| The current file | .claude/rules/verification.md, or template.md (this skill's own directory) when the file is absent |
| The current shape | template.md — the shipped template, current as of the last install or refresh |
| What sections are missing | check-verification-unfilled (functional-verification.js), read for missingSections |
| Repo signals | package.json scripts, docker-compose*, .env*.example (key names only — see Never), vercel.json, railway.json/railway.toml, .claude/verification-notes.md, CLAUDE.md |
| Installed detectors | tooling-detector, framework-detector, test-detector, cloud-provider-detector, whichever exist under .claude/skills/ in this project — used when present, never assumed |
| A coverage-floor recommendation | recommend-coverage-floor .trd-state (functional-verification.js), reading every */verification-state.json |
| Recorded needs | .trd-state/*/discovered.jsonl rows whose file is .claude/rules/verification.md — the needs /verify-build --fix records |
Topics
One AskUserQuestion call per topic, in the file's own order, so the interview reads the
way the file does rather than jumping around:
- §1 Environments — name, URL/reach, purpose, and the three permission columns (may write data?, may deploy?, may restart?).
- §1a Resource capacity — how many of each resource may exist at once, and how the loop tells instances apart when more than one exists.
- §2 Refresh and deploy — the fast refresh run after every debug pass, and the full deploy run once at the end.
- §3 Test identities — where each credential lives (a vault item, an env key, a file path) — never its value.
- §4 Tooling — what verification tooling is actually installed and configured today.
- §5 What cannot be verified here — the gaps, stated plainly, so they read as a stated limit rather than a silent pass.
- §5a Coverage floor — see Coverage floor, below.
- §5b Never unattended — see Never unattended, below.
- §6 Multi-repo — only when the system spans more than one repository.
Each call offers, in this order: the detected value (marked as detected, with its source), then the file's current value where it differs from the detection, then "keep". An answer of "keep" — or skipping the topic — leaves that section's current content untouched; nothing is rewritten just because the topic was visited.
The three permission columns, the §1a counts, and whether a gap in §5 is permanent are owner-only: nothing in the repository can tell the skill whether staging may be written to. These default to the template's own example row for that environment kind, labelled "not detectable — the conservative default" rather than presented as a real detection.
Re-running on an already-filled file asks only what changed. A topic is asked again only when: its section is missing from the current file, the repo's detected evidence now differs from what the file says, or a recorded need (see Inputs) names it. Every other topic is left alone and listed as unchanged in the closing summary — a re-run is a targeted update, not a second full interview.
Coverage floor
The question itself tells the owner what the floor is before asking for a value, in these words or close to them:
"The coverage floor is the share of the success definition's criteria that must be proven (met) before a verification run may report satisfied; a run that proves less than this reports insufficient-coverage instead, even with no open gaps."
It is asked in the same AskUserQuestion call that carries the table and recommendation below, so the owner sees the definition, the working and the recommended value together.
Shown as one small table, one row per past run this project has: feature, proven/total
criteria, and the proven share. Then the recommendation itself, with the reasoning that
produced it in one line — which run was lowest, and what its share rounded down to the
nearest 5% — because that is showing the owner the working, not just the number. When the
lowest satisfied run proved very little of its own criteria, the skill says so plainly, with
that run's own figures, and leaves the decision to the owner rather than filing the number
past them. With no past run that ended satisfied, the recommendation is "no floor
recommended yet — none of this project's runs has ended satisfied; a floor can be added
after the first ones do." Any answer is accepted at this topic, including none, but it is
written as Coverage floor: <N>% or Coverage floor: none — the only two forms
read-coverage-floor parses. An answer of 0.6 or 60 is written as 60%, and the
recommendation (a fraction in the CLI's output) is offered as a percentage too.
Never unattended
§5b is the list of paths /plan --implement will never build without the owner watching.
The question itself states that in one sentence before asking for a value: "Never-unattended
paths are folders /plan --implement will never build without you watching — nothing is
written without your answer." It is asked in the same AskUserQuestion call that carries the
detected default below, so the owner sees the reasoning and the proposal together.
The detected default is every folder that EXISTS in this repository whose path matches
auth, payments, billing, migrations, secrets, or infra/prod (substring match,
same as the brake itself) — offered as a starting list for the owner to edit, never written
as-is without an answer. With no matching folder in the repo, the default is Paths: none.
Any answer is accepted, including none or an edited list, but it is written in exactly the
two forms readNeverUnattended parses: one - <fragment> bullet per path, or a single
Paths: none line — never both in the same file, and never a bullet or a Paths: value left
empty.
Writing
Once every topic has an answer (an explicit value, "keep", or an owner-only default), the whole file is written at once, in the current shape. There is no preview step and no second confirmation — invoking this skill was the approval. A section the interview did not change keeps its owner-authored content verbatim.
After writing, the skill re-runs check-verification-unfilled, read-coverage-floor, and
read-never-unattended against the file it just wrote. A non-empty missingSections, a
floor that reads invalid, or a never-unattended list that reads invalid, is the skill's
own defect — report it in ISSUES rather than silently shipping a file the next check would
flag.
Never
- Write a credential's value. Only a vault item name, an env key name, or a file path — never a password, token, or connection string. If an answer to a topic looks like it holds a value rather than a location, do not write it; ask for the location instead.
- Contact or probe an environment. Detection reads files already in the repository; it never makes a network call to confirm a URL is reachable or a service is up.
- Edit any file other than
.claude/rules/verification.md. Not the template, not a rule file, not a TRD — one file, always. - Start a verification run, or any other command. Writing the file is this skill's whole
job. Running
/verify-build,/implement-trd, or anything else that reads the file it just wrote is the owner's own next invocation to make.
Readout
Ends with the framework's standard four-section readout (STATE / DECISIONS / ISSUES / NEXT,
.claude/rules/command-status.md). STATE lists what changed, section by section, and what
stayed unchanged. DECISIONS lists every owner-only default applied where no answer came in.
ISSUES lists anything the topics left blank, plus anything the post-write re-check found.
NEXT gives the next command a filled file makes possible — typically /verify-build or
/implement-trd.
Then the ═══ COMMAND COMPLETE: /verification-setup ═══ banner, and a call to
.claude/hooks/notify-complete.sh verification-setup complete "<one-line summary>" — the
same close every workflow command uses, so the run-state marker autonomy.md's Judgment B
depends on is actually cleared.