create-claude-cabinet 0.6.3 → 0.6.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-claude-cabinet",
3
- "version": "0.6.3",
3
+ "version": "0.6.4",
4
4
  "description": "Claude Cabinet — opinionated process scaffolding for Claude Code projects",
5
5
  "bin": {
6
6
  "create-claude-cabinet": "bin/create-claude-cabinet.js"
@@ -117,7 +117,7 @@ execution, audit). Each is a named domain expert encoded in markdown.
117
117
  | `_briefing-template.md` | 1+2 | Template for the project-specific briefing every cabinet member reads. Wave 2 added: Scan Scopes, API Configuration, Entity Types, User Context. |
118
118
  | `_prompt-guide.md` | 2 | Craft knowledge for writing cabinet member prompts. 17 principles including Levitin's cognitive architecture. |
119
119
  | `output-contract.md` | 5 | How cabinet members produce structured findings for the audit system. Defines the assumption/evidence/question triad, severity calibration, positive findings, autoFixable field, JSON output format. |
120
- | `committees-template.yaml` | 5 | Technology-implied starter committees for organizing cabinet members (ux, code, health, process). Copy as `committees.yaml` and customize. |
120
+ | `committees.yaml` | 5 | Upstream committee definitions for organizing cabinet members (ux, code, health, process, strategic). Upstream-owned; project customizations go in `committees-project.yaml`. |
121
121
  | `_lifecycle.md` | 5 | When to adopt, retire, and assess cabinet members. Cross-cutting vs grouped distinction. |
122
122
 
123
123
  ### Memory (1 pattern + 1 template)
@@ -281,7 +281,7 @@ when you outgrow them.
281
281
  3. **Copy cabinet member infrastructure:**
282
282
  ```bash
283
283
  cp process-in-a-box/skills/cabinet/output-contract.md .claude/skills/cabinet/
284
- cp process-in-a-box/skills/cabinet/committees-template.yaml .claude/skills/cabinet/
284
+ cp process-in-a-box/skills/cabinet/committees.yaml .claude/skills/cabinet/
285
285
  cp process-in-a-box/skills/cabinet/_lifecycle.md .claude/skills/cabinet/
286
286
  ```
287
287
 
@@ -294,11 +294,11 @@ when you outgrow them.
294
294
  cp process-in-a-box/scripts/finding-schema.json your-project/scripts/
295
295
  ```
296
296
 
297
- 5. **Set up committees** (optional):
298
- ```bash
299
- cp .claude/skills/cabinet/committees-template.yaml .claude/skills/cabinet/committees.yaml
300
- ```
301
- Uncomment the committees relevant to your project.
297
+ 5. **Customize committees** (optional):
298
+ Create a `committees-project.yaml` in `.claude/cabinet/` to add custom
299
+ members or committees. The upstream `committees.yaml` is installed
300
+ automatically. Run `node scripts/resolve-committees.js` to see the
301
+ merged result.
302
302
 
303
303
  6. **Run your first audit:** `/audit` — it discovers cabinet members, runs
304
304
  them, and persists findings. Then `/triage-audit` to review results.
@@ -346,8 +346,9 @@ These are the project-specific pieces to build as you adopt:
346
346
  checks as you discover what drifts.
347
347
  - **Triage phase files** — Where findings come from, how to present them,
348
348
  how to apply verdicts. Defaults use the local triage UI and pib-db.
349
- - **Committees** — Copy `committees-template.yaml` as `committees.yaml`
350
- and uncomment the committees relevant to your technology stack.
349
+ - **Committees** — The upstream `committees.yaml` is installed automatically.
350
+ Create `committees-project.yaml` to add custom members to upstream
351
+ committees or define new project-specific committees.
351
352
 
352
353
  None of this requires working alone. Claude is the constant companion
353
354
  throughout — the package provides the structure, and you build the
@@ -3,7 +3,9 @@
3
3
  ## Active Cabinet Members
4
4
 
5
5
  *Which cabinet members are active in this project and how they're organized into committees.
6
- Reference `committees.yaml` for the canonical grouping.*
6
+ Reference `committees.yaml` (upstream) and `committees-project.yaml` (project
7
+ customizations) for the canonical grouping. Run `node scripts/resolve-committees.js`
8
+ to see the merged result.*
7
9
 
8
10
  ## Portfolio Rules
9
11
 
@@ -0,0 +1,49 @@
1
+ # Cabinet member committees — canonical groupings of upstream cabinet members.
2
+ #
3
+ # This file is upstream-owned and manifest-tracked. It is updated automatically
4
+ # by the installer. Do not edit — your customizations go in committees-project.yaml.
5
+ #
6
+ # Consumed by:
7
+ # - /audit skill (committee selection menu)
8
+ # - scripts/resolve-committees.js (merges with committees-project.yaml)
9
+ #
10
+ # Cross-portfolio cabinet members are NOT in any committee. They activate via
11
+ # standing-mandate in their SKILL.md frontmatter and run on every audit:
12
+ # anti-confirmation, qa, debugger, organized-mind
13
+
14
+ committees:
15
+ ux:
16
+ name: "UX & Design"
17
+ members:
18
+ - usability
19
+ - accessibility
20
+ - small-screen
21
+
22
+ code:
23
+ name: "Code Quality"
24
+ members:
25
+ - technical-debt
26
+ - architecture
27
+ - boundary-man
28
+
29
+ health:
30
+ name: "System Health"
31
+ members:
32
+ - security
33
+ - data-integrity
34
+ - speed-freak
35
+
36
+ process:
37
+ name: "Process & Meta"
38
+ members:
39
+ - workflow-cop
40
+ - record-keeper
41
+ - process-therapist
42
+ - roster-check
43
+ - cc-health
44
+
45
+ strategic:
46
+ name: "Strategic"
47
+ members:
48
+ - system-advocate
49
+ - historian
@@ -60,7 +60,9 @@ of calibration quality.
60
60
 
61
61
  ## Cross-Portfolio vs Committee-Assigned
62
62
 
63
- Most cabinet members belong in exactly one committee (see `committees-template.yaml`).
63
+ Most cabinet members belong in exactly one committee (see `committees.yaml`
64
+ for upstream committees and `committees-project.yaml` for project-specific
65
+ additions).
64
66
  They cover a specific domain and stay in their portfolio.
65
67
 
66
68
  **Cross-portfolio cabinet members** intentionally span domains. Their expertise
@@ -85,7 +87,9 @@ A cabinet member is a skill with `user-invocable: false`. Create it in
85
87
  5. **Calibration Examples** — good findings, wrong-portfolio findings, severity
86
88
  anchors
87
89
 
88
- Add the cabinet member to your `committees.yaml` under the appropriate committee.
90
+ Add the cabinet member to your `committees-project.yaml` under the appropriate
91
+ committee (using `additional_members` to append to an upstream committee, or
92
+ a new committee definition).
89
93
  It's automatically discovered by the audit skill.
90
94
 
91
95
  The best cabinet members emerge from real incidents and real audit findings.
@@ -0,0 +1,218 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /**
5
+ * resolve-committees.js — Merge upstream committees.yaml with project committees-project.yaml
6
+ *
7
+ * Usage:
8
+ * node scripts/resolve-committees.js [path-to-claude-dir]
9
+ *
10
+ * Default path: .claude
11
+ *
12
+ * Reads:
13
+ * <claude-dir>/cabinet/committees.yaml (upstream, required)
14
+ * <claude-dir>/cabinet/committees-project.yaml (project, optional)
15
+ *
16
+ * Merge rules:
17
+ * - Project `additional_members` appends to upstream member lists
18
+ * - Project `members` replaces upstream member lists entirely
19
+ * - Project `skip: true` removes that committee
20
+ * - Project `name` overrides upstream display name
21
+ * - New committees in project file are added
22
+ *
23
+ * Outputs merged JSON to stdout.
24
+ */
25
+
26
+ const fs = require('fs');
27
+ const path = require('path');
28
+
29
+ // --- Simple YAML parser (handles only what we need) ---
30
+
31
+ function parseSimpleYaml(text) {
32
+ // Our YAML is exactly 3 levels deep with 2-space indentation:
33
+ // committees: (indent 0 — top level)
34
+ // ux: (indent 2 — committee name)
35
+ // name: "UX" (indent 4 — property)
36
+ // members: (indent 4 — property, value is list below)
37
+ // - usability (indent 6+ — list item)
38
+ const result = {};
39
+ const lines = text.split('\n');
40
+ let topKey = null; // e.g., 'committees'
41
+ let committeeKey = null; // e.g., 'ux'
42
+ let propKey = null; // e.g., 'members'
43
+
44
+ for (const line of lines) {
45
+ const trimmed = line.trimEnd();
46
+ if (trimmed === '' || /^\s*#/.test(trimmed)) continue;
47
+
48
+ const indent = line.length - line.trimStart().length;
49
+ const content = trimmed.trim();
50
+
51
+ if (indent === 0) {
52
+ const m = content.match(/^(\w[\w-]*):\s*(.*)$/);
53
+ if (m) {
54
+ topKey = m[1];
55
+ result[topKey] = {};
56
+ committeeKey = null;
57
+ propKey = null;
58
+ }
59
+ } else if (indent >= 2 && indent < 4 && topKey) {
60
+ // Committee name level
61
+ const m = content.match(/^(\w[\w-]*):\s*(.*)$/);
62
+ if (m) {
63
+ committeeKey = m[1];
64
+ const val = m[2].trim();
65
+ if (val === 'true' || val === 'false') {
66
+ result[topKey][committeeKey] = parseValue(val);
67
+ } else {
68
+ result[topKey][committeeKey] = {};
69
+ }
70
+ propKey = null;
71
+ }
72
+ } else if (indent >= 4 && indent < 6 && topKey && committeeKey) {
73
+ // Property level (name, members, additional_members, skip)
74
+ const m = content.match(/^(\w[\w-]*):\s*(.*)$/);
75
+ if (m) {
76
+ propKey = m[1];
77
+ const val = m[2].trim();
78
+ if (val && val !== '') {
79
+ result[topKey][committeeKey][propKey] = parseValue(val);
80
+ } else {
81
+ // Empty value — will be a list (members:) or object
82
+ result[topKey][committeeKey][propKey] = [];
83
+ }
84
+ }
85
+ } else if (indent >= 6 && topKey && committeeKey && propKey) {
86
+ // List item
87
+ const m = content.match(/^- (.+)$/);
88
+ if (m) {
89
+ const container = result[topKey][committeeKey];
90
+ if (!Array.isArray(container[propKey])) {
91
+ container[propKey] = [];
92
+ }
93
+ container[propKey].push(m[1].trim());
94
+ }
95
+ }
96
+ }
97
+
98
+ return result;
99
+ }
100
+
101
+ function parseValue(str) {
102
+ if (str === 'true') return true;
103
+ if (str === 'false') return false;
104
+ if (str === 'null') return null;
105
+ // Strip quotes
106
+ if ((str.startsWith('"') && str.endsWith('"')) || (str.startsWith("'") && str.endsWith("'"))) {
107
+ return str.slice(1, -1);
108
+ }
109
+ // Try number
110
+ if (/^-?\d+(\.\d+)?$/.test(str)) return Number(str);
111
+ return str;
112
+ }
113
+
114
+ // --- Main ---
115
+
116
+ function main() {
117
+ const claudeDir = process.argv[2] || '.claude';
118
+ const upstreamPath = path.join(claudeDir, 'cabinet', 'committees.yaml');
119
+ const projectPath = path.join(claudeDir, 'cabinet', 'committees-project.yaml');
120
+
121
+ // Read upstream (required)
122
+ if (!fs.existsSync(upstreamPath)) {
123
+ console.error(`Error: Upstream committees file not found at ${upstreamPath}`);
124
+ console.error('');
125
+ console.error('This file is installed by Claude Cabinet and should be at:');
126
+ console.error(` ${upstreamPath}`);
127
+ console.error('');
128
+ console.error('Run the Claude Cabinet installer to restore it, or check that');
129
+ console.error('the path to your .claude directory is correct.');
130
+ process.exit(1);
131
+ }
132
+
133
+ let upstreamText;
134
+ try {
135
+ upstreamText = fs.readFileSync(upstreamPath, 'utf8');
136
+ } catch (err) {
137
+ console.error(`Error reading ${upstreamPath}: ${err.message}`);
138
+ process.exit(1);
139
+ }
140
+
141
+ let upstream;
142
+ try {
143
+ upstream = parseSimpleYaml(upstreamText);
144
+ } catch (err) {
145
+ console.error(`Error parsing ${upstreamPath}: ${err.message}`);
146
+ console.error('The file may be malformed. Check that it uses valid YAML syntax.');
147
+ process.exit(1);
148
+ }
149
+
150
+ const committees = upstream.committees || {};
151
+
152
+ // Read project overrides (optional)
153
+ if (!fs.existsSync(projectPath)) {
154
+ // No project file — output upstream as-is
155
+ console.log(JSON.stringify({ committees }, null, 2));
156
+ return;
157
+ }
158
+
159
+ let projectText;
160
+ try {
161
+ projectText = fs.readFileSync(projectPath, 'utf8');
162
+ } catch (err) {
163
+ console.error(`Error reading ${projectPath}: ${err.message}`);
164
+ process.exit(1);
165
+ }
166
+
167
+ let project;
168
+ try {
169
+ project = parseSimpleYaml(projectText);
170
+ } catch (err) {
171
+ console.error(`Error parsing ${projectPath}: ${err.message}`);
172
+ console.error('The file may be malformed. Check that it uses valid YAML syntax.');
173
+ process.exit(1);
174
+ }
175
+
176
+ const projectCommittees = project.committees || {};
177
+
178
+ // Merge
179
+ const merged = Object.assign({}, committees);
180
+
181
+ for (const key of Object.keys(projectCommittees)) {
182
+ const projectDef = projectCommittees[key];
183
+
184
+ // skip: true removes the committee
185
+ if (projectDef && projectDef.skip === true) {
186
+ delete merged[key];
187
+ continue;
188
+ }
189
+
190
+ if (merged[key]) {
191
+ // Existing upstream committee — apply overrides
192
+ if (projectDef.name) {
193
+ merged[key] = Object.assign({}, merged[key], { name: projectDef.name });
194
+ }
195
+
196
+ if (Array.isArray(projectDef.members)) {
197
+ // Full replacement
198
+ merged[key] = Object.assign({}, merged[key], { members: projectDef.members });
199
+ } else if (Array.isArray(projectDef.additional_members)) {
200
+ // Append to upstream
201
+ const existing = Array.isArray(merged[key].members) ? merged[key].members : [];
202
+ merged[key] = Object.assign({}, merged[key], {
203
+ members: existing.concat(projectDef.additional_members)
204
+ });
205
+ }
206
+ } else {
207
+ // New committee from project
208
+ merged[key] = {
209
+ name: projectDef.name || key,
210
+ members: Array.isArray(projectDef.members) ? projectDef.members : []
211
+ };
212
+ }
213
+ }
214
+
215
+ console.log(JSON.stringify({ committees: merged }, null, 2));
216
+ }
217
+
218
+ main();
@@ -111,10 +111,15 @@ project. Adjust.
111
111
  Read `phases/member-selection.md` for which cabinet members to run.
112
112
 
113
113
  **Default (absent/empty):** Discover all cabinet members from
114
- `skills/cabinet-*/SKILL.md`. If `cabinet/committees.yaml`
115
- exists (copied from `committees-template.yaml`), present committees and let the
116
- user choose which to run. If no committees file exists, run all discovered
117
- cabinet members.
114
+ `skills/cabinet-*/SKILL.md`. Run `node scripts/resolve-committees.js` to
115
+ get the merged committee list (upstream `cabinet/committees.yaml` merged
116
+ with project `cabinet/committees-project.yaml`). Present the merged
117
+ committees and let the user choose which to run. If neither committees
118
+ file exists, run all discovered cabinet members.
119
+
120
+ Cross-portfolio cabinet members (anti-confirmation, qa, debugger,
121
+ organized-mind) always run regardless of committee selection — they
122
+ activate via `standing-mandate` in their SKILL.md frontmatter.
118
123
 
119
124
  The selection determines what the audit looks at. A full audit runs
120
125
  everything; a focused audit runs one committee or a specific set of
@@ -4,9 +4,11 @@ Define how the audit selects which cabinet members to run. The /audit skill
4
4
  reads this file before spawning cabinet member agents.
5
5
 
6
6
  When this file is absent or empty, the default behavior is: discover all
7
- cabinet members from `skills/cabinet-*/SKILL.md`, present committees if
8
- `committees.yaml` exists, otherwise run all. To explicitly skip member
9
- selection (and run no audit), write only `skip: true`.
7
+ cabinet members from `skills/cabinet-*/SKILL.md`, run
8
+ `node scripts/resolve-committees.js` to merge upstream `cabinet/committees.yaml`
9
+ with project `cabinet/committees-project.yaml`, present merged committees,
10
+ otherwise run all. Cross-portfolio members always run regardless of selection.
11
+ To explicitly skip member selection (and run no audit), write only `skip: true`.
10
12
 
11
13
  ## What to Include
12
14
 
@@ -26,14 +28,11 @@ Discover all cabinet members in `skills/cabinet-*/SKILL.md`.
26
28
  Run every one. Good for small projects with few cabinet members.
27
29
 
28
30
  ### Committee-Based Selection
29
- Read `cabinet/committees.yaml` for committee definitions.
30
- Present committees to the user:
31
- 1. ux accessibility, small-screen
32
- 2. code — technical-debt, architecture
33
- 3. health security, data-integrity, speed-freak
34
- 4. process — workflow-cop, record-keeper
35
-
36
- Cross-portfolio cabinet members (marked in committees.yaml) always run
31
+ Run `node scripts/resolve-committees.js` to merge upstream
32
+ `cabinet/committees.yaml` with project `cabinet/committees-project.yaml`.
33
+ Present merged committees to the user.
34
+
35
+ Cross-portfolio cabinet members (standing-mandate in SKILL.md) always run
37
36
  regardless of committee selection.
38
37
 
39
38
  ### Targeted Audit
@@ -15,7 +15,8 @@ files:
15
15
  - .claude/skills/*/SKILL.md
16
16
  - .claude/skills/*/phases/*.md
17
17
  - .claude/skills/cabinet-*/SKILL.md
18
- - .claude/skills/cabinet-*/committees.yaml
18
+ - .claude/cabinet/committees.yaml
19
+ - .claude/cabinet/committees-project.yaml
19
20
  - .claude/hooks/*.sh
20
21
  topics:
21
22
  - cc health
@@ -30,8 +31,11 @@ related:
30
31
  path: .claude/skills/cabinet-*/_lifecycle.md
31
32
  role: "Cabinet member lifecycle — when to adopt, when to retire"
32
33
  - type: file
33
- path: .claude/skills/cabinet-*/committees-template.yaml
34
- role: "Committee structure template"
34
+ path: .claude/cabinet/committees.yaml
35
+ role: "Upstream committee definitions (installer-owned)"
36
+ - type: file
37
+ path: .claude/cabinet/committees-project.yaml
38
+ role: "Project committee customizations (user-owned)"
35
39
  - type: file
36
40
  path: .claude/skills/cabinet-process-therapist/SKILL.md
37
41
  role: "Adjacent cabinet member — skill quality (not adoption health)"
@@ -90,7 +94,7 @@ Also activates when:
90
94
  - New skills or cabinet members are added (adoption decision to evaluate)
91
95
  - Phase files are modified (customization to assess)
92
96
  - Hook scripts are changed (enforcement layer shift)
93
- - `committees.yaml` is updated (committee composition change)
97
+ - `committees.yaml` or `committees-project.yaml` is updated (committee composition change)
94
98
 
95
99
  ## Research Method
96
100
 
@@ -127,8 +131,10 @@ empty").
127
131
 
128
132
  ### 2. Cabinet Member Activation Patterns
129
133
 
130
- Read `committees.yaml` to understand which cabinet members are active and how they're
131
- grouped. Cross-reference against:
134
+ Run `node scripts/resolve-committees.js` to get the merged committee list
135
+ (upstream `committees.yaml` + project `committees-project.yaml`). Also
136
+ validate that any members listed in `committees-project.yaml` actually
137
+ exist as `cabinet-*` directories. Cross-reference against:
132
138
 
133
139
  - **Technology signals.** Does the project's stack imply cabinet members that
134
140
  aren't activated? (React app without accessibility? API without security?
@@ -387,8 +393,9 @@ entropy.
387
393
  ### Scan Scope
388
394
 
389
395
  - `.claude/skills/` — all skill definitions and phase files
390
- - `.claude/skills/cabinet-*/` — all cabinet member definitions, `committees.yaml`,
391
- `_briefing.md`, `_lifecycle.md`, `committees.yaml`
396
+ - `.claude/skills/cabinet-*/` — all cabinet member definitions
397
+ - `.claude/cabinet/` — `committees.yaml`, `committees-project.yaml`,
398
+ `_lifecycle.md`, and other infrastructure
392
399
  - `.claude/hooks/` — hook scripts
393
400
  - `.claude/settings.json` — hook configuration
394
401
  - `memory/patterns/` — enforcement pipeline state
@@ -409,7 +416,7 @@ Do not cross into adjacent cabinet members' territory:
409
416
  That's process-therapist. You care whether the skill is *installed and used*,
410
417
  not whether its output is good.
411
418
  - **One-time setup** — initial CC installation, first-time skeleton
412
- adoption, bootstrapping `committees.yaml`. That's the onboard skill. You
419
+ adoption, bootstrapping `committees-project.yaml`. That's the onboard skill. You
413
420
  evaluate the ongoing health of an already-adopted configuration, not the
414
421
  initial adoption process.
415
422
  - **Specific technology expertise** — you don't know whether React components
@@ -305,6 +305,22 @@ The upgrade skill only surfaces phase opportunities that are *relevant
305
305
  to what changed* in this upgrade — including cases where the project's
306
306
  context makes a default obviously insufficient.
307
307
 
308
+ #### Committees Split Migration
309
+ If the project has a project-owned `committees.yaml` that contains custom
310
+ content (members not in the new upstream `committees.yaml`), split it:
311
+ 1. Compare the project's existing `committees.yaml` against the new upstream
312
+ version to identify which members are upstream and which are custom
313
+ 2. Generate `committees-project.yaml` with only the custom additions
314
+ (using `additional_members` for appending to upstream committees, or
315
+ new committee definitions for entirely custom committees)
316
+ 3. Present the split to the user — show what goes in `committees-project.yaml`
317
+ and explain that the installer's `committees.yaml` is now upstream-owned
318
+ 4. After approval, let the installer overwrite `committees.yaml` with the
319
+ upstream version, and write the custom content to `committees-project.yaml`
320
+
321
+ If the project's `committees.yaml` matches the upstream version exactly
322
+ (no custom content), no migration is needed.
323
+
308
324
  #### Schema Migrations
309
325
  If the upstream schema has new columns or tables:
310
326
  - Detect the difference between the shipped schema and the project's DB
@@ -262,7 +262,7 @@ relevant expertise ever activates because nobody ran `/seed`.
262
262
  touched. Did the work involve a framework, library, data store, or
263
263
  infrastructure that isn't covered by any existing cabinet member? Compare
264
264
  against the cabinet members in `.claude/skills/cabinet-*/` and the
265
- committees in `committees.yaml`.
265
+ merged committees (run `node scripts/resolve-committees.js`).
266
266
 
267
267
  Examples of what to catch:
268
268
  - Session used Mantine components but there's no framework-quality
@@ -272,8 +272,8 @@ Examples of what to catch:
272
272
  - Session built UI but accessibility isn't in any active committee
273
273
 
274
274
  **Check B — Dormant cabinet member that should be active.** Are there
275
- cabinet members installed in the project that aren't in any `committees.yaml`
276
- committee, but based on the last few sessions, probably should be? A
275
+ cabinet members installed in the project that aren't in any committee
276
+ (check merged output from `node scripts/resolve-committees.js`), but based on the last few sessions, probably should be? A
277
277
  cabinet member sitting dormant while the project does exactly the kind of
278
278
  work it's designed to review is a waste.
279
279
 
@@ -303,7 +303,7 @@ or:
303
303
  > sense as it grows. Want me to set that up?"
304
304
 
305
305
  If the user says yes, either:
306
- - Activate a dormant cabinet member (add it to `committees.yaml`)
306
+ - Activate a dormant cabinet member (add it to `committees-project.yaml`)
307
307
  - Run `/seed` to build a new one
308
308
  - Install a Tier 3 cabinet member that isn't in the project yet
309
309
 
@@ -45,7 +45,7 @@ generated phase files:
45
45
  - **Skipped modules:** No phase file should reference a skipped module's
46
46
  infrastructure. If work-tracking was skipped, no phase should reference
47
47
  `pib.db` or `pib-db.js`. If audit was skipped, no phase should reference
48
- `committees.yaml` or cabinet member activation.
48
+ `committees.yaml`, `committees-project.yaml`, or cabinet member activation.
49
49
  - **Installed modules:** Each installed module should have at least a
50
50
  minimal presence in the generated configuration. A module that's installed
51
51
  but has zero phase file references is a configuration gap.
@@ -75,7 +75,8 @@ technologies against the cabinet member catalog:
75
75
  - **Many skills (5+)** → roster-check
76
76
  - **Features shipping regularly** → system-advocate
77
77
 
78
- If implied cabinet members aren't in `committees.yaml` (or equivalent), note
78
+ If implied cabinet members aren't in the merged committees (upstream
79
+ `committees.yaml` + project `committees-project.yaml`), note
79
80
  it as a recommendation — not a blocker. The user may have good reasons
80
81
  to skip them, or may want to add them later via `/seed`.
81
82
 
@@ -137,7 +137,10 @@ collaborative expertise-building conversation:
137
137
  4. Walk through Identity, Research Method, Boundaries, and Calibration
138
138
  with the user
139
139
  5. Create the file in `cabinet-{name}/SKILL.md`
140
- 6. Update `committees.yaml` if the cabinet member belongs in a committee
140
+ 6. Update `committees-project.yaml` if the cabinet member belongs in a committee
141
+ (add to `additional_members` of an existing upstream committee, or create
142
+ a new committee definition). Create `committees-project.yaml` if it
143
+ doesn't exist yet.
141
144
 
142
145
  This is co-authoring, not auto-generating. The user's domain knowledge
143
146
  is what makes a cabinet member useful for their specific project. A generic
@@ -69,8 +69,11 @@ Write the cabinet member's `SKILL.md` following `_lifecycle.md` guidance:
69
69
 
70
70
  ### Step 4: Wire It Up
71
71
 
72
- - Add to `committees.yaml` under the appropriate committee (unless it's
73
- cross-portfolio, in which case it activates via `standing-mandate` signals)
72
+ - Add to `committees-project.yaml` under the appropriate committee use
73
+ `additional_members` to append to an existing upstream committee, or create
74
+ a new committee definition. Create `committees-project.yaml` if it doesn't
75
+ exist yet. (Unless the cabinet member is cross-portfolio, in which case it
76
+ activates via `standing-mandate` signals and needs no committee entry.)
74
77
  - Verify the cabinet member is discoverable by the audit skill
75
78
 
76
79
  ### Emphasis
@@ -1,49 +0,0 @@
1
- # Cabinet member committees — canonical mapping of committee slugs to cabinet member lists.
2
- #
3
- # Copy this file as committees.yaml and uncomment/customize the committees that
4
- # match your project. Technology choices imply expertise needs: if your
5
- # project has a UI, you need a UI committee. If it has an API, you need
6
- # a system health committee.
7
- #
8
- # Consumed by:
9
- # - /audit skill (committee selection menu)
10
- # - scripts (--committee flag, resolve-committees helpers)
11
- #
12
- # Cross-portfolio cabinet members are NOT in any committee. They activate via
13
- # standing-mandate in their SKILL.md frontmatter:
14
- # anti-confirmation, qa, debugger, organized-mind
15
-
16
- committees:
17
- # -- If your project has a user interface --
18
- # ux:
19
- # name: "UX & Design"
20
- # members:
21
- # - accessibility
22
- # - small-screen
23
- # # Add framework-specific cabinet members (e.g., mantine-quality, tailwind-quality)
24
-
25
- # -- If your project has code (most projects) --
26
- # code:
27
- # name: "Code Quality"
28
- # members:
29
- # - technical-debt
30
- # - boundary-man
31
- # # Add: architecture (if multi-layer system)
32
-
33
- # -- If your project has an API, database, or infrastructure --
34
- # health:
35
- # name: "System Health"
36
- # members:
37
- # - security
38
- # - data-integrity
39
- # - speed-freak
40
- # # Add: sync-health (if remote sync), deployment (if CI/CD)
41
-
42
- # -- If your project has established process/methodology --
43
- # process:
44
- # name: "Process & Meta"
45
- # members:
46
- # - workflow-cop
47
- # - record-keeper
48
- # - process-therapist
49
- # - cc-health # CC adoption health, configuration drift, anti-bloat