skilldrop-cli 0.13.1 → 0.13.2

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 CHANGED
@@ -8,8 +8,8 @@
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
- npx skilldrop-cli install --pack product-manager # or: solution-architect, dev-team,
12
- npx skilldrop-cli list # sre-oncall, stakeholder-comms, ai-engineering, claude-api
11
+ npx skilldrop-cli install --pack product-manager # or: solution-architect, dev-team, sre-oncall,
12
+ npx skilldrop-cli list # stakeholder-comms, ai-engineering, claude-api (each brings core)
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.
@@ -425,17 +425,18 @@ Why not have an LLM pick the model live on every call? Because that pays tokens
425
425
 
426
426
  ## Skill packs — install a role's toolkit in one command
427
427
 
428
- Categories (above) say what a skill *is*; packs say *who needs it*. [`packs.json`](packs.json) defines six role-based bundles — packs overlap where a skill serves several roles, and every skill belongs to at least one:
428
+ Categories (above) say what a skill *is*; packs say *who needs it*. [`packs.json`](packs.json) gives every skill and every loop **exactly one home** ([RFC-0033](docs/rfcs/0033-core-pack-and-single-home-skills.md)). Skills every role uses live in **`core`**, and each role pack `requires` it, so installing a role pack installs `core` with it in the same command:
429
429
 
430
- | Pack | Skills | For |
431
- |---|---|---|
432
- | `solution-architect` | 17 | Design-phase artifacts: diagrams, ADRs, design docs, contracts, schemas, threat models, and the reviews that gate them |
433
- | `dev-team` | 14 | Build-and-ship loop: implementation with adversarial review, test plans, triage, migrations, release notes, quality gates, pre-ship hygiene |
434
- | `product-manager` | 13 | Direction to requirements: PR/FAQs, strategy frameworks, OKRs, PRDs, journey maps, story splitting, success measurement |
435
- | `ai-engineering` | 12 | Build and run AI systems: agent loop design, subagent orchestration, spend budgets, eval harnesses, usage reporting, data contracts |
436
- | `stakeholder-comms` | 9 | Non-technical audiences: audience profiling, deck outlines and real `.pptx` decks, exec summaries, decision logs, guides |
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 |
430
+ | Pack | Skills | Loops | For |
431
+ |---|---|---|---|
432
+ | `core` | 4 | `ship-a-draft` | Every role: structured intake, document critique, the review council, output hygiene. Comes with every role pack |
433
+ | `dev-team` | 14 + core | `build`, `release` | Build-and-ship: story splitting, implementation with adversarial review, test plans, triage, migrations, launch readiness, release notes, quality gates |
434
+ | `solution-architect` | 11 + core | `design` | Design-phase artifacts: diagrams, ADRs, design docs, contracts, schemas, threat models |
435
+ | `ai-engineering` | 11 + core | — | Adopt and build AI systems: readiness, use-case triage, rollout and policy, agent loop design, subagents, spend budgets, agent threat models, evals, usage reporting |
436
+ | `product-manager` | 8 + core | `discover` | Direction to requirements: PR/FAQs, strategy frameworks, OKRs, business cases, interviews, PRDs, journey maps, success measurement |
437
+ | `stakeholder-comms` | 6 + core | — | Non-technical audiences: audience profiling, deck outlines and real `.pptx` decks, exec summaries, decision logs, guides |
438
+ | `sre-oncall` | 5 + core | `operate` | Operate the service: runbooks, observability design, incident comms, postmortems, capacity/cost models |
439
+ | `claude-api` | 4 | — | Build on the Anthropic API: prompt caching strategy, token budgeting, eval generation for skills, tool-use schema writing. A specialist add-on; it does not bring core |
439
440
 
440
441
  ```bash
441
442
  python3 pack.py # list packs
@@ -445,7 +446,7 @@ python3 pack.py product-manager --install --project # into .claude/skills/
445
446
  python3 pack.py product-manager --install --dest .cursor/skills # any dir, for non-Claude IDEs
446
447
  ```
447
448
 
448
- For non-Claude IDEs, `--dest` drops the folders where your tool expects them; the per-IDE wiring steps below still apply. Packs are metadata only — skills stay in flat `skills/<name>` folders, so per-skill `cp -R` installs keep working unchanged ([RFC-0001](docs/rfcs/0001-skill-packs.md) records the design decision).
449
+ For non-Claude IDEs, `--dest` drops the folders where your tool expects them; the per-IDE wiring steps below still apply. Packs are metadata only — skills stay in flat `skills/<name>` folders, so per-skill `cp -R` installs keep working unchanged ([RFC-0001](docs/rfcs/0001-skill-packs.md) records the original decision; [RFC-0033](docs/rfcs/0033-core-pack-and-single-home-skills.md) replaced its overlapping packs with `core` and one home per skill).
449
450
 
450
451
  ## Outcomes — browse by why you're here
451
452
 
@@ -485,7 +486,7 @@ npx skilldrop-cli install --loop --pack sre-oncall # every loop that pack d
485
486
  npx skilldrop-cli agents # the reviewer subagents
486
487
  npx skilldrop-cli install --agent devils-advocate # -> ~/.claude/agents/ (RFC-0012)
487
488
  npx skilldrop-cli install --panel review # the whole review fleet: 3 subagents + the pre-merge-review orchestrator (RFC-0020)
488
- npx skilldrop-cli outdated && npx skilldrop-cli update # skills improve; cp -R never tells you
489
+ npx skilldrop-cli outdated && npx skilldrop-cli update # skills improve; files you edited are kept, new copy as <file>.upstream
489
490
  npx skilldrop-cli list | skilldrop info <skill> | skilldrop packs | skilldrop uninstall <skill>
490
491
  npx skilldrop-cli list --json # machine-readable: list/info/packs/agents/outdated (RFC-0021)
491
492
  ```
@@ -504,17 +505,19 @@ Then take the whole catalogue, or just your role's pack:
504
505
 
505
506
  ```text
506
507
  /plugin install skilldrop@skilldrop # all 63 skills + 3 reviewer subagents
507
- /plugin install solution-architect@skilldrop # 17 skills
508
- /plugin install dev-team@skilldrop # 14 skills + the 3 reviewer subagents
509
- /plugin install product-manager@skilldrop # 13 skills
510
- /plugin install ai-engineering@skilldrop # 12 skills
511
- /plugin install stakeholder-comms@skilldrop # 9 skills
512
- /plugin install sre-oncall@skilldrop # 5 skills
508
+ /plugin install dev-team@skilldrop # 18 skills (incl. core) + the 3 reviewer subagents
509
+ /plugin install solution-architect@skilldrop # 15 skills (incl. core)
510
+ /plugin install ai-engineering@skilldrop # 15 skills (incl. core)
511
+ /plugin install product-manager@skilldrop # 12 skills (incl. core)
512
+ /plugin install stakeholder-comms@skilldrop # 10 skills (incl. core)
513
+ /plugin install sre-oncall@skilldrop # 9 skills (incl. core)
514
+ /plugin install claude-api@skilldrop # 4 skills
515
+ /plugin install core@skilldrop # 4 skills, on their own
513
516
  ```
514
517
 
515
518
  Every skill then invokes as `/<plugin>:<name>` (e.g. `/skilldrop:prfaq`). The whole-catalogue plugin ships the flat `skills/` and `agents/` trees at the repo root unchanged — same copy-install premise, expressed in Claude's own plugin format.
516
519
 
517
- The six **pack plugins** work differently, because a plugin's skills have to sit in a `skills/` folder inside the plugin. Rather than duplicate every skill into six directories on `main` — physical packs, which [RFC-0001](docs/rfcs/0001-skill-packs.md) rejected — the marketplace entries use Claude's `git-subdir` source to point at `packs/<name>/` on a generated [`plugins`](https://github.com/sananthanarayan/skilldrop/tree/plugins) branch, rebuilt by CI on every push to main. Nothing moves in the source tree, and you still only ever type the one `marketplace add`. A pack carries the reviewer subagents its own skills delegate to, so `dev-team` brings the review panel and `sre-oncall` does not.
520
+ The eight **pack plugins** work differently, because a plugin's skills have to sit in a `skills/` folder inside the plugin. Rather than duplicate every skill into eight directories on `main` — physical packs, which [RFC-0001](docs/rfcs/0001-skill-packs.md) rejected — the marketplace entries use Claude's `git-subdir` source to point at `packs/<name>/` on a generated [`plugins`](https://github.com/sananthanarayan/skilldrop/tree/plugins) branch, rebuilt by CI on every push to main. Nothing moves in the source tree, and you still only ever type the one `marketplace add`. Each role pack's plugin also carries `core`'s skills and loops, since a plugin installs on its own. A pack carries the reviewer subagents its own skills delegate to, so `dev-team` brings the review panel and `sre-oncall` does not.
518
521
 
519
522
  `.claude-plugin/{marketplace,plugin}.json` are generated from `package.json` + `packs.json` by [`build_marketplace.py`](build_marketplace.py) (`--check` guards drift in CI; `--dist` renders the branch). Use the CLI above when you want per-skill granularity, another IDE, or hooks; use the marketplace when you're in Claude Code. Rationale: [RFC-0027](docs/rfcs/0027-retire-agentbundle-export.md).
520
523
 
package/bin/skilldrop.js CHANGED
@@ -13,6 +13,7 @@ const fs = require("fs");
13
13
  const path = require("path");
14
14
  const os = require("os");
15
15
  const { execFileSync } = require("child_process");
16
+ const crypto = require("crypto");
16
17
 
17
18
  const ROOT = path.resolve(__dirname, "..");
18
19
  const LEDGER = ".skilldrop.json";
@@ -48,7 +49,9 @@ Usage:
48
49
  (--no-skills for the loop alone) (RFC-0028)
49
50
  skilldrop install --panel review install the review panel — the 3 reviewer subagents +
50
51
  the pre-merge-review orchestrator that fires them (RFC-0020)
51
- skilldrop update re-copy installed skills whose version changed
52
+ skilldrop update [--force] re-copy installed skills whose version changed; files
53
+ you edited are kept and the new copy lands beside them
54
+ as <file>.upstream (--force overwrites) (RFC-0032)
52
55
  skilldrop outdated show installed vs current versions, change nothing
53
56
  skilldrop uninstall <skill...> remove skills (and wiring files this tool wrote)
54
57
  skilldrop uninstall --agent <name...> remove subagents
@@ -264,6 +267,15 @@ function packsOf(cat) {
264
267
  const p = path.join(cat.dir, "packs.json");
265
268
  return fs.existsSync(p) ? readJSON(p).packs : null;
266
269
  }
270
+ /* RFC-0033: a pack installs together with the packs it `requires` (in practice, core), so
271
+ one --pack still delivers a role's whole toolkit now that shared skills have one home. */
272
+ function packMembers(ps, name, key) {
273
+ const req = (ps[name].requires || []).filter((r) => ps[r]);
274
+ const out = [];
275
+ for (const n of [...req, name]) for (const x of ps[n][key] || []) if (!out.includes(x)) out.push(x);
276
+ if (req.length) console.log(`pack '${name}' includes ${req.join(", ")}`);
277
+ return out;
278
+ }
267
279
  function profilesOf(cat) {
268
280
  const p = path.join(cat.dir, "profiles.json");
269
281
  return fs.existsSync(p) ? readJSON(p).profiles : null;
@@ -709,7 +721,7 @@ function expandNames(args, cat) {
709
721
  if (!ps) die(`catalog '${cat.source}' has no packs.json — install skills by name`);
710
722
  const p = ps[args.flags.pack];
711
723
  if (!p) die(`unknown pack '${args.flags.pack}' in catalog '${cat.source}'`);
712
- return p.skills.slice();
724
+ return packMembers(ps, args.flags.pack, "skills");
713
725
  }
714
726
  if (!args._.length) die("nothing to install — pass skill names, --pack <name>, or --all");
715
727
  for (const s of args._) if (!skillExists(cat, s)) die(`unknown skill '${s}' in catalog '${cat.source}'`);
@@ -721,10 +733,64 @@ function copyOne(cat, s, dest, ide, l, notes) {
721
733
  fs.cpSync(skillDir(cat, s), path.join(dest, s), { recursive: true });
722
734
  const note = writeWiring(ide, dest, s, m.description);
723
735
  if (note && notes) notes.push(note);
724
- l.data[s] = { version: m.version, source: cat.source };
736
+ l.data[s] = { version: m.version, source: cat.source, files: fileHashes(skillDir(cat, s)) };
725
737
  return m;
726
738
  }
727
739
 
740
+ /* RFC-0032: per-file SHA-256 of a skill as the catalog shipped it, recorded in the ledger at
741
+ copy time. It is the baseline `update` compares against, so a file the user edited is never
742
+ overwritten. Paths are forward-slash relative; *.upstream files are this tool's output. */
743
+ function sha256(buf) { return crypto.createHash("sha256").update(buf).digest("hex"); }
744
+ function fileHashes(dir) {
745
+ const out = {};
746
+ (function walk(d, rel) {
747
+ for (const e of fs.readdirSync(d, { withFileTypes: true })) {
748
+ const r = rel ? `${rel}/${e.name}` : e.name;
749
+ if (e.isDirectory()) walk(path.join(d, e.name), r);
750
+ else if (e.isFile() && !e.name.endsWith(".upstream")) out[r] = sha256(fs.readFileSync(path.join(d, e.name)));
751
+ }
752
+ })(dir, "");
753
+ return out;
754
+ }
755
+
756
+ /* Update one skill file by file against the ledger baseline (RFC-0032):
757
+ upstream unchanged -> leave the local file alone, edited or not
758
+ local untouched, or new file -> take the new version
759
+ local edited, upstream moved -> keep the local file, write the new one as <file>.upstream
760
+ A file the catalog dropped is removed only if the user never touched it. The new baseline is
761
+ what the catalog ships now, so a kept edit stays "edited" until the user merges it. */
762
+ function mergeOne(cat, s, dest, ide, l, notes) {
763
+ const m = manifestOf(cat, s);
764
+ const src = skillDir(cat, s), dst = path.join(dest, s);
765
+ const base = l.data[s].files, next = fileHashes(src);
766
+ const kept = [], orphaned = [];
767
+ const at = (root, rel) => path.join(root, ...rel.split("/"));
768
+ const localHash = (rel) => { try { return sha256(fs.readFileSync(at(dst, rel))); } catch (e) { return null; } };
769
+ for (const [rel, h] of Object.entries(next)) {
770
+ const mine = localHash(rel), to = at(dst, rel);
771
+ if (mine === h) { fs.rmSync(to + ".upstream", { force: true }); continue; }
772
+ if (h === base[rel]) continue;
773
+ fs.mkdirSync(path.dirname(to), { recursive: true });
774
+ if (mine === null ? !(rel in base) : mine === base[rel]) {
775
+ fs.copyFileSync(at(src, rel), to);
776
+ fs.rmSync(to + ".upstream", { force: true });
777
+ } else {
778
+ fs.copyFileSync(at(src, rel), to + ".upstream");
779
+ kept.push(rel);
780
+ }
781
+ }
782
+ for (const rel of Object.keys(base)) {
783
+ if (rel in next) continue;
784
+ const mine = localHash(rel);
785
+ if (mine === base[rel]) fs.rmSync(at(dst, rel), { force: true });
786
+ else if (mine !== null) orphaned.push(rel);
787
+ }
788
+ const note = writeWiring(ide, dest, s, m.description);
789
+ if (note && notes) notes.push(note);
790
+ l.data[s] = { version: m.version, source: cat.source, files: next };
791
+ return { m, kept, orphaned };
792
+ }
793
+
728
794
  /* Install a whole review panel — the reviewer subagents + the orchestrator skill — in one
729
795
  command (RFC-0020). Needs a target with BOTH a subagent and a skill format, so it accepts
730
796
  the default (Claude Code), --project, --ide kiro, or --dest; other IDEs install the halves
@@ -874,18 +940,30 @@ function installedRows(flags) {
874
940
  function update(args) {
875
941
  const { dest, ide, l, rows } = installedRows(args.flags);
876
942
  if (!rows.length) return console.log(`nothing installed at ${dest}`);
877
- let n = 0;
943
+ let n = 0, conflicts = 0;
878
944
  for (const r of rows) {
879
945
  if (!r.current) { console.log(`skip ${r.s}: source '${r.src}' unreachable or skill gone from it`); continue; }
880
946
  if (r.current === r.installed) continue;
881
947
  const problems = checkSkill(r.cat, r.s);
882
948
  if (problems.length) { console.log(`skip ${r.s}: fails structural check in '${r.src}' (${problems[0]})`); continue; }
883
- copyOne(r.cat, r.s, dest, ide, l);
884
- console.log(`updated ${r.s} ${r.installed} -> ${r.current} (${r.src})`);
949
+ // No baseline (installed before RFC-0032) or --force: overwrite as before, and record one.
950
+ const entry = l.data[r.s];
951
+ if (args.flags.force || typeof entry !== "object" || !entry.files) {
952
+ copyOne(r.cat, r.s, dest, ide, l);
953
+ console.log(`updated ${r.s} ${r.installed} -> ${r.current} (${r.src})`);
954
+ } else {
955
+ const { kept, orphaned } = mergeOne(r.cat, r.s, dest, ide, l);
956
+ console.log(`updated ${r.s} ${r.installed} -> ${r.current} (${r.src})`);
957
+ for (const f of kept) console.log(` kept your edits in ${f} — new version at ${f}.upstream`);
958
+ for (const f of orphaned) console.log(` kept ${f} — dropped upstream, but you edited it`);
959
+ conflicts += kept.length;
960
+ }
885
961
  n++;
886
962
  }
887
963
  saveLedger(l);
888
964
  console.log(n ? `\n${n} skill(s) updated.` : "everything up to date.");
965
+ if (conflicts)
966
+ console.log(`${conflicts} file(s) kept your edits. Merge each <file>.upstream into its file, then delete it — or rerun with --force to take every new version.`);
889
967
  }
890
968
 
891
969
  function outdated(args) {
@@ -1013,7 +1091,7 @@ function installLoops(args) {
1013
1091
  if (!ps) die(`catalog '${cat.source}' has no packs.json`);
1014
1092
  const pk = ps[args.flags.pack];
1015
1093
  if (!pk) die(`unknown pack '${args.flags.pack}' in catalog '${cat.source}'`);
1016
- names = (pk.loops || []).slice();
1094
+ names = packMembers(ps, args.flags.pack, "loops");
1017
1095
  if (!names.length) die(`pack '${args.flags.pack}' declares no loops`);
1018
1096
  }
1019
1097
  if (!names.length && args.flags.all) names = available.slice();
@@ -1182,13 +1260,13 @@ function listPacks(args) {
1182
1260
  catalog: cat.source,
1183
1261
  count: ps ? Object.keys(ps).length : 0,
1184
1262
  packs: Object.entries(ps || {}).map(([name, p]) => ({
1185
- name, description: p.description || null, skills: p.skills || [],
1263
+ name, description: p.description || null, skills: p.skills || [], requires: p.requires || [],
1186
1264
  })),
1187
1265
  });
1188
1266
  if (!ps) return console.log(`catalog '${cat.source}' defines no packs.`);
1189
1267
  const w = Math.max(...Object.keys(ps).map((n) => n.length));
1190
1268
  for (const [n, p] of Object.entries(ps))
1191
- console.log(`${n.padEnd(w)} (${p.skills.length} skills) ${p.description}`);
1269
+ console.log(`${n.padEnd(w)} (${p.skills.length} skills${(p.requires || []).length ? ` + ${p.requires.join(", ")}` : ""}) ${p.description}`);
1192
1270
  console.log("\nInstall one: skilldrop install --pack <name>");
1193
1271
  }
1194
1272
 
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://github.com/sananthanarayan/skilldrop/contracts/pack.schema.json",
4
4
  "title": "skilldrop packs.json",
5
- "$comment": "RFC-0001 / RFC-0026 / RFC-0029. Packs and outcomes are METADATA ONLY — skills never move out of flat skills/<name> folders. Packs answer WHO needs a skill; outcomes answer WHY someone opened the catalogue. Both get the same two-way membership check in validate.py.",
5
+ "$comment": "RFC-0001 / RFC-0026 / RFC-0029 / RFC-0033. Packs and outcomes are METADATA ONLY — skills never move out of flat skills/<name> folders. RFC-0033: each skill and loop sits in exactly one pack; shared skills live in `core`, which other packs pull in via `requires`. Packs answer WHO needs a skill; outcomes answer WHY someone opened the catalogue. Both get the same two-way membership check in validate.py.",
6
6
  "type": "object",
7
7
  "additionalProperties": false,
8
8
  "required": ["version", "packs", "outcomes"],
@@ -20,7 +20,14 @@
20
20
  "description": { "type": "string", "description": "One line — who this pack is for." },
21
21
  "skills": { "type": "array", "items": { "type": "string" }, "minItems": 1,
22
22
  "description": "Real skill folders. Every skill must appear in at least one pack." },
23
- "loops": { "type": "array", "items": { "type": "string" },
23
+ "requires": {
24
+ "type": "array",
25
+ "items": {
26
+ "type": "string"
27
+ },
28
+ "description": "RFC-0033. Packs installed together with this one (in practice, `core`). One level only: a required pack may not itself require."
29
+ },
30
+ "loops": { "type": "array", "items": { "type": "string" },
24
31
  "description": "RFC-0028. Real loops/ folders. Every loop must appear in at least one pack." }
25
32
  }
26
33
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skilldrop-cli",
3
- "version": "0.13.1",
3
+ "version": "0.13.2",
4
4
  "description": "Portable AI-agent skills for the deliverables knowledge workers ship \u2014 diagrams, ADRs, PRDs, runbooks, decks, reviews \u2014 installable into Claude Code, Cursor, Kiro, and any IDE that takes custom instructions. One command per skill or per role-based pack.",
5
5
  "author": {
6
6
  "name": "Sanjay Ananthanarayan",
package/packs.json CHANGED
@@ -1,12 +1,22 @@
1
1
  {
2
- "$comment": "Virtual skill packs — role-based bundles for one-command install. Packs are METADATA ONLY: skills stay in flat skills/<name> folders (golden rule: skills are discovered by path), a skill may belong to several packs, and every skill must belong to at least one (validate.py enforces both directions). Install a pack with `python3 pack.py <pack> --install`; see README. Rationale: docs/rfcs/0001-skill-packs.md. `outcomes` (RFC-0026) is the second browse axis: packs say WHO needs a skill, outcomes say WHY someone opens the catalogue. It is the README's nine categories restated as seven outcomes and made machine-readable so the site cannot drift from them. Outcomes are a browse aid only — not an install unit — and validate.py enforces the same two-way check packs get.",
3
- "version": "0.1.0",
2
+ "$comment": "Virtual skill packs — role-based bundles for one-command install. Packs are METADATA ONLY: skills stay in flat skills/<name> folders (golden rule: skills are discovered by path), every skill and every loop belongs to exactly one pack (RFC-0033 — the shape a later physical packs/<name>/ layout needs), and a pack may `requires` the `core` pack, which every installer then installs with it. validate.py enforces all of this. Install a pack with `python3 pack.py <pack> --install`; see README. Rationale: docs/rfcs/0001-skill-packs.md. `outcomes` (RFC-0026) is the second browse axis: packs say WHO needs a skill, outcomes say WHY someone opens the catalogue. It is the README's nine categories restated as seven outcomes and made machine-readable so the site cannot drift from them. Outcomes are a browse aid only — not an install unit — and validate.py enforces the same two-way check packs get.",
3
+ "version": "0.2.0",
4
4
  "packs": {
5
+ "core": {
6
+ "description": "The cross-role toolkit every pack builds on: structured intake, document critique, the review council, and output hygiene, plus the ship-a-draft wrapper. Installed automatically with every role pack.",
7
+ "loops": ["ship-a-draft"],
8
+ "skills": [
9
+ "brief-intake",
10
+ "doc-critique",
11
+ "output-hygiene",
12
+ "council-review"
13
+ ]
14
+ },
5
15
  "solution-architect": {
6
16
  "description": "Design-phase artifacts: diagrams, decision records, design docs, contracts, schemas, threat models, and the reviews that gate them.",
7
- "loops": ["design", "ship-a-draft"],
17
+ "requires": ["core"],
18
+ "loops": ["design"],
8
19
  "skills": [
9
- "brief-intake",
10
20
  "architecture-diagrams",
11
21
  "reverse-architecture",
12
22
  "figma-diagrams",
@@ -14,22 +24,17 @@
14
24
  "design-doc",
15
25
  "tech-comparison-matrix",
16
26
  "threat-model",
17
- "agent-threat-model",
18
- "agents-md-generator",
19
27
  "api-contract-draft",
20
28
  "data-contract",
21
29
  "db-schema-design",
22
- "nfr-spec",
23
- "capacity-cost-model",
24
- "council-review",
25
- "doc-critique"
30
+ "nfr-spec"
26
31
  ]
27
32
  },
28
33
  "product-manager": {
29
- "description": "Direction to requirements: PR/FAQs, strategy frameworks, OKRs, PRDs, journey maps, story splitting, and success measurement.",
30
- "loops": ["discover", "ship-a-draft"],
34
+ "description": "Direction to requirements: PR/FAQs, strategy frameworks, OKRs, business cases, interviews, PRDs, journey maps, and success measurement.",
35
+ "requires": ["core"],
36
+ "loops": ["discover"],
31
37
  "skills": [
32
- "brief-intake",
33
38
  "prfaq",
34
39
  "strategy-analysis",
35
40
  "okr-cascade",
@@ -37,23 +42,19 @@
37
42
  "requirements-interview",
38
43
  "prd-draft",
39
44
  "user-journey-map",
40
- "user-story-splitter",
41
- "success-metrics",
42
- "exec-summary",
43
- "doc-critique",
44
- "ai-use-case-triage"
45
+ "success-metrics"
45
46
  ]
46
47
  },
47
48
  "dev-team": {
48
- "description": "Build-and-ship loop: story implementation with adversarial review, test plans, triage, migrations, release notes, agent-policy files, and code-quality gates.",
49
- "loops": ["build", "release", "ship-a-draft"],
49
+ "description": "Build-and-ship: story splitting, implementation with adversarial review, test plans, triage, migrations, launch readiness, release notes, agent-policy files, and code-quality gates.",
50
+ "requires": ["core"],
51
+ "loops": ["build", "release"],
50
52
  "skills": [
51
53
  "agents-md-generator",
52
54
  "user-story-splitter",
53
55
  "feature-implement-loop",
54
56
  "pre-merge-review",
55
57
  "devils-advocate",
56
- "council-review",
57
58
  "test-plan-generator",
58
59
  "bug-triage",
59
60
  "migration-plan",
@@ -61,41 +62,39 @@
61
62
  "sonar-onboard",
62
63
  "sonar-review",
63
64
  "accessibility-audit",
64
- "output-hygiene",
65
65
  "contribution-wizard",
66
66
  "launch-readiness"
67
67
  ]
68
68
  },
69
69
  "sre-oncall": {
70
70
  "description": "Operate the service: runbooks, observability design, incident communications, postmortems, and capacity/cost models.",
71
- "loops": ["release", "operate"],
71
+ "requires": ["core"],
72
+ "loops": ["operate"],
72
73
  "skills": [
73
74
  "runbook-generator",
74
75
  "observability-plan",
75
76
  "incident-comms",
76
77
  "postmortem-generator",
77
- "capacity-cost-model",
78
- "launch-readiness"
78
+ "capacity-cost-model"
79
79
  ]
80
80
  },
81
81
  "stakeholder-comms": {
82
82
  "description": "Non-technical audiences: audience profiling, deck outlines and real .pptx decks, exec summaries, decision logs, and guides.",
83
- "loops": ["ship-a-draft"],
83
+ "requires": ["core"],
84
+ "loops": [],
84
85
  "skills": [
85
- "brief-intake",
86
86
  "audience-profile",
87
87
  "slide-outliner",
88
88
  "deck-builder",
89
89
  "exec-summary",
90
90
  "decision-log",
91
- "guide-builder",
92
- "doc-critique",
93
- "output-hygiene"
91
+ "guide-builder"
94
92
  ]
95
93
  },
96
94
  "ai-engineering": {
97
- "description": "Adopt and build AI systems: readiness assessment, use-case triage, rollout and acceptable-use policy, plus agent loop design, subagent orchestration, spend budgets, agent security review, eval harnesses, AI-usage reporting, and the data contracts AI pipelines depend on.",
98
- "loops": ["design", "build"],
95
+ "description": "Adopt and build AI systems: readiness assessment, use-case triage, rollout and acceptable-use policy, plus agent loop design, subagent orchestration, spend budgets, agent security review, eval harnesses, and AI-usage reporting.",
96
+ "requires": ["core"],
97
+ "loops": [],
99
98
  "skills": [
100
99
  "agent-loop-design",
101
100
  "subagent-design",
@@ -103,7 +102,6 @@
103
102
  "agent-threat-model",
104
103
  "llm-eval-harness",
105
104
  "ai-usage-report",
106
- "data-contract",
107
105
  "ai-readiness-assessment",
108
106
  "ai-use-case-triage",
109
107
  "ai-adoption-rollout",