skilldrop-cli 0.12.2 → 0.13.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +61 -6
- package/bin/skilldrop.js +56 -1
- package/loops/release/LOOP.md +76 -0
- package/loops/release/loop.json +47 -0
- package/model-routing.json +258 -63
- package/package.json +1 -1
- package/packs.json +31 -6
- package/skills/contribution-wizard/SKILL.md +132 -0
- package/skills/contribution-wizard/manifest.json +11 -0
- package/skills/eval-harness-generator/SKILL.md +84 -0
- package/skills/eval-harness-generator/manifest.json +11 -0
- package/skills/launch-readiness/SKILL.md +95 -0
- package/skills/launch-readiness/evals/eval_queries.json +10 -0
- package/skills/launch-readiness/evals/evals.json +19 -0
- package/skills/launch-readiness/examples/schema-change-revise.md +54 -0
- package/skills/launch-readiness/manifest.json +24 -0
- package/skills/launch-readiness/templates/readiness-report.md +41 -0
- package/skills/prompt-caching-advisor/SKILL.md +90 -0
- package/skills/prompt-caching-advisor/manifest.json +11 -0
- package/skills/token-budget-estimator/SKILL.md +75 -0
- package/skills/token-budget-estimator/manifest.json +11 -0
- package/skills/tool-use-schema-writer/SKILL.md +111 -0
- package/skills/tool-use-schema-writer/manifest.json +11 -0
package/README.md
CHANGED
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/skilldrop-cli)
|
|
4
4
|
[](LICENSE)
|
|
5
5
|
|
|
6
|
-
**[Browse the catalogue →](https://sananthanarayan.github.io/skilldrop/)** — all
|
|
6
|
+
**[Browse the catalogue →](https://sananthanarayan.github.io/skilldrop/)** — all 63 skills, filterable by outcome, pack, tag, and model tier.
|
|
7
7
|
|
|
8
|
-
**
|
|
8
|
+
**63 portable AI-agent skills for the deliverables knowledge workers actually ship** — diagrams, design docs, ADRs, PRDs, runbooks, decks, decision logs, threat models, adversarial reviews — installable into **Claude Code**, **Cursor**, **Kiro**, **Codex**, **GitHub Copilot**, and any AI tool that accepts custom instructions, one skill or one role-based pack at a time:
|
|
9
9
|
|
|
10
10
|
```bash
|
|
11
11
|
npx skilldrop-cli install --pack product-manager # or: solution-architect, dev-team,
|
|
12
|
-
npx skilldrop-cli list # sre-oncall, stakeholder-comms, ai-engineering
|
|
12
|
+
npx skilldrop-cli list # sre-oncall, stakeholder-comms, ai-engineering, claude-api
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
Originally scoped to solution architects, now broadly useful to PMs, founders, consultants, engineering leaders, exec assistants — anyone who turns ideas into stakeholder-ready artifacts.
|
|
@@ -24,13 +24,14 @@ skilldrop ships **loops**, not just parts. A loop is a named sequence of stages
|
|
|
24
24
|
|
|
25
25
|
A loop *sequences* skills — it never contains one. Every skill stays independently installable and runnable on its own, which is what keeps a single-folder copy working in Cursor, Kiro, or Aider.
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
Five loops cover the lifecycle, and they are separated by **reversibility** — how expensive the mistake is to unwind — which is why each gets its own gate rather than folding into a neighbour:
|
|
28
28
|
|
|
29
29
|
| Loop | Takes | Gate | Produces | Mistake costs |
|
|
30
30
|
|---|---|---|---|---|
|
|
31
31
|
| [`discover`](loops/discover/LOOP.md) | interviews, journeys, a strategy question | **G0** human — a person ratifies the brief | a ratified requirement | a re-brief |
|
|
32
32
|
| [`design`](loops/design/LOOP.md) | a ratified requirement | **G1** review — `council-review`'s panel | a recorded decision (ADR) | months, unwound in code |
|
|
33
33
|
| [`build`](loops/build/LOOP.md) | an agreed requirement or triaged defect | **G2** mechanical — `pre-merge-review`'s gate script decides | merged code | a revert |
|
|
34
|
+
| [`release`](loops/release/LOOP.md) | merged code | **G2.5** review — `launch-readiness` on evidence; **G2.6** human go/no-go | a live, reversible rollout | users and data, often irreversible |
|
|
34
35
|
| [`operate`](loops/operate/LOOP.md) | a shipped service | **G3** human — the incident is closed | a postmortem and runbook deltas | live users, irreversible |
|
|
35
36
|
|
|
36
37
|
Plus one **wrapper**, which is not a lifecycle stage but the two passes either side of *any* generator:
|
|
@@ -144,6 +145,41 @@ flowchart LR
|
|
|
144
145
|
|
|
145
146
|
<!-- loop:build:end -->
|
|
146
147
|
|
|
148
|
+
### `release` — merged code to live users
|
|
149
|
+
|
|
150
|
+
Plan the rollout and the way back, judge readiness on evidence, draft the release notes, then a human makes the go/no-go call. The gap between a merge you can revert and a launch you often cannot.
|
|
151
|
+
|
|
152
|
+
<!-- loop:release:start -->
|
|
153
|
+
|
|
154
|
+
```mermaid
|
|
155
|
+
%%{init: {'theme':'base','themeVariables':{'fontFamily':'Segoe UI, Helvetica, Arial','fontSize':'15px','lineColor':'#9AA5B1'},'flowchart':{'curve':'basis','rankSpacing':70,'nodeSpacing':50,'padding':16}}}%%
|
|
156
|
+
flowchart LR
|
|
157
|
+
classDef gen fill:#E8F0FE,stroke:#4C7DF0,stroke-width:1.5px,color:#1A3A8F;
|
|
158
|
+
classDef review fill:#FDEAEA,stroke:#E05B5B,stroke-width:1.5px,color:#8A1F1F;
|
|
159
|
+
classDef gate fill:#FBE3A2,stroke:#D9971E,stroke-width:2px,color:#6B4500,font-weight:bold;
|
|
160
|
+
classDef ship fill:#E6F7EC,stroke:#34A853,stroke-width:2px,color:#0F6B33,font-weight:bold;
|
|
161
|
+
|
|
162
|
+
plan["plan<br/><small>migration-plan</small>"]:::gen
|
|
163
|
+
ready["ready<br/><small>launch-readiness</small>"]:::review
|
|
164
|
+
announce["announce<br/><small>release-notes</small>"]:::gen
|
|
165
|
+
go["go<br/><small>council-review</small>"]:::gate
|
|
166
|
+
G2_5{"G2.5 · review"}:::gate
|
|
167
|
+
G2_6{"G2.6 · human"}:::gate
|
|
168
|
+
DONE(["complete"]):::ship
|
|
169
|
+
|
|
170
|
+
plan --> ready
|
|
171
|
+
ready --> G2_5
|
|
172
|
+
G2_5 == "PROCEED" ==> announce
|
|
173
|
+
announce --> go
|
|
174
|
+
go --> G2_6
|
|
175
|
+
G2_6 == "PROCEED" ==> DONE
|
|
176
|
+
|
|
177
|
+
G2_5 -- "REVISE (max 3)" --> plan
|
|
178
|
+
G2_6 -- "REVISE (max 3)" --> plan
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
<!-- loop:release:end -->
|
|
182
|
+
|
|
147
183
|
### `operate` — a shipped service through detection and learning
|
|
148
184
|
|
|
149
185
|
Instrument, write the runbook, communicate the incident, then feed the postmortem's runbook deltas straight back into the runbook. The one loop whose failures are live.
|
|
@@ -235,6 +271,7 @@ Skills for the SDLC steps around the code itself — turning raw requirements in
|
|
|
235
271
|
| [`release-notes`](skills/release-notes/SKILL.md) | Turn git history between two refs (default: last tag → HEAD) into two artifacts: customer-facing release notes rewritten in reader benefits — no commit-speak, no ticket IDs, no "various improvements" — and an internal Keep-a-Changelog version with a commit hash on every line. Breaking changes hoisted to the top of both with an "Action required" line (detected via `!:` markers, removed public API, migration files, major bumps); internal noise (refactors, CI, deps) never leaks into customer notes; vague commits land in a "Needs review" list instead of being guessed at. |
|
|
236
272
|
| [`bug-triage`](skills/bug-triage/SKILL.md) | Turn a vague bug report ("it's broken on mobile sometimes") into a ticket an engineer can start without contacting the reporter: searchable symptom-plus-condition title, numbered repro steps from a clean state (or an explicit "no repro yet" with the exact diagnostics to collect), expected-vs-actual with the verbatim error string, every claim tagged `[reported]` / `[verified]` / `[assumption]`, severity and priority judged independently (S4/P1 is a legitimate combination), ≤3 hypotheses each with a 5-minute check, and duplicate-search hints. One bug per ticket — multi-symptom reports get split. |
|
|
237
273
|
| [`migration-plan`](skills/migration-plan/SKILL.md) | Phased migration/rollout plan (schema change with live backfill, API version, datastore/auth/platform swap) built on the parallel-change pattern: expand → migrate → contract. One change per phase (a failed phase implicates exactly one thing); every phase carries an observable gate with bake time, a tested rollback with an explicit data story, and a blast radius; at most one **named point of no return**; backfill specified idempotent + resumable + rate-limited with 3-depth parity checks; dual-write requires a named reconciler; the contract phase gets a date and an owner so "we'll remove the old path later" actually happens. |
|
|
274
|
+
| [`launch-readiness`](skills/launch-readiness/SKILL.md) | Go/no-go readiness report for a merged change before it reaches users. It lists the change's own failure modes first, then judges seven checks in order: rollback, detection, response, measured NFR targets, data & privacy, comms, staged exposure. Each row is met / not met / n/a-with-reason, with an evidence link and an owner role, and a row with no evidence is `not met`. The verdict (PROCEED / PROCEED WITH CONDITIONS / REVISE / BLOCKED) follows mechanically from the rows, and a missing rollback blocks on its own. Gaps go to `migration-plan`, `observability-plan` or `runbook-generator` instead of being drafted inline. The `ready` stage of the `release` loop. |
|
|
238
275
|
|
|
239
276
|
### Product strategy
|
|
240
277
|
|
|
@@ -308,6 +345,23 @@ Designing the agentic systems themselves — the loops, orchestrations, and budg
|
|
|
308
345
|
| [`ai-usage-report`](skills/ai-usage-report/SKILL.md) | Turn a CSV/JSONL of AI usage events (exported from an MCP server or other telemetry source) into a per-user, team-rollup, or effectiveness-focused report. Surfaces volume, breadth, session depth, and — where the data supports it — whether AI outputs were actually consumed in shipped artifacts vs generated and discarded (the "AI theater" question). Refuses to generate an aggregate rollup for teams smaller than 5 to preserve anonymity. |
|
|
309
346
|
| [`llm-eval-harness`](skills/llm-eval-harness/SKILL.md) | Design the **dev-loop quality gate** for an LLM-powered feature (prompt, RAG, agent, classifier) — so prompt and model changes ship on numbers, not vibes. A versioned golden set in three deliberate buckets (representative from real logs, adversarial/edge, and regression cases frozen from every past failure); the **cheapest adequate grading method per case** (programmatic → structured assertions → LLM-as-judge only when quality is genuinely subjective, and then validated against human labels with bias controls); a metric matched to the task with **both gates set before the first run** (no-regression + critical-subset-at-100%); a failure taxonomy that points iteration at the biggest bucket; and cost/latency tracked beside quality. Enforces the held-out split and the no-tuning-on-test rule. Provider-neutral. |
|
|
310
347
|
|
|
348
|
+
### Claude API
|
|
349
|
+
|
|
350
|
+
Skills for teams building directly on the Anthropic API — prompt caching strategy, token budgeting, eval generation for skills, and tool-use schema authoring.
|
|
351
|
+
|
|
352
|
+
| Skill | What it does |
|
|
353
|
+
|---|---|
|
|
354
|
+
| [`prompt-caching-advisor`](skills/prompt-caching-advisor/SKILL.md) | Analyzes a prompt or conversation structure and identifies the highest-value `cache_control` breakpoints — which blocks to cache, where to place the checkpoint, and estimated hit rate. Warns when a cacheable block is below the minimum threshold (~1,024 tokens for Haiku, ~2,048 for Sonnet/Opus). Produces an annotated messages array and a one-paragraph cache strategy summary. |
|
|
355
|
+
| [`token-budget-estimator`](skills/token-budget-estimator/SKILL.md) | Breaks down token usage for an agentic workflow by component — system prompt, injected context, tool definitions, tool results, context accumulation, and output — surfaces the dominant cost driver, and recommends concrete `max_tokens` controls. Covers extended thinking (`budget_tokens`) when relevant. |
|
|
356
|
+
| [`eval-harness-generator`](skills/eval-harness-generator/SKILL.md) | Takes a SKILL.md and generates 8–12 eval cases (happy path, edge, anti-pattern, refusal) ready to drop into `skills/<name>/evals/cases.json`. Each case has a realistic trigger, checkable `expected_shape` criteria, and `must_not_include` guards from the skill's own quality bar. |
|
|
357
|
+
| [`tool-use-schema-writer`](skills/tool-use-schema-writer/SKILL.md) | Converts a function description into a valid Anthropic `tool_use` JSON schema with typed properties, required arrays, and decision-condition descriptions. Validates that required arrays are present and enum values are described. Produces a Python `client.messages.create(tools=[...])` usage snippet. |
|
|
358
|
+
|
|
359
|
+
### Skill authoring
|
|
360
|
+
|
|
361
|
+
| Skill | What it does |
|
|
362
|
+
|---|---|
|
|
363
|
+
| [`contribution-wizard`](skills/contribution-wizard/SKILL.md) | Guides an author through creating a new skilldrop skill from scratch — single-block intake, then one response generating the manifest, SKILL.md, 8 eval cases, README row, and packs.json addition. Enforces schema compliance and names the `python3 validate.py` check as the gate before opening a PR. |
|
|
364
|
+
|
|
311
365
|
### Stakeholder communication
|
|
312
366
|
|
|
313
367
|
| Skill | What it does |
|
|
@@ -381,6 +435,7 @@ Categories (above) say what a skill *is*; packs say *who needs it*. [`packs.json
|
|
|
381
435
|
| `ai-engineering` | 12 | Build and run AI systems: agent loop design, subagent orchestration, spend budgets, eval harnesses, usage reporting, data contracts |
|
|
382
436
|
| `stakeholder-comms` | 9 | Non-technical audiences: audience profiling, deck outlines and real `.pptx` decks, exec summaries, decision logs, guides |
|
|
383
437
|
| `sre-oncall` | 5 | Operate the service: runbooks, observability design, incident comms, postmortems, capacity/cost models |
|
|
438
|
+
| `claude-api` | 4 | Build on the Anthropic API: prompt caching strategy, token budgeting, eval generation for skills, tool-use schema writing |
|
|
384
439
|
|
|
385
440
|
```bash
|
|
386
441
|
python3 pack.py # list packs
|
|
@@ -424,7 +479,7 @@ npx skilldrop-cli install --pack dev-team --project # .claude/skills — als
|
|
|
424
479
|
npx skilldrop-cli install prfaq --ide cursor # + writes .cursor/rules/prfaq.mdc
|
|
425
480
|
npx skilldrop-cli install --pack sre-oncall --ide kiro # .kiro/skills — Kiro IDE + Kiro CLI, discovered natively
|
|
426
481
|
npx skilldrop-cli install adr-generator --dest .agents/skills # Codex + Copilot CLI (see below)
|
|
427
|
-
npx skilldrop-cli loops # the
|
|
482
|
+
npx skilldrop-cli loops # the six loops, their stages and gates
|
|
428
483
|
npx skilldrop-cli install --loop build # a loop + every stage skill it sequences (RFC-0028)
|
|
429
484
|
npx skilldrop-cli install --loop --pack sre-oncall # every loop that pack declares
|
|
430
485
|
npx skilldrop-cli agents # the reviewer subagents
|
|
@@ -448,7 +503,7 @@ skilldrop is also a **Claude Code plugin marketplace** — one marketplace, seve
|
|
|
448
503
|
Then take the whole catalogue, or just your role's pack:
|
|
449
504
|
|
|
450
505
|
```text
|
|
451
|
-
/plugin install skilldrop@skilldrop # all
|
|
506
|
+
/plugin install skilldrop@skilldrop # all 63 skills + 3 reviewer subagents
|
|
452
507
|
/plugin install solution-architect@skilldrop # 17 skills
|
|
453
508
|
/plugin install dev-team@skilldrop # 14 skills + the 3 reviewer subagents
|
|
454
509
|
/plugin install product-manager@skilldrop # 13 skills
|
package/bin/skilldrop.js
CHANGED
|
@@ -40,6 +40,8 @@ Usage:
|
|
|
40
40
|
skilldrop loops [--from <src>] loops — sequenced stages over skills (RFC-0028)
|
|
41
41
|
skilldrop install <skill...> install skills (default: Claude Code, user scope)
|
|
42
42
|
skilldrop install --pack <name> install a whole pack
|
|
43
|
+
skilldrop install --profile <name> install a named bundle of packs, agents, and loops
|
|
44
|
+
skilldrop profiles [--from <src>] list available profiles
|
|
43
45
|
skilldrop install --all install every skill in the catalog
|
|
44
46
|
skilldrop install --agent <name...> install reviewer subagents (RFC-0012)
|
|
45
47
|
skilldrop install --loop <name...> install loops + the stage skills they sequence
|
|
@@ -262,6 +264,10 @@ function packsOf(cat) {
|
|
|
262
264
|
const p = path.join(cat.dir, "packs.json");
|
|
263
265
|
return fs.existsSync(p) ? readJSON(p).packs : null;
|
|
264
266
|
}
|
|
267
|
+
function profilesOf(cat) {
|
|
268
|
+
const p = path.join(cat.dir, "profiles.json");
|
|
269
|
+
return fs.existsSync(p) ? readJSON(p).profiles : null;
|
|
270
|
+
}
|
|
265
271
|
|
|
266
272
|
/* Structural gate (RFC-0003): a skill must pass before it is copied anywhere. */
|
|
267
273
|
function checkSkill(cat, s) {
|
|
@@ -744,8 +750,57 @@ function installPanel(args) {
|
|
|
744
750
|
console.log(`Codex / Antigravity multi-agent runners), and sweeps the lenses inline otherwise. Per-tool: agents/README.md.`);
|
|
745
751
|
}
|
|
746
752
|
|
|
753
|
+
function listProfiles(args) {
|
|
754
|
+
const cat = resolveCatalog(args.flags.from);
|
|
755
|
+
const ps = profilesOf(cat);
|
|
756
|
+
if (args.flags.json)
|
|
757
|
+
return emitJSON({
|
|
758
|
+
catalog: cat.source,
|
|
759
|
+
count: ps ? Object.keys(ps).length : 0,
|
|
760
|
+
profiles: Object.entries(ps || {}).map(([name, p]) => ({
|
|
761
|
+
name, description: p.description || null,
|
|
762
|
+
packs: p.packs || [], agents: p.agents || [], loops: p.loops || [],
|
|
763
|
+
})),
|
|
764
|
+
});
|
|
765
|
+
if (!ps) return console.log(`catalog '${cat.source}' defines no profiles.`);
|
|
766
|
+
const w = Math.max(...Object.keys(ps).map((n) => n.length));
|
|
767
|
+
for (const [n, p] of Object.entries(ps))
|
|
768
|
+
console.log(`${n.padEnd(w)} ${p.description}`);
|
|
769
|
+
console.log("\nInstall one: skilldrop install --profile <name>");
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
function installProfile(args) {
|
|
773
|
+
const name = args.flags.profile;
|
|
774
|
+
const cat = resolveCatalog(args.flags.from);
|
|
775
|
+
const profiles = profilesOf(cat);
|
|
776
|
+
if (!profiles) die(`catalog '${cat.source}' has no profiles.json`);
|
|
777
|
+
const p = profiles[name];
|
|
778
|
+
if (!p) die(`unknown profile '${name}' — available: ${Object.keys(profiles).join(", ")}`);
|
|
779
|
+
|
|
780
|
+
console.log(`Installing profile '${name}': ${p.description}\n`);
|
|
781
|
+
const flags = Object.assign({}, args.flags);
|
|
782
|
+
delete flags.profile;
|
|
783
|
+
|
|
784
|
+
for (const pack of (p.packs || [])) {
|
|
785
|
+
console.log(`\n── pack: ${pack} ──`);
|
|
786
|
+
install({ _: [], flags: Object.assign({}, flags, { pack }) });
|
|
787
|
+
}
|
|
788
|
+
for (const loop of (p.loops || [])) {
|
|
789
|
+
if (loopsIn(cat).includes(loop)) {
|
|
790
|
+
console.log(`\n── loop: ${loop} ──`);
|
|
791
|
+
installLoops({ _: [loop], flags: Object.assign({}, flags, { loop: true }) });
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
if ((p.agents || []).length) {
|
|
795
|
+
console.log(`\n── agents: ${p.agents.join(", ")} ──`);
|
|
796
|
+
installAgents({ _: p.agents.slice(), flags: Object.assign({}, flags, { agent: true }) });
|
|
797
|
+
}
|
|
798
|
+
console.log(`\nProfile '${name}' installed.`);
|
|
799
|
+
}
|
|
800
|
+
|
|
747
801
|
function install(args) {
|
|
748
802
|
if (args.flags.panel) return installPanel(args);
|
|
803
|
+
if (args.flags.profile) return installProfile(args);
|
|
749
804
|
if (args.flags.loop) return installLoops(args);
|
|
750
805
|
if (args.flags.agent) return installAgents(args);
|
|
751
806
|
const cat = resolveCatalog(args.flags.from);
|
|
@@ -1192,7 +1247,7 @@ function bootstrap() {
|
|
|
1192
1247
|
|
|
1193
1248
|
const args = parseArgs(process.argv.slice(2));
|
|
1194
1249
|
const cmd = args._.shift();
|
|
1195
|
-
const commands = { list, info, packs: listPacks, agents: listAgents, loops: listLoops, install, update, outdated, uninstall, validate: validateCmd, scan, bootstrap };
|
|
1250
|
+
const commands = { list, info, packs: listPacks, profiles: listProfiles, agents: listAgents, loops: listLoops, install, update, outdated, uninstall, validate: validateCmd, scan, bootstrap };
|
|
1196
1251
|
if (!cmd || cmd === "help" || args.flags.help) console.log(HELP);
|
|
1197
1252
|
else if (commands[cmd]) commands[cmd](args);
|
|
1198
1253
|
else die(`unknown command '${cmd}' — run: skilldrop help`);
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: release
|
|
3
|
+
description: Take merged code to live users through a planned, reversible rollout — plan the phases and the rollback, judge readiness on evidence, draft the release notes, then a human makes the go/no-go call. Use when the user has merged a change and asks how to roll it out, whether they are ready to launch, or for a go/no-go decision.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# release
|
|
7
|
+
|
|
8
|
+
This loop covers the step between `build`, which ends when a human merges, and `operate`,
|
|
9
|
+
which assumes the service is already live. A merge can be undone with a revert. A launch that
|
|
10
|
+
has touched users or data often cannot be undone, so this loop gets its own gates instead of
|
|
11
|
+
being folded into either neighbour.
|
|
12
|
+
|
|
13
|
+
## Stages
|
|
14
|
+
|
|
15
|
+
| # | Stage | Type | Skills | Gate |
|
|
16
|
+
|---|---|---|---|---|
|
|
17
|
+
| 1 | `plan` | generate | [`migration-plan`](../../skills/migration-plan/SKILL.md) | — |
|
|
18
|
+
| 2 | `ready` | verify | [`launch-readiness`](../../skills/launch-readiness/SKILL.md) | **G2.5** review |
|
|
19
|
+
| 3 | `announce` | generate | [`release-notes`](../../skills/release-notes/SKILL.md) | — |
|
|
20
|
+
| 4 | `go` | gate | [`council-review`](../../skills/council-review/SKILL.md) | **G2.6** human |
|
|
21
|
+
|
|
22
|
+
## How to run this loop
|
|
23
|
+
|
|
24
|
+
1. **Plan the rollout and the way back.** `migration-plan` sets out the phases, a tested
|
|
25
|
+
rollback for each one, and at most one named point of no return. For a code-only change
|
|
26
|
+
behind a flag, the plan can be short: the flag, the stages and how to turn it off. It still
|
|
27
|
+
has to exist.
|
|
28
|
+
2. **Judge readiness at G2.5.** `launch-readiness` lists the change's own failure modes, then
|
|
29
|
+
checks rollback, detection, response, measured targets, data and privacy, comms and
|
|
30
|
+
exposure, each with evidence. `REVISE` returns to `plan`, and the report names which gap to
|
|
31
|
+
close and which skill closes it. A missing rollback is `BLOCKED` on its own.
|
|
32
|
+
3. **Announce only once it is ready.** `release-notes` drafts the customer-facing and
|
|
33
|
+
internal notes from the git range. Writing them before G2.5 risks announcing a launch that
|
|
34
|
+
then does not happen.
|
|
35
|
+
4. **A human decides at G2.6.** The release owner decides whether to ship *now*, given
|
|
36
|
+
timing, freeze windows and on-call coverage. When that decision is contested, use
|
|
37
|
+
`council-review`. `RECONSIDER` means it is ready but this is the wrong time, and the work
|
|
38
|
+
waits instead of going back to `plan`.
|
|
39
|
+
|
|
40
|
+
After `PROCEED`, the change is live and the work moves to `operate`. Gaps that G2.5 sent to
|
|
41
|
+
`observability-plan` or `runbook-generator` are the first things `operate` picks up.
|
|
42
|
+
|
|
43
|
+
## Verdicts
|
|
44
|
+
|
|
45
|
+
Defined in [`contracts/terminals.json`](../../contracts/terminals.json). G2.5 emits `PROCEED`,
|
|
46
|
+
`PROCEED WITH CONDITIONS`, `REVISE` or `BLOCKED`. G2.6 adds `RECONSIDER`. `PROCEED WITH
|
|
47
|
+
CONDITIONS` at G2.5 is allowed only when the open rows are comms or exposure. A detection or
|
|
48
|
+
response gap is always `REVISE`.
|
|
49
|
+
|
|
50
|
+
## Non-interactive runs
|
|
51
|
+
|
|
52
|
+
Never invent evidence such as rehearsal logs, load-test numbers, dashboards or sign-offs.
|
|
53
|
+
When the change being released cannot be identified, emit `BLOCKED: need <the PR, tag, or
|
|
54
|
+
feature name>`. G2.6 is a human gate. A headless run stops after `announce` and reports the
|
|
55
|
+
G2.5 verdict for a person to act on.
|
|
56
|
+
|
|
57
|
+
## When a stage's skill is not installed
|
|
58
|
+
|
|
59
|
+
Name the missing skill and skilldrop as its source, do the minimal inline version of that
|
|
60
|
+
stage, and record the stage as degraded. For `ready`, the minimal version is the seven checks
|
|
61
|
+
written as a list, each marked met, not met or n/a with a reason. Skipping it is never the
|
|
62
|
+
minimal version.
|
|
63
|
+
|
|
64
|
+
## Quality bar
|
|
65
|
+
|
|
66
|
+
- **Rollback exists before readiness is judged.** A plan with no way back is the one thing that cannot be fixed after launch.
|
|
67
|
+
- **Readiness rests on evidence.** Every check links to something; "we're good" is `not met`.
|
|
68
|
+
- **Can and should are separate gates.** G2.5 says whether it can ship; G2.6 says whether it should ship now.
|
|
69
|
+
- **Detection gaps leave this loop as hand-offs.** `operate` picks them up first, rather than discovering them during the first incident.
|
|
70
|
+
|
|
71
|
+
## Anti-patterns to avoid
|
|
72
|
+
|
|
73
|
+
- ❌ **Jumping from merge to "instrument a running service".** That skips this loop entirely, which is the gap it exists to close.
|
|
74
|
+
- ❌ **Announcing before G2.5.** Customers hear about a launch that is then pulled.
|
|
75
|
+
- ❌ **Treating flag-off as a rollback without a data story.** If dual-write or a backfill has run, turning the flag off does not undo the data.
|
|
76
|
+
- ❌ **Letting G2.6 overrule a G2.5 `BLOCKED`.** A human can delay a ready launch; they cannot make an unready one ready by deciding to go.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$comment": "RFC-0031. Covers the step between build (ends at merge, G2.1) and operate (starts at instrument). The gate ids sit between G2 and G3 to match where the loop sits in the lifecycle.",
|
|
3
|
+
"name": "release",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"description": "Take merged code to live users through a planned, reversible rollout — plan the phases and the rollback, judge readiness on evidence, draft the release notes, then a human makes the go/no-go call. Use when the user has merged a change and asks how to roll it out, whether they are ready to launch, or for a go/no-go decision.",
|
|
6
|
+
"entrypoint": "LOOP.md",
|
|
7
|
+
"kind": "loop",
|
|
8
|
+
"cap": 3,
|
|
9
|
+
"stages": [
|
|
10
|
+
{
|
|
11
|
+
"id": "plan",
|
|
12
|
+
"type": "generate",
|
|
13
|
+
"intent": "Decide the rollout phases, the rollback for each, and the one point of no return, before anything reaches users.",
|
|
14
|
+
"skills": ["migration-plan"]
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"id": "ready",
|
|
18
|
+
"type": "verify",
|
|
19
|
+
"intent": "Judge on evidence whether the change can go live: rollback, detection, response, measured targets, data, comms, exposure.",
|
|
20
|
+
"skills": ["launch-readiness"],
|
|
21
|
+
"gate": {
|
|
22
|
+
"id": "G2.5",
|
|
23
|
+
"kind": "review",
|
|
24
|
+
"verdicts": ["PROCEED", "PROCEED WITH CONDITIONS", "REVISE", "BLOCKED"],
|
|
25
|
+
"revise_to": "plan"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"id": "announce",
|
|
30
|
+
"type": "generate",
|
|
31
|
+
"intent": "Write what users and the team are told. Only after readiness, so nobody announces a launch that then fails the check.",
|
|
32
|
+
"skills": ["release-notes"]
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"id": "go",
|
|
36
|
+
"type": "gate",
|
|
37
|
+
"intent": "A human decides whether it should ship now. Readiness says it can; this decides timing, freeze windows, and who is on call.",
|
|
38
|
+
"skills": ["council-review"],
|
|
39
|
+
"gate": {
|
|
40
|
+
"id": "G2.6",
|
|
41
|
+
"kind": "human",
|
|
42
|
+
"verdicts": ["PROCEED", "PROCEED WITH CONDITIONS", "REVISE", "RECONSIDER", "BLOCKED"],
|
|
43
|
+
"revise_to": "plan"
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
]
|
|
47
|
+
}
|