agentleFS
chrisalehmanchrisalehman/bionic/skills/canonical-sdlc/SKILL.md

canonical-sdlc

Skill9 starsChanged 30 days agoMITView on GitHub

Use when starting a large-scale development effort (new feature, architectural change, multi-day project) or when picking the skill for the current SDLC step. Routes to the canonical skill per step and gates every commit on the current step's evidence.

  • Commits and pushes

The file

We split this skill into the rules it gives an agent

2 rules. About 0 are common, 1 is distinctive, and 1 is very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈1

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 1

    Very specific

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

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

    Iron law: No commit without evidence from the current step.

    line 44
  2. Distinctive:

    Do not carve a sensitive concern into a tiny unflagged wave to dodge a minimum.

    line 101

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “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
<!-- GENERATED FILE — DO NOT EDIT. Rendered by agents-src/render.sh from agents-src/templates/skills/canonical-sdlc/SKILL.md.tmpl. -->

Canonical SDLC

Governs non-trivial engineering work. Every run declares a triple — <intent> · <rigor> · <scale> — and walks the applicable steps, leaving evidence a hook can read.

Only the ## Hooks section names anything that blocks. Everything else here is judgment, and you own it.

No ceremony. Do everything necessary, once. A task, check, review or approval earns its place only if it can fail in a way nothing already run can: never re-run a suite a gate already runs, never re-review a fix that carries its own red test. Read the record before you dispatch, and cite what is done.

Decisions. Every decision you put to the user, at any step and with no run open, goes through the decision skill: invoke it, never restate its shape. The Step-1 and Step-2 interviews are its heaviest users; small decisions may share a turn, a momentous one goes alone. An ask that holds the run is recorded in the run's register by its verb before it is put to the user — a decision or a stop-rule call by decisions put D<n> '<what is decided>' — so the sitrep cannot miss it. Approvals wait for the release approval card (release-approval, answered by reply); a reversible call is yours to make.

Iron law. No commit without evidence from the current step. The evidence gate reads the plan's current: and validates that step's evidence only — it never re-checks earlier steps, so a skipped step is caught by review, not by code.

Bulk reference. Artifact shape and authoring detail live in skills/canonical-sdlc/operational-rules.md, beside this file, and the version history in the CHANGELOG. Read it when you need the detail this file compresses; nothing loads it for you.

Load-time announcement

First user-facing action:

Canonical SDLC engaged — <intent> · <level> rigor · <scale> (for example build · double rigor · wave), then the line bash <plugin-root>/scripts/card.sh rigor <rigor> prints, which says what that rigor buys: review rigor: double (two independent minds).

Triple not yet declared → say so and list the axes. Invoked as help → render the axis tables and stop.

The triple

intent — what the deliverable is.

IntentUse whenEvidence delta
buildCapability that did not exist, or capability restored by ADDING machinery/interfaces/config (the machinery test).RED→GREEN per task. When the build IS a verification instrument, prove it CATCHES planted failures — a check that never fails is not proven to work.
bugfixRestore intended behavior WITHIN the existing design. A repair, not new machinery.The RED test is the failing repro.
refactorChange structure, preserve behavior. Covers upgrades, migrations, removals/deprecations.behavior-preservation: in the Step-5 block; migrations add compat-matrix:/revert-plan: (or n/a: not a migration). Log-only.
tuneMove a NAMED measurement toward a target. If you cannot name the measurement, it is not tune.baseline:/target:/re-measure: in the Step-5 block, all three. Log-only.
spikeTimeboxed research. Ships no code at any rigor.Writeup only at <docs-root>/spikes/spike-<slug>-<YYYYMMDD>.md. No plan file, no spec, no ADR, no commits to the integration branch.
incident-responseA live deployed surface — production or tooling — is broken for its users. The clock matters.RCA, not ADR. Minimum double. Monitoring-gap closure is part of Close-out.

Document and research deliverables — writeups, research reports — don't belong here. Plain plan mode serves them better than any row in this table, spike included: it ships no code at any rigor, but its writeup is a timeboxed research artifact, not a general document-production mode.

rigor — how many independent minds answer the questions: single (one) or double (two). A level sets four things, each the user's to set at Step 0: the reviewers, review-cadence:, fix-policy: and fix-cap:.

Every run that ships code answers four questions, at every rigor. The first, does it do what was asked, is answered by TDD RED→GREEN, the matrix discharged at each row's tier and the regression: one whole run plus the greens of what changed. The other three are read by independent minds: evidence, is the proof honest; adversarial, what is wrong that nobody asked about; structure, is it built from what exists, and shaped well.

Findings are classed by payment date, not by reviewer: harm (the user, now), evidence (the claim, now), debt (the next change). The reviewer roster follows from the classes, not the other way round.

Rigor follows one principle: the moment of a check is set by its cost model; machine checks run early and often, mind checks run once, on the settled whole. A fix row born of a registered review finding covers every question once it lands.

singledouble
reviewersone: the critic holds every questiontwo: the auditor takes evidence
when (review-cadence:)once, at Step 6, on the settled wholeonce, at Step 6
becomes a row unasked (fix-policy:)S1 + S2-on, in-diffS1 + S2-on, in-diff
cap on review-born rows (fix-cap:)210% of the plan

steps/6.md holds the review findings disposition and turns a review into a fact.

scale — the decomposition unit; rows are lib/scale.sh's. At pr, close-out merges nothing and records gh pr create; at piece+whole, each code question also owes scope=whole.

ScaleStepsArtifactsPatrolRigorWritersRegressionBranchIntegrateDealing
task0–9one plan + ## Tasksnosingle3noanyprpiece
wave0–9, the defaultwave spec + planyesdoubleuncappedyeswave/<NN>-<slug>mergepiece+whole
epic0–3; carves wavesepic spec + planyesdoubleuncappednoepic/<NN>-<slug>mergepiece

Rigor minimums. Default is the Rigor cell: at task, single unless a flag raises it; at wave and above, double. Effective rigor is the MAX of the default and four minimums — intent (incident-response is at least double, spike is CAPPED at single), flag (security-touching or privacy/vulnerable-population work is at least double), project (rigor-minimum: in .bionic/config.yaml), epic (rigor-minimum: in epic frontmatter). Provisional at Step 0, locked at Step 3. Minimums advise; they never force. Upgrades are free, and a rigor below the minimum is the user's to choose: advised against at Step 0, then accepted and recorded as rigor-override: (see the Override DSL). One adjacent check does block, and it is not a minimum: a task-ledger row whose rigor cell sits below the plan's own frontmatter rigor: is refused unless the row records a waiver. That is a consistency check against the value the plan declares — lower the frontmatter and the rows follow it down, so it never re-imposes a minimum the user has overridden.

Do not carve a sensitive concern into a tiny unflagged wave to dodge a minimum. The wave that owns the integration point carries the flag minimum.

Artifact layout

<docs-root>/specs/epic-NN-<slug>/{epic.spec.md, wave-NN-<slug>.spec.md, wave-NN-<slug>.requirements.md}
<docs-root>/plans/epic-NN-<slug>/{epic.plan.md, wave-NN-<slug>.plan.md}
<docs-root>/adrs/epic-NN-<slug>/adr-NNN-<slug>.md
<docs-root>/incidents/NNNN-<slug>/{spec.md, plan.md, rca.md}
<docs-root>/spikes/spike-<slug>-<YYYYMMDD>.md
<docs-root>/record/               # operational record: session logs, rotated archives,
                                  # closed-wave handoffs, inert audits. Survives Step 8.
<docs-root>/ideas/                # deferred-work briefs awaiting a wave to adopt them
.bionic/tests/                    # validation protocols re-run by hand, not by tests/run.sh
.bionic/tmp/                      # ephemera only, wiped at Step 8 — NOT a home for evidence.
                                  # Session-keyed state survives while its owning session is
                                  # alive, never by class name
.bionic/.gitignore                # literally `*` — written on tree creation; this is what
                                  # keeps the whole tree out of git, not the project .gitignore
.bionic/config.yaml               # optional; `docs-root:` moves <docs-root> off the default;
                                  # `release-check:`, and `regression-command:`
                                  # when a project's regression is not tests/run.sh

The first five are lifecycle artifacts and are gated: the governing-skill hook enforces frontmatter on them and blocks a canonical artifact written anywhere else. record/ and ideas/ are operational — nothing loads them, nothing validates them, and they are reached only by citing a path. That is the whole distinction, and it is the boundary test applied to this tree: growth in the gated dirs is governed, growth in the operational ones is free.

Three artifacts, three steps — Steps 1–3 write exactly one artifact apiece, chained requirement → criterion → design decision → eval → evidence. Step 1 writes wave-NN-<slug>.requirements.md: numbered requirements/user stories, each with provenance and acceptance criteria written so a "fails when" is nameable, plus Not Doing. Step 2 writes wave-NN-<slug>.spec.md: the technical design (domain model, architecture, ownership table, rejected alternatives), the Eval design table, and ADR pointers. Step 3 writes wave-NN-<slug>.plan.md: tasks, sequencing, the dispatch ledger, and the verification matrix rendered from Step 2's Eval design. Requirements live beside the spec, both under specs/epic-NN-<slug>/ — the governing-skill hook validates *.requirements.md frontmatter the same way it validates *.spec.md, minus the design three-way rule (that stays spec-only). Each of the three opens with a ## Goal section — one concise paragraph, first after the title — and a governing-skill arm at scale: wave or scale: epic refuses a write whose first section is not Goal, or whose Goal section is empty.

Anything the matrix cites as evidence goes in record/, never tmp/. Auditor reports, review records, test-run captures — the matrix names them by path, so they must outlive the run that produced them. tmp/ is wiped at Step 8 and takes its contents with it — everything, that is, except a live session's own keyed state, which the wipe spares by owner liveness, not file name. Give an agent a record/ path in its brief.

Every artifact carries frontmatter with governing-skill:, sdlc-step:, intent:/rigor:/scale:, canonical_sdlc_version: 14, the 5 discriminator flags, the 2 opt-in flags, and model_plan:. A missing one blocks the write. Artifacts never declare mode:. Plan files additionally carry walk: required | exempt — Step 0's derivation, and the key the Verify gate reads — Step 0's design-interview: value beside it, regression: (yes or no, Step 0's setting) and, where it differs from the scale default, regression-override: beside those, and, where the run's rigor sits below its derived minimum, rigor-override:. None of these is required to write, but a walk: value outside the enum blocks.

14 is the only supported version. Any other value — an older number, an empty value, a typo — blocks at both hooks. A run that predates it is brought forward to 14, not exempted.

Steps

StepFileGoverning skillGate
0 Configuresteps/0.mdcanonical-sdlcFrontmatter complete, matrix derived, user confirmed, task list created
1 Scopesteps/1.mdagent-skills:idea-refineRefined idea + explicit "Not Doing" + alternatives lens cites prior art; writes wave-NN-<slug>.requirements.md — numbered requirements/user stories with provenance and acceptance criteria, plus Not Doing
2 Designsteps/2.mdagent-skills:spec-driven-developmentEvery requirement has an acceptance criterion; every criterion cites its provenance:; wave+ carries a governing design; writes wave-NN-<slug>.spec.md — the technical design, ownership table, and the Eval design table
3 Plansteps/3.mdsuperpowers:writing-plansNo placeholders; integration-branch: present; matrix locked; tasks tagged; user approved; writes wave-NN-<slug>.plan.md — tasks, sequencing, and the verification matrix rendered from Step 2's Eval design
4 Implementsteps/4.mdagent-skills:incremental-implementationEvery task RED before GREEN; assumptions logged
5 Verifysteps/5.mdsuperpowers:verification-before-completionWalk artifact in record/; every matrix row discharged at tier or waived; auditor CONFIRMED; regression run once
6 Reviewsteps/6.mdcanonical-sdlcOne fact per owed question at the head, or its waiver
7 Documentsteps/7.mdagent-skills:documentation-and-adrsEvery decision at medium significance or above is recorded
8 Integratesteps/8.mdsuperpowers:finishing-a-development-branchWave reachable from the integration branch; worktree removed; tmp ephemera wiped
9 Close-outsteps/9.mdagent-skills:shipping-and-launchChecklist + rollback; continuation.md written

Before any Step-N action, read steps/N.md. Before Step 4's first action and before the first dispatch, read dispatch.md. The load-time announcement names the file just read.

<!-- BRIEF-SCAFFOLD-BEGIN -->

Scaffold

Expected duration: <N> minutes
Expected artifact: <ONE path inside the repo, or a bare file name, e.g. .bionic/docs/record/<wave>/<name>.md>
Progress artifact: <path>  (tasks of 15 min or more)
Cadence: <N> min  (tasks of 15 min or more)
Done marker: <path>  # optional
Subprocess claim: <process pattern>   # a backgrounded watcher, e.g. gh run watch — optional
Files: <every path the task may create or edit>  # a reviewer lists its records here, one per question, its artifact among them; a researcher or test-runner omits it; a suite's `# pins:` header adds its files, which `brief <row>` marks `# (pinned by <suite>)`
Suites: none  # *.test.sh names or a path-qualified run.sh; other runners: Re-executes:; a reviewer dealt evidence names 1 to 3 runs across both labels
Re-executes: `<cmd>`
Questions: <q>[, <q>]  # reviewer roles only
Row: <id>  # the plan row a writer runs; the integrate row runs reviews-part <id>, push, gh pr create
Lands-on: <suite>[, <suite>] | none <reason>  # what ready proves, within Suites:
Lands-red: <suite> until <ext:slug | approval:name>  # optional
Red-evidence: <path under record/>  # with Lands-red:
Deliverable-waiver: <reason>  # only for a report returned by message
<!-- BRIEF-SCAFFOLD-END -->

Committing is a cross-cutting rhythm (~once per step), not a numbered step. Update ## SDLC State before staging — the gate reads the file, not the diff. Do not add a commit: field; the SHA lives in git.

Engagement: a clean run has five human stops: the configuration, requirements, design and plan cards, then the release approval card. Steps 4–9 are unattended within the stop-and-wake rules.

Per-intent deltas. bugfix: Step 4's failing test is the repro. refactor: the Step-2 spec is "behavior preserved"; a new acceptance criterion means reclassify as build. tune: Step 1 routes to the domain skill (impeccable for UX, security-and-hardening, performance-optimization) and Step 5 is the baseline→target→re-measure loop. spike: no plan file at all. incident-response: Step 1 compresses to triage, and triage asks first whether service can be restored NOW — if a revert restores it, revert and verify before debugging anything; Step 7 is an RCA (summary, timeline, root cause, contributing factors, the fix, prevention with commit links, monitoring-gap analysis); Step 9 is deploy with rollback → monitor ≥1 cycle → close the monitoring gap or prove there is none.

scale: epic short-circuits any intent after Step 3.

Evidence shapes

One evidence artifact per step under Step N: in ## SDLC State. The gate validates the current step only.

StepRequired fields
0prereqs: ok
1, 2, 3pointer (presence only)
4pointer, plus worktree:/base-sha:/branch:, owed at every scale and whatever use_worktree: says; current 4 fills them at wave scale
5head:/cmd:/pass:/total:/output: optional, read by no gate; a valid ## Verification Matrix, walk-artifact: naming a real file under <docs-root>/record/ once any row is discharged (unless walk: exempt), once no row is pending/blocked a non-empty auditor:, and at regression: no the line regression: no (Step 0, <user>) — <where it runs>. The whole run is Step 5's, once after the build; a red is a fix row's (steps/5.md)
6one fact per owed question (proved: kind=review), or its waived: line; matrix re-validated here
7adr: OR rca: OR n/a:
8merge:, worktree-removed:, and (cleanup:, tmp-wiped:, tasks-completed: OR cleanup: n/a)
9delivered: always, ON the Step 9: line itself — the run-closure predicate (lib/run.sh) greps that one line, so a delivered: written on a continuation line leaves the run open forever; archived: always, naming what archive_run moved or why nothing moved; plus deployed:, verified:, monitored: exactly when deploy_target names a live surface

The matrix. Step 3 renders the matrix (matrix-render); Step 5 fills values.

Placeholder ban. These exact values are rejected anywhere evidence is required: todo, pending, in progress, inprogress, xxx, tbd, placeholder.

Handoff. A plan spanning sessions carries one ## Handoff pointer line to the file session-poker.sh handoff writes (record/<wave>/handoff.md: the machine's facts, the five human lines carried, safe to clear or wait N minutes, the door last), never by hand. Invoked with that file's path, run session-poker.sh resume <path> first and do what it prints: it binds, arms, adopts and ticks, and prints the task list, the recap, the step file and the Patrol job. At Step 9 write continuation.md — wave completed, integration branch + merge SHA, next wave, open carry-overs.

Hooks

bash-walls.sh (PreToolUse|Bash) fires only on a real git commit segment. It validates the session's bound plan: the current step's evidence, the matrix, and the task ledger. From current: 5 onward it also blocks on provenance: implementation in any AC block. The gate reads the plan as it is when the call starts, not as it will be once the rest of the command runs — a Bash call that edits the plan and commits in the same invocation is judged on the pre-edit plan, so edit the plan in one call and commit in a separate one. Log-only (never blocks): the epic merge-target check, and the refactor/tune intent-scoped Step-5 keys. A task row's agent cell carries the agent's ROSTER NAME, never its role, matched byte for byte.

canonical-sdlc-governing-skill.sh (PreToolUse|Write,Edit) blocks any artifact under <docs-root>/{specs,plans,adrs,incidents}/ lacking governing-skill: frontmatter, and blocks a mode: line, a missing or non-enum triple, a missing flag or model_plan, a walk: value outside required|exempt, or a missing ## Verification Matrix at sdlc-step ≥ 3. On a spec artifact at scale: wave or scale: epic it also blocks a write satisfying no arm of the three-way design rule: no flush-left ## Design in place, no design: pointer resolving to a real file that itself carries a flush-left ## Design (a dangling path, a target without the section, and a .. component each fail the arm), and no design-waived: token. A design: pointer that is present is validated on the unwaived path whether or not the spec also carries its own section. On the same wave/epic spec it also blocks, from sdlc-step ≥ 3 only, an adrs: frontmatter line naming a path (or several, joined by ·) that does not resolve to a real file — the momentous-ADR pointer D6 requires; below sdlc-step 3 the arm is silent, since the ADR is drafted alongside the spec that names it. Plans and every task-scale artifact are untouched by it. Minimum-consistency checks are log-only, and log user-overridden in place of a minimum violation when frontmatter carries rigor-override: — presence only; the marker's fields are never validated, and it does not quiet a malformed rigor-minimum: value in config.yaml.

Known holes — do not mistake these for enforcement. Flag values are never checked, only presence. The evidence gate reads the plan file's text, so an Edit that writes evidence for tests never run passes unseen. Proof-shape is a heuristic: a digit plus a / satisfies it. Task-scale ledgers have no write-time check. An active row whose agent the session's roster names needs no evidence line; with no roster, an agent-named one still does. The fact gate knows who answered which question about which code, never that the answer is right, and a hand-typed git merge meets no gate: only the step advance, the integrate row and close-out ask it.

Diagrams

diagrams/lifecycle.svg — the 10 steps, the two gates, and the commit rhythm. diagrams/hook-chain.svg — which hook fires on which tool event, and which arms block versus log.

Format policy. Composed SVG is the default for a diagram here; Excalidraw (bionic:excalidraw-diagram) is the backup, for a drawing whose layout is genuinely hand-arranged.

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.