agentleFS
exerias21exerias21/brainstorm-toolkit/skills/sdlc/SKILL.md

sdlc

Skill0 starsChanged 39 days agoMITView on GitHub

Run the full SDLC pipeline on a plan file, task id, task range (e.g. "1-5"), or an ad-hoc description: sanity-check → implement → evals → fix → validate → flowsim, then hand off the validated changes in your working tree for you to commit. Never commits, branches, pushes, or opens a PR — no git writes at all. Use when you want full SDLC discipline on work you will review and commit yourself, e.g. onto an open PR's branch.

  • Commits and pushes

8 other projects use a version of this.

Adopted by

Most recently taken up by

The file

Show its rules and text

We split this skill into the rules it gives an agent

14 rules. 0 are common, 2 are distinctive, and 12 are very specific to this project.

  • 0

    Common

    Most of the 7 edited versions we read keep these.

  • 2

    Distinctive

    This author's own choices. Worth a look.

  • 12

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    But: if project.json is absent while project.json.example is present, warn once at Stage 0 — every gated setting (models.cap, pipeline.*, …

    line 38
  2. Very specific:

    When pipeline.question_advisor.enabled is true, read skills/sdlc/templates/operator-gate.md now and run it before asking the operator …

    line 52
  3. Very specific:

    Independence pre-check (before any spend): If the review stage resolves ON (pipeline.review_fix.enabled: true.

    line 168
  4. Distinctive:

    Then parse the plan: Read the resolved plan/task file(s) fully and extract: feature name/slug.

    line 175
  5. Very specific:

    Bug rows: If any taken or resolved row carries _bug_ in its trailer (the bug field from close-tasks.sh rows.

    line 207
  6. Very specific:

    Vendored-skill guard: if .claude-plugin/marketplace.json is absent (an ordinary consumer repo) but the plan's changed files target …

    line 225
  7. Very specific:

    Only when the argument is --queue [N].

    line 246
  8. Very specific:

    When it *is* --queue, read skills/sdlc/templates/queue-mode.md now and run it.

    line 250
  9. Distinctive:

    If the sanity check surfaces a blocker (plan references nonexistent files, contradictory steps), stop and report rather than implementing …

    line 265
  10. Very specific:

    Decompose (large multi-surface plan): run 2a/2b/2c — skills/sdlc/templates/stage-2a-decompose.md (decomposer at models.implement → …

    line 292
  11. Very specific:

    When review.json.data.independence == "degraded", add the line independence: degraded — findings surfaced only, never auto-fixed (wording: …

    line 382
  12. Very specific:

    When Stage 6 wrote data.waves, add waves: now N across L lane(s), next M from its summary (now, lanes, next) and one warning line per …

    line 385
  13. Very specific:

    If the delivered diff departs from the plan (a step skipped, reordered, or solved differently), say where and why in one line each — the …

    line 387
  14. Very specific:

    It does no git writes — ever: No commit, no branch, no push, no PR, no /review.

    line 421

“Common” is measured: kept by at least 6 in 10 of the 7 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

sdlc — the full SDLC pipeline, leaving the commit to you (no git writes)

Toolkit paths. Every toolkit script or template path cited here resolves, first hit wins, against: a repo-local copy installed by setup.sh; else the plugin root (this skill's base directory two levels up, <base>/../..) when it holds that path; else ~/.claude/brainstorm-toolkit/ (the global shell install).

When to use

SkillInputPipelineTerminal action
/task <description>ad-hoc askTDD red→green onlycommit only if you ask
/sdlc <plan | task-id | range | desc>plan, task(s), or askfull (sanity→implement→evals→validate→flowsim)validated changes left in your working tree — you commit

For a single small fix with no plan behind it, prefer /task: the full pipeline costs more than it buys there.

Stage bodies live in skills/sdlc/templates/ (a shared template tree, not a skill); each stage below names the one it loads.

Prerequisites

  • You are on the branch the changes should land on (typically an open PR's branch). /sdlc never switches branches and never commits.
  • .claude/project.json optional; every key optional. The eval stage and Stage 5's plan check + flowsim flow trace skip silently when their config or a plan target is absent. But if project.json is absent while project.json.example is present, warn once at Stage 0 — every gated setting (models.cap, pipeline.*, test commands) is silently inert and the run will report cap: none. Then, if .claude/project.json exists, run bash scripts/migrate-project-json.sh check and print one warning line per move: <old> is ignored — rename to <new>; run bash scripts/migrate-project-json.sh apply, and per conflict a line saying both keys are set and <new> wins. Never apply from /sdlc; continue either way.

Output verbosity (default: quiet)

Read skills/sdlc/templates/output-verbosity.md now — default quiet, one line per stage.

Operator questions (opt-in)

When pipeline.question_advisor.enabled is true, read skills/sdlc/templates/operator-gate.md now and run it before asking the operator anything. Otherwise never open it.

State envelope

Writes to .claude/pipeline/<slug>/ — the canonical envelope (see skills/sdlc/templates/state-schema.md). Two additive fields:

  • run.json.pipeline = "sdlc".
  • Stage 6 sidecar is handoff.json ({branch, files_changed[], committed: false, suggested_commit_msg})

Resumption (--resume). /sdlc <input> --resume resumes a paused/failed prior run for the resolved slug instead of restarting from scratch — read skills/sdlc/templates/resumption.md now and follow it (read run.json; reject on a plan_hash mismatch; skip stages whose sidecar shows status: "pass"; resume at the first non-passing one). The only differences are the terminal stage (hand-off, not PR) and the handoff.json sidecar it writes at Stage 6. Resume keys on the resolved slug, so an ad-hoc-description run must be resumed with the same description text (a reworded description derives a different slug → "no prior run"); task-id / range / plan-file inputs resolve to a stable slug and resume cleanly.

For a task range, run.json.data.task_range records the resolved ids.


Stage 0 — Resolve input

Detect the argument shape:

  1. Plan file — arg is a path ending .md that exists (e.g. plans/my-feature.md). Use it as the plan and parse it per Stage 0 below. This is the primary path and the one that exercises the full pipeline (Stage 5's plan check has a plan to check against). Look up this plan's TASKS.md rows by calling scripts/close-tasks.sh rows --plan <slug> --plan-file <path> — compute <slug> here using the Derive slug rule below (basename minus extension, minus a leading brainstorm- / team-brainstorm- / pbi-NNN- / task-NNN- prefix) before this call, not the raw basename: /brainstorm tags rows with the stripped slug (_plan: add-orders_, never _plan: brainstorm-add-orders_), so pass the stripped slug, never the raw basename — never reconcile | grep <slug>: reconcile only reports drift against existing pipeline envelopes, so on a first run for this plan it always returns zero rows even though correctly-tagged rows are sitting open. rows reads TASKS.md alone, matching the _plan: <slug>_ marker /brainstorm appends, with a legacy path-substring fallback for untagged rows. Do not mark any row [~] yet — the Scope gate below (after parse.json) decides which of these rows are in scope for this run and marks only those; Stage 6 closes taken rows via scripts/close-tasks.sh. A plan-file run whose rows call returns no matched[] updates no TASKS.md — that's expected, not a miss.
  2. Task id — arg matches task-NNN or a bare row number. Read that TASKS.md row and its linked plans/tasks/task-N-<slug>.md. The task file's parent_plan: frontmatter (if present) becomes the flowsim / Stage 5 plan target. Mark the row [~] (not under writer: "orchestrator").
  3. Task range — arg is N-M, task-N..task-M, or tasks N-M. Resolve every Active / Pending row in that inclusive range to its task file. Execute them as a batch (see Stage 6 range semantics). Record the resolved ids in run.json.data.task_range. Mark each resolved row [~] (not under writer: "orchestrator"), except a _manual_ row — leave it Active / Pending and report it, never execute it.
  4. Ad-hoc description — anything else. Create a new TASKS.md row + task file using /task's procedure (skills/task/SKILL.md Sections 1–2), which at its own step 5 already writes .claude/pipeline/task-<N>-<slug>/run.json at in_progress. This run's slug IS that task-<N>-<slug> — one envelope, not two — the same rule skills/sdlc/templates/queue-mode.md already applies to a row with a linked task file ("uses that task slug instead"). Do not derive a second slug from the description text here: doing so leaves the /task-written envelope in_progress forever, which feeds next-action.sh's stale-run warning on every Stop and makes stop-gate.sh re-run tests indefinitely under pipeline.stop_gate: "tests". Adopting this envelope means /sdlc owns it: set run.json.pipeline: "sdlc" (not "task") and record the additive data.adopted_from: "task" (state-schema.md). There's no plan, so Stage 5's plan check self-skips. Mark the new row [~].

Task id / range / ad-hoc-description runs have no _plan: key (that tag only exists on plan-file rows), so Stage 6 can't close them by key. Instead, persist the resolved row id(s) at Stage 0 into run.json.data.tasks.resolved[] — one entry per row, each a substring unique to that row (its linked task file path, e.g. plans/tasks/task-N-<slug>.md, is the natural choice). Stage 6 closes exactly these entries via scripts/close-tasks.sh close --scope resolved, never a fuzzy match — this is also what makes a task-id --resume (which skips Stage 0) work: it re-reads this same array from the existing envelope rather than re-deriving anything from session memory.

  1. Queue mode — arg is --queue [N]. Select the work set from TASKS.md by state + priority (not a hand-typed range): the Active / Pending rows, top N (or pipeline.loop.max_items, default 5) by priority P0 > P1 > P2 > P3, an [~] in-progress row first. Then loop the pipeline over them with a re-scan and stop conditions — see Queue mode below (that re-scan is what makes it a loop, not a one-shot range).

Mark resolved rows [~] (in-progress; never under writer: "orchestrator") — cases 2–5 mark immediately; case 1 (plan file) marks only the rows the Scope gate below takes, once parse.json exists to size them. Derive slug: the plan filename minus its extension, minus a leading brainstorm- / team-brainstorm- / pbi-NNN- / task-NNN- prefix, lowercased, every character outside [a-z0-9-] replaced with -, runs collapsed, ends trimmed; it must match ^[a-z0-9]([a-z0-9-]*[a-z0-9])?$ or the run stops with a clear error (maintainer record: docs/CONVENTIONS.md). Capture base_commit = git rev-parse HEAD and initialize the state envelope at .claude/pipeline/<slug>/ with pipeline: "sdlc", base_commit, status: "in_progress", args.toolkit_version (the plugin's plugin.json version).

Dirty-at-start snapshot (envelope creation only, never on --resume). Right after base_commit, record run.json.data.dirty_at_start and data.live_envelopes (skills/sdlc/templates/state-schema.md). Another session's uncommitted files in a shared worktree otherwise land in this run's hand-off and review scope. Run git status --porcelain -z --untracked-files=all, drop .claude/pipeline/, take a rename's new path (the old path is dirty too), and store {path: <git hash-object of the file, or "deleted">}. live_envelopes is informational only (a crashed run stays in_progress); nothing gates on it.

Report-rows mode (pipeline.tasks.writer, default "self"). Record the resolved value in run.json.data.tasks.writer. Under "orchestrator" a delegated run never edits TASKS.md — the orchestrator owns those writes, and two writers race: cases 2–5 mark no row [~]; the scope gate records the taken rows' unique substrings in data.tasks.resolved[] instead of marking them; an ad-hoc description creates no row and no task file (skip /task's procedure, derive the slug as for a plan, and carry the would-be row to tasks_report.add); --queue stops with one line (--queue needs TASKS.md writes; set pipeline.tasks.writer to "self"). Stage 6 reports the rows instead of editing them (skills/sdlc/templates/stage-6-handoff.md).

Independence pre-check (before any spend). If the review stage resolves ON (pipeline.review_fix.enabled: true; --no-review always wins OFF), compute whether models.code_review collides with the implementer's effective tier per skills/sdlc/templates/models.md "Independence" — do not open skills/sdlc/templates/stage-5.7-review-fix.md for this, it is opt-in and a default run must never load it. On a collision, print the same degraded line Stage 5.7 emits before dispatching now, before Stage 1.5 spends a token, rather than only surfacing it once Stage 5.7 runs.

Then parse the plan. Read the resolved plan/task file(s) fully and extract: feature name/slug; implementation steps (numbered lists with file paths, or checkbox rows); files to create or modify (file paths, a table of files, or each linked task file's files: frontmatter); acceptance criteria ("expected", "should", "must", "verify" language); cross-module touchpoints; when present, the ### Premises, ### Baseline & exit measurement and ### Pins and forward behaviour sections. A TASKS.md-style checkbox list counts every [ ]/[~] row in Active / Pending as an implementation step.

Write stage-outputs/parse.json with data.feature_name, data.files_to_change, data.implementation_step_count, data.acceptance_criteria_count, data.premises[], data.baseline (string or null) and data.pins[] ({kind: "pin"|"forward", text}; empty/null when the plan has no such section), and append parse to run.json.stages_completed. This is not bookkeeping: Stage 2's decompose gate reads data.files_to_change and data.implementation_step_count and cannot run without them.

Scope gate (plan-file runs only)

Immediately after parse.json is written, decide how much of this plan to take this run. Skip this gate entirely for task-id / range / ad-hoc / --queue inputs — each is already bounded to one row or an explicit range — and for --no-scope-gate, which forces whole-plan execution (taken = every open row). Under pipeline.tasks.writer: "orchestrator" the scope gate never runs, so record every open row's unique substring (from the close-tasks.sh rows result) in data.tasks.resolved[] yourself, or the Stage 6 close preview is empty.

Read skills/sdlc/templates/scope-gate.md now and follow it: it sizes the plan, prefers the plan's own phase boundaries, handles a plan with zero rows and _manual_-only phases, runs a warn-only reconcile check before taking, records run.json.data.scope_gate (accumulating taken_phases across re-runs), and prints the verdict line.

Bug rows. If any taken or resolved row carries _bug_ in its trailer (the bug field from close-tasks.sh rows; for a task-id, range or queue item, the row itself), read skills/sdlc/templates/bug-triage.md now; otherwise never open it.

Native task mirror (Claude only; skip silently elsewhere). Once the stage list for this run is known, call TaskCreate once per stage that will actually run — the gates above have already decided which those are, so a review-off run creates no review task. Mark each in_progress on entry and completed on its sidecar write; a paused run leaves its stage in_progress, which is the correct reading.

This is a progress indicator, not state. The durable record is run.json + stage-outputs/; TASKS.md is the durable backlog. The native list is session-scoped and Claude-only, so nothing may read it back — never let a decision depend on it. What it buys is a live view of a long run outside the context window: the stage narration it replaces is re-read by every later turn, the task list is not. That is why this is worth the calls.

Skill-repo detection (automatic, no flag): if .claude-plugin/marketplace.json exists at repo root, the repo is itself a markdown-skill plugin — switch to the substitutions in Skill-repo mode below for the rest of the run.

Vendored-skill guard: if .claude-plugin/marketplace.json is absent (an ordinary consumer repo) but the plan's changed files target .claude/skills/**, .github/skills/**, or .agents/skills/** — i.e. it edits installed skill copies — stop and report. Those edits belong upstream in the canonical toolkit repo and then get re-installed; shipping them through a consumer's pipeline diverges the vendored copy from canonical. Queue-mode exception: the plan-file slug is shared by every row of a plan, so a queued item derives a distinct per-item slug (<plan-slug>-<row-id>, or the linked task-file slug) — see Queue mode — otherwise all its items collide on one .claude/pipeline/<slug>/ envelope.

Continuity detection (prompt, never auto) — the shared scan in skills/sdlc/templates/envelope-staleness.md: skip entirely when on the main_branch (merges make every run an ancestor there — pure noise). On a feature branch, take only the single most-recently-updated run whose base_commit is an ancestor of HEAD, and prompt only if it's non-terminal OR complete with HEAD advanced past that base_commit (follow-up landed outside the pipeline). One prompt at most, or none.

Queue mode (--queue) — attended backlog loop

Only when the argument is --queue [N]. Resolve that first — on any other input, skip this section entirely and go to Stage 1.5 without opening the template. Under pipeline.tasks.writer: "orchestrator" stop with the one line above instead.

When it is --queue, read skills/sdlc/templates/queue-mode.md now and run it. It carries the selection rule (highest-priority Active / Pending row, [~] first), the per-item envelope and its distinct slug, the four stop conditions, the TASKS.md re-scan that makes it a loop rather than a batch, the park protocol and its mandatory .claude/.next-action sentinel, and the long-run context-hygiene note.

Stage 1.5 — Sanity check

Read skills/sdlc/templates/stage-1.5-sanity-check.md now and run it (parallel focus agents on Claude; sequential on the overlays). It carries the orchestration and the per-focus prompts. This is full SDLC discipline — it is not gated or optional. Built-in per-focus defaults are paths: haiku, completeness: sonnet, gotchas: sonnet; models.sanity (a string or a per-focus map) and agents.sanity_focuses tune it, and because the cap only lowers, models.sanity is the only way to raise a focus above its default. For a task range, run it once over the combined set before the implement loop.

If the sanity check surfaces a blocker (plan references nonexistent files, contradictory steps), stop and report rather than implementing on a bad premise.

Stage 2 — Implement

Delegation is mandatory. During this stage you do not call Write or Edit. Dispatch the implement agent(s) below and receive git diff --numstat back; the file bodies stay in the agent's context, not yours — every file body you take directly is context you carry for the rest of the run. If a change is too small to be worth an agent, it is too small for /sdlc — use /task.

Read skills/sdlc/templates/stage-2-implement.md now, before dispatching.

Then apply the live-code grounding — follow skills/sdlc/templates/convention-grounding.md — and the auto-gate: read skills/sdlc/templates/stage-2-gate.md now — it computes surfaces_touched (via skills/sdlc/templates/changed-files-gate.md) and task_count, then decides single-agent vs. decompose.

  • Single-agent (default): dispatch one agent with skills/sdlc/templates/stage-2-implement.md, substitute {feature_name}, {plan_content} and {slug}; models.implement (Sonnet default, per skills/sdlc/templates/models.md) on Claude, inline on Copilot/Codex. State write (orchestrator, not the agent): the agent's prompt writes no state or sidecar files — when it returns git diff --numstat, you write stage-outputs/implement.json from that summary (applying the files_changed rule in state-schema.md implement), plus data.dispatch = {agent_id, model} from the dispatch result (the only proof an agent ran), append implement to run.json.stages_completed, and refresh updated_at. No decompose/converge sidecars.
  • Decompose (large multi-surface plan): run 2a/2b/2c — skills/sdlc/templates/stage-2a-decompose.md (decomposer at models.implement → decompose.json), skills/sdlc/templates/stage-2b-dispatch.md (one subagent per lane, sequential by depends_on → implement-<lane>.json), then skills/sdlc/templates/stage-2c-converge.md (orchestrator reconcile prompt — it also writes nothing itself). State write (orchestrator): after 2c's reconcile returns, you write stage-outputs/converge.json (files_changed rule applied, per 2c), set run.json.data.stage2_decomposed = true and run.json.data.lanes (converge.json carries each lane's data.dispatch, per 2c), and append a single implement (never per-lane) to run.json.stages_completed — the canonical stage name either path completes under, per skills/sdlc/templates/state-schema.md.

For a task range, the gate sees the combined file/step set. After implementation, review git diff --stat and confirm expected files were touched. Stop and report on any blocker.

Stage 3 — Generate evals

Read skills/sdlc/templates/stage-3-evals.md now and run it. Skip silently if no eval.runner is configured — record data.skipped_reason: "no eval.runner", append generate-evals to run.json.stages_skipped and set data.skip_reasons.generate-evals: "no eval.runner". Pure-docs work degenerates cleanly into edit + commit.

Stage 5 — Validate

Read skills/sdlc/templates/stage-5-validate.md now and run it — one stage: (1) dispatch the test-runner agent (Haiku, structured pass/fail only — never run the suites inline; test output is the biggest single source of context bloat) over the touched surfaces, then (2) one agent given the plan + diff that reports requirements (met/partial/missing, each with a file:line) and flow (MISMATCH/UNCLEAR/MISSING) separately. Skip axis (2) when there is no plan target, and say so.

Route failures through the shared fix loop (read skills/sdlc/templates/fix-loop.md at the first failure; 3-iteration budget). Writes one validate.json.

Stage 5.7 — Adversarial review

Opt-in, permanently OFF by default — resolve the gate before loading anything. ON only on an pipeline.review_fix.enabled: true; --no-review always wins OFF. When OFF, do not load the template — append review to run.json.stages_skipped (reason in data.skip_reasons.review) and go to Stage 6. When ON, read skills/sdlc/templates/stage-5.7-review-fix.md now and run it: it carries the lens fan-out and its cost knobs, the reviewer-model axis and its cap caveat, the verify pass and the circuit breaker. Runs after Stage 5, before Stage 6; writes stage-outputs/review.json.

Stage 5.8 — Fix loop

Specified in that same template, on its own budget (agents.code_review_max_fix_loops) — the HIGH-finding posture and the post-fix re-validation rule live there.

Stage 5.9 — Cleanup pass

Opt-in, permanently OFF by default. ON only via pipeline.cleanup.enabled: true or --cleanup; --no-cleanup always wins OFF. Auto-off when Stage 5 isn't green, implement was skipped, or the diff touched no code surface. When OFF, append cleanup to run.json.stages_skipped (reason in data.skip_reasons.cleanup) and skip to Stage 6 — do not load the template. When ON, read skills/sdlc/templates/stage-5.9-cleanup.md now (two-lens fan-out, safe_to_apply rubric).

Stage 6 — Hand off (no commit, no git writes)

/sdlc runs the full pipeline and then stops at the edge of git; the user reviews the validated working tree and commits it themselves. Do NOT run git add, git commit, git checkout -b, git push, gh pr create, or /review — leave the working tree exactly as the pipeline produced it.

Read skills/sdlc/templates/stage-6-handoff.md now and run it. It carries the secret scan, the diff report and suggested commit message, gotcha capture and the seam sentinel, the TASKS.md close-out and re-entry rows (reported, not written, under pipeline.tasks.writer: "orchestrator"), and the terminal state write.

Stage 7 — Report

Degrade check (Claude only). Skip it, printing degrade check: skipped (run predates it), when run.json.args.toolkit_version is absent. Otherwise, if implement is in stages_completed and the Stage 2 sidecar for the path taken — implement.json (single-agent) or converge.json (decomposed, run.json.data.stage2_decomposed: true) — is missing or lacks data.dispatch, the orchestrator did the work itself: after Stage 6's terminal write, write run.json.data.degraded = {reason, missing} and print DEGRADED: <reason> — missing <what> as the first line of the report. Leave status alone. Never load stage-5.7-review-fix.md for this.

Stage table. Print one table: each stage as ran (in stages_completed) or skipped: <reason> (from data.skip_reasons).

Summarize: branch the changes are sitting on (uncommitted), files changed, suggested commit message, eval pass/fail (or "skipped — no test surface"), test-check summary, the Stage 5 plan check — requirements verdict plus the flowsim flow trace and whether it was witnessed or advisory (or "skipped — no plan target") — and anything left open. Always print tasks: N closed, M moved (K matched) from Stage 6's handoff.json data.tasks — including tasks: 0 closed (0 matched) when nothing matched — this is the line that turns a silent close-out miss into a visible one; when unmatched is non-empty, add (U unmatched — see /sdlc-status --reconcile). Under writer: "orchestrator" print tasks: reported to orchestrator (N close, M add) — /sdlc-status --reconcile shows these rows open until applied instead. List data.shared paths apart from the files changed, as shared (stage by hunk). When review.json.data.independence == "degraded", add the line independence: degraded — findings surfaced only, never auto-fixed (wording: skills/sdlc/templates/stage-5.7-review-fix.md "Independence enforcement"). When Stage 6 wrote data.waves, add waves: now N across L lane(s), next M from its summary (now, lanes, next) and one warning line per overlaps[] entry; omit both when it did not. If the delivered diff departs from the plan (a step skipped, reordered, or solved differently), say where and why in one line each — the plan-conformance-validator's partial/missing rows are the source. Check coauthor_trailer in .claude/project.json: unless it is literally true, the suggested commit message contains no Co-Authored-By (or other attribution) line — strip one if present. Make it explicit that nothing was committed — the next move is yours.

Skill-repo mode (auto-detected)

Active when .claude-plugin/marketplace.json exists at repo root (detected at Stage 0). The standard pipeline is shaped for "code-with-tests"; a skill repo has no test surface, so the eval-driven stages are inapplicable. Three stages change; every other stage runs unmodified.

StageSkill-repo behavior
Stage 3 — Generate evalsskip (no test surface) — append generate-evals to run.json.stages_skipped, data.skip_reasons.generate-evals: "skill repo, no test surface"
Stage 5 — Validatesubstitute the test half only with skills/sdlc/templates/stage-5-skill-repo.md (HARD: validator, marketplace registration, template-reference resolution, setup.sh dry install; SOFT: line-count ceiling, README skills-table drift, overlay parity) — the plan-vs-diff check stays on whenever there is a plan target: requirements gate as normal, flow is advisory-only (no test evidence to witness it). Writes validate.json with data.mode = "skill-repo"
Stage 5.7 — Adversarial reviewadapt when enabled, never self-skip — still opt-in/OFF-by-default per Stage 5.7 above; when it's ON, a docs-only diff is the code surface here. Correctness and plan-alignment apply equally to prose; security applies its skill-repo shell-injection check; config-env-docs repoints to the frontmatter / marketplace / template-reference checks in stage-5-skill-repo.md

Safety rules

  • Stop on ambiguity — if the plan has unclear steps, pause and ask.
  • Stop on repeated failures — if a fix loop can't resolve within its budget, report rather than grinding.
  • Don't fix pre-existing failures — only fix what this run introduced. Stage 5's preexisting[] is reported, never gated on.
  • Autonomy overrides interactive output styles — this is an autonomous pipeline. If an interactive output style (a "learning"/contribution-seeking mode) is active, the explicit invocation wins: run autonomously, don't pause to solicit user-authored code mid-pipeline.

Gotchas

  • It does no git writes — ever. No commit, no branch, no push, no PR, no /review. It hands you a validated working tree; you commit.
  • Stage 5's plan check runs whenever there's a plan to check — pass a plan file (or a task with parent_plan) and they run unconditionally. They skip only when there is literally no plan target to validate against — never behind a separate opt-in flag or frontmatter knob.
  • Don't fork the shared templates. Stage bodies live once in skills/sdlc/templates/; edit the template, never copy it into this file. Zero template duplication is the contract.
  • Range accumulates in the tree. A range runs the pipeline over each task and leaves all changes uncommitted together; you choose how to slice the commits when you review.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.