popeye-cli 1.10.0 → 2.1.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.
Files changed (326) hide show
  1. package/CHANGELOG.md +114 -0
  2. package/CONTRIBUTING.md +38 -3
  3. package/README.md +104 -18
  4. package/dist/adapters/gemini.js +3 -3
  5. package/dist/adapters/openai.js +2 -2
  6. package/dist/adapters/openai.js.map +1 -1
  7. package/dist/auth/gemini.js +1 -1
  8. package/dist/cli/commands/create.d.ts.map +1 -1
  9. package/dist/cli/commands/create.js +11 -5
  10. package/dist/cli/commands/create.js.map +1 -1
  11. package/dist/cli/commands/resume.d.ts.map +1 -1
  12. package/dist/cli/commands/resume.js +9 -1
  13. package/dist/cli/commands/resume.js.map +1 -1
  14. package/dist/cli/interactive.d.ts.map +1 -1
  15. package/dist/cli/interactive.js +29 -3
  16. package/dist/cli/interactive.js.map +1 -1
  17. package/dist/config/defaults.d.ts.map +1 -1
  18. package/dist/config/defaults.js +7 -2
  19. package/dist/config/defaults.js.map +1 -1
  20. package/dist/config/index.d.ts +1 -7
  21. package/dist/config/index.d.ts.map +1 -1
  22. package/dist/config/popeye-md.d.ts +32 -0
  23. package/dist/config/popeye-md.d.ts.map +1 -0
  24. package/dist/config/popeye-md.js +111 -0
  25. package/dist/config/popeye-md.js.map +1 -0
  26. package/dist/config/schema.d.ts +3 -21
  27. package/dist/config/schema.d.ts.map +1 -1
  28. package/dist/config/schema.js +21 -8
  29. package/dist/config/schema.js.map +1 -1
  30. package/dist/pipeline/artifact-manager.d.ts +47 -0
  31. package/dist/pipeline/artifact-manager.d.ts.map +1 -0
  32. package/dist/pipeline/artifact-manager.js +251 -0
  33. package/dist/pipeline/artifact-manager.js.map +1 -0
  34. package/dist/pipeline/artifact-validators.d.ts +29 -0
  35. package/dist/pipeline/artifact-validators.d.ts.map +1 -0
  36. package/dist/pipeline/artifact-validators.js +173 -0
  37. package/dist/pipeline/artifact-validators.js.map +1 -0
  38. package/dist/pipeline/bridges/review-bridge.d.ts +70 -0
  39. package/dist/pipeline/bridges/review-bridge.d.ts.map +1 -0
  40. package/dist/pipeline/bridges/review-bridge.js +266 -0
  41. package/dist/pipeline/bridges/review-bridge.js.map +1 -0
  42. package/dist/pipeline/change-request.d.ts +47 -0
  43. package/dist/pipeline/change-request.d.ts.map +1 -0
  44. package/dist/pipeline/change-request.js +91 -0
  45. package/dist/pipeline/change-request.js.map +1 -0
  46. package/dist/pipeline/check-runner.d.ts +47 -0
  47. package/dist/pipeline/check-runner.d.ts.map +1 -0
  48. package/dist/pipeline/check-runner.js +417 -0
  49. package/dist/pipeline/check-runner.js.map +1 -0
  50. package/dist/pipeline/command-resolver.d.ts +9 -0
  51. package/dist/pipeline/command-resolver.d.ts.map +1 -0
  52. package/dist/pipeline/command-resolver.js +140 -0
  53. package/dist/pipeline/command-resolver.js.map +1 -0
  54. package/dist/pipeline/consensus/consensus-runner.d.ts +44 -0
  55. package/dist/pipeline/consensus/consensus-runner.d.ts.map +1 -0
  56. package/dist/pipeline/consensus/consensus-runner.js +212 -0
  57. package/dist/pipeline/consensus/consensus-runner.js.map +1 -0
  58. package/dist/pipeline/constitution.d.ts +45 -0
  59. package/dist/pipeline/constitution.d.ts.map +1 -0
  60. package/dist/pipeline/constitution.js +82 -0
  61. package/dist/pipeline/constitution.js.map +1 -0
  62. package/dist/pipeline/gate-engine.d.ts +55 -0
  63. package/dist/pipeline/gate-engine.d.ts.map +1 -0
  64. package/dist/pipeline/gate-engine.js +270 -0
  65. package/dist/pipeline/gate-engine.js.map +1 -0
  66. package/dist/pipeline/index.d.ts +26 -0
  67. package/dist/pipeline/index.d.ts.map +1 -0
  68. package/dist/pipeline/index.js +35 -0
  69. package/dist/pipeline/index.js.map +1 -0
  70. package/dist/pipeline/migration.d.ts +15 -0
  71. package/dist/pipeline/migration.d.ts.map +1 -0
  72. package/dist/pipeline/migration.js +76 -0
  73. package/dist/pipeline/migration.js.map +1 -0
  74. package/dist/pipeline/orchestrator.d.ts +30 -0
  75. package/dist/pipeline/orchestrator.d.ts.map +1 -0
  76. package/dist/pipeline/orchestrator.js +242 -0
  77. package/dist/pipeline/orchestrator.js.map +1 -0
  78. package/dist/pipeline/packets/audit-report-builder.d.ts +11 -0
  79. package/dist/pipeline/packets/audit-report-builder.d.ts.map +1 -0
  80. package/dist/pipeline/packets/audit-report-builder.js +32 -0
  81. package/dist/pipeline/packets/audit-report-builder.js.map +1 -0
  82. package/dist/pipeline/packets/consensus-packet-builder.d.ts +35 -0
  83. package/dist/pipeline/packets/consensus-packet-builder.d.ts.map +1 -0
  84. package/dist/pipeline/packets/consensus-packet-builder.js +80 -0
  85. package/dist/pipeline/packets/consensus-packet-builder.js.map +1 -0
  86. package/dist/pipeline/packets/index.d.ts +12 -0
  87. package/dist/pipeline/packets/index.d.ts.map +1 -0
  88. package/dist/pipeline/packets/index.js +8 -0
  89. package/dist/pipeline/packets/index.js.map +1 -0
  90. package/dist/pipeline/packets/plan-packet-builder.d.ts +21 -0
  91. package/dist/pipeline/packets/plan-packet-builder.d.ts.map +1 -0
  92. package/dist/pipeline/packets/plan-packet-builder.js +27 -0
  93. package/dist/pipeline/packets/plan-packet-builder.js.map +1 -0
  94. package/dist/pipeline/packets/rca-packet-builder.d.ts +19 -0
  95. package/dist/pipeline/packets/rca-packet-builder.d.ts.map +1 -0
  96. package/dist/pipeline/packets/rca-packet-builder.js +22 -0
  97. package/dist/pipeline/packets/rca-packet-builder.js.map +1 -0
  98. package/dist/pipeline/phases/architecture.d.ts +7 -0
  99. package/dist/pipeline/phases/architecture.d.ts.map +1 -0
  100. package/dist/pipeline/phases/architecture.js +60 -0
  101. package/dist/pipeline/phases/architecture.js.map +1 -0
  102. package/dist/pipeline/phases/audit.d.ts +8 -0
  103. package/dist/pipeline/phases/audit.d.ts.map +1 -0
  104. package/dist/pipeline/phases/audit.js +144 -0
  105. package/dist/pipeline/phases/audit.js.map +1 -0
  106. package/dist/pipeline/phases/consensus-architecture.d.ts +7 -0
  107. package/dist/pipeline/phases/consensus-architecture.d.ts.map +1 -0
  108. package/dist/pipeline/phases/consensus-architecture.js +84 -0
  109. package/dist/pipeline/phases/consensus-architecture.js.map +1 -0
  110. package/dist/pipeline/phases/consensus-master-plan.d.ts +7 -0
  111. package/dist/pipeline/phases/consensus-master-plan.d.ts.map +1 -0
  112. package/dist/pipeline/phases/consensus-master-plan.js +81 -0
  113. package/dist/pipeline/phases/consensus-master-plan.js.map +1 -0
  114. package/dist/pipeline/phases/consensus-role-plans.d.ts +7 -0
  115. package/dist/pipeline/phases/consensus-role-plans.d.ts.map +1 -0
  116. package/dist/pipeline/phases/consensus-role-plans.js +85 -0
  117. package/dist/pipeline/phases/consensus-role-plans.js.map +1 -0
  118. package/dist/pipeline/phases/done.d.ts +7 -0
  119. package/dist/pipeline/phases/done.d.ts.map +1 -0
  120. package/dist/pipeline/phases/done.js +45 -0
  121. package/dist/pipeline/phases/done.js.map +1 -0
  122. package/dist/pipeline/phases/implementation.d.ts +8 -0
  123. package/dist/pipeline/phases/implementation.d.ts.map +1 -0
  124. package/dist/pipeline/phases/implementation.js +45 -0
  125. package/dist/pipeline/phases/implementation.js.map +1 -0
  126. package/dist/pipeline/phases/index.d.ts +20 -0
  127. package/dist/pipeline/phases/index.d.ts.map +1 -0
  128. package/dist/pipeline/phases/index.js +19 -0
  129. package/dist/pipeline/phases/index.js.map +1 -0
  130. package/dist/pipeline/phases/intake.d.ts +8 -0
  131. package/dist/pipeline/phases/intake.d.ts.map +1 -0
  132. package/dist/pipeline/phases/intake.js +49 -0
  133. package/dist/pipeline/phases/intake.js.map +1 -0
  134. package/dist/pipeline/phases/phase-context.d.ts +30 -0
  135. package/dist/pipeline/phases/phase-context.d.ts.map +1 -0
  136. package/dist/pipeline/phases/phase-context.js +33 -0
  137. package/dist/pipeline/phases/phase-context.js.map +1 -0
  138. package/dist/pipeline/phases/production-gate.d.ts +8 -0
  139. package/dist/pipeline/phases/production-gate.d.ts.map +1 -0
  140. package/dist/pipeline/phases/production-gate.js +84 -0
  141. package/dist/pipeline/phases/production-gate.js.map +1 -0
  142. package/dist/pipeline/phases/qa-validation.d.ts +7 -0
  143. package/dist/pipeline/phases/qa-validation.d.ts.map +1 -0
  144. package/dist/pipeline/phases/qa-validation.js +50 -0
  145. package/dist/pipeline/phases/qa-validation.js.map +1 -0
  146. package/dist/pipeline/phases/recovery-loop.d.ts +7 -0
  147. package/dist/pipeline/phases/recovery-loop.d.ts.map +1 -0
  148. package/dist/pipeline/phases/recovery-loop.js +93 -0
  149. package/dist/pipeline/phases/recovery-loop.js.map +1 -0
  150. package/dist/pipeline/phases/review.d.ts +8 -0
  151. package/dist/pipeline/phases/review.d.ts.map +1 -0
  152. package/dist/pipeline/phases/review.js +127 -0
  153. package/dist/pipeline/phases/review.js.map +1 -0
  154. package/dist/pipeline/phases/role-planning.d.ts +7 -0
  155. package/dist/pipeline/phases/role-planning.d.ts.map +1 -0
  156. package/dist/pipeline/phases/role-planning.js +75 -0
  157. package/dist/pipeline/phases/role-planning.js.map +1 -0
  158. package/dist/pipeline/phases/stuck.d.ts +7 -0
  159. package/dist/pipeline/phases/stuck.d.ts.map +1 -0
  160. package/dist/pipeline/phases/stuck.js +51 -0
  161. package/dist/pipeline/phases/stuck.js.map +1 -0
  162. package/dist/pipeline/repo-snapshot.d.ts +24 -0
  163. package/dist/pipeline/repo-snapshot.d.ts.map +1 -0
  164. package/dist/pipeline/repo-snapshot.js +343 -0
  165. package/dist/pipeline/repo-snapshot.js.map +1 -0
  166. package/dist/pipeline/role-execution-adapter.d.ts +59 -0
  167. package/dist/pipeline/role-execution-adapter.d.ts.map +1 -0
  168. package/dist/pipeline/role-execution-adapter.js +159 -0
  169. package/dist/pipeline/role-execution-adapter.js.map +1 -0
  170. package/dist/pipeline/skill-loader.d.ts +34 -0
  171. package/dist/pipeline/skill-loader.d.ts.map +1 -0
  172. package/dist/pipeline/skill-loader.js +156 -0
  173. package/dist/pipeline/skill-loader.js.map +1 -0
  174. package/dist/pipeline/skills/defaults.d.ts +16 -0
  175. package/dist/pipeline/skills/defaults.d.ts.map +1 -0
  176. package/dist/pipeline/skills/defaults.js +189 -0
  177. package/dist/pipeline/skills/defaults.js.map +1 -0
  178. package/dist/pipeline/type-defs/artifacts.d.ts +207 -0
  179. package/dist/pipeline/type-defs/artifacts.d.ts.map +1 -0
  180. package/dist/pipeline/type-defs/artifacts.js +67 -0
  181. package/dist/pipeline/type-defs/artifacts.js.map +1 -0
  182. package/dist/pipeline/type-defs/audit.d.ts +259 -0
  183. package/dist/pipeline/type-defs/audit.d.ts.map +1 -0
  184. package/dist/pipeline/type-defs/audit.js +54 -0
  185. package/dist/pipeline/type-defs/audit.js.map +1 -0
  186. package/dist/pipeline/type-defs/checks.d.ts +82 -0
  187. package/dist/pipeline/type-defs/checks.d.ts.map +1 -0
  188. package/dist/pipeline/type-defs/checks.js +38 -0
  189. package/dist/pipeline/type-defs/checks.js.map +1 -0
  190. package/dist/pipeline/type-defs/enums.d.ts +43 -0
  191. package/dist/pipeline/type-defs/enums.d.ts.map +1 -0
  192. package/dist/pipeline/type-defs/enums.js +55 -0
  193. package/dist/pipeline/type-defs/enums.js.map +1 -0
  194. package/dist/pipeline/type-defs/index.d.ts +12 -0
  195. package/dist/pipeline/type-defs/index.d.ts.map +1 -0
  196. package/dist/pipeline/type-defs/index.js +12 -0
  197. package/dist/pipeline/type-defs/index.js.map +1 -0
  198. package/dist/pipeline/type-defs/packets.d.ts +821 -0
  199. package/dist/pipeline/type-defs/packets.d.ts.map +1 -0
  200. package/dist/pipeline/type-defs/packets.js +109 -0
  201. package/dist/pipeline/type-defs/packets.js.map +1 -0
  202. package/dist/pipeline/type-defs/snapshot.d.ts +52 -0
  203. package/dist/pipeline/type-defs/snapshot.d.ts.map +1 -0
  204. package/dist/pipeline/type-defs/snapshot.js +35 -0
  205. package/dist/pipeline/type-defs/snapshot.js.map +1 -0
  206. package/dist/pipeline/type-defs/state.d.ts +455 -0
  207. package/dist/pipeline/type-defs/state.d.ts.map +1 -0
  208. package/dist/pipeline/type-defs/state.js +90 -0
  209. package/dist/pipeline/type-defs/state.js.map +1 -0
  210. package/dist/pipeline/types.d.ts +16 -0
  211. package/dist/pipeline/types.d.ts.map +1 -0
  212. package/dist/pipeline/types.js +16 -0
  213. package/dist/pipeline/types.js.map +1 -0
  214. package/dist/types/audit.d.ts +6 -6
  215. package/dist/types/consensus.d.ts +5 -1
  216. package/dist/types/consensus.d.ts.map +1 -1
  217. package/dist/types/consensus.js +15 -4
  218. package/dist/types/consensus.js.map +1 -1
  219. package/dist/types/index.d.ts +1 -1
  220. package/dist/types/index.d.ts.map +1 -1
  221. package/dist/types/index.js +1 -1
  222. package/dist/types/index.js.map +1 -1
  223. package/dist/types/project.d.ts +1 -1
  224. package/dist/types/project.d.ts.map +1 -1
  225. package/dist/types/project.js +39 -10
  226. package/dist/types/project.js.map +1 -1
  227. package/dist/types/workflow.d.ts +1 -7
  228. package/dist/types/workflow.d.ts.map +1 -1
  229. package/dist/types/workflow.js +1 -1
  230. package/dist/types/workflow.js.map +1 -1
  231. package/dist/upgrade/handlers.js +5 -5
  232. package/dist/upgrade/handlers.js.map +1 -1
  233. package/dist/workflow/index.d.ts.map +1 -1
  234. package/dist/workflow/index.js +52 -0
  235. package/dist/workflow/index.js.map +1 -1
  236. package/dist/workflow/website-strategy.js +1 -1
  237. package/dist/workflow/website-strategy.js.map +1 -1
  238. package/package.json +1 -1
  239. package/skills/PHASE_GATE_ENGINE_SPEC.md +113 -20
  240. package/skills/POPEYE_FULL_AUTONOMY_PIPELINE.md +66 -13
  241. package/src/adapters/gemini.ts +3 -3
  242. package/src/adapters/openai.ts +2 -2
  243. package/src/auth/gemini.ts +1 -1
  244. package/src/cli/commands/create.ts +12 -6
  245. package/src/cli/commands/resume.ts +9 -1
  246. package/src/cli/interactive.ts +32 -3
  247. package/src/config/defaults.ts +7 -2
  248. package/src/config/popeye-md.ts +139 -0
  249. package/src/config/schema.ts +21 -8
  250. package/src/pipeline/artifact-manager.ts +339 -0
  251. package/src/pipeline/artifact-validators.ts +224 -0
  252. package/src/pipeline/bridges/review-bridge.ts +371 -0
  253. package/src/pipeline/change-request.ts +119 -0
  254. package/src/pipeline/check-runner.ts +504 -0
  255. package/src/pipeline/command-resolver.ts +168 -0
  256. package/src/pipeline/consensus/consensus-runner.ts +317 -0
  257. package/src/pipeline/constitution.ts +109 -0
  258. package/src/pipeline/gate-engine.ts +347 -0
  259. package/src/pipeline/index.ts +82 -0
  260. package/src/pipeline/migration.ts +91 -0
  261. package/src/pipeline/orchestrator.ts +322 -0
  262. package/src/pipeline/packets/audit-report-builder.ts +47 -0
  263. package/src/pipeline/packets/consensus-packet-builder.ts +112 -0
  264. package/src/pipeline/packets/index.ts +15 -0
  265. package/src/pipeline/packets/plan-packet-builder.ts +52 -0
  266. package/src/pipeline/packets/rca-packet-builder.ts +38 -0
  267. package/src/pipeline/phases/architecture.ts +73 -0
  268. package/src/pipeline/phases/audit.ts +193 -0
  269. package/src/pipeline/phases/consensus-architecture.ts +104 -0
  270. package/src/pipeline/phases/consensus-master-plan.ts +100 -0
  271. package/src/pipeline/phases/consensus-role-plans.ts +105 -0
  272. package/src/pipeline/phases/done.ts +68 -0
  273. package/src/pipeline/phases/implementation.ts +52 -0
  274. package/src/pipeline/phases/index.ts +21 -0
  275. package/src/pipeline/phases/intake.ts +68 -0
  276. package/src/pipeline/phases/phase-context.ts +86 -0
  277. package/src/pipeline/phases/production-gate.ts +113 -0
  278. package/src/pipeline/phases/qa-validation.ts +63 -0
  279. package/src/pipeline/phases/recovery-loop.ts +120 -0
  280. package/src/pipeline/phases/review.ts +149 -0
  281. package/src/pipeline/phases/role-planning.ts +92 -0
  282. package/src/pipeline/phases/stuck.ts +62 -0
  283. package/src/pipeline/repo-snapshot.ts +395 -0
  284. package/src/pipeline/role-execution-adapter.ts +238 -0
  285. package/src/pipeline/skill-loader.ts +192 -0
  286. package/src/pipeline/skills/defaults.ts +215 -0
  287. package/src/pipeline/type-defs/artifacts.ts +82 -0
  288. package/src/pipeline/type-defs/audit.ts +67 -0
  289. package/src/pipeline/type-defs/checks.ts +47 -0
  290. package/src/pipeline/type-defs/enums.ts +62 -0
  291. package/src/pipeline/type-defs/index.ts +12 -0
  292. package/src/pipeline/type-defs/packets.ts +131 -0
  293. package/src/pipeline/type-defs/snapshot.ts +55 -0
  294. package/src/pipeline/type-defs/state.ts +167 -0
  295. package/src/pipeline/types.ts +16 -0
  296. package/src/types/consensus.ts +16 -4
  297. package/src/types/index.ts +1 -0
  298. package/src/types/project.ts +39 -10
  299. package/src/types/workflow.ts +1 -1
  300. package/src/upgrade/handlers.ts +5 -5
  301. package/src/workflow/index.ts +52 -0
  302. package/src/workflow/website-strategy.ts +1 -1
  303. package/tests/cli/model-command.test.ts +19 -9
  304. package/tests/config/config.test.ts +3 -3
  305. package/tests/config/popeye-md.test.ts +168 -0
  306. package/tests/pipeline/artifact-manager.test.ts +183 -0
  307. package/tests/pipeline/artifact-validators.test.ts +207 -0
  308. package/tests/pipeline/bridges/review-bridge.test.ts +243 -0
  309. package/tests/pipeline/change-request.test.ts +180 -0
  310. package/tests/pipeline/check-runner.test.ts +157 -0
  311. package/tests/pipeline/command-resolver.test.ts +159 -0
  312. package/tests/pipeline/consensus-runner.test.ts +206 -0
  313. package/tests/pipeline/consensus-scoring.test.ts +163 -0
  314. package/tests/pipeline/constitution.test.ts +122 -0
  315. package/tests/pipeline/gate-engine.test.ts +195 -0
  316. package/tests/pipeline/migration.test.ts +133 -0
  317. package/tests/pipeline/orchestrator.test.ts +614 -0
  318. package/tests/pipeline/packets/builders.test.ts +347 -0
  319. package/tests/pipeline/repo-snapshot.test.ts +189 -0
  320. package/tests/pipeline/role-execution-adapter.test.ts +299 -0
  321. package/tests/pipeline/session-guidance.test.ts +205 -0
  322. package/tests/pipeline/skill-loader.test.ts +186 -0
  323. package/tests/pipeline/start-env-checks.test.ts +123 -0
  324. package/tests/pipeline/types.test.ts +156 -0
  325. package/tests/types/consensus.test.ts +1 -1
  326. package/tests/workflow/pipeline-bootstrap.test.ts +162 -0
@@ -0,0 +1,238 @@
1
+ /**
2
+ * Role Execution Adapter — bridges pipeline role planning
3
+ * with the existing runExecutionMode().
4
+ *
5
+ * Builds role-specific execution contexts by combining skill prompts
6
+ * with role plan constraints, then injects them as systemPrompt
7
+ * into ClaudeExecuteOptions for prompt-based enforcement.
8
+ */
9
+
10
+ import { existsSync, readFileSync } from 'node:fs';
11
+ import { join } from 'node:path';
12
+
13
+ import type {
14
+ PipelineRole,
15
+ PipelineState,
16
+ ArtifactEntry,
17
+ } from './types.js';
18
+ import type { SkillLoader, SkillDefinition } from './skill-loader.js';
19
+
20
+ // ─── Types ───────────────────────────────────────────────
21
+
22
+ export interface RoleExecutionContext {
23
+ role: PipelineRole;
24
+ systemPrompt: string;
25
+ allowedPaths: string[];
26
+ forbiddenPatterns: string[];
27
+ taskScope: string;
28
+ }
29
+
30
+ export interface ClaudeExecuteOptions {
31
+ projectDir: string;
32
+ systemPrompt?: string;
33
+ [key: string]: unknown;
34
+ }
35
+
36
+ // ─── Context Builder ─────────────────────────────────────
37
+
38
+ /**
39
+ * Build a role-specific execution context from a skill definition and role plan artifact.
40
+ *
41
+ * Args:
42
+ * role: The pipeline role to build context for.
43
+ * skill: The skill definition loaded by SkillLoader.
44
+ * rolePlan: The approved role plan artifact entry.
45
+ * projectDir: Root project directory.
46
+ *
47
+ * Returns:
48
+ * RoleExecutionContext with system prompt, allowed paths, and task scope.
49
+ */
50
+ export function buildRoleExecutionContext(
51
+ role: PipelineRole,
52
+ skill: SkillDefinition,
53
+ rolePlan: ArtifactEntry,
54
+ projectDir: string,
55
+ ): RoleExecutionContext {
56
+ // Read role plan content
57
+ const planPath = join(projectDir, rolePlan.path);
58
+ let planContent = '';
59
+ if (existsSync(planPath)) {
60
+ planContent = readFileSync(planPath, 'utf-8');
61
+ }
62
+
63
+ // Extract task scope from role plan
64
+ const taskScope = extractTaskScope(planContent);
65
+ const allowedPaths = extractAllowedPaths(planContent, role);
66
+ const forbiddenPatterns = extractForbiddenPatterns(role);
67
+
68
+ // Build system prompt combining skill + role constraints
69
+ const systemPrompt = buildRoleSystemPrompt(role, skill, planContent, forbiddenPatterns);
70
+
71
+ return {
72
+ role,
73
+ systemPrompt,
74
+ allowedPaths,
75
+ forbiddenPatterns,
76
+ taskScope,
77
+ };
78
+ }
79
+
80
+ /**
81
+ * Inject role context into ClaudeExecuteOptions by setting the systemPrompt field.
82
+ *
83
+ * Args:
84
+ * context: The role execution context.
85
+ * options: The execution options to augment.
86
+ *
87
+ * Returns:
88
+ * Modified options with systemPrompt injected.
89
+ */
90
+ export function executeWithRoleContext(
91
+ context: RoleExecutionContext,
92
+ options: ClaudeExecuteOptions,
93
+ ): ClaudeExecuteOptions {
94
+ return {
95
+ ...options,
96
+ systemPrompt: context.systemPrompt,
97
+ };
98
+ }
99
+
100
+ // ─── Role-to-Plan Mapping ────────────────────────────────
101
+
102
+ /**
103
+ * Find role plan artifacts for each active role in the pipeline.
104
+ *
105
+ * Args:
106
+ * pipeline: Current pipeline state.
107
+ * skillLoader: Skill loader instance.
108
+ * projectDir: Root project directory.
109
+ *
110
+ * Returns:
111
+ * Map of role to RoleExecutionContext.
112
+ */
113
+ export function buildAllRoleContexts(
114
+ pipeline: PipelineState,
115
+ skillLoader: SkillLoader,
116
+ projectDir: string,
117
+ ): Map<PipelineRole, RoleExecutionContext> {
118
+ const contexts = new Map<PipelineRole, RoleExecutionContext>();
119
+
120
+ // Find all role_plan artifacts
121
+ const rolePlanArtifacts = pipeline.artifacts.filter((a) => a.type === 'role_plan');
122
+
123
+ for (const rolePlan of rolePlanArtifacts) {
124
+ // Determine which role this plan belongs to by checking plan content
125
+ const planPath = join(projectDir, rolePlan.path);
126
+ if (!existsSync(planPath)) continue;
127
+
128
+ const content = readFileSync(planPath, 'utf-8');
129
+ const role = detectRoleFromPlan(content, pipeline.activeRoles);
130
+ if (!role) continue;
131
+
132
+ const skill = skillLoader.loadSkill(role);
133
+ contexts.set(role, buildRoleExecutionContext(role, skill, rolePlan, projectDir));
134
+ }
135
+
136
+ return contexts;
137
+ }
138
+
139
+ // ─── Internal Helpers ────────────────────────────────────
140
+
141
+ /** Extract task scope description from role plan content */
142
+ function extractTaskScope(planContent: string): string {
143
+ // Look for "## Tasks" or "## Responsibilities" section
144
+ const taskMatch = planContent.match(
145
+ /#+\s*(?:Tasks?|Responsibilities?|Work\s+Items?)\s*\n([\s\S]*?)(?=\n#+\s|\n---|\s*$)/i,
146
+ );
147
+ if (taskMatch) {
148
+ return taskMatch[1].trim().slice(0, 2000);
149
+ }
150
+ // Fallback: first 500 chars
151
+ return planContent.slice(0, 500).trim();
152
+ }
153
+
154
+ /** Extract allowed file paths from role plan */
155
+ function extractAllowedPaths(planContent: string, role: PipelineRole): string[] {
156
+ // Default paths based on role
157
+ const roleDefaults: Partial<Record<PipelineRole, string[]>> = {
158
+ FRONTEND_PROGRAMMER: ['src/', 'app/', 'pages/', 'components/', 'styles/', 'public/'],
159
+ BACKEND_PROGRAMMER: ['src/', 'server/', 'api/', 'lib/', 'db/', 'prisma/'],
160
+ WEBSITE_PROGRAMMER: ['apps/website/', 'src/', 'app/', 'pages/', 'public/'],
161
+ DB_EXPERT: ['prisma/', 'migrations/', 'db/', 'alembic/', 'models/'],
162
+ QA_TESTER: ['tests/', '__tests__/', 'test/', 'spec/'],
163
+ UI_UX_SPECIALIST: ['src/', 'app/', 'styles/', 'components/'],
164
+ };
165
+
166
+ // Extract explicit file references from plan
167
+ const fileRefs = planContent.match(/(?:src|app|pages|lib|server|api|tests?)\/[\w\-./]+/g) ?? [];
168
+ const defaults = roleDefaults[role] ?? [];
169
+
170
+ return [...new Set([...defaults, ...fileRefs])];
171
+ }
172
+
173
+ /** Get forbidden patterns based on role boundaries */
174
+ function extractForbiddenPatterns(role: PipelineRole): string[] {
175
+ const roleForbidden: Partial<Record<PipelineRole, string[]>> = {
176
+ FRONTEND_PROGRAMMER: ['server/', 'api/', 'prisma/', 'migrations/', 'alembic/'],
177
+ BACKEND_PROGRAMMER: ['components/', 'styles/', 'public/assets/'],
178
+ WEBSITE_PROGRAMMER: ['server/', 'api/', 'prisma/', 'migrations/'],
179
+ DB_EXPERT: ['components/', 'styles/', 'public/', 'pages/'],
180
+ QA_TESTER: [], // QA can touch anything
181
+ };
182
+
183
+ return roleForbidden[role] ?? [];
184
+ }
185
+
186
+ /** Build the full system prompt for a role */
187
+ function buildRoleSystemPrompt(
188
+ role: PipelineRole,
189
+ skill: SkillDefinition,
190
+ planContent: string,
191
+ forbiddenPatterns: string[],
192
+ ): string {
193
+ const lines = [
194
+ `# Role: ${role}`,
195
+ '',
196
+ '## Skill System Prompt',
197
+ skill.systemPrompt,
198
+ '',
199
+ '## Your Approved Role Plan',
200
+ planContent.slice(0, 4000),
201
+ '',
202
+ '## Constraints',
203
+ ...skill.constraints.map((c) => `- ${c}`),
204
+ ];
205
+
206
+ if (forbiddenPatterns.length > 0) {
207
+ lines.push(
208
+ '',
209
+ '## Forbidden Paths (Do NOT modify these)',
210
+ ...forbiddenPatterns.map((p) => `- ${p}`),
211
+ );
212
+ }
213
+
214
+ lines.push(
215
+ '',
216
+ '## Rules',
217
+ '- Stay within your role boundaries',
218
+ '- Only modify files in your allowed paths',
219
+ '- If you need changes outside your scope, flag them as dependencies',
220
+ '- Follow the approved plan — do not add unplanned features',
221
+ );
222
+
223
+ return lines.join('\n');
224
+ }
225
+
226
+ /** Detect which role a plan belongs to by matching role names in content */
227
+ function detectRoleFromPlan(
228
+ content: string,
229
+ activeRoles: PipelineRole[],
230
+ ): PipelineRole | undefined {
231
+ const uppercaseContent = content.toUpperCase();
232
+ for (const role of activeRoles) {
233
+ if (uppercaseContent.includes(role)) {
234
+ return role;
235
+ }
236
+ }
237
+ return undefined;
238
+ }
@@ -0,0 +1,192 @@
1
+ /**
2
+ * Skill Loader — hybrid system loading from TS defaults + .md overrides.
3
+ * .md files use YAML frontmatter for structured fields (P1-1).
4
+ * If no frontmatter, entire file treated as raw systemPrompt override.
5
+ */
6
+
7
+ import { existsSync, readFileSync, readdirSync } from 'node:fs';
8
+ import { join } from 'node:path';
9
+
10
+ import type { PipelineRole } from './types.js';
11
+ import { DEFAULT_SKILLS } from './skills/defaults.js';
12
+
13
+ // ─── Types ───────────────────────────────────────────────
14
+
15
+ export interface SkillDefinition {
16
+ role: PipelineRole;
17
+ version: string;
18
+ systemPrompt: string;
19
+ required_outputs: string[];
20
+ constraints: string[];
21
+ depends_on?: PipelineRole[];
22
+ }
23
+
24
+ // ─── Skill Loader ────────────────────────────────────────
25
+
26
+ export class SkillLoader {
27
+ private readonly skillsDir: string | undefined;
28
+ private readonly cache = new Map<PipelineRole, SkillDefinition>();
29
+
30
+ constructor(skillsDir?: string) {
31
+ this.skillsDir = skillsDir;
32
+ }
33
+
34
+ /** Load skill definition for a role. Merges TS default + .md override. */
35
+ loadSkill(role: PipelineRole): SkillDefinition {
36
+ const cached = this.cache.get(role);
37
+ if (cached) return cached;
38
+
39
+ const defaultSkill = getDefaultSkill(role);
40
+ const override = this.loadMarkdownOverride(role);
41
+
42
+ const merged: SkillDefinition = {
43
+ ...defaultSkill,
44
+ ...override,
45
+ role, // Always keep the role
46
+ };
47
+
48
+ // If override has systemPrompt, use it; otherwise keep default
49
+ if (override?.systemPrompt) {
50
+ merged.systemPrompt = override.systemPrompt;
51
+ }
52
+
53
+ this.cache.set(role, merged);
54
+ return merged;
55
+ }
56
+
57
+ /** Load all skills for the given roles */
58
+ loadAllSkills(roles: PipelineRole[]): Map<PipelineRole, SkillDefinition> {
59
+ const result = new Map<PipelineRole, SkillDefinition>();
60
+ for (const role of roles) {
61
+ result.set(role, this.loadSkill(role));
62
+ }
63
+ return result;
64
+ }
65
+
66
+ /** Clear cache (useful after reloading .md files) */
67
+ clearCache(): void {
68
+ this.cache.clear();
69
+ }
70
+
71
+ /** List available .md skill files */
72
+ listAvailableOverrides(): string[] {
73
+ if (!this.skillsDir || !existsSync(this.skillsDir)) return [];
74
+ return readdirSync(this.skillsDir)
75
+ .filter((f) => f.endsWith('.md'))
76
+ .map((f) => f.replace('.md', ''));
77
+ }
78
+
79
+ // ─── Internal ────────────────────────────────────────────
80
+
81
+ private loadMarkdownOverride(role: PipelineRole): Partial<SkillDefinition> | null {
82
+ if (!this.skillsDir) return null;
83
+
84
+ const mdPath = join(this.skillsDir, `${role}.md`);
85
+ if (!existsSync(mdPath)) return null;
86
+
87
+ try {
88
+ const content = readFileSync(mdPath, 'utf-8');
89
+ return parseSkillMarkdown(content);
90
+ } catch {
91
+ return null;
92
+ }
93
+ }
94
+ }
95
+
96
+ // ─── Default Skill Lookup ────────────────────────────────
97
+
98
+ export function getDefaultSkill(role: PipelineRole): SkillDefinition {
99
+ return DEFAULT_SKILLS[role] ?? {
100
+ role,
101
+ version: '1.0',
102
+ systemPrompt: `You are the ${role} in the Popeye pipeline.`,
103
+ required_outputs: [],
104
+ constraints: [],
105
+ };
106
+ }
107
+
108
+ // ─── Markdown Parsing ────────────────────────────────────
109
+
110
+ /** Parse skill markdown with optional YAML frontmatter */
111
+ export function parseSkillMarkdown(content: string): Partial<SkillDefinition> {
112
+ const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
113
+
114
+ if (!frontmatterMatch) {
115
+ // No frontmatter: entire content is systemPrompt
116
+ return { systemPrompt: content.trim() };
117
+ }
118
+
119
+ const frontmatterRaw = frontmatterMatch[1];
120
+ const body = frontmatterMatch[2].trim();
121
+
122
+ const result: Partial<SkillDefinition> = {};
123
+
124
+ // Parse simple YAML fields (no dependency on yaml library here)
125
+ const lines = frontmatterRaw.split('\n');
126
+ let currentKey = '';
127
+ let currentList: string[] = [];
128
+
129
+ for (const line of lines) {
130
+ const kvMatch = line.match(/^(\w+):\s*(.*)$/);
131
+ if (kvMatch) {
132
+ // Flush previous list
133
+ if (currentKey && currentList.length > 0) {
134
+ setField(result, currentKey, currentList);
135
+ currentList = [];
136
+ }
137
+
138
+ const [, key, value] = kvMatch;
139
+ currentKey = key;
140
+
141
+ if (value.trim()) {
142
+ setField(result, key, value.trim());
143
+ currentKey = '';
144
+ }
145
+ } else {
146
+ const listItemMatch = line.match(/^\s+-\s+(.*)$/);
147
+ if (listItemMatch) {
148
+ currentList.push(listItemMatch[1]);
149
+ }
150
+ }
151
+ }
152
+
153
+ // Flush last list
154
+ if (currentKey && currentList.length > 0) {
155
+ setField(result, currentKey, currentList);
156
+ }
157
+
158
+ // Body is always the systemPrompt
159
+ if (body) {
160
+ result.systemPrompt = body;
161
+ }
162
+
163
+ return result;
164
+ }
165
+
166
+ function setField(result: Partial<SkillDefinition>, key: string, value: string | string[]): void {
167
+ switch (key) {
168
+ case 'role':
169
+ if (typeof value === 'string') result.role = value as PipelineRole;
170
+ break;
171
+ case 'version':
172
+ if (typeof value === 'string') result.version = value;
173
+ break;
174
+ case 'required_outputs':
175
+ if (Array.isArray(value)) result.required_outputs = value;
176
+ break;
177
+ case 'constraints':
178
+ if (Array.isArray(value)) result.constraints = value;
179
+ break;
180
+ }
181
+ }
182
+
183
+ // ─── Factory ─────────────────────────────────────────────
184
+
185
+ export function resolveSkillsDir(projectDir: string): string {
186
+ return join(projectDir, 'skills');
187
+ }
188
+
189
+ export function createSkillLoader(projectDir?: string): SkillLoader {
190
+ const skillsDir = projectDir ? resolveSkillsDir(projectDir) : undefined;
191
+ return new SkillLoader(skillsDir);
192
+ }
@@ -0,0 +1,215 @@
1
+ /**
2
+ * Default skill definitions for all 16 pipeline roles.
3
+ * Each contains a system prompt, required outputs, and constraints.
4
+ * These can be overridden by .md files in the project's skills/ directory.
5
+ */
6
+
7
+ import type { PipelineRole } from '../types.js';
8
+
9
+ export interface SkillDefinition {
10
+ role: PipelineRole;
11
+ version: string;
12
+ systemPrompt: string;
13
+ required_outputs: string[];
14
+ constraints: string[];
15
+ depends_on?: PipelineRole[];
16
+ }
17
+
18
+ export const DEFAULT_SKILLS: Record<PipelineRole, SkillDefinition> = {
19
+ DISPATCHER: {
20
+ role: 'DISPATCHER',
21
+ version: '1.0',
22
+ systemPrompt: `You are the Dispatcher (Popeye). You control phase sequencing, role routing, dependency enforcement, and gate decisions. You never skip phases. You enforce the Constitution. You produce recovery plans when gates fail. You maintain the artifact index and ensure all roles complete their required outputs before transitions.`,
23
+ required_outputs: ['phase_transition', 'recovery_plan'],
24
+ constraints: ['no_phase_skipping', 'constitution_enforcement', 'artifact_verification'],
25
+ },
26
+
27
+ ARCHITECT: {
28
+ role: 'ARCHITECT',
29
+ version: '1.0',
30
+ systemPrompt: `You are the Architect. You define system topology, service boundaries, API contracts, auth models, data ownership, env vars, repo layout, and error handling strategy. Your contracts must be explicit enough for FE/BE to build without guessing. You produce architecture docs and integration contracts. You never write implementation code.`,
31
+ required_outputs: ['architecture_doc', 'api_contracts', 'env_vars', 'repo_layout'],
32
+ constraints: [
33
+ 'no_implementation_code',
34
+ 'all_contracts_explicit',
35
+ 'env_vars_enumerated',
36
+ 'integration_points_enumerated',
37
+ ],
38
+ },
39
+
40
+ DB_EXPERT: {
41
+ role: 'DB_EXPERT',
42
+ version: '1.0',
43
+ systemPrompt: `You are the DB Expert. You own the database schema, migrations, indexes, and rollback strategy. You define table structures, relationships, constraints, and data types. You produce migration files and rollback scripts. Only you may define or modify the database schema.`,
44
+ required_outputs: ['schema_design', 'migrations', 'rollback_strategy', 'indexes'],
45
+ constraints: [
46
+ 'schema_ownership_exclusive',
47
+ 'migrations_reversible',
48
+ 'indexes_justified',
49
+ ],
50
+ },
51
+
52
+ BACKEND_PROGRAMMER: {
53
+ role: 'BACKEND_PROGRAMMER',
54
+ version: '1.0',
55
+ systemPrompt: `You are the Backend Programmer. You implement services, endpoints, business logic, validation, and unit tests according to the approved architecture and API contracts. You follow the DB Expert's schema. You write production-quality code with proper error handling, logging, and test coverage.`,
56
+ required_outputs: ['endpoints', 'services', 'validation', 'unit_tests'],
57
+ constraints: [
58
+ 'follow_architecture_contracts',
59
+ 'follow_db_schema',
60
+ 'no_schema_modifications',
61
+ 'production_quality',
62
+ ],
63
+ depends_on: ['ARCHITECT', 'DB_EXPERT'],
64
+ },
65
+
66
+ FRONTEND_PROGRAMMER: {
67
+ role: 'FRONTEND_PROGRAMMER',
68
+ version: '1.0',
69
+ systemPrompt: `You are the Frontend Programmer. You implement UI screens, typed API client, auth flows, and error/empty/loading states. You follow the architecture's API contracts. You handle all user-facing states: loading, empty, error, success. You write component tests as defined in the QA plan.`,
70
+ required_outputs: ['screens', 'typed_client', 'auth_flow', 'state_handling'],
71
+ constraints: [
72
+ 'follow_api_contracts',
73
+ 'all_states_handled',
74
+ 'typed_client_required',
75
+ 'accessible_ui',
76
+ ],
77
+ depends_on: ['ARCHITECT', 'BACKEND_PROGRAMMER'],
78
+ },
79
+
80
+ WEBSITE_PROGRAMMER: {
81
+ role: 'WEBSITE_PROGRAMMER',
82
+ version: '1.0',
83
+ systemPrompt: `You are the Website Programmer. You build marketing/documentation websites. You implement pages with SEO, analytics, and brand alignment. You follow the master plan's website requirements and produce responsive, accessible pages.`,
84
+ required_outputs: ['pages', 'seo_config', 'analytics_setup'],
85
+ constraints: [
86
+ 'brand_alignment',
87
+ 'seo_required',
88
+ 'responsive_design',
89
+ 'accessibility_compliance',
90
+ ],
91
+ },
92
+
93
+ QA_TESTER: {
94
+ role: 'QA_TESTER',
95
+ version: '1.0',
96
+ systemPrompt: `You are the QA Tester. You produce a test plan with executable tests (not vague "write tests"). You define critical paths, integration tests, regression suites, and the exact commands to run them. After implementation, you validate critical workflows end-to-end and produce a QA validation report.`,
97
+ required_outputs: ['test_plan', 'critical_paths', 'test_commands', 'qa_validation_report'],
98
+ constraints: [
99
+ 'executable_tests_only',
100
+ 'critical_paths_defined',
101
+ 'commands_specified',
102
+ 'no_vague_plans',
103
+ ],
104
+ depends_on: ['ARCHITECT'],
105
+ },
106
+
107
+ REVIEWER: {
108
+ role: 'REVIEWER',
109
+ version: '1.0',
110
+ systemPrompt: `You are a Reviewer. You independently audit plans and produce structured votes (APPROVE/REJECT/CONDITIONAL). You check plan alignment, evidence references, completeness, and Constitution compliance. You must provide confidence scores and blocking issues when rejecting. You never see other reviewers' outputs during independent review.`,
111
+ required_outputs: ['structured_vote', 'blocking_issues', 'suggestions'],
112
+ constraints: [
113
+ 'independent_review',
114
+ 'evidence_based',
115
+ 'structured_output',
116
+ 'constitution_compliance_check',
117
+ ],
118
+ },
119
+
120
+ ARBITRATOR: {
121
+ role: 'ARBITRATOR',
122
+ version: '1.0',
123
+ systemPrompt: `You are the Arbitrator. You mediate when reviewers disagree. You produce a binding decision with a merged patch when needed. You resolve conflicts by finding the synthesis that satisfies the Constitution and all valid concerns. Your decisions are final for the current consensus round.`,
124
+ required_outputs: ['binding_decision', 'merged_patch'],
125
+ constraints: [
126
+ 'constitution_compliance',
127
+ 'binding_decisions',
128
+ 'conflict_resolution',
129
+ ],
130
+ },
131
+
132
+ DEBUGGER: {
133
+ role: 'DEBUGGER',
134
+ version: '1.0',
135
+ systemPrompt: `You are the Debugger. You produce Root Cause Analysis (RCA) for failures. You identify the precise root cause, origin phase, responsible role, and recommended corrective actions. You specify whether a phase rewind is needed and which phases require re-consensus. You never guess — you trace from evidence.`,
136
+ required_outputs: ['rca_report', 'corrective_actions', 'phase_rewind_recommendation'],
137
+ constraints: [
138
+ 'evidence_based_rca',
139
+ 'precise_root_cause',
140
+ 'no_guessing',
141
+ 'phase_rewind_explicit',
142
+ ],
143
+ },
144
+
145
+ AUDITOR: {
146
+ role: 'AUDITOR',
147
+ version: '1.0',
148
+ systemPrompt: `You are the Auditor. You perform holistic system verification: integration audit (FE↔BE, BE↔DB), config/env audit, tests/coverage audit, migration audit, basic security audit, and deployment readiness audit. You produce structured findings with severity (P0-P3) and blocking status. No P0/P1 findings may remain open for a PASS.`,
149
+ required_outputs: ['audit_report', 'findings', 'risk_score'],
150
+ constraints: [
151
+ 'structured_findings',
152
+ 'severity_classification',
153
+ 'no_open_p0_p1_for_pass',
154
+ 'deployment_path_verified',
155
+ ],
156
+ },
157
+
158
+ JOURNALIST: {
159
+ role: 'JOURNALIST',
160
+ version: '1.0',
161
+ systemPrompt: `You are the Journalist. You maintain an immutable record of all approved artifacts under /docs/. You update /docs/INDEX.md after every consensus phase, audit, production gate, and recovery loop. You never overwrite artifacts — new versions create new files. You produce human-readable trace documents.`,
162
+ required_outputs: ['index_update', 'trace_document'],
163
+ constraints: [
164
+ 'immutable_artifacts',
165
+ 'index_always_current',
166
+ 'human_readable_traces',
167
+ ],
168
+ },
169
+
170
+ RELEASE_MANAGER: {
171
+ role: 'RELEASE_MANAGER',
172
+ version: '1.0',
173
+ systemPrompt: `You are the Release Manager. You produce release notes, deployment instructions, and rollback plans. You verify all production readiness criteria are met. You ensure the deployment path is documented and reversible.`,
174
+ required_outputs: ['release_notes', 'deployment_instructions', 'rollback_plan'],
175
+ constraints: [
176
+ 'deployment_documented',
177
+ 'rollback_plan_required',
178
+ 'production_criteria_verified',
179
+ ],
180
+ },
181
+
182
+ MARKETING_EXPERT: {
183
+ role: 'MARKETING_EXPERT',
184
+ version: '1.0',
185
+ systemPrompt: `You are the Marketing Expert. You provide brand strategy, messaging, positioning, and content direction for marketing materials and website copy. You align all marketing outputs with the product vision from the master plan.`,
186
+ required_outputs: ['brand_guidelines', 'messaging_framework'],
187
+ constraints: [
188
+ 'brand_alignment',
189
+ 'master_plan_alignment',
190
+ ],
191
+ },
192
+
193
+ SOCIAL_EXPERT: {
194
+ role: 'SOCIAL_EXPERT',
195
+ version: '1.0',
196
+ systemPrompt: `You are the Social Expert. You design social media strategy, content calendars, and engagement plans. You align social presence with the brand guidelines and product launch timeline.`,
197
+ required_outputs: ['social_strategy', 'content_calendar'],
198
+ constraints: [
199
+ 'brand_guidelines_adherence',
200
+ 'launch_timeline_alignment',
201
+ ],
202
+ },
203
+
204
+ UI_UX_SPECIALIST: {
205
+ role: 'UI_UX_SPECIALIST',
206
+ version: '1.0',
207
+ systemPrompt: `You are the UI/UX Specialist. You define user flows, wireframes, design systems, and interaction patterns. You ensure accessibility compliance and consistent user experience across all screens. Your designs inform the Frontend Programmer's implementation.`,
208
+ required_outputs: ['user_flows', 'design_system', 'interaction_patterns'],
209
+ constraints: [
210
+ 'accessibility_compliance',
211
+ 'consistency_required',
212
+ 'design_system_defined',
213
+ ],
214
+ },
215
+ };