/sdlc:find-quality-checks
Generated from solutions/ontological/skills/find-quality-checks/SKILL.md.
Description
Section titled “Description”Interactively populate or update the quality_checks: list in a project’s
top-level sdlc.yaml. Probes the project root via
sdlc quality detect, presents the detected runners through
AskUserQuestion (multiSelect), and writes the approved subset back to
sdlc.yaml. Idempotent — re-running with the same selection is a no-op. Runs
standalone or as a called step of /sdlc:setup.
Allowed tools
Section titled “Allowed tools”ReadWriteEditBashAskUserQuestion
Source
Section titled “Source”Usage:
/sdlc:find-quality-checks— probe the current project, present detected quality-check candidates, write the user-approved subset to<project-root>/sdlc.yaml.
Read ${CLAUDE_PLUGIN_ROOT}conventions/sdlc-yaml.md once before running this
skill — it documents the schema and execution semantics of quality_checks:.
Edit only <project-root>/sdlc.yaml; touch no other file.
1. Read the existing quality_checks: list
Section titled “1. Read the existing quality_checks: list”Read the current list deterministically:
${CLAUDE_PLUGIN_ROOT}cli/sdlc config get-quality-checks --config <project-root>/sdlc.yamlParse the JSON on stdout: verbs is the configured list in file order,
fileExists is whether sdlc.yaml is present. Remember verbs — those
entries pre-select in Step 3 so re-runs preserve prior choices.
A missing file is not an error (fileExists:false, verbs:[]); treat
the existing list as empty and Step 4 creates the file from scratch. If
the op exits non-zero (a present-but-malformed sdlc.yaml), surface its
stderr to the user and stop.
2. Probe the project for runner candidates
Section titled “2. Probe the project for runner candidates”Shell out to the detector:
${CLAUDE_PLUGIN_ROOT}cli/sdlc quality detect --project-root <project-root>Parse the JSON on stdout (the op defaults to --output json). Runners are under the runners key;
each entry has {kind, name, command, source} fields; command is the shell verb a user would
type. The detector is deterministic and best-effort — missing runners are simply absent from the
report, not errors.
If the detector exits non-zero, surface its stderr to the user and stop.
If the runners array is empty, tell the user no runners were detected
(no Justfile, no package.json scripts, no Makefile, no Python check
scripts, no eval harnesses, no pyproject [tool.*] sections) and offer
two options via AskUserQuestion:
- “Open the empty
sdlc.yamlin an editor” — runsdlc config set-quality-checks --verbs '[]' --config <project-root>/sdlc.yamlto write a starter file with an explicit emptyquality_checks: []and the canonical header (the op stamps it on create); then go to Step 5 to report and exit. - “Stop” — do nothing.
3. Present candidates to the user
Section titled “3. Present candidates to the user”If the detector returned at least one runner, call AskUserQuestion
with a multiSelect field listing every detected command as an option.
Each option’s label is the command itself (e.g. just full-check,
bun run scripts/lint.ts); the option’s description can cite
the source and kind (“from Justfile”, “Bun script under
scripts/”, etc.).
Pre-select any option whose command appears in the existing
quality_checks: list from Step 1 — this is what makes the skill
idempotent under repeat runs.
Phrase the question something like:
“Which of the detected commands should run as quality gates for this
project? (Select all that apply — these will be written to
sdlc.yaml’s quality_checks: list and executed in order by
/sdlc:task-work Step 7.)”
Capture the user’s selection. Order the resulting list to match the order entries appear in the detector’s report (the detector already sorts deterministically), not the AskUserQuestion-return order.
4. Write sdlc.yaml
Section titled “4. Write sdlc.yaml”Hand the ordered selection from Step 3 to the write op as a JSON array:
${CLAUDE_PLUGIN_ROOT}cli/sdlc config set-quality-checks --verbs '<json-array>' --config <project-root>/sdlc.yaml<json-array> is the detector-ordered selection (e.g. ["just ci","bun run scripts/lint.ts"]). The op:
- round-trips sibling top-level keys (
worktree_init:,orchestrator:, …) and comments untouched — it mutates thequality_checks:key in place rather than re-dumping a plain object; - writes an explicit
quality_checks: []on an empty selection (the documented opt-out — never a key-delete); - stamps the canonical header when creating the file from scratch;
- is idempotent: a write whose list matches the existing one reports
unchanged:trueand leaves the file byte-for-byte untouched.
Parse the JSON on stdout: count is the configured verb count,
unchanged is the idempotent no-op flag, created is true on a
from-scratch write, path is the absolute file written. If the op exits
non-zero, surface its stderr and stop.
5. Report
Section titled “5. Report”Print a one-line summary to stdout, driven by the op’s output from Step 4
(unchanged, count, path):
FIND-QUALITY-CHECKS-WROTE quality_checks=<count> path=<path>(or FIND-QUALITY-CHECKS-UNCHANGED quality_checks=<count> path=<path> when the
op reported unchanged:true — the idempotent no-op case).
Tell the user the file path and remind them they can re-run this skill any time to update the list.
- Slug-namespaced markers. This skill’s terminal markers are prefixed
FIND-QUALITY-CHECKS-(per${CLAUDE_PLUGIN_ROOT}skills/CLAUDE.md) so a parent reading its output can’t mistake them for its own verdict. - Schema + execution semantics. See
${CLAUDE_PLUGIN_ROOT}conventions/sdlc-yaml.md— thequality_checks:section documents the list shape, the/sdlc:task-workStep 7 executor, and why an empty/missing list warns rather than silently passing. - Related surfaces.
/sdlc:setupcreates an empty startersdlc.yamlif absent and invokes this skill as its Step 6;sdlc quality runexecutes the configured verbs;/sdlc:find-worktree-initis the twin configurator for theworktree_init:bootstrap list (setup’s Step 7). - Idempotent. Re-running with no detector changes and the same user
selection is a no-op (the
FIND-QUALITY-CHECKS-UNCHANGEDbranch above). The write op owns byte-for-byte parity; the skill’s only ordering obligation is to hand it the detector-sorted selection (Step 3), not the AskUserQuestion return order. - No commits. Write
sdlc.yaml; do not stage or commit it — leave that to the user. - Branch naming. When invoked inside a worktree (e.g. as part of
bootstrapping a new project’s planning setup), follow the existing
branch convention rather than inventing one. See
${CLAUDE_PLUGIN_ROOT}conventions/branch-naming.md.