role-os 2.0.0 → 2.2.0

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/src/packs.mjs CHANGED
@@ -1,359 +1,430 @@
1
- /**
2
- * Proven Team Packs — Calibrated.
3
- *
4
- * Battle-tested role combinations for common task families.
5
- * Each pack was proven through execution trials (G1–G10) and
6
- * calibrated by pack comparison trials (PACK-COMPARISON.md).
7
- *
8
- * Calibration findings applied:
9
- * - Orchestrator is conditional (only when task is multi-role + ambiguous)
10
- * - Every pack has mismatch detection + alternative suggestion
11
- * - Treatment includes Security Reviewer by default
12
- * - Research opens with Product Strategist (framing before research)
13
- * - Docs has upstream-synthesis gate
14
- *
15
- * Usage: `roleos route --pack feature` or auto-detected from packet content.
16
- */
17
-
18
- // ── Mismatch detection ────────────────────────────────────────────────────────
19
- // Each pack declares what it is NOT for, and which pack IS right.
20
-
21
- /**
22
- * @typedef {Object} MismatchGuard
23
- * @property {string[]} notForSignals - Content patterns that indicate this pack is wrong
24
- * @property {string} suggestInstead - Which pack to suggest instead
25
- * @property {string} reason - Why this pack is wrong for that signal
26
- */
27
-
28
- // ── Pack definitions ──────────────────────────────────────────────────────────
29
-
30
- export const TEAM_PACKS = {
31
- // ── Feature Build ─────────────────────────────────────────────────────────
32
- feature: {
33
- name: "Feature Build",
34
- description: "Full feature delivery: scope → spec → implement → test → review",
35
- roles: [
36
- "Orchestrator",
37
- "Product Strategist",
38
- "Spec Writer",
39
- "Backend Engineer",
40
- "Test Engineer",
41
- "Critic Reviewer",
42
- ],
43
- orchestratorRequired: true, // multi-role, cross-functional — Orchestrator adds value
44
- optionalRoles: ["UI Designer", "Frontend Developer", "Security Reviewer"],
45
- chainOrder: "Product Strategist → Spec Writer → Backend Engineer → Test Engineer",
46
- requiredArtifacts: ["scope doc", "spec", "implementation", "test results", "verdict"],
47
- stopConditions: [
48
- "Spec Writer finds scope ambiguity → escalate to Product Strategist",
49
- "Test Engineer finds untestable spec → escalate to Spec Writer",
50
- "Critic rejects → loop back to responsible role",
51
- ],
52
- escalationOwner: "Orchestrator",
53
- dispatchDefaults: { model: "sonnet", maxTurns: 30, maxBudgetUsd: 5.0 },
54
- trialEvidence: "G1 (Product), G2 (Engineering) — 6/6 gold-task passes. Pack comparison: wins vs free routing.",
55
- mismatchGuards: [
56
- { notForSignals: ["security review", "threat model", "vulnerability", "injection"], suggestInstead: "security", reason: "This is a security review, not a feature build" },
57
- { notForSignals: ["launch", "announce", "release notes", "messaging"], suggestInstead: "launch", reason: "This is launch/messaging work, not feature implementation" },
58
- { notForSignals: ["bug", "fix", "crash", "broken", "regression"], suggestInstead: "bugfix", reason: "This is a bug to fix, not a feature to build" },
59
- { notForSignals: ["handbook", "documentation", "restructure docs"], suggestInstead: "docs", reason: "This is docs work, not feature implementation" },
60
- { notForSignals: ["research", "should we", "competitive", "trend"], suggestInstead: "research", reason: "This is a research/strategy question, not a feature build" },
61
- { notForSignals: ["treatment", "repo audit", "shipcheck", "full treatment", "polish"], suggestInstead: "treatment", reason: "This is repo treatment work, not feature implementation" },
62
- ],
63
- },
64
-
65
- // ── Bugfix / Repair ───────────────────────────────────────────────────────
66
- bugfix: {
67
- name: "Bugfix / Repair",
68
- description: "Diagnose → fix → verify → review. Minimal chain, fast turnaround.",
69
- roles: [
70
- "Repo Researcher",
71
- "Backend Engineer",
72
- "Test Engineer",
73
- "Critic Reviewer",
74
- ],
75
- orchestratorRequired: false,
76
- optionalRoles: ["Frontend Developer", "Performance Engineer"],
77
- chainOrder: "Repo Researcher → Backend Engineer → Test Engineer",
78
- requiredArtifacts: ["repo map / diagnosis", "fix implementation", "regression tests", "verdict"],
79
- stopConditions: [
80
- "Repo Researcher cannot reproduce → escalate to user",
81
- "Fix introduces new failures → loop back to Backend Engineer",
82
- ],
83
- escalationOwner: "Critic Reviewer",
84
- dispatchDefaults: { model: "sonnet", maxTurns: 20, maxBudgetUsd: 3.0 },
85
- trialEvidence: "G2 (Engineering), G7 (Repo Researcher), I-2 (shipped real fix).",
86
- mismatchGuards: [
87
- { notForSignals: ["launch", "announce", "release notes", "messaging"], suggestInstead: "launch", reason: "This is launch work, not a bugfix" },
88
- { notForSignals: ["research", "should we", "tradeoff", "strategy"], suggestInstead: "research", reason: "This is a research/strategy question, not a bug to fix" },
89
- { notForSignals: ["feature", "new command", "add", "create", "implement"], suggestInstead: "feature", reason: "This is a new feature, not a bug to fix" },
90
- { notForSignals: ["handbook", "documentation", "restructure docs", "starlight"], suggestInstead: "docs", reason: "This is docs work, not a bugfix" },
91
- { notForSignals: ["security review", "threat model", "vulnerability"], suggestInstead: "security", reason: "This is a security review, not a bugfix" },
92
- { notForSignals: ["treatment", "repo audit", "shipcheck", "polish"], suggestInstead: "treatment", reason: "This is repo treatment, not a bugfix" },
93
- ],
94
- },
95
-
96
- // ── Security Review ───────────────────────────────────────────────────────
97
- security: {
98
- name: "Security Review",
99
- description: "Threat model → code review → dependency audit → verdict",
100
- roles: [
101
- "Security Reviewer",
102
- "Dependency Auditor",
103
- "Critic Reviewer",
104
- ],
105
- orchestratorRequired: false, // single-domain, clear scope
106
- optionalRoles: ["Backend Engineer", "Test Engineer"],
107
- chainOrder: "Security Reviewer → Dependency Auditor",
108
- requiredArtifacts: ["threat model", "code review findings", "dependency audit", "verdict"],
109
- stopConditions: [
110
- "Critical vulnerability found → immediate escalation to user",
111
- "Dependency with known CVE → flag for Engineering",
112
- ],
113
- escalationOwner: "Security Reviewer",
114
- dispatchDefaults: { model: "sonnet", maxTurns: 25, maxBudgetUsd: 4.0 },
115
- trialEvidence: "G6 (Security Reviewer, Dependency Auditor) — 2/2 gold-task passes. I-3 Critic found 3 gaps prior roles missed.",
116
- mismatchGuards: [
117
- { notForSignals: ["documentation", "handbook", "restructure", "navigation"], suggestInstead: "docs", reason: "This is docs/structure work, not a security review" },
118
- { notForSignals: ["feature", "implement", "build", "add command"], suggestInstead: "feature", reason: "This is feature work, not a security review" },
119
- { notForSignals: ["bug", "fix", "crash", "broken", "regression"], suggestInstead: "bugfix", reason: "This is a bug to fix, not a security review" },
120
- { notForSignals: ["launch", "announce", "release notes", "messaging"], suggestInstead: "launch", reason: "This is launch work, not a security review" },
121
- { notForSignals: ["research", "should we", "competitive", "strategy"], suggestInstead: "research", reason: "This is a research question, not a security review" },
122
- { notForSignals: ["treatment", "repo audit", "shipcheck", "polish"], suggestInstead: "treatment", reason: "This is repo treatment, not a security review" },
123
- ],
124
- },
125
-
126
- // ── Docs / Handbook ─────────────────────────────────────────────────
127
- docs: {
128
- name: "Docs / Handbook",
129
- description: "Triage → synthesize → structure → write → metadata → review",
130
- roles: [
131
- "Support Triage Lead", // interpret raw input (triage reports, issue lists, feedback)
132
- "Feedback Synthesizer", // cluster and theme the interpreted input
133
- "Docs Architect", // structure and write the docs
134
- "Metadata Curator", // verify metadata alignment
135
- "Critic Reviewer",
136
- ],
137
- orchestratorRequired: false,
138
- optionalRoles: ["Repo Translator", "Brand Guardian", "Release Engineer", "Deployment Verifier"],
139
- chainOrder: "Support Triage Lead → Feedback Synthesizer → Docs Architect → Metadata Curator",
140
- requiredArtifacts: ["classified input", "synthesized themes", "docs structure", "metadata audit", "verdict"],
141
- stopConditions: [
142
- "Support Triage Lead finds input data ambiguous → request clarification",
143
- "Feedback Synthesizer finds insufficient signal → escalate to user",
144
- "Docs Architect finds product direction unclear → escalate to Product Strategist",
145
- ],
146
- escalationOwner: "Docs Architect",
147
- dispatchDefaults: { model: "sonnet", maxTurns: 25, maxBudgetUsd: 4.0 },
148
- trialEvidence: "G4 (Docs Architect), G7 (Treatment), I-4 (shipped page). Calibrated: Support Triage Lead + Feedback Synthesizer upstream. Release/Deploy moved to optional (overhead for docs-only tasks).",
149
- mismatchGuards: [
150
- { notForSignals: ["research", "should we", "competitive", "strategy"], suggestInstead: "research", reason: "This is a research/strategy question — decide before documenting" },
151
- { notForSignals: ["security review", "threat", "vulnerability", "injection"], suggestInstead: "security", reason: "This is a security review, not docs work" },
152
- { notForSignals: ["feature", "implement", "build", "add command"], suggestInstead: "feature", reason: "This is feature work, not docs" },
153
- { notForSignals: ["bug", "fix", "crash", "broken"], suggestInstead: "bugfix", reason: "This is a bugfix, not docs work" },
154
- { notForSignals: ["launch", "announce", "go-to-market", "messaging"], suggestInstead: "launch", reason: "This is launch work, not docs" },
155
- { notForSignals: ["treatment", "repo audit", "shipcheck", "full treatment"], suggestInstead: "treatment", reason: "This is repo treatment, not docs only" },
156
- ],
157
- },
158
-
159
- // ── Launch / Messaging ────────────────────────────────────────────────────
160
- launch: {
161
- name: "Launch / Messaging",
162
- description: "Plan launch → write copy. Hard pipeline: Strategist → Copywriter.",
163
- roles: [
164
- "Launch Strategist",
165
- "Launch Copywriter",
166
- "Critic Reviewer",
167
- ],
168
- orchestratorRequired: false, // smallest pack, hard pipeline, no decomposition needed
169
- optionalRoles: ["Content Strategist", "Community Manager"],
170
- chainOrder: "Launch Strategist → Launch Copywriter",
171
- requiredArtifacts: ["launch plan", "release copy", "verdict"],
172
- stopConditions: [
173
- "Launch Strategist finds no proof assets → delay launch",
174
- "Launch Copywriter finds product claims unverifiable → escalate to Product Strategist",
175
- ],
176
- escalationOwner: "Launch Strategist",
177
- dispatchDefaults: { model: "sonnet", maxTurns: 20, maxBudgetUsd: 3.0 },
178
- trialEvidence: "G3 (pipeline proven), I-5 (v1.1.0 launch, Accept). Pack comparison: tie/marginal win. TRUE DEFAULT.",
179
- mismatchGuards: [
180
- { notForSignals: ["bug", "fix", "crash", "broken", "error"], suggestInstead: "bugfix", reason: "This is a bug to fix, not a launch to plan" },
181
- { notForSignals: ["implement", "build", "add command", "new feature"], suggestInstead: "feature", reason: "This is feature work — build first, launch second" },
182
- { notForSignals: ["security review", "threat", "vulnerability", "injection"], suggestInstead: "security", reason: "This is a security review, not launch work" },
183
- { notForSignals: ["handbook", "documentation", "restructure docs"], suggestInstead: "docs", reason: "This is docs work, not launch messaging" },
184
- { notForSignals: ["research", "should we", "competitive", "trend"], suggestInstead: "research", reason: "This is research, not launch messaging" },
185
- { notForSignals: ["treatment", "repo audit", "shipcheck", "polish"], suggestInstead: "treatment", reason: "This is repo treatment, not launch" },
186
- ],
187
- },
188
-
189
- // ── Research / Strategy ───────────────────────────────────────────────────
190
- research: {
191
- name: "Research / Strategy",
192
- description: "Frame decision → gather evidence → synthesize → recommend",
193
- roles: [
194
- "Product Strategist", // REORDERED: framing first, then research
195
- "UX Researcher",
196
- "Competitive Analyst",
197
- "Feedback Synthesizer",
198
- "Critic Reviewer",
199
- ],
200
- orchestratorRequired: false, // clear pipeline, Product Strategist frames
201
- optionalRoles: ["Trend Researcher", "User Interview Synthesizer"],
202
- chainOrder: "Product Strategist → UX Researcher → Competitive Analyst → Feedback Synthesizer",
203
- requiredArtifacts: ["decision frame", "friction inventory", "competitive landscape", "signal synthesis", "verdict"],
204
- stopConditions: [
205
- "Product Strategist finds the question too vague → request clarification",
206
- "UX Researcher finds insufficient user data → escalate to Product Strategist",
207
- "Competitive Analyst finds no comparable products → narrow scope",
208
- ],
209
- escalationOwner: "Product Strategist",
210
- dispatchDefaults: { model: "sonnet", maxTurns: 25, maxBudgetUsd: 4.0 },
211
- trialEvidence: "G8 (Research cluster), G9 (Growth/Product), I-6 (game dev decision). Calibrated: Product Strategist now opens (framing before research).",
212
- mismatchGuards: [
213
- { notForSignals: ["implement", "build", "add command", "write code"], suggestInstead: "feature", reason: "This is implementation work, not research" },
214
- { notForSignals: ["bug", "fix", "crash", "broken"], suggestInstead: "bugfix", reason: "This is a bugfix, not a research question" },
215
- { notForSignals: ["security review", "threat", "vulnerability", "injection"], suggestInstead: "security", reason: "This is a security review, not research" },
216
- { notForSignals: ["handbook", "documentation", "restructure docs"], suggestInstead: "docs", reason: "This is docs work, not research" },
217
- { notForSignals: ["launch", "announce", "release notes", "messaging"], suggestInstead: "launch", reason: "This is launch work, not research" },
218
- { notForSignals: ["treatment", "repo audit", "shipcheck", "polish"], suggestInstead: "treatment", reason: "This is repo treatment, not research" },
219
- ],
220
- },
221
-
222
- // ── Treatment (repo polish) ───────────────────────────────────────────────
223
- treatment: {
224
- name: "Treatment (Repo Polish)",
225
- description: "Full repo treatment: research → security → audit → docs → metadata → release → deploy → verify",
226
- roles: [
227
- "Repo Researcher",
228
- "Security Reviewer", // ADDED: was optional, now default (pack comparison finding)
229
- "Coverage Auditor",
230
- "Docs Architect",
231
- "Metadata Curator",
232
- "Release Engineer",
233
- "Deployment Verifier",
234
- "Critic Reviewer",
235
- ],
236
- orchestratorRequired: false, // long but sequential — each role has a clear handoff
237
- optionalRoles: ["Brand Guardian", "Repo Translator", "Dependency Auditor"],
238
- chainOrder: "Repo Researcher → Security Reviewer → Coverage Auditor → Docs Architect → Metadata Curator → Release Engineer → Deployment Verifier",
239
- requiredArtifacts: ["repo map", "security findings", "coverage audit", "docs", "metadata audit", "release", "deployment verification", "verdict"],
240
- stopConditions: [
241
- "Security Reviewer finds critical vulnerability → block release until resolved",
242
- "Coverage Auditor finds false confidence → flag for Test Engineer",
243
- "Deployment Verifier finds broken live artifacts → loop back to Release Engineer",
244
- ],
245
- escalationOwner: "Repo Researcher",
246
- dispatchDefaults: { model: "sonnet", maxTurns: 30, maxBudgetUsd: 5.0 },
247
- trialEvidence: "G6-G7 (roles proven), I-7 (full chain, Accept-with-notes). Calibrated: Security Reviewer now default (was optional — pack comparison loss).",
248
- mismatchGuards: [
249
- { notForSignals: ["launch", "announce", "release notes", "social", "messaging"], suggestInstead: "launch", reason: "This is launch/messaging work — Treatment audits repos, it doesn't write announcements" },
250
- { notForSignals: ["research", "should we", "competitive", "strategy"], suggestInstead: "research", reason: "This is a research/strategy question, not a repo treatment" },
251
- { notForSignals: ["feature", "new command", "implement", "add", "create"], suggestInstead: "feature", reason: "This is feature work, not repo treatment" },
252
- { notForSignals: ["bug", "fix", "crash", "broken"], suggestInstead: "bugfix", reason: "This is a bugfix, not a full treatment" },
253
- { notForSignals: ["security review", "threat model", "injection"], suggestInstead: "security", reason: "This is a security review — treatment includes security but this task is security-only" },
254
- { notForSignals: ["handbook", "documentation", "restructure docs"], suggestInstead: "docs", reason: "This is docs-only work, not a full treatment" },
255
- ],
256
- },
257
- };
258
-
259
- // ── Pack selection ────────────────────────────────────────────────────────────
260
-
261
- const PACK_KEYWORDS = {
262
- feature: ["feature", "build", "implement", "new", "add", "create"],
263
- bugfix: ["bug", "fix", "repair", "broken", "crash", "error", "regression"],
264
- security: ["security", "threat", "vulnerability", "audit", "owasp", "cve"],
265
- docs: ["docs", "documentation", "handbook", "release", "publish", "changelog"],
266
- launch: ["launch", "announce", "release notes", "messaging", "go-to-market"],
267
- research: ["research", "competitive", "ux", "friction", "user", "strategy", "trend"],
268
- treatment: ["treatment", "polish", "cleanup", "repo audit", "shipcheck", "full treatment"],
269
- };
270
-
271
- /**
272
- * Suggest the best pack for a packet based on content analysis.
273
- */
274
- export function suggestPack(content) {
275
- const lower = content.toLowerCase();
276
- const scores = {};
277
-
278
- for (const [packName, keywords] of Object.entries(PACK_KEYWORDS)) {
279
- let score = 0;
280
- for (const kw of keywords) {
281
- if (lower.includes(kw)) score++;
282
- }
283
- if (score > 0) scores[packName] = score;
284
- }
285
-
286
- const sorted = Object.entries(scores).sort((a, b) => b[1] - a[1]);
287
- if (sorted.length === 0) return null;
288
-
289
- const [topPack, topScore] = sorted[0];
290
- const confidence = topScore >= 3 ? "high" : topScore >= 2 ? "medium" : "low";
291
-
292
- return { pack: topPack, confidence, scores };
293
- }
294
-
295
- /**
296
- * Check if a pack is a mismatch for the given content.
297
- * Returns null if no mismatch, or the suggested alternative if mismatch detected.
298
- *
299
- * @param {string} packName
300
- * @param {string} content - Packet content
301
- * @returns {{ suggestInstead: string, reason: string } | null}
302
- */
303
- export function checkPackMismatch(packName, content) {
304
- const pack = TEAM_PACKS[packName];
305
- if (!pack || !pack.mismatchGuards) return null;
306
-
307
- const lower = content.toLowerCase();
308
- for (const guard of pack.mismatchGuards) {
309
- const triggered = guard.notForSignals.some(signal => lower.includes(signal));
310
- if (triggered) {
311
- return { suggestInstead: guard.suggestInstead, reason: guard.reason };
312
- }
313
- }
314
- return null;
315
- }
316
-
317
- /**
318
- * Get a pack's effective roles (with conditional Orchestrator).
319
- *
320
- * @param {string} packName
321
- * @param {boolean} [forceOrchestrator=false]
322
- * @returns {string[] | null}
323
- */
324
- export function getPackRoles(packName, forceOrchestrator = false) {
325
- const pack = TEAM_PACKS[packName];
326
- if (!pack) return null;
327
-
328
- const roles = [...pack.roles];
329
- // Add Orchestrator only if the pack requires it or forced
330
- if ((pack.orchestratorRequired || forceOrchestrator) && !roles.includes("Orchestrator")) {
331
- roles.unshift("Orchestrator");
332
- }
333
- // Remove Orchestrator if pack doesn't require it and not forced
334
- if (!pack.orchestratorRequired && !forceOrchestrator && roles[0] === "Orchestrator") {
335
- roles.shift();
336
- }
337
- return roles;
338
- }
339
-
340
- /**
341
- * Get a pack by name.
342
- */
343
- export function getPack(name) {
344
- return TEAM_PACKS[name] || null;
345
- }
346
-
347
- /**
348
- * List all available packs.
349
- */
350
- export function listPacks() {
351
- return Object.entries(TEAM_PACKS).map(([key, pack]) => ({
352
- key,
353
- name: pack.name,
354
- description: pack.description,
355
- roleCount: pack.roles.length,
356
- optionalCount: pack.optionalRoles.length,
357
- orchestratorRequired: pack.orchestratorRequired,
358
- }));
359
- }
1
+ /**
2
+ * Proven Team Packs — Calibrated.
3
+ *
4
+ * Battle-tested role combinations for common task families.
5
+ * Each pack was proven through execution trials (G1–G10) and
6
+ * calibrated by pack comparison trials (PACK-COMPARISON.md).
7
+ *
8
+ * Calibration findings applied:
9
+ * - Orchestrator is conditional (only when task is multi-role + ambiguous)
10
+ * - Every pack has mismatch detection + alternative suggestion
11
+ * - Treatment includes Security Reviewer by default
12
+ * - Research opens with Product Strategist (framing before research)
13
+ * - Docs has upstream-synthesis gate
14
+ *
15
+ * Usage: `roleos route --pack feature` or auto-detected from packet content.
16
+ */
17
+
18
+ // ── Mismatch detection ────────────────────────────────────────────────────────
19
+ // Each pack declares what it is NOT for, and which pack IS right.
20
+
21
+ /**
22
+ * @typedef {Object} MismatchGuard
23
+ * @property {string[]} notForSignals - Content patterns that indicate this pack is wrong
24
+ * @property {string} suggestInstead - Which pack to suggest instead
25
+ * @property {string} reason - Why this pack is wrong for that signal
26
+ */
27
+
28
+ // ── Pack definitions ──────────────────────────────────────────────────────────
29
+
30
+ export const TEAM_PACKS = {
31
+ // ── Feature Build ─────────────────────────────────────────────────────────
32
+ feature: {
33
+ name: "Feature Build",
34
+ description: "Full feature delivery: scope → spec → implement → test → review",
35
+ roles: [
36
+ "Orchestrator",
37
+ "Product Strategist",
38
+ "Spec Writer",
39
+ "Backend Engineer",
40
+ "Test Engineer",
41
+ "Critic Reviewer",
42
+ ],
43
+ orchestratorRequired: true, // multi-role, cross-functional — Orchestrator adds value
44
+ optionalRoles: ["UI Designer", "Frontend Developer", "Security Reviewer"],
45
+ chainOrder: "Product Strategist → Spec Writer → Backend Engineer → Test Engineer",
46
+ requiredArtifacts: ["scope doc", "spec", "implementation", "test results", "verdict"],
47
+ stopConditions: [
48
+ "Spec Writer finds scope ambiguity → escalate to Product Strategist",
49
+ "Test Engineer finds untestable spec → escalate to Spec Writer",
50
+ "Critic rejects → loop back to responsible role",
51
+ ],
52
+ escalationOwner: "Orchestrator",
53
+ dispatchDefaults: { model: "sonnet", maxTurns: 30, maxBudgetUsd: 5.0 },
54
+ trialEvidence: "G1 (Product), G2 (Engineering) — 6/6 gold-task passes. Pack comparison: wins vs free routing.",
55
+ mismatchGuards: [
56
+ { notForSignals: ["security review", "threat model", "vulnerability", "injection"], suggestInstead: "security", reason: "This is a security review, not a feature build" },
57
+ { notForSignals: ["launch", "announce", "release notes", "messaging"], suggestInstead: "launch", reason: "This is launch/messaging work, not feature implementation" },
58
+ { notForSignals: ["bug", "fix", "crash", "broken", "regression"], suggestInstead: "bugfix", reason: "This is a bug to fix, not a feature to build" },
59
+ { notForSignals: ["handbook", "documentation", "restructure docs"], suggestInstead: "docs", reason: "This is docs work, not feature implementation" },
60
+ { notForSignals: ["research", "should we", "competitive", "trend"], suggestInstead: "research", reason: "This is a research/strategy question, not a feature build" },
61
+ { notForSignals: ["treatment", "repo audit", "shipcheck", "full treatment", "polish"], suggestInstead: "treatment", reason: "This is repo treatment work, not feature implementation" },
62
+ ],
63
+ },
64
+
65
+ // ── Bugfix / Repair ───────────────────────────────────────────────────────
66
+ bugfix: {
67
+ name: "Bugfix / Repair",
68
+ description: "Diagnose → fix → verify → review. Minimal chain, fast turnaround.",
69
+ roles: [
70
+ "Repo Researcher",
71
+ "Backend Engineer",
72
+ "Test Engineer",
73
+ "Critic Reviewer",
74
+ ],
75
+ orchestratorRequired: false,
76
+ optionalRoles: ["Frontend Developer", "Performance Engineer"],
77
+ chainOrder: "Repo Researcher → Backend Engineer → Test Engineer",
78
+ requiredArtifacts: ["repo map / diagnosis", "fix implementation", "regression tests", "verdict"],
79
+ stopConditions: [
80
+ "Repo Researcher cannot reproduce → escalate to user",
81
+ "Fix introduces new failures → loop back to Backend Engineer",
82
+ ],
83
+ escalationOwner: "Critic Reviewer",
84
+ dispatchDefaults: { model: "sonnet", maxTurns: 20, maxBudgetUsd: 3.0 },
85
+ trialEvidence: "G2 (Engineering), G7 (Repo Researcher), I-2 (shipped real fix).",
86
+ mismatchGuards: [
87
+ { notForSignals: ["launch", "announce", "release notes", "messaging"], suggestInstead: "launch", reason: "This is launch work, not a bugfix" },
88
+ { notForSignals: ["research", "should we", "tradeoff", "strategy"], suggestInstead: "research", reason: "This is a research/strategy question, not a bug to fix" },
89
+ { notForSignals: ["feature", "new command", "add", "create", "implement"], suggestInstead: "feature", reason: "This is a new feature, not a bug to fix" },
90
+ { notForSignals: ["handbook", "documentation", "restructure docs", "starlight"], suggestInstead: "docs", reason: "This is docs work, not a bugfix" },
91
+ { notForSignals: ["security review", "threat model", "vulnerability"], suggestInstead: "security", reason: "This is a security review, not a bugfix" },
92
+ { notForSignals: ["treatment", "repo audit", "shipcheck", "polish"], suggestInstead: "treatment", reason: "This is repo treatment, not a bugfix" },
93
+ ],
94
+ },
95
+
96
+ // ── Security Review ───────────────────────────────────────────────────────
97
+ security: {
98
+ name: "Security Review",
99
+ description: "Threat model → code review → dependency audit → verdict",
100
+ roles: [
101
+ "Security Reviewer",
102
+ "Dependency Auditor",
103
+ "Critic Reviewer",
104
+ ],
105
+ orchestratorRequired: false, // single-domain, clear scope
106
+ optionalRoles: ["Backend Engineer", "Test Engineer"],
107
+ chainOrder: "Security Reviewer → Dependency Auditor",
108
+ requiredArtifacts: ["threat model", "code review findings", "dependency audit", "verdict"],
109
+ stopConditions: [
110
+ "Critical vulnerability found → immediate escalation to user",
111
+ "Dependency with known CVE → flag for Engineering",
112
+ ],
113
+ escalationOwner: "Security Reviewer",
114
+ dispatchDefaults: { model: "sonnet", maxTurns: 25, maxBudgetUsd: 4.0 },
115
+ trialEvidence: "G6 (Security Reviewer, Dependency Auditor) — 2/2 gold-task passes. I-3 Critic found 3 gaps prior roles missed.",
116
+ mismatchGuards: [
117
+ { notForSignals: ["documentation", "handbook", "restructure", "navigation"], suggestInstead: "docs", reason: "This is docs/structure work, not a security review" },
118
+ { notForSignals: ["feature", "implement", "build", "add command"], suggestInstead: "feature", reason: "This is feature work, not a security review" },
119
+ { notForSignals: ["bug", "fix", "crash", "broken", "regression"], suggestInstead: "bugfix", reason: "This is a bug to fix, not a security review" },
120
+ { notForSignals: ["launch", "announce", "release notes", "messaging"], suggestInstead: "launch", reason: "This is launch work, not a security review" },
121
+ { notForSignals: ["research", "should we", "competitive", "strategy"], suggestInstead: "research", reason: "This is a research question, not a security review" },
122
+ { notForSignals: ["treatment", "repo audit", "shipcheck", "polish"], suggestInstead: "treatment", reason: "This is repo treatment, not a security review" },
123
+ ],
124
+ },
125
+
126
+ // ── Docs / Handbook ─────────────────────────────────────────────────
127
+ docs: {
128
+ name: "Docs / Handbook",
129
+ description: "Triage → synthesize → structure → write → metadata → review",
130
+ roles: [
131
+ "Support Triage Lead", // interpret raw input (triage reports, issue lists, feedback)
132
+ "Feedback Synthesizer", // cluster and theme the interpreted input
133
+ "Docs Architect", // structure and write the docs
134
+ "Metadata Curator", // verify metadata alignment
135
+ "Critic Reviewer",
136
+ ],
137
+ orchestratorRequired: false,
138
+ optionalRoles: ["Repo Translator", "Brand Guardian", "Release Engineer", "Deployment Verifier"],
139
+ chainOrder: "Support Triage Lead → Feedback Synthesizer → Docs Architect → Metadata Curator",
140
+ requiredArtifacts: ["classified input", "synthesized themes", "docs structure", "metadata audit", "verdict"],
141
+ stopConditions: [
142
+ "Support Triage Lead finds input data ambiguous → request clarification",
143
+ "Feedback Synthesizer finds insufficient signal → escalate to user",
144
+ "Docs Architect finds product direction unclear → escalate to Product Strategist",
145
+ ],
146
+ escalationOwner: "Docs Architect",
147
+ dispatchDefaults: { model: "sonnet", maxTurns: 25, maxBudgetUsd: 4.0 },
148
+ trialEvidence: "G4 (Docs Architect), G7 (Treatment), I-4 (shipped page). Calibrated: Support Triage Lead + Feedback Synthesizer upstream. Release/Deploy moved to optional (overhead for docs-only tasks).",
149
+ mismatchGuards: [
150
+ { notForSignals: ["research", "should we", "competitive", "strategy"], suggestInstead: "research", reason: "This is a research/strategy question — decide before documenting" },
151
+ { notForSignals: ["security review", "threat", "vulnerability", "injection"], suggestInstead: "security", reason: "This is a security review, not docs work" },
152
+ { notForSignals: ["feature", "implement", "build", "add command"], suggestInstead: "feature", reason: "This is feature work, not docs" },
153
+ { notForSignals: ["bug", "fix", "crash", "broken"], suggestInstead: "bugfix", reason: "This is a bugfix, not docs work" },
154
+ { notForSignals: ["launch", "announce", "go-to-market", "messaging"], suggestInstead: "launch", reason: "This is launch work, not docs" },
155
+ { notForSignals: ["treatment", "repo audit", "shipcheck", "full treatment"], suggestInstead: "treatment", reason: "This is repo treatment, not docs only" },
156
+ ],
157
+ },
158
+
159
+ // ── Launch / Messaging ────────────────────────────────────────────────────
160
+ launch: {
161
+ name: "Launch / Messaging",
162
+ description: "Plan launch → write copy. Hard pipeline: Strategist → Copywriter.",
163
+ roles: [
164
+ "Launch Strategist",
165
+ "Launch Copywriter",
166
+ "Critic Reviewer",
167
+ ],
168
+ orchestratorRequired: false, // smallest pack, hard pipeline, no decomposition needed
169
+ optionalRoles: ["Content Strategist", "Community Manager"],
170
+ chainOrder: "Launch Strategist → Launch Copywriter",
171
+ requiredArtifacts: ["launch plan", "release copy", "verdict"],
172
+ stopConditions: [
173
+ "Launch Strategist finds no proof assets → delay launch",
174
+ "Launch Copywriter finds product claims unverifiable → escalate to Product Strategist",
175
+ ],
176
+ escalationOwner: "Launch Strategist",
177
+ dispatchDefaults: { model: "sonnet", maxTurns: 20, maxBudgetUsd: 3.0 },
178
+ trialEvidence: "G3 (pipeline proven), I-5 (v1.1.0 launch, Accept). Pack comparison: tie/marginal win. TRUE DEFAULT.",
179
+ mismatchGuards: [
180
+ { notForSignals: ["bug", "fix", "crash", "broken", "error"], suggestInstead: "bugfix", reason: "This is a bug to fix, not a launch to plan" },
181
+ { notForSignals: ["implement", "build", "add command", "new feature"], suggestInstead: "feature", reason: "This is feature work — build first, launch second" },
182
+ { notForSignals: ["security review", "threat", "vulnerability", "injection"], suggestInstead: "security", reason: "This is a security review, not launch work" },
183
+ { notForSignals: ["handbook", "documentation", "restructure docs"], suggestInstead: "docs", reason: "This is docs work, not launch messaging" },
184
+ { notForSignals: ["research", "should we", "competitive", "trend"], suggestInstead: "research", reason: "This is research, not launch messaging" },
185
+ { notForSignals: ["treatment", "repo audit", "shipcheck", "polish"], suggestInstead: "treatment", reason: "This is repo treatment, not launch" },
186
+ ],
187
+ },
188
+
189
+ // ── Research / Strategy ───────────────────────────────────────────────────
190
+ research: {
191
+ name: "Research / Strategy",
192
+ description: "Frame decision → gather evidence → synthesize → recommend",
193
+ roles: [
194
+ "Product Strategist", // REORDERED: framing first, then research
195
+ "UX Researcher",
196
+ "Competitive Analyst",
197
+ "Feedback Synthesizer",
198
+ "Critic Reviewer",
199
+ ],
200
+ orchestratorRequired: false, // clear pipeline, Product Strategist frames
201
+ optionalRoles: ["Trend Researcher", "User Interview Synthesizer"],
202
+ chainOrder: "Product Strategist → UX Researcher → Competitive Analyst → Feedback Synthesizer",
203
+ requiredArtifacts: ["decision frame", "friction inventory", "competitive landscape", "signal synthesis", "verdict"],
204
+ stopConditions: [
205
+ "Product Strategist finds the question too vague → request clarification",
206
+ "UX Researcher finds insufficient user data → escalate to Product Strategist",
207
+ "Competitive Analyst finds no comparable products → narrow scope",
208
+ ],
209
+ escalationOwner: "Product Strategist",
210
+ dispatchDefaults: { model: "sonnet", maxTurns: 25, maxBudgetUsd: 4.0 },
211
+ trialEvidence: "G8 (Research cluster), G9 (Growth/Product), I-6 (game dev decision). Calibrated: Product Strategist now opens (framing before research).",
212
+ mismatchGuards: [
213
+ { notForSignals: ["implement", "build", "add command", "write code"], suggestInstead: "feature", reason: "This is implementation work, not research" },
214
+ { notForSignals: ["bug", "fix", "crash", "broken"], suggestInstead: "bugfix", reason: "This is a bugfix, not a research question" },
215
+ { notForSignals: ["security review", "threat", "vulnerability", "injection"], suggestInstead: "security", reason: "This is a security review, not research" },
216
+ { notForSignals: ["handbook", "documentation", "restructure docs"], suggestInstead: "docs", reason: "This is docs work, not research" },
217
+ { notForSignals: ["launch", "announce", "release notes", "messaging"], suggestInstead: "launch", reason: "This is launch work, not research" },
218
+ { notForSignals: ["treatment", "repo audit", "shipcheck", "polish"], suggestInstead: "treatment", reason: "This is repo treatment, not research" },
219
+ ],
220
+ },
221
+
222
+ // ── Treatment (repo polish) ───────────────────────────────────────────────
223
+ treatment: {
224
+ name: "Treatment (Repo Polish)",
225
+ description: "Full repo treatment: research → security → audit → docs → metadata → release → deploy → verify",
226
+ roles: [
227
+ "Repo Researcher",
228
+ "Security Reviewer", // ADDED: was optional, now default (pack comparison finding)
229
+ "Coverage Auditor",
230
+ "Docs Architect",
231
+ "Metadata Curator",
232
+ "Release Engineer",
233
+ "Deployment Verifier",
234
+ "Critic Reviewer",
235
+ ],
236
+ orchestratorRequired: false, // long but sequential — each role has a clear handoff
237
+ optionalRoles: ["Brand Guardian", "Repo Translator", "Dependency Auditor"],
238
+ chainOrder: "Repo Researcher → Security Reviewer → Coverage Auditor → Docs Architect → Metadata Curator → Release Engineer → Deployment Verifier",
239
+ requiredArtifacts: ["repo map", "security findings", "coverage audit", "docs", "metadata audit", "release", "deployment verification", "verdict"],
240
+ stopConditions: [
241
+ "Security Reviewer finds critical vulnerability → block release until resolved",
242
+ "Coverage Auditor finds false confidence → flag for Test Engineer",
243
+ "Deployment Verifier finds broken live artifacts → loop back to Release Engineer",
244
+ ],
245
+ escalationOwner: "Repo Researcher",
246
+ dispatchDefaults: { model: "sonnet", maxTurns: 30, maxBudgetUsd: 5.0 },
247
+ trialEvidence: "G6-G7 (roles proven), I-7 (full chain, Accept-with-notes). Calibrated: Security Reviewer now default (was optional — pack comparison loss).",
248
+ mismatchGuards: [
249
+ { notForSignals: ["launch", "announce", "release notes", "social", "messaging"], suggestInstead: "launch", reason: "This is launch/messaging work — Treatment audits repos, it doesn't write announcements" },
250
+ { notForSignals: ["research", "should we", "competitive", "strategy"], suggestInstead: "research", reason: "This is a research/strategy question, not a repo treatment" },
251
+ { notForSignals: ["feature", "new command", "implement", "add", "create"], suggestInstead: "feature", reason: "This is feature work, not repo treatment" },
252
+ { notForSignals: ["bug", "fix", "crash", "broken"], suggestInstead: "bugfix", reason: "This is a bugfix, not a full treatment" },
253
+ { notForSignals: ["security review", "threat model", "injection"], suggestInstead: "security", reason: "This is a security review — treatment includes security but this task is security-only" },
254
+ { notForSignals: ["handbook", "documentation", "restructure docs"], suggestInstead: "docs", reason: "This is docs-only work, not a full treatment" },
255
+ ],
256
+ },
257
+
258
+ // ── Deep Audit (Componentized Repo Understanding) ──────────────────────────
259
+ "deep-audit": {
260
+ name: "Deep Audit",
261
+ description: "Decompose repo into components, audit each deeply, inspect seams, synthesize verdict. Scales with repo graph.",
262
+ roles: [
263
+ "Component Auditor",
264
+ "Test Truth Auditor",
265
+ "Seam Auditor",
266
+ "Audit Synthesizer",
267
+ "Critic Reviewer",
268
+ ],
269
+ orchestratorRequired: false, // mission step sequence handles orchestration
270
+ optionalRoles: ["Security Reviewer", "Dependency Auditor"],
271
+ chainOrder: "Component Auditor (×N, parallel) + Test Truth Auditor (×M) → Seam Auditor (×K, from graph) → Audit Synthesizer",
272
+ requiredArtifacts: ["audit-manifest", "component-audit-report", "seam-audit-report", "test-truth-report", "audit-summary", "audit-action-plan"],
273
+ stopConditions: [
274
+ "All component parcels audited + seams inspected + synthesis complete",
275
+ "Critical finding in decomposition phase — repo too tangled to slice cleanly",
276
+ "Component auditor finds scope exceeds 8K lines — request re-slice",
277
+ ],
278
+ escalationOwner: "Audit Synthesizer",
279
+ dispatchDefaults: { model: "sonnet", maxTurns: 25, maxBudgetUsd: 3.0 },
280
+ trialEvidence: "New mission no trial evidence yet. First test: role-os self-audit.",
281
+ mismatchGuards: [
282
+ { notForSignals: ["fix bug", "crash", "broken", "regression"], suggestInstead: "bugfix", reason: "This is a bug to fix, not a deep audit" },
283
+ { notForSignals: ["implement", "build", "add command", "new feature"], suggestInstead: "feature", reason: "This is feature work, not an audit" },
284
+ { notForSignals: ["launch", "announce", "release notes", "messaging"], suggestInstead: "launch", reason: "This is launch work, not an audit" },
285
+ { notForSignals: ["treatment", "shipcheck", "polish"], suggestInstead: "treatment", reason: "This is repo treatment (surface polish), not a deep audit" },
286
+ { notForSignals: ["brainstorm", "explore ideas", "ideate"], suggestInstead: "brainstorm", reason: "This is brainstorming, not an audit" },
287
+ ],
288
+ },
289
+
290
+ // ── Brainstorm (Structured Inquiry) ─────────────────────────────────────────
291
+ brainstorm: {
292
+ name: "Brainstorm (Structured Inquiry)",
293
+ description: "Specialized roles under law, with traceable disagreement and verdict-bearing output.",
294
+ roles: [
295
+ "Context Analyst",
296
+ "User Value Analyst",
297
+ "Mechanics Analyst",
298
+ "Positioning Analyst",
299
+ "Normalizer",
300
+ "Contrarian Analyst",
301
+ "Synthesizer",
302
+ "Product Expander",
303
+ "Judge",
304
+ ],
305
+ orchestratorRequired: false,
306
+ optionalRoles: ["Scenario Expander", "Moat Expander"],
307
+ chainOrder: "Context Analyst + User Value Analyst + Mechanics Analyst + Positioning Analyst (parallel) → Normalizer → Contrarian Analyst → Normalizer (rebut) → Synthesizer → Product Expander → Judge",
308
+ requiredArtifacts: ["context-map", "user-value-map", "mechanics-map", "positioning-map", "provenance-atoms", "challenge-set", "rebuttal-set", "synthesis-report", "expanded-concept", "judge-report"],
309
+ stopConditions: [
310
+ "Judge accepts — both truth and render layers assembled, trace links verified",
311
+ "Judge rejects — return honest partial with truth artifacts intact",
312
+ "Judge revises — loop back to targeted phase (max 3 loops)",
313
+ ],
314
+ escalationOwner: "Judge",
315
+ dispatchDefaults: { model: "sonnet", maxTurns: 40, maxBudgetUsd: 6.0 },
316
+ trialEvidence: "v0.4 golden run — 894 tests, full chain of custody proven. Architecture frozen 2026-03-27.",
317
+ mismatchGuards: [
318
+ { notForSignals: ["fix bug", "crash", "broken", "regression", "error"], suggestInstead: "bugfix", reason: "This is a bug to fix, not a brainstorm" },
319
+ { notForSignals: ["implement", "build", "add command", "write code"], suggestInstead: "feature", reason: "This is implementation work, not exploration" },
320
+ { notForSignals: ["security review", "threat model", "vulnerability"], suggestInstead: "security", reason: "This is a security review, not a brainstorm" },
321
+ { notForSignals: ["treatment", "repo audit", "shipcheck", "polish"], suggestInstead: "treatment", reason: "This is repo treatment, not a brainstorm" },
322
+ { notForSignals: ["launch", "announce", "release notes", "messaging"], suggestInstead: "launch", reason: "This is launch work, not a brainstorm" },
323
+ { notForSignals: ["handbook", "documentation", "restructure docs"], suggestInstead: "docs", reason: "This is docs work, not a brainstorm" },
324
+ ],
325
+ },
326
+ };
327
+
328
+ // ── Pack selection ────────────────────────────────────────────────────────────
329
+
330
+ const PACK_KEYWORDS = {
331
+ feature: ["feature", "build", "implement", "new", "add", "create"],
332
+ bugfix: ["bug", "fix", "repair", "broken", "crash", "error", "regression"],
333
+ security: ["security", "threat", "vulnerability", "audit", "owasp", "cve"],
334
+ docs: ["docs", "documentation", "handbook", "release", "publish", "changelog"],
335
+ launch: ["launch", "announce", "release notes", "messaging", "go-to-market"],
336
+ research: ["research", "competitive", "ux", "friction", "user", "strategy", "trend"],
337
+ treatment: ["treatment", "polish", "cleanup", "repo audit", "shipcheck", "full treatment"],
338
+ brainstorm: ["brainstorm", "explore", "ideate", "divergent", "opportunity", "creative directions", "concept exploration", "what could", "possibilities"],
339
+ "deep-audit": ["deep audit", "component audit", "repo audit deep", "decompose and audit", "audit components", "code audit", "structural audit", "deep review"],
340
+ };
341
+
342
+ /**
343
+ * Suggest the best pack for a packet based on content analysis.
344
+ */
345
+ export function suggestPack(content) {
346
+ const lower = content.toLowerCase();
347
+ const scores = {};
348
+
349
+ for (const [packName, keywords] of Object.entries(PACK_KEYWORDS)) {
350
+ let score = 0;
351
+ for (const kw of keywords) {
352
+ if (lower.includes(kw)) score++;
353
+ }
354
+ if (score > 0) scores[packName] = score;
355
+ }
356
+
357
+ const sorted = Object.entries(scores).sort((a, b) => b[1] - a[1]);
358
+ if (sorted.length === 0) return null;
359
+
360
+ const [topPack, topScore] = sorted[0];
361
+ const confidence = topScore >= 3 ? "high" : topScore >= 2 ? "medium" : "low";
362
+
363
+ return { pack: topPack, confidence, scores };
364
+ }
365
+
366
+ /**
367
+ * Check if a pack is a mismatch for the given content.
368
+ * Returns null if no mismatch, or the suggested alternative if mismatch detected.
369
+ *
370
+ * @param {string} packName
371
+ * @param {string} content - Packet content
372
+ * @returns {{ suggestInstead: string, reason: string } | null}
373
+ */
374
+ export function checkPackMismatch(packName, content) {
375
+ const pack = TEAM_PACKS[packName];
376
+ if (!pack || !pack.mismatchGuards) return null;
377
+
378
+ const lower = content.toLowerCase();
379
+ for (const guard of pack.mismatchGuards) {
380
+ const triggered = guard.notForSignals.some(signal => lower.includes(signal));
381
+ if (triggered) {
382
+ return { suggestInstead: guard.suggestInstead, reason: guard.reason };
383
+ }
384
+ }
385
+ return null;
386
+ }
387
+
388
+ /**
389
+ * Get a pack's effective roles (with conditional Orchestrator).
390
+ *
391
+ * @param {string} packName
392
+ * @param {boolean} [forceOrchestrator=false]
393
+ * @returns {string[] | null}
394
+ */
395
+ export function getPackRoles(packName, forceOrchestrator = false) {
396
+ const pack = TEAM_PACKS[packName];
397
+ if (!pack) return null;
398
+
399
+ const roles = [...pack.roles];
400
+ // Add Orchestrator only if the pack requires it or forced
401
+ if ((pack.orchestratorRequired || forceOrchestrator) && !roles.includes("Orchestrator")) {
402
+ roles.unshift("Orchestrator");
403
+ }
404
+ // Remove Orchestrator if pack doesn't require it and not forced
405
+ if (!pack.orchestratorRequired && !forceOrchestrator && roles[0] === "Orchestrator") {
406
+ roles.shift();
407
+ }
408
+ return roles;
409
+ }
410
+
411
+ /**
412
+ * Get a pack by name.
413
+ */
414
+ export function getPack(name) {
415
+ return TEAM_PACKS[name] || null;
416
+ }
417
+
418
+ /**
419
+ * List all available packs.
420
+ */
421
+ export function listPacks() {
422
+ return Object.entries(TEAM_PACKS).map(([key, pack]) => ({
423
+ key,
424
+ name: pack.name,
425
+ description: pack.description,
426
+ roleCount: pack.roles.length,
427
+ optionalCount: pack.optionalRoles.length,
428
+ orchestratorRequired: pack.orchestratorRequired,
429
+ }));
430
+ }