popeye-cli 1.10.0 → 2.0.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 (253) hide show
  1. package/CHANGELOG.md +59 -0
  2. package/CONTRIBUTING.md +15 -1
  3. package/README.md +57 -0
  4. package/dist/pipeline/artifact-manager.d.ts +47 -0
  5. package/dist/pipeline/artifact-manager.d.ts.map +1 -0
  6. package/dist/pipeline/artifact-manager.js +251 -0
  7. package/dist/pipeline/artifact-manager.js.map +1 -0
  8. package/dist/pipeline/artifact-validators.d.ts +29 -0
  9. package/dist/pipeline/artifact-validators.d.ts.map +1 -0
  10. package/dist/pipeline/artifact-validators.js +173 -0
  11. package/dist/pipeline/artifact-validators.js.map +1 -0
  12. package/dist/pipeline/change-request.d.ts +47 -0
  13. package/dist/pipeline/change-request.d.ts.map +1 -0
  14. package/dist/pipeline/change-request.js +91 -0
  15. package/dist/pipeline/change-request.js.map +1 -0
  16. package/dist/pipeline/check-runner.d.ts +47 -0
  17. package/dist/pipeline/check-runner.d.ts.map +1 -0
  18. package/dist/pipeline/check-runner.js +417 -0
  19. package/dist/pipeline/check-runner.js.map +1 -0
  20. package/dist/pipeline/command-resolver.d.ts +9 -0
  21. package/dist/pipeline/command-resolver.d.ts.map +1 -0
  22. package/dist/pipeline/command-resolver.js +140 -0
  23. package/dist/pipeline/command-resolver.js.map +1 -0
  24. package/dist/pipeline/consensus/consensus-runner.d.ts +44 -0
  25. package/dist/pipeline/consensus/consensus-runner.d.ts.map +1 -0
  26. package/dist/pipeline/consensus/consensus-runner.js +212 -0
  27. package/dist/pipeline/consensus/consensus-runner.js.map +1 -0
  28. package/dist/pipeline/constitution.d.ts +45 -0
  29. package/dist/pipeline/constitution.d.ts.map +1 -0
  30. package/dist/pipeline/constitution.js +82 -0
  31. package/dist/pipeline/constitution.js.map +1 -0
  32. package/dist/pipeline/gate-engine.d.ts +55 -0
  33. package/dist/pipeline/gate-engine.d.ts.map +1 -0
  34. package/dist/pipeline/gate-engine.js +270 -0
  35. package/dist/pipeline/gate-engine.js.map +1 -0
  36. package/dist/pipeline/index.d.ts +26 -0
  37. package/dist/pipeline/index.d.ts.map +1 -0
  38. package/dist/pipeline/index.js +35 -0
  39. package/dist/pipeline/index.js.map +1 -0
  40. package/dist/pipeline/migration.d.ts +15 -0
  41. package/dist/pipeline/migration.d.ts.map +1 -0
  42. package/dist/pipeline/migration.js +76 -0
  43. package/dist/pipeline/migration.js.map +1 -0
  44. package/dist/pipeline/orchestrator.d.ts +28 -0
  45. package/dist/pipeline/orchestrator.d.ts.map +1 -0
  46. package/dist/pipeline/orchestrator.js +238 -0
  47. package/dist/pipeline/orchestrator.js.map +1 -0
  48. package/dist/pipeline/packets/audit-report-builder.d.ts +11 -0
  49. package/dist/pipeline/packets/audit-report-builder.d.ts.map +1 -0
  50. package/dist/pipeline/packets/audit-report-builder.js +32 -0
  51. package/dist/pipeline/packets/audit-report-builder.js.map +1 -0
  52. package/dist/pipeline/packets/consensus-packet-builder.d.ts +35 -0
  53. package/dist/pipeline/packets/consensus-packet-builder.d.ts.map +1 -0
  54. package/dist/pipeline/packets/consensus-packet-builder.js +80 -0
  55. package/dist/pipeline/packets/consensus-packet-builder.js.map +1 -0
  56. package/dist/pipeline/packets/index.d.ts +12 -0
  57. package/dist/pipeline/packets/index.d.ts.map +1 -0
  58. package/dist/pipeline/packets/index.js +8 -0
  59. package/dist/pipeline/packets/index.js.map +1 -0
  60. package/dist/pipeline/packets/plan-packet-builder.d.ts +21 -0
  61. package/dist/pipeline/packets/plan-packet-builder.d.ts.map +1 -0
  62. package/dist/pipeline/packets/plan-packet-builder.js +27 -0
  63. package/dist/pipeline/packets/plan-packet-builder.js.map +1 -0
  64. package/dist/pipeline/packets/rca-packet-builder.d.ts +19 -0
  65. package/dist/pipeline/packets/rca-packet-builder.d.ts.map +1 -0
  66. package/dist/pipeline/packets/rca-packet-builder.js +22 -0
  67. package/dist/pipeline/packets/rca-packet-builder.js.map +1 -0
  68. package/dist/pipeline/phases/architecture.d.ts +7 -0
  69. package/dist/pipeline/phases/architecture.d.ts.map +1 -0
  70. package/dist/pipeline/phases/architecture.js +60 -0
  71. package/dist/pipeline/phases/architecture.js.map +1 -0
  72. package/dist/pipeline/phases/audit.d.ts +8 -0
  73. package/dist/pipeline/phases/audit.d.ts.map +1 -0
  74. package/dist/pipeline/phases/audit.js +144 -0
  75. package/dist/pipeline/phases/audit.js.map +1 -0
  76. package/dist/pipeline/phases/consensus-architecture.d.ts +7 -0
  77. package/dist/pipeline/phases/consensus-architecture.d.ts.map +1 -0
  78. package/dist/pipeline/phases/consensus-architecture.js +84 -0
  79. package/dist/pipeline/phases/consensus-architecture.js.map +1 -0
  80. package/dist/pipeline/phases/consensus-master-plan.d.ts +7 -0
  81. package/dist/pipeline/phases/consensus-master-plan.d.ts.map +1 -0
  82. package/dist/pipeline/phases/consensus-master-plan.js +81 -0
  83. package/dist/pipeline/phases/consensus-master-plan.js.map +1 -0
  84. package/dist/pipeline/phases/consensus-role-plans.d.ts +7 -0
  85. package/dist/pipeline/phases/consensus-role-plans.d.ts.map +1 -0
  86. package/dist/pipeline/phases/consensus-role-plans.js +85 -0
  87. package/dist/pipeline/phases/consensus-role-plans.js.map +1 -0
  88. package/dist/pipeline/phases/done.d.ts +7 -0
  89. package/dist/pipeline/phases/done.d.ts.map +1 -0
  90. package/dist/pipeline/phases/done.js +45 -0
  91. package/dist/pipeline/phases/done.js.map +1 -0
  92. package/dist/pipeline/phases/implementation.d.ts +8 -0
  93. package/dist/pipeline/phases/implementation.d.ts.map +1 -0
  94. package/dist/pipeline/phases/implementation.js +42 -0
  95. package/dist/pipeline/phases/implementation.js.map +1 -0
  96. package/dist/pipeline/phases/index.d.ts +20 -0
  97. package/dist/pipeline/phases/index.d.ts.map +1 -0
  98. package/dist/pipeline/phases/index.js +19 -0
  99. package/dist/pipeline/phases/index.js.map +1 -0
  100. package/dist/pipeline/phases/intake.d.ts +8 -0
  101. package/dist/pipeline/phases/intake.d.ts.map +1 -0
  102. package/dist/pipeline/phases/intake.js +40 -0
  103. package/dist/pipeline/phases/intake.js.map +1 -0
  104. package/dist/pipeline/phases/phase-context.d.ts +30 -0
  105. package/dist/pipeline/phases/phase-context.d.ts.map +1 -0
  106. package/dist/pipeline/phases/phase-context.js +33 -0
  107. package/dist/pipeline/phases/phase-context.js.map +1 -0
  108. package/dist/pipeline/phases/production-gate.d.ts +8 -0
  109. package/dist/pipeline/phases/production-gate.d.ts.map +1 -0
  110. package/dist/pipeline/phases/production-gate.js +84 -0
  111. package/dist/pipeline/phases/production-gate.js.map +1 -0
  112. package/dist/pipeline/phases/qa-validation.d.ts +7 -0
  113. package/dist/pipeline/phases/qa-validation.d.ts.map +1 -0
  114. package/dist/pipeline/phases/qa-validation.js +50 -0
  115. package/dist/pipeline/phases/qa-validation.js.map +1 -0
  116. package/dist/pipeline/phases/recovery-loop.d.ts +7 -0
  117. package/dist/pipeline/phases/recovery-loop.d.ts.map +1 -0
  118. package/dist/pipeline/phases/recovery-loop.js +91 -0
  119. package/dist/pipeline/phases/recovery-loop.js.map +1 -0
  120. package/dist/pipeline/phases/review.d.ts +8 -0
  121. package/dist/pipeline/phases/review.d.ts.map +1 -0
  122. package/dist/pipeline/phases/review.js +127 -0
  123. package/dist/pipeline/phases/review.js.map +1 -0
  124. package/dist/pipeline/phases/role-planning.d.ts +7 -0
  125. package/dist/pipeline/phases/role-planning.d.ts.map +1 -0
  126. package/dist/pipeline/phases/role-planning.js +75 -0
  127. package/dist/pipeline/phases/role-planning.js.map +1 -0
  128. package/dist/pipeline/phases/stuck.d.ts +7 -0
  129. package/dist/pipeline/phases/stuck.d.ts.map +1 -0
  130. package/dist/pipeline/phases/stuck.js +51 -0
  131. package/dist/pipeline/phases/stuck.js.map +1 -0
  132. package/dist/pipeline/repo-snapshot.d.ts +24 -0
  133. package/dist/pipeline/repo-snapshot.d.ts.map +1 -0
  134. package/dist/pipeline/repo-snapshot.js +343 -0
  135. package/dist/pipeline/repo-snapshot.js.map +1 -0
  136. package/dist/pipeline/role-execution-adapter.d.ts +59 -0
  137. package/dist/pipeline/role-execution-adapter.d.ts.map +1 -0
  138. package/dist/pipeline/role-execution-adapter.js +159 -0
  139. package/dist/pipeline/role-execution-adapter.js.map +1 -0
  140. package/dist/pipeline/skill-loader.d.ts +34 -0
  141. package/dist/pipeline/skill-loader.d.ts.map +1 -0
  142. package/dist/pipeline/skill-loader.js +156 -0
  143. package/dist/pipeline/skill-loader.js.map +1 -0
  144. package/dist/pipeline/skills/defaults.d.ts +16 -0
  145. package/dist/pipeline/skills/defaults.d.ts.map +1 -0
  146. package/dist/pipeline/skills/defaults.js +189 -0
  147. package/dist/pipeline/skills/defaults.js.map +1 -0
  148. package/dist/pipeline/type-defs/artifacts.d.ts +202 -0
  149. package/dist/pipeline/type-defs/artifacts.d.ts.map +1 -0
  150. package/dist/pipeline/type-defs/artifacts.js +66 -0
  151. package/dist/pipeline/type-defs/artifacts.js.map +1 -0
  152. package/dist/pipeline/type-defs/audit.d.ts +256 -0
  153. package/dist/pipeline/type-defs/audit.d.ts.map +1 -0
  154. package/dist/pipeline/type-defs/audit.js +54 -0
  155. package/dist/pipeline/type-defs/audit.js.map +1 -0
  156. package/dist/pipeline/type-defs/checks.d.ts +81 -0
  157. package/dist/pipeline/type-defs/checks.d.ts.map +1 -0
  158. package/dist/pipeline/type-defs/checks.js +38 -0
  159. package/dist/pipeline/type-defs/checks.js.map +1 -0
  160. package/dist/pipeline/type-defs/enums.d.ts +43 -0
  161. package/dist/pipeline/type-defs/enums.d.ts.map +1 -0
  162. package/dist/pipeline/type-defs/enums.js +55 -0
  163. package/dist/pipeline/type-defs/enums.js.map +1 -0
  164. package/dist/pipeline/type-defs/index.d.ts +12 -0
  165. package/dist/pipeline/type-defs/index.d.ts.map +1 -0
  166. package/dist/pipeline/type-defs/index.js +12 -0
  167. package/dist/pipeline/type-defs/index.js.map +1 -0
  168. package/dist/pipeline/type-defs/packets.d.ts +806 -0
  169. package/dist/pipeline/type-defs/packets.d.ts.map +1 -0
  170. package/dist/pipeline/type-defs/packets.js +109 -0
  171. package/dist/pipeline/type-defs/packets.js.map +1 -0
  172. package/dist/pipeline/type-defs/snapshot.d.ts +52 -0
  173. package/dist/pipeline/type-defs/snapshot.d.ts.map +1 -0
  174. package/dist/pipeline/type-defs/snapshot.js +35 -0
  175. package/dist/pipeline/type-defs/snapshot.js.map +1 -0
  176. package/dist/pipeline/type-defs/state.d.ts +449 -0
  177. package/dist/pipeline/type-defs/state.d.ts.map +1 -0
  178. package/dist/pipeline/type-defs/state.js +88 -0
  179. package/dist/pipeline/type-defs/state.js.map +1 -0
  180. package/dist/pipeline/types.d.ts +16 -0
  181. package/dist/pipeline/types.d.ts.map +1 -0
  182. package/dist/pipeline/types.js +16 -0
  183. package/dist/pipeline/types.js.map +1 -0
  184. package/dist/types/audit.d.ts +6 -6
  185. package/dist/workflow/index.d.ts.map +1 -1
  186. package/dist/workflow/index.js +48 -0
  187. package/dist/workflow/index.js.map +1 -1
  188. package/package.json +1 -1
  189. package/skills/PHASE_GATE_ENGINE_SPEC.md +113 -20
  190. package/skills/POPEYE_FULL_AUTONOMY_PIPELINE.md +66 -13
  191. package/src/pipeline/artifact-manager.ts +339 -0
  192. package/src/pipeline/artifact-validators.ts +224 -0
  193. package/src/pipeline/change-request.ts +119 -0
  194. package/src/pipeline/check-runner.ts +504 -0
  195. package/src/pipeline/command-resolver.ts +168 -0
  196. package/src/pipeline/consensus/consensus-runner.ts +317 -0
  197. package/src/pipeline/constitution.ts +109 -0
  198. package/src/pipeline/gate-engine.ts +347 -0
  199. package/src/pipeline/index.ts +82 -0
  200. package/src/pipeline/migration.ts +91 -0
  201. package/src/pipeline/orchestrator.ts +314 -0
  202. package/src/pipeline/packets/audit-report-builder.ts +47 -0
  203. package/src/pipeline/packets/consensus-packet-builder.ts +112 -0
  204. package/src/pipeline/packets/index.ts +15 -0
  205. package/src/pipeline/packets/plan-packet-builder.ts +52 -0
  206. package/src/pipeline/packets/rca-packet-builder.ts +38 -0
  207. package/src/pipeline/phases/architecture.ts +73 -0
  208. package/src/pipeline/phases/audit.ts +193 -0
  209. package/src/pipeline/phases/consensus-architecture.ts +104 -0
  210. package/src/pipeline/phases/consensus-master-plan.ts +100 -0
  211. package/src/pipeline/phases/consensus-role-plans.ts +105 -0
  212. package/src/pipeline/phases/done.ts +68 -0
  213. package/src/pipeline/phases/implementation.ts +48 -0
  214. package/src/pipeline/phases/index.ts +21 -0
  215. package/src/pipeline/phases/intake.ts +54 -0
  216. package/src/pipeline/phases/phase-context.ts +86 -0
  217. package/src/pipeline/phases/production-gate.ts +113 -0
  218. package/src/pipeline/phases/qa-validation.ts +63 -0
  219. package/src/pipeline/phases/recovery-loop.ts +118 -0
  220. package/src/pipeline/phases/review.ts +149 -0
  221. package/src/pipeline/phases/role-planning.ts +92 -0
  222. package/src/pipeline/phases/stuck.ts +62 -0
  223. package/src/pipeline/repo-snapshot.ts +395 -0
  224. package/src/pipeline/role-execution-adapter.ts +238 -0
  225. package/src/pipeline/skill-loader.ts +192 -0
  226. package/src/pipeline/skills/defaults.ts +215 -0
  227. package/src/pipeline/type-defs/artifacts.ts +81 -0
  228. package/src/pipeline/type-defs/audit.ts +67 -0
  229. package/src/pipeline/type-defs/checks.ts +47 -0
  230. package/src/pipeline/type-defs/enums.ts +62 -0
  231. package/src/pipeline/type-defs/index.ts +12 -0
  232. package/src/pipeline/type-defs/packets.ts +131 -0
  233. package/src/pipeline/type-defs/snapshot.ts +55 -0
  234. package/src/pipeline/type-defs/state.ts +165 -0
  235. package/src/pipeline/types.ts +16 -0
  236. package/src/workflow/index.ts +48 -0
  237. package/tests/pipeline/artifact-manager.test.ts +183 -0
  238. package/tests/pipeline/artifact-validators.test.ts +207 -0
  239. package/tests/pipeline/change-request.test.ts +180 -0
  240. package/tests/pipeline/check-runner.test.ts +157 -0
  241. package/tests/pipeline/command-resolver.test.ts +159 -0
  242. package/tests/pipeline/consensus-runner.test.ts +206 -0
  243. package/tests/pipeline/consensus-scoring.test.ts +163 -0
  244. package/tests/pipeline/constitution.test.ts +122 -0
  245. package/tests/pipeline/gate-engine.test.ts +195 -0
  246. package/tests/pipeline/migration.test.ts +133 -0
  247. package/tests/pipeline/orchestrator.test.ts +614 -0
  248. package/tests/pipeline/packets/builders.test.ts +347 -0
  249. package/tests/pipeline/repo-snapshot.test.ts +189 -0
  250. package/tests/pipeline/role-execution-adapter.test.ts +299 -0
  251. package/tests/pipeline/skill-loader.test.ts +186 -0
  252. package/tests/pipeline/start-env-checks.test.ts +123 -0
  253. package/tests/pipeline/types.test.ts +156 -0
@@ -0,0 +1,193 @@
1
+ /**
2
+ * AUDIT phase — holistic system verification before Production Gate.
3
+ * Creates structured AuditReport with AuditFindings (P2-1).
4
+ * v1.1: Creates Change Requests for architectural findings.
5
+ */
6
+
7
+ import type { PhaseContext, PhaseResult } from './phase-context.js';
8
+ import { successResult, failureResult, triggerJournalist } from './phase-context.js';
9
+ import { buildAuditReport } from '../packets/audit-report-builder.js';
10
+ import { generateRepoSnapshot, createSnapshotArtifact } from '../repo-snapshot.js';
11
+ import { buildChangeRequest, formatChangeRequest, routeChangeRequest } from '../change-request.js';
12
+ import type { AuditFinding, ArtifactEntry, ChangeRequest } from '../types.js';
13
+ import type { ArtifactManager } from '../artifact-manager.js';
14
+
15
+ export async function runAudit(context: PhaseContext): Promise<PhaseResult> {
16
+ const { pipeline, artifactManager, skillLoader, projectDir } = context;
17
+ const artifacts = [];
18
+
19
+ try {
20
+ // 1. Fresh repo snapshot
21
+ const snapshot = await generateRepoSnapshot(projectDir);
22
+ const snapshotEntry = createSnapshotArtifact(snapshot, artifactManager, 'AUDIT');
23
+ artifacts.push(snapshotEntry);
24
+ pipeline.latestRepoSnapshot = artifactManager.toArtifactRef(snapshotEntry);
25
+
26
+ // 2. Load auditor skill
27
+ const auditorSkill = skillLoader.loadSkill('AUDITOR');
28
+
29
+ // 3. Run audit checks via Claude
30
+ const { executePrompt } = await import('../../adapters/claude.js');
31
+ const auditPrompt = [
32
+ auditorSkill.systemPrompt,
33
+ '',
34
+ '## Audit Instructions',
35
+ 'Perform a holistic system audit covering:',
36
+ '1. Integration audit (FE<->BE, BE<->DB)',
37
+ '2. Config/env audit',
38
+ '3. Tests/coverage audit',
39
+ '4. Migration audit',
40
+ '5. Basic security audit',
41
+ '6. Deployment readiness audit',
42
+ '',
43
+ 'For each finding, classify severity as P0/P1/P2/P3.',
44
+ 'Mark blocking findings that must be resolved before production.',
45
+ '',
46
+ `## Repo Snapshot`,
47
+ `Total files: ${snapshot.total_files}`,
48
+ `Languages: ${snapshot.languages_detected.join(', ')}`,
49
+ `Test framework: ${snapshot.test_framework ?? 'none'}`,
50
+ `Build tool: ${snapshot.build_tool ?? 'none'}`,
51
+ ].join('\n');
52
+
53
+ const auditResult = await executePrompt(auditPrompt);
54
+ const auditResponse = auditResult.response;
55
+
56
+ // 4. Parse findings from audit response (simplified extraction)
57
+ const findings = parseAuditFindings(auditResponse);
58
+
59
+ // 5. Build structured audit report
60
+ const auditReport = buildAuditReport({
61
+ repoSnapshot: artifactManager.toArtifactRef(snapshotEntry),
62
+ findings,
63
+ });
64
+
65
+ // 6. Store audit report
66
+ const auditEntry = artifactManager.createAndStoreJson(
67
+ 'audit_report',
68
+ auditReport,
69
+ 'AUDIT',
70
+ );
71
+ artifacts.push(auditEntry);
72
+
73
+ // Also store the raw audit text
74
+ const auditTextEntry = artifactManager.createAndStoreText(
75
+ 'audit_report',
76
+ auditResponse,
77
+ 'AUDIT',
78
+ );
79
+ artifacts.push(auditTextEntry);
80
+
81
+ // 7. v1.1: Create change requests for architectural findings
82
+ const changeRequests = createAuditChangeRequests(findings, artifactManager, snapshotEntry);
83
+ for (const cr of changeRequests) {
84
+ const crEntry = artifactManager.createAndStoreText(
85
+ 'change_request',
86
+ formatChangeRequest(cr),
87
+ 'AUDIT',
88
+ );
89
+ artifacts.push(crEntry);
90
+
91
+ // Register CR in pipeline state for orchestrator routing
92
+ if (!pipeline.pendingChangeRequests) {
93
+ pipeline.pendingChangeRequests = [];
94
+ }
95
+ pipeline.pendingChangeRequests.push({
96
+ cr_id: cr.cr_id,
97
+ change_type: cr.change_type,
98
+ target_phase: routeChangeRequest(cr),
99
+ status: 'proposed',
100
+ });
101
+ }
102
+
103
+ pipeline.artifacts.push(...artifacts);
104
+
105
+ // 8. Journalist trigger
106
+ await triggerJournalist('AUDIT', artifacts, context);
107
+
108
+ return successResult(
109
+ 'AUDIT',
110
+ artifacts,
111
+ `Audit ${auditReport.overall_status}: ${findings.length} findings, risk score ${auditReport.system_risk_score}, ${changeRequests.length} CRs`,
112
+ );
113
+ } catch (err) {
114
+ const message = err instanceof Error ? err.message : 'Unknown error';
115
+ return failureResult('AUDIT', 'Audit failed', message);
116
+ }
117
+ }
118
+
119
+ /** Parse audit findings from LLM response (best-effort) */
120
+ function parseAuditFindings(response: string): AuditFinding[] {
121
+ const findings: AuditFinding[] = [];
122
+ const lines = response.split('\n');
123
+ let findingCount = 0;
124
+
125
+ for (const line of lines) {
126
+ // Look for severity markers: P0, P1, P2, P3
127
+ const severityMatch = line.match(/\b(P[0-3])\b/);
128
+ if (severityMatch) {
129
+ findingCount++;
130
+ const severity = severityMatch[1] as 'P0' | 'P1' | 'P2' | 'P3';
131
+ findings.push({
132
+ id: `finding-${findingCount}`,
133
+ severity,
134
+ category: 'integration', // Default; would be refined with better parsing
135
+ description: line.trim(),
136
+ evidence: [],
137
+ suggested_owner: 'DISPATCHER',
138
+ blocking: severity === 'P0' || severity === 'P1',
139
+ });
140
+ }
141
+ }
142
+
143
+ return findings;
144
+ }
145
+
146
+ /** Create change requests for high-severity audit findings (v1.1) */
147
+ function createAuditChangeRequests(
148
+ findings: AuditFinding[],
149
+ artifactManager: ArtifactManager,
150
+ snapshotEntry: ArtifactEntry,
151
+ ): ChangeRequest[] {
152
+ const changeRequests: ChangeRequest[] = [];
153
+
154
+ // Create CRs for blocking findings in integration/schema categories
155
+ const architecturalFindings = findings.filter(
156
+ (f) => f.blocking && (f.category === 'integration' || f.category === 'schema'),
157
+ );
158
+
159
+ if (architecturalFindings.length > 0) {
160
+ const cr = buildChangeRequest({
161
+ originPhase: 'AUDIT',
162
+ requestedBy: 'AUDITOR',
163
+ changeType: 'architecture',
164
+ description: `${architecturalFindings.length} blocking architectural findings: ${architecturalFindings.map((f) => f.description.slice(0, 80)).join('; ')}`,
165
+ justification: 'Blocking audit findings require architectural review before production',
166
+ affectedArtifacts: [artifactManager.toArtifactRef(snapshotEntry)],
167
+ affectedPhases: ['CONSENSUS_ARCHITECTURE', 'IMPLEMENTATION'],
168
+ riskLevel: architecturalFindings.some((f) => f.severity === 'P0') ? 'high' : 'medium',
169
+ });
170
+ changeRequests.push(cr);
171
+ }
172
+
173
+ // Create CRs for security findings
174
+ const securityFindings = findings.filter(
175
+ (f) => f.blocking && f.category === 'security',
176
+ );
177
+
178
+ if (securityFindings.length > 0) {
179
+ const cr = buildChangeRequest({
180
+ originPhase: 'AUDIT',
181
+ requestedBy: 'AUDITOR',
182
+ changeType: 'requirement',
183
+ description: `${securityFindings.length} blocking security findings require review`,
184
+ justification: 'Security issues must be resolved before production deployment',
185
+ affectedArtifacts: [artifactManager.toArtifactRef(snapshotEntry)],
186
+ affectedPhases: ['CONSENSUS_MASTER_PLAN', 'IMPLEMENTATION'],
187
+ riskLevel: 'high',
188
+ });
189
+ changeRequests.push(cr);
190
+ }
191
+
192
+ return changeRequests;
193
+ }
@@ -0,0 +1,104 @@
1
+ /**
2
+ * CONSENSUS_ARCHITECTURE phase — validate architecture is feasible,
3
+ * consistent, and complete. Same pattern as consensus-master-plan.
4
+ */
5
+
6
+ import type { PhaseContext, PhaseResult } from './phase-context.js';
7
+ import { successResult, failureResult, triggerJournalist } from './phase-context.js';
8
+ import { buildPlanPacket } from '../packets/plan-packet-builder.js';
9
+ import { generateRepoSnapshot, createSnapshotArtifact } from '../repo-snapshot.js';
10
+ import type { PipelineState, ArtifactRef } from '../types.js';
11
+
12
+ /** Get constitution artifact ref from pipeline state, or fallback */
13
+ function getConstitutionRef(pipeline: PipelineState): ArtifactRef {
14
+ const constitutionArtifact = pipeline.artifacts.find((a) => a.type === 'constitution');
15
+ if (constitutionArtifact) {
16
+ return {
17
+ artifact_id: constitutionArtifact.id,
18
+ path: constitutionArtifact.path,
19
+ sha256: constitutionArtifact.sha256,
20
+ version: constitutionArtifact.version,
21
+ type: 'constitution',
22
+ };
23
+ }
24
+ return { artifact_id: 'constitution', path: 'skills/POPEYE_CONSTITUTION.md', sha256: '', version: 1, type: 'constitution' };
25
+ }
26
+
27
+ export async function runConsensusArchitecture(context: PhaseContext): Promise<PhaseResult> {
28
+ const { pipeline, artifactManager, gateEngine, consensusRunner, projectDir } = context;
29
+ const artifacts = [];
30
+
31
+ try {
32
+ // 1. Fresh repo snapshot
33
+ const snapshot = await generateRepoSnapshot(projectDir);
34
+ const snapshotEntry = createSnapshotArtifact(snapshot, artifactManager, 'CONSENSUS_ARCHITECTURE');
35
+ artifacts.push(snapshotEntry);
36
+ pipeline.latestRepoSnapshot = artifactManager.toArtifactRef(snapshotEntry);
37
+
38
+ // 2. Find architecture artifact
39
+ const archArtifact = pipeline.artifacts.find((a) => a.type === 'architecture');
40
+ if (!archArtifact) {
41
+ return failureResult('CONSENSUS_ARCHITECTURE', 'No architecture artifact found');
42
+ }
43
+
44
+ const masterPlanArtifact = pipeline.artifacts.find((a) => a.type === 'master_plan');
45
+
46
+ // 3. Build plan packet
47
+ const planPacket = buildPlanPacket({
48
+ phase: 'CONSENSUS_ARCHITECTURE',
49
+ submittedBy: 'ARCHITECT',
50
+ masterPlanRef: masterPlanArtifact
51
+ ? artifactManager.toArtifactRef(masterPlanArtifact)
52
+ : { artifact_id: 'none', path: '', sha256: '', version: 1, type: 'master_plan' },
53
+ constitutionRef: getConstitutionRef(pipeline),
54
+ repoSnapshotRef: artifactManager.toArtifactRef(snapshotEntry),
55
+ proposedArtifacts: [artifactManager.toArtifactRef(archArtifact)],
56
+ acceptanceCriteria: [
57
+ 'Contracts explicit enough for FE/BE to build without guessing',
58
+ 'Env vars enumerated',
59
+ 'Integration points enumerated',
60
+ 'No contradictory contracts',
61
+ ],
62
+ dependencies: [],
63
+ constraints: [],
64
+ });
65
+
66
+ // 4. Run consensus
67
+ const gateDef = gateEngine.getGateDefinition('CONSENSUS_ARCHITECTURE');
68
+ const consensusPacket = await consensusRunner.runStructuredConsensus(planPacket, gateDef);
69
+
70
+ // 5. Store consensus artifact
71
+ const consensusEntry = artifactManager.createAndStoreJson(
72
+ 'consensus',
73
+ consensusPacket,
74
+ 'CONSENSUS_ARCHITECTURE',
75
+ );
76
+ artifacts.push(consensusEntry);
77
+ pipeline.artifacts.push(...artifacts);
78
+
79
+ // 5b. Store consensus score in gateResults for parseConsensusScore()
80
+ pipeline.gateResults['CONSENSUS_ARCHITECTURE'] = {
81
+ phase: 'CONSENSUS_ARCHITECTURE',
82
+ pass: consensusPacket.final_status === 'APPROVED' || consensusPacket.final_status === 'ARBITRATED',
83
+ score: consensusPacket.consensus_result.weighted_score,
84
+ blockers: [],
85
+ missingArtifacts: [],
86
+ failedChecks: [],
87
+ consensusScore: consensusPacket.consensus_result.score,
88
+ timestamp: new Date().toISOString(),
89
+ };
90
+
91
+ // 6. Journalist trigger
92
+ await triggerJournalist('CONSENSUS_ARCHITECTURE', artifacts, context);
93
+
94
+ const approved = consensusPacket.final_status === 'APPROVED' || consensusPacket.final_status === 'ARBITRATED';
95
+ return successResult(
96
+ 'CONSENSUS_ARCHITECTURE',
97
+ artifacts,
98
+ approved ? 'Architecture consensus APPROVED' : 'Architecture consensus REJECTED',
99
+ );
100
+ } catch (err) {
101
+ const message = err instanceof Error ? err.message : 'Unknown error';
102
+ return failureResult('CONSENSUS_ARCHITECTURE', 'Architecture consensus failed', message);
103
+ }
104
+ }
@@ -0,0 +1,100 @@
1
+ /**
2
+ * CONSENSUS_MASTER_PLAN phase — multi-LLM validation of Master Plan.
3
+ * Uses independent review mode by default (P1-D).
4
+ */
5
+
6
+ import type { PhaseContext, PhaseResult } from './phase-context.js';
7
+ import { successResult, failureResult, triggerJournalist } from './phase-context.js';
8
+ import { buildPlanPacket } from '../packets/plan-packet-builder.js';
9
+ import { generateRepoSnapshot, createSnapshotArtifact } from '../repo-snapshot.js';
10
+ import type { PipelineState, ArtifactRef } from '../types.js';
11
+
12
+ /** Get constitution artifact ref from pipeline state, or fallback */
13
+ function getConstitutionRef(pipeline: PipelineState): ArtifactRef {
14
+ const constitutionArtifact = pipeline.artifacts.find((a) => a.type === 'constitution');
15
+ if (constitutionArtifact) {
16
+ return {
17
+ artifact_id: constitutionArtifact.id,
18
+ path: constitutionArtifact.path,
19
+ sha256: constitutionArtifact.sha256,
20
+ version: constitutionArtifact.version,
21
+ type: 'constitution',
22
+ };
23
+ }
24
+ return { artifact_id: 'constitution', path: 'skills/POPEYE_CONSTITUTION.md', sha256: '', version: 1, type: 'constitution' };
25
+ }
26
+
27
+ export async function runConsensusMasterPlan(context: PhaseContext): Promise<PhaseResult> {
28
+ const { pipeline, artifactManager, gateEngine, consensusRunner, projectDir } = context;
29
+ const artifacts = [];
30
+
31
+ try {
32
+ // 1. Fresh repo snapshot for consensus
33
+ const snapshot = await generateRepoSnapshot(projectDir);
34
+ const snapshotEntry = createSnapshotArtifact(snapshot, artifactManager, 'CONSENSUS_MASTER_PLAN');
35
+ artifacts.push(snapshotEntry);
36
+ pipeline.latestRepoSnapshot = artifactManager.toArtifactRef(snapshotEntry);
37
+
38
+ // 2. Find master plan artifact
39
+ const masterPlanArtifact = pipeline.artifacts.find((a) => a.type === 'master_plan');
40
+ if (!masterPlanArtifact) {
41
+ return failureResult('CONSENSUS_MASTER_PLAN', 'No master plan artifact found');
42
+ }
43
+
44
+ // 3. Build plan packet
45
+ const planPacket = buildPlanPacket({
46
+ phase: 'CONSENSUS_MASTER_PLAN',
47
+ submittedBy: 'DISPATCHER',
48
+ masterPlanRef: artifactManager.toArtifactRef(masterPlanArtifact),
49
+ constitutionRef: getConstitutionRef(pipeline),
50
+ repoSnapshotRef: artifactManager.toArtifactRef(snapshotEntry),
51
+ proposedArtifacts: [],
52
+ acceptanceCriteria: [
53
+ 'Master plan is deterministic (no vague features)',
54
+ 'Assumptions are explicit',
55
+ 'Out-of-scope is explicit',
56
+ 'Success criteria defined',
57
+ ],
58
+ dependencies: [],
59
+ constraints: [],
60
+ });
61
+
62
+ // 4. Run structured consensus
63
+ const gateDef = gateEngine.getGateDefinition('CONSENSUS_MASTER_PLAN');
64
+ const consensusPacket = await consensusRunner.runStructuredConsensus(planPacket, gateDef);
65
+
66
+ // 5. Store consensus artifact
67
+ const consensusEntry = artifactManager.createAndStoreJson(
68
+ 'consensus',
69
+ consensusPacket,
70
+ 'CONSENSUS_MASTER_PLAN',
71
+ );
72
+ artifacts.push(consensusEntry);
73
+ pipeline.artifacts.push(...artifacts);
74
+
75
+ // 5b. Store consensus score in gateResults for parseConsensusScore()
76
+ pipeline.gateResults['CONSENSUS_MASTER_PLAN'] = {
77
+ phase: 'CONSENSUS_MASTER_PLAN',
78
+ pass: consensusPacket.final_status === 'APPROVED' || consensusPacket.final_status === 'ARBITRATED',
79
+ score: consensusPacket.consensus_result.weighted_score,
80
+ blockers: [],
81
+ missingArtifacts: [],
82
+ failedChecks: [],
83
+ consensusScore: consensusPacket.consensus_result.score,
84
+ timestamp: new Date().toISOString(),
85
+ };
86
+
87
+ // 6. Trigger journalist (P1-F)
88
+ await triggerJournalist('CONSENSUS_MASTER_PLAN', artifacts, context);
89
+
90
+ const approved = consensusPacket.final_status === 'APPROVED' || consensusPacket.final_status === 'ARBITRATED';
91
+ return successResult(
92
+ 'CONSENSUS_MASTER_PLAN',
93
+ artifacts,
94
+ approved ? 'Master Plan consensus APPROVED' : 'Master Plan consensus REJECTED',
95
+ );
96
+ } catch (err) {
97
+ const message = err instanceof Error ? err.message : 'Unknown error';
98
+ return failureResult('CONSENSUS_MASTER_PLAN', 'Consensus failed', message);
99
+ }
100
+ }
@@ -0,0 +1,105 @@
1
+ /**
2
+ * CONSENSUS_ROLE_PLANS phase — validate each role plan.
3
+ * Checks dependency satisfaction (FE->API, BE->DB, QA->features).
4
+ */
5
+
6
+ import type { PhaseContext, PhaseResult } from './phase-context.js';
7
+ import { successResult, failureResult, triggerJournalist } from './phase-context.js';
8
+ import { buildPlanPacket } from '../packets/plan-packet-builder.js';
9
+ import { generateRepoSnapshot, createSnapshotArtifact } from '../repo-snapshot.js';
10
+ import type { PipelineState, ArtifactRef } from '../types.js';
11
+
12
+ /** Get constitution artifact ref from pipeline state, or fallback */
13
+ function getConstitutionRef(pipeline: PipelineState): ArtifactRef {
14
+ const constitutionArtifact = pipeline.artifacts.find((a) => a.type === 'constitution');
15
+ if (constitutionArtifact) {
16
+ return {
17
+ artifact_id: constitutionArtifact.id,
18
+ path: constitutionArtifact.path,
19
+ sha256: constitutionArtifact.sha256,
20
+ version: constitutionArtifact.version,
21
+ type: 'constitution',
22
+ };
23
+ }
24
+ return { artifact_id: 'constitution', path: 'skills/POPEYE_CONSTITUTION.md', sha256: '', version: 1, type: 'constitution' };
25
+ }
26
+
27
+ export async function runConsensusRolePlans(context: PhaseContext): Promise<PhaseResult> {
28
+ const { pipeline, artifactManager, gateEngine, consensusRunner, projectDir } = context;
29
+ const artifacts = [];
30
+
31
+ try {
32
+ // 1. Fresh repo snapshot
33
+ const snapshot = await generateRepoSnapshot(projectDir);
34
+ const snapshotEntry = createSnapshotArtifact(snapshot, artifactManager, 'CONSENSUS_ROLE_PLANS');
35
+ artifacts.push(snapshotEntry);
36
+ pipeline.latestRepoSnapshot = artifactManager.toArtifactRef(snapshotEntry);
37
+
38
+ // 2. Find all role plan artifacts
39
+ const rolePlanArtifacts = pipeline.artifacts.filter((a) => a.type === 'role_plan');
40
+ if (rolePlanArtifacts.length === 0) {
41
+ return failureResult('CONSENSUS_ROLE_PLANS', 'No role plan artifacts found');
42
+ }
43
+
44
+ const masterPlanArtifact = pipeline.artifacts.find((a) => a.type === 'master_plan');
45
+
46
+ // 3. Build plan packet referencing all role plans
47
+ const planPacket = buildPlanPacket({
48
+ phase: 'CONSENSUS_ROLE_PLANS',
49
+ submittedBy: 'DISPATCHER',
50
+ masterPlanRef: masterPlanArtifact
51
+ ? artifactManager.toArtifactRef(masterPlanArtifact)
52
+ : { artifact_id: 'none', path: '', sha256: '', version: 1, type: 'master_plan' },
53
+ constitutionRef: getConstitutionRef(pipeline),
54
+ repoSnapshotRef: artifactManager.toArtifactRef(snapshotEntry),
55
+ proposedArtifacts: rolePlanArtifacts.map((a) => artifactManager.toArtifactRef(a)),
56
+ acceptanceCriteria: [
57
+ 'All required role plans present',
58
+ 'Each plan includes deterministic file-level outputs',
59
+ 'FE plan references API contracts',
60
+ 'BE plan references DB schema',
61
+ 'QA plan lists executable tests',
62
+ ],
63
+ dependencies: [],
64
+ constraints: [],
65
+ });
66
+
67
+ // 4. Run consensus
68
+ const gateDef = gateEngine.getGateDefinition('CONSENSUS_ROLE_PLANS');
69
+ const consensusPacket = await consensusRunner.runStructuredConsensus(planPacket, gateDef);
70
+
71
+ // 5. Store consensus artifact
72
+ const consensusEntry = artifactManager.createAndStoreJson(
73
+ 'consensus',
74
+ consensusPacket,
75
+ 'CONSENSUS_ROLE_PLANS',
76
+ );
77
+ artifacts.push(consensusEntry);
78
+ pipeline.artifacts.push(...artifacts);
79
+
80
+ // 5b. Store consensus score in gateResults for parseConsensusScore()
81
+ pipeline.gateResults['CONSENSUS_ROLE_PLANS'] = {
82
+ phase: 'CONSENSUS_ROLE_PLANS',
83
+ pass: consensusPacket.final_status === 'APPROVED' || consensusPacket.final_status === 'ARBITRATED',
84
+ score: consensusPacket.consensus_result.weighted_score,
85
+ blockers: [],
86
+ missingArtifacts: [],
87
+ failedChecks: [],
88
+ consensusScore: consensusPacket.consensus_result.score,
89
+ timestamp: new Date().toISOString(),
90
+ };
91
+
92
+ // 6. Journalist trigger
93
+ await triggerJournalist('CONSENSUS_ROLE_PLANS', artifacts, context);
94
+
95
+ const approved = consensusPacket.final_status === 'APPROVED' || consensusPacket.final_status === 'ARBITRATED';
96
+ return successResult(
97
+ 'CONSENSUS_ROLE_PLANS',
98
+ artifacts,
99
+ approved ? 'Role plans consensus APPROVED' : 'Role plans consensus REJECTED',
100
+ );
101
+ } catch (err) {
102
+ const message = err instanceof Error ? err.message : 'Unknown error';
103
+ return failureResult('CONSENSUS_ROLE_PLANS', 'Role plans consensus failed', message);
104
+ }
105
+ }
@@ -0,0 +1,68 @@
1
+ /**
2
+ * DONE phase — finalize documentation + release packaging.
3
+ * RELEASE_MANAGER creates release/deployment/rollback artifacts.
4
+ */
5
+
6
+ import type { PhaseContext, PhaseResult } from './phase-context.js';
7
+ import { successResult, failureResult } from './phase-context.js';
8
+
9
+ export async function runDone(context: PhaseContext): Promise<PhaseResult> {
10
+ const { pipeline, artifactManager, skillLoader } = context;
11
+ const artifacts = [];
12
+
13
+ try {
14
+ // 1. Load release manager skill
15
+ const rmSkill = skillLoader.loadSkill('RELEASE_MANAGER');
16
+
17
+ // 2. Generate release notes
18
+ const { executePrompt } = await import('../../adapters/claude.js');
19
+
20
+ const releasePrompt = [
21
+ rmSkill.systemPrompt,
22
+ '',
23
+ '## Instructions',
24
+ 'Generate release notes, deployment instructions, and rollback plan.',
25
+ 'Base this on the artifacts produced during the pipeline.',
26
+ '',
27
+ '## Artifacts Summary',
28
+ ...pipeline.artifacts.map((a) => `- [${a.type}] v${a.version}: ${a.path}`),
29
+ ].join('\n');
30
+
31
+ const releaseResult = await executePrompt(releasePrompt);
32
+ const releaseResponse = releaseResult.response;
33
+
34
+ // 3. Create release notes artifact
35
+ const releaseEntry = artifactManager.createAndStoreText(
36
+ 'release_notes',
37
+ releaseResponse,
38
+ 'DONE',
39
+ );
40
+ artifacts.push(releaseEntry);
41
+
42
+ // 4. Create deployment instructions artifact
43
+ const deployEntry = artifactManager.createAndStoreText(
44
+ 'deployment',
45
+ `# Deployment Instructions\n\n${releaseResponse.includes('deployment') ? 'See release notes.' : 'Standard deployment procedure.'}`,
46
+ 'DONE',
47
+ );
48
+ artifacts.push(deployEntry);
49
+
50
+ // 5. Create rollback plan artifact
51
+ const rollbackEntry = artifactManager.createAndStoreText(
52
+ 'rollback',
53
+ `# Rollback Plan\n\nRevert to previous version if issues detected post-deploy.`,
54
+ 'DONE',
55
+ );
56
+ artifacts.push(rollbackEntry);
57
+
58
+ pipeline.artifacts.push(...artifacts);
59
+
60
+ // 6. Final INDEX.md update
61
+ artifactManager.updateIndex(pipeline.artifacts);
62
+
63
+ return successResult('DONE', artifacts, 'Pipeline complete. Release artifacts created.');
64
+ } catch (err) {
65
+ const message = err instanceof Error ? err.message : 'Unknown error';
66
+ return failureResult('DONE', 'Release packaging failed', message);
67
+ }
68
+ }
@@ -0,0 +1,48 @@
1
+ /**
2
+ * IMPLEMENTATION phase — build the system according to approved plans.
3
+ * Reuses runExecutionMode() from existing workflow.
4
+ * v1.1: Injects role-specific execution contexts via role-execution-adapter.
5
+ */
6
+
7
+ import type { PhaseContext, PhaseResult } from './phase-context.js';
8
+ import { successResult, failureResult } from './phase-context.js';
9
+ import { generateRepoSnapshot, createSnapshotArtifact } from '../repo-snapshot.js';
10
+ import { buildAllRoleContexts } from '../role-execution-adapter.js';
11
+
12
+ export async function runImplementation(context: PhaseContext): Promise<PhaseResult> {
13
+ const { pipeline, artifactManager, projectDir, skillLoader } = context;
14
+ const artifacts = [];
15
+
16
+ try {
17
+ // v1.1: Build role contexts for execution
18
+ const roleContexts = buildAllRoleContexts(pipeline, skillLoader, projectDir);
19
+
20
+ // Build combined role context for system prompt injection
21
+ let combinedRolePrompt = '';
22
+ if (roleContexts.size > 0) {
23
+ const contextEntries = Array.from(roleContexts.entries());
24
+ combinedRolePrompt = contextEntries
25
+ .map(([role, ctx]) => `## ${role}\nScope: ${ctx.taskScope.slice(0, 500)}`)
26
+ .join('\n\n');
27
+ }
28
+
29
+ // Run existing execution mode with optional role context
30
+ const { runExecutionMode } = await import('../../workflow/execution-mode.js');
31
+ await runExecutionMode({
32
+ projectDir,
33
+ ...(combinedRolePrompt ? { systemPrompt: combinedRolePrompt } : {}),
34
+ });
35
+
36
+ // Generate post-implementation repo snapshot
37
+ const snapshot = await generateRepoSnapshot(projectDir);
38
+ const snapshotEntry = createSnapshotArtifact(snapshot, artifactManager, 'IMPLEMENTATION');
39
+ artifacts.push(snapshotEntry);
40
+ pipeline.latestRepoSnapshot = artifactManager.toArtifactRef(snapshotEntry);
41
+
42
+ pipeline.artifacts.push(...artifacts);
43
+ return successResult('IMPLEMENTATION', artifacts, `Implementation complete. ${roleContexts.size} roles active.`);
44
+ } catch (err) {
45
+ const message = err instanceof Error ? err.message : 'Unknown error';
46
+ return failureResult('IMPLEMENTATION', 'Implementation failed', message);
47
+ }
48
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Re-exports all phase implementations.
3
+ */
4
+
5
+ export { runIntake } from './intake.js';
6
+ export { runConsensusMasterPlan } from './consensus-master-plan.js';
7
+ export { runArchitecture } from './architecture.js';
8
+ export { runConsensusArchitecture } from './consensus-architecture.js';
9
+ export { runRolePlanning } from './role-planning.js';
10
+ export { runConsensusRolePlans } from './consensus-role-plans.js';
11
+ export { runImplementation } from './implementation.js';
12
+ export { runQaValidation } from './qa-validation.js';
13
+ export { runReview } from './review.js';
14
+ export { runAudit } from './audit.js';
15
+ export { runProductionGate } from './production-gate.js';
16
+ export { runRecoveryLoop } from './recovery-loop.js';
17
+ export { runDone } from './done.js';
18
+ export { runStuck } from './stuck.js';
19
+
20
+ export type { PhaseContext, PhaseResult } from './phase-context.js';
21
+ export { triggerJournalist, successResult, failureResult } from './phase-context.js';