@smartmemory/compose 0.3.7 → 0.4.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 (217) hide show
  1. package/.claude/skills/compose/SKILL.md +12 -3
  2. package/.compose-deps.json +51 -25
  3. package/README.md +79 -7
  4. package/bin/compose.js +495 -360
  5. package/bin/judgment-migrate.js +387 -0
  6. package/contracts/comp-obs-contract.schema.json +9 -3
  7. package/contracts/fluid-record.schema.json +209 -0
  8. package/contracts/lifecycle-backfill.schema.json +322 -0
  9. package/dist/assets/App-Z4MU-H_F.js +916 -0
  10. package/dist/assets/{_baseUniq-Bo837sRJ.js → _baseUniq-ClWoCPFl.js} +1 -1
  11. package/dist/assets/{arc-BafGpyqE.js → arc-DY26UIVo.js} +1 -1
  12. package/dist/assets/{architectureDiagram-Q4EWVU46-BOBfUsqL.js → architectureDiagram-Q4EWVU46-6Ggq4DqJ.js} +1 -1
  13. package/dist/assets/{blockDiagram-DXYQGD6D-Dwodev1a.js → blockDiagram-DXYQGD6D-CH3Ked0l.js} +1 -1
  14. package/dist/assets/{browser-1ntj1-x_.js → browser-BWkrenen.js} +1 -1
  15. package/dist/assets/{c4Diagram-AHTNJAMY-CU_bhYag.js → c4Diagram-AHTNJAMY-Bk8dYilu.js} +1 -1
  16. package/dist/assets/channel-SnZzzh7k.js +1 -0
  17. package/dist/assets/{chunk-4BX2VUAB-p8WsDwnO.js → chunk-4BX2VUAB-BMR0XaAQ.js} +1 -1
  18. package/dist/assets/{chunk-4TB4RGXK-B8h7-eR0.js → chunk-4TB4RGXK-JytR14a9.js} +1 -1
  19. package/dist/assets/{chunk-55IACEB6-DxeEr98s.js → chunk-55IACEB6-B4Q97BCP.js} +1 -1
  20. package/dist/assets/{chunk-EDXVE4YY-BYt8F151.js → chunk-EDXVE4YY-R_qarkSf.js} +1 -1
  21. package/dist/assets/{chunk-FMBD7UC4-DGSOVeie.js → chunk-FMBD7UC4-C9s7KR9m.js} +1 -1
  22. package/dist/assets/{chunk-OYMX7WX6-B-QdgYR2.js → chunk-OYMX7WX6-BySQzVxc.js} +1 -1
  23. package/dist/assets/{chunk-QZHKN3VN-Du5UAZLs.js → chunk-QZHKN3VN-DdpSYZsW.js} +1 -1
  24. package/dist/assets/{chunk-YZCP3GAM-C8JbNBSk.js → chunk-YZCP3GAM-iE_tzriw.js} +1 -1
  25. package/dist/assets/classDiagram-6PBFFD2Q-CBu92dSH.js +1 -0
  26. package/dist/assets/classDiagram-v2-HSJHXN6E-CBu92dSH.js +1 -0
  27. package/dist/assets/clone-DgklGjHm.js +1 -0
  28. package/dist/assets/{cose-bilkent-S5V4N54A-O1ESaqge.js → cose-bilkent-S5V4N54A-BdlU6ZX_.js} +1 -1
  29. package/dist/assets/{dagre-KV5264BT-CPTmFPHw.js → dagre-KV5264BT-Cp3F5KTn.js} +1 -1
  30. package/dist/assets/{diagram-5BDNPKRD-B3PNrWs5.js → diagram-5BDNPKRD-DiR6_2q_.js} +1 -1
  31. package/dist/assets/{diagram-G4DWMVQ6-Cscfr6vc.js → diagram-G4DWMVQ6-w0i-p5HX.js} +1 -1
  32. package/dist/assets/{diagram-MMDJMWI5-CSfqZ-TM.js → diagram-MMDJMWI5-tIHhwUv3.js} +1 -1
  33. package/dist/assets/{diagram-TYMM5635-Cg4aYS7W.js → diagram-TYMM5635-BAeY3B19.js} +1 -1
  34. package/dist/assets/{erDiagram-SMLLAGMA-_ZqwG5pl.js → erDiagram-SMLLAGMA-Ckx_Knko.js} +1 -1
  35. package/dist/assets/{flowDiagram-DWJPFMVM-C83boxFT.js → flowDiagram-DWJPFMVM-DeoNka6J.js} +1 -1
  36. package/dist/assets/{ganttDiagram-T4ZO3ILL-CWnIjuEi.js → ganttDiagram-T4ZO3ILL-BmGnFbEg.js} +1 -1
  37. package/dist/assets/{gitGraphDiagram-UUTBAWPF-DrMdxZfH.js → gitGraphDiagram-UUTBAWPF-Dk48IHsx.js} +1 -1
  38. package/dist/assets/{graph-RE4I7Ty7.js → graph-BNzKGvoy.js} +1 -1
  39. package/dist/assets/{graph-Bi99_6Yf.js → graph-CI_1htl0.js} +1 -1
  40. package/dist/assets/{index-Rm2RE-c0.js → index-BEfrNBp8.js} +3 -3
  41. package/dist/assets/index-yyrA5OZd.css +1 -0
  42. package/dist/assets/{infoDiagram-42DDH7IO-BLmP4Epr.js → infoDiagram-42DDH7IO-BRf827i0.js} +1 -1
  43. package/dist/assets/{ishikawaDiagram-UXIWVN3A-yuWWshKN.js → ishikawaDiagram-UXIWVN3A-0kCZaeCM.js} +1 -1
  44. package/dist/assets/{journeyDiagram-VCZTEJTY-BOfhaJov.js → journeyDiagram-VCZTEJTY-rvU7ayRt.js} +1 -1
  45. package/dist/assets/{kanban-definition-6JOO6SKY-Bbolde15.js → kanban-definition-6JOO6SKY-DpQwX1C5.js} +1 -1
  46. package/dist/assets/{layout-BSf33zm8.js → layout-BI8cXFPI.js} +1 -1
  47. package/dist/assets/{linear-AvSTWMqx.js → linear-a0glcDiw.js} +1 -1
  48. package/dist/assets/{min-QBM8H4xN.js → min-vPHfnXcC.js} +1 -1
  49. package/dist/assets/{mindmap-definition-QFDTVHPH-BuvgtqIc.js → mindmap-definition-QFDTVHPH-D14eF-7C.js} +1 -1
  50. package/dist/assets/mobile-B7m9EO9D.js +17 -0
  51. package/dist/assets/{pieDiagram-DEJITSTG-DIzF16vh.js → pieDiagram-DEJITSTG-Cno-gETh.js} +1 -1
  52. package/dist/assets/{quadrantDiagram-34T5L4WZ-D-mbUIjS.js → quadrantDiagram-34T5L4WZ-BUQM1Hfm.js} +1 -1
  53. package/dist/assets/{requirementDiagram-MS252O5E-CEs4kCLd.js → requirementDiagram-MS252O5E-pOXlN2-q.js} +1 -1
  54. package/dist/assets/{sankeyDiagram-XADWPNL6-DFsnCr9n.js → sankeyDiagram-XADWPNL6-Crynd3_b.js} +1 -1
  55. package/dist/assets/{sequenceDiagram-FGHM5R23-BEJYdTjQ.js → sequenceDiagram-FGHM5R23-D9fZdCM8.js} +1 -1
  56. package/dist/assets/{stateDiagram-FHFEXIEX-BBXs57uY.js → stateDiagram-FHFEXIEX-CW9qVec8.js} +1 -1
  57. package/dist/assets/stateDiagram-v2-QKLJ7IA2-DkVLzHbY.js +1 -0
  58. package/dist/assets/{timeline-definition-GMOUNBTQ-BGvLoVAY.js → timeline-definition-GMOUNBTQ-BcHzhm_8.js} +1 -1
  59. package/dist/assets/{vennDiagram-DHZGUBPP-9LaBTMe0.js → vennDiagram-DHZGUBPP-BfytJcWk.js} +1 -1
  60. package/dist/assets/{wardley-RL74JXVD-P4MEqMTP.js → wardley-RL74JXVD-DLj-IjyB.js} +1 -1
  61. package/dist/assets/{wardleyDiagram-NUSXRM2D-o-tmxnlC.js → wardleyDiagram-NUSXRM2D-Ds0Ue68c.js} +1 -1
  62. package/dist/assets/{xychartDiagram-5P7HB3ND-Dpn7V6qk.js → xychartDiagram-5P7HB3ND-vjWDXFL6.js} +1 -1
  63. package/dist/index.html +3 -3
  64. package/lib/agent-string.js +7 -5
  65. package/lib/append-integrity.js +81 -0
  66. package/lib/backfill-evidence.js +109 -0
  67. package/lib/bug-escalation.js +9 -0
  68. package/lib/build-stream-schema.js +3 -1
  69. package/lib/build-stream-writer.js +25 -0
  70. package/lib/build.js +874 -170
  71. package/lib/canon-guard.js +28 -6
  72. package/lib/canon-override.js +196 -0
  73. package/lib/canon-registry.js +104 -0
  74. package/lib/cli-commands.js +144 -0
  75. package/lib/codex-preflight.js +26 -13
  76. package/lib/colleague/context.js +215 -0
  77. package/lib/colleague/writeback.js +95 -0
  78. package/lib/completion-gate.js +1421 -0
  79. package/lib/completion-writer.js +47 -47
  80. package/lib/consumer-fanout.js +105 -11
  81. package/lib/coverage-gate.js +200 -0
  82. package/lib/deps.js +164 -7
  83. package/lib/dir-lock.js +170 -0
  84. package/lib/dispatch-ledger.js +3 -3
  85. package/lib/feature-json.js +1 -1
  86. package/lib/feature-reconciler.js +8 -0
  87. package/lib/feature-validator.js +64 -1
  88. package/lib/feature-writer.js +57 -2
  89. package/lib/fluid/factory.js +167 -0
  90. package/lib/fluid/ideabox-dates.js +73 -0
  91. package/lib/fluid/ideabox-migrate.js +154 -0
  92. package/lib/fluid/ideabox-ops.js +585 -0
  93. package/lib/fluid/ideabox-view.js +146 -0
  94. package/lib/fluid/import-ideabox.js +186 -0
  95. package/lib/fluid/local-provider.js +606 -0
  96. package/lib/fluid/provider.js +684 -0
  97. package/lib/fluid/record-shape.js +214 -0
  98. package/lib/fluid/record-store.js +328 -0
  99. package/lib/fluid/render-ideabox.js +261 -0
  100. package/lib/fluid/schema.js +40 -0
  101. package/lib/fluid/smartmemory-provider.js +1695 -0
  102. package/lib/gsd.js +63 -23
  103. package/lib/guard-cli.js +175 -0
  104. package/lib/guard-custody.js +141 -0
  105. package/lib/guard-descriptors.js +530 -0
  106. package/lib/guard-enrol.js +254 -0
  107. package/lib/health-score.js +1 -1
  108. package/lib/ideabox-cli.js +315 -0
  109. package/lib/ideabox.js +121 -21
  110. package/lib/judgment/store/index.js +9 -1
  111. package/lib/judgment/store/records.js +1 -1
  112. package/lib/judgment/trace.js +380 -0
  113. package/lib/judgment-decision-write.js +277 -0
  114. package/lib/judgment-decisions.js +466 -0
  115. package/lib/judgment-gen.js +5 -1
  116. package/lib/judgment-writer.js +56 -2
  117. package/lib/lifecycle-modes.js +4 -4
  118. package/lib/lineage.js +400 -0
  119. package/lib/local-claude-connector.js +52 -1
  120. package/lib/maya-client.js +302 -0
  121. package/lib/maya-config.js +53 -0
  122. package/lib/maya-identity.js +283 -0
  123. package/lib/migrate-anon.js +5 -0
  124. package/lib/migrate-roadmap.js +15 -0
  125. package/lib/new.js +13 -1
  126. package/lib/pipeline-compat.js +104 -0
  127. package/lib/policy-catalog.js +295 -0
  128. package/lib/policy-check.js +0 -0
  129. package/lib/process-termination.js +98 -0
  130. package/lib/resolve-workspace.js +5 -1
  131. package/lib/result-normalizer.js +396 -199
  132. package/lib/roadmap-errors.js +65 -0
  133. package/lib/roadmap-preservers.js +24 -4
  134. package/lib/roadmap-residue.js +299 -0
  135. package/lib/smartmemory-client.js +614 -78
  136. package/lib/smartmemory-config.js +54 -0
  137. package/lib/smartmemory-ingest.js +19 -2
  138. package/lib/step-prompt.js +7 -6
  139. package/lib/stratum-engine.js +53 -4
  140. package/lib/stratum-mcp-client.js +271 -36
  141. package/lib/test-bootstrap.js +31 -0
  142. package/lib/tool-inventory.js +122 -0
  143. package/lib/version-check.js +91 -19
  144. package/lib/vision-writer.js +88 -1
  145. package/package.json +7 -6
  146. package/pipelines/bug-fix.stratum.yaml +205 -211
  147. package/pipelines/build-quick.profiles.json +12 -0
  148. package/pipelines/build-quick.stratum.yaml +263 -350
  149. package/pipelines/content.stratum.yaml +81 -77
  150. package/pipelines/coverage-sweep.stratum.yaml +49 -30
  151. package/pipelines/plan.stratum.yaml +76 -86
  152. package/pipelines/refactor.stratum.yaml +125 -125
  153. package/pipelines/research.stratum.yaml +56 -58
  154. package/pipelines/review-fix.profiles.json +6 -0
  155. package/pipelines/review-fix.stratum.yaml +110 -83
  156. package/presets/team-feature.profiles.json +6 -0
  157. package/presets/team-feature.stratum.yaml +93 -66
  158. package/presets/team-research.profiles.json +6 -0
  159. package/presets/team-research.stratum.yaml +89 -80
  160. package/presets/team-review.profiles.json +8 -0
  161. package/presets/team-review.stratum.yaml +98 -80
  162. package/scripts/cost-census.mjs +70 -0
  163. package/scripts/guard-sign/compose-guard-sign.sh +62 -0
  164. package/server/agent-health.js +22 -0
  165. package/server/agent-hooks.js +14 -1
  166. package/server/agent-server.js +5 -248
  167. package/server/agent-spawn.js +3 -4
  168. package/server/agent-workspace.js +294 -0
  169. package/server/build-routes.js +6 -5
  170. package/server/build-stream-bridge.js +53 -0
  171. package/server/cc-session-watcher.js +4 -1
  172. package/server/coalescing-buffer.js +7 -1
  173. package/server/completion-projection.js +228 -0
  174. package/server/compose-mcp-tools.js +109 -23
  175. package/server/compose-mcp.js +88 -882
  176. package/server/decision-event-emit.js +41 -2
  177. package/server/decision-event-id.js +17 -0
  178. package/server/decision-events-snapshot.js +3 -0
  179. package/server/design-routes.js +14 -8
  180. package/server/feature-scan.js +76 -2
  181. package/server/file-watcher.js +170 -21
  182. package/server/ideabox-routes.js +166 -224
  183. package/server/index.js +70 -100
  184. package/server/lifecycle-guard.js +240 -10
  185. package/server/lifecycle-phase-history.js +276 -0
  186. package/server/maya-routes.js +507 -0
  187. package/server/mcp-tool-defs.js +940 -0
  188. package/server/mcp-tool-policy.js +34 -2
  189. package/server/model-tiers.js +22 -5
  190. package/server/pipeline-routes.js +21 -11
  191. package/server/project-root.js +58 -19
  192. package/server/remote-utils.js +3 -1
  193. package/server/schema-validator.js +7 -1
  194. package/server/session-manager.js +5 -6
  195. package/server/session-routes.js +3 -1
  196. package/server/stratum-client.js +57 -10
  197. package/server/stratum-sync.js +6 -3
  198. package/server/summarizer.js +3 -4
  199. package/server/supervisor.js +0 -1
  200. package/server/vision-routes.js +208 -98
  201. package/server/vision-server.js +86 -23
  202. package/server/vision-store.js +60 -6
  203. package/server/vision-utils.js +3 -4
  204. package/server/workspace-activity.js +18 -0
  205. package/server/workspace-middleware.js +2 -2
  206. package/server/workspace-runtime.js +243 -0
  207. package/server/worktree-gc.js +1 -0
  208. package/dist/assets/App-PkZzHeMj.js +0 -894
  209. package/dist/assets/channel-qVK_qn4E.js +0 -1
  210. package/dist/assets/classDiagram-6PBFFD2Q-B8UcfC1q.js +0 -1
  211. package/dist/assets/classDiagram-v2-HSJHXN6E-B8UcfC1q.js +0 -1
  212. package/dist/assets/clone-Pu3RyLUh.js +0 -1
  213. package/dist/assets/index-LIwREYgH.css +0 -1
  214. package/dist/assets/mobile-BnXEOE3U.js +0 -17
  215. package/dist/assets/stateDiagram-v2-QKLJ7IA2-BqKuX4rj.js +0 -1
  216. package/lib/staleness.js +0 -87
  217. package/server/ideabox-cache.js +0 -77
@@ -3,266 +3,260 @@
3
3
  # label: "Bug Fix"
4
4
  # description: "Diagnose and fix a bug — reproduce, trace root cause, scope audit, fix, test, verify, ship"
5
5
  # category: maintenance
6
- # steps: 8
6
+ # steps: 9
7
7
  # estimated_minutes: 40
8
8
 
9
- version: "0.1"
9
+ version: 1
10
10
 
11
11
  # bug-fix pipeline
12
12
  #
13
- # Eight-step flow for disciplined bug resolution:
13
+ # Nine-step flow for disciplined bug resolution:
14
14
  # 1. reproduce — confirm the bug exists with a failing test
15
15
  # 2. diagnose — trace root cause by OBSERVING actual data (not assuming)
16
- # 3. scope_check grep audit if change spans multiple layers/repos
17
- # 4. fix implement the minimal correct fix across ALL affected layers
18
- # 5. test run full test suite, ensure no regressions
19
- # 6. verify confirm original reproduction case now passes
20
- # 7. retro_check detect fix chains and log discipline signals
21
- # 8. ship commit and report
16
+ # 3. bisect optionally git-bisect a suspected regression
17
+ # 4. scope_check grep audit if change spans multiple layers/repos
18
+ # 5. fix implement the minimal correct fix across ALL affected layers
19
+ # 6. test run full test suite, ensure no regressions
20
+ # 7. verify confirm original reproduction case now passes
21
+ # 8. retro_check detect fix chains and log discipline signals
22
+ # 9. ship — commit and report
22
23
  #
23
24
  # Debug Discipline (COMP-DEBUG-1):
24
25
  # - diagnose requires trace_evidence (actual command output, not prose assumptions)
25
26
  # - scope_check prevents incremental multi-layer discovery
26
27
  # - retro_check detects fix chains and feeds iteration ledger
27
28
  #
29
+ # COMP-PIPELINE-QUARANTINE: re-authored from the v0.1 `functions:` dialect to TS
30
+ # v1. STRAT-PY-RETIRE converted only build and gsd and deleted the older
31
+ # execution paths, so this spec had been unrunnable since that cutover — every
32
+ # `compose fix` died on a bare `MCP error -32602: spec validation failed`.
33
+ #
34
+ # Conversion notes (semantics preserved, not redesigned):
35
+ # - `functions:` + `flows.steps[].function` collapse into inline `do` steps;
36
+ # v1 has no separate function table.
37
+ # - `depends_on` -> `after`. The chain is linear and has NO backward routing,
38
+ # so unlike the build conversion there are no ROUTING_CYCLE gates to model.
39
+ # - `retries: N` -> `attempts: N + 1`. v0.1 counted retries AFTER the first
40
+ # try; v1 `attempts` is the total, so a bare rename would silently cut every
41
+ # step's budget by one.
42
+ # - Enum constraints move from `ensure` into the contract (`a|b|c`), which is
43
+ # where v1 expresses them — the engine rejects a bad value at the contract
44
+ # boundary instead of one step later.
45
+ # - bisect's approve/skip/kill remains PROSE inside `do`, exactly as in v0.1.
46
+ # Promoting it to a real engine `gate:` step would change runner behavior
47
+ # (gate routing + promptGate handling) and is a redesign, not a migration.
48
+ #
28
49
  # Inputs:
29
50
  # task — bug description (symptoms, steps to reproduce, affected files)
30
- #
31
- # Usage:
32
- # stratum_plan <this yaml> "bug_fix" {"task": "..."}
33
51
 
34
52
  contracts:
35
53
  BugFixResult:
36
- phase: {type: string}
37
- summary: {type: string}
38
- outcome: {type: string, values: [complete, failed]}
39
- references_addressed: {type: string} # stringified int
54
+ phase: string
55
+ summary: string
56
+ outcome: complete|skipped|failed # `skipped` is reachable: compose offers an interactive skip
57
+ references_addressed: string? # stringified int; set by the fix step
58
+
59
+ # The `ship` step is INTERCEPTED by compose (lib/build.js shouldInterceptShip:
60
+ # any step named `ship` outside plan mode), which submits this shape regardless
61
+ # of what the spec declares. It is a SEPARATE contract, not extra optional
62
+ # fields on the pipeline's own result: outputFieldsToJsonSchema marks every
63
+ # declared field required and ignores `?`, so widening the shared contract
64
+ # would instruct every other step to return commit metadata it has no business
65
+ # producing. Third instance of this defect class; see COMP-SHIP-CONTRACT.
66
+ ShipResult:
67
+ phase: string
68
+ artifact: string
69
+ outcome: complete|skipped|failed
70
+ summary: string
71
+ files_changed: string[]?
72
+ commit_hash: string?
40
73
 
41
74
  TestResult:
42
- passing: {type: boolean}
43
- summary: {type: string}
44
- failures: {type: array}
75
+ passing: boolean
76
+ summary: string
77
+ failures: string[]
45
78
 
46
79
  TraceEvidence:
47
- command: {type: string}
48
- actual_output: {type: string}
49
- conclusion: {type: string}
80
+ command: string
81
+ actual_output: string
82
+ conclusion: string
50
83
 
51
84
  DiagnoseResult:
52
- root_cause: {type: string}
53
- affected_layers: {type: array}
54
- trace_evidence: {type: array, items: TraceEvidence}
55
- summary: {type: string}
56
- scope_hint: {type: string} # single | cross-layer | unknown
85
+ root_cause: string
86
+ affected_layers: string[]
87
+ trace_evidence: TraceEvidence[]
88
+ summary: string
89
+ scope_hint: single|cross-layer|unknown
57
90
 
58
91
  ScopeResult:
59
- scope: {type: string, values: [single, cross_layer]}
60
- references_found: {type: array}
61
- repos_scanned: {type: number}
62
- summary: {type: string}
63
- references_count: {type: string} # stringified int for Stratum compat
92
+ scope: single|cross_layer
93
+ references_found: string[]
94
+ repos_scanned: number
95
+ summary: string
96
+ references_count: string # stringified int for Stratum compat
64
97
 
65
98
  RetroCheckResult:
66
- fix_chains: {type: array}
67
- attempt_count: {type: number}
68
- escalation: {type: boolean}
69
- discipline_score: {type: number}
70
- summary: {type: string}
99
+ fix_chains: string[]
100
+ attempt_count: number
101
+ escalation: boolean
102
+ discipline_score: number
103
+ summary: string
71
104
 
72
105
  BisectResult:
73
- skipped: {type: boolean}
74
- bisect_commit: {type: string} # nullable; empty string when skipped
75
- estimate_minutes: {type: number}
76
- log_path: {type: string} # nullable; empty string when skipped
77
- summary: {type: string}
78
-
79
- functions:
80
- reproduce:
81
- mode: compute
82
- intent: >
83
- Write a failing test that demonstrates the bug. The test must fail
84
- before any fix is applied. Return a summary of the reproduction.
85
- input:
86
- task: {type: string}
87
- output: BugFixResult
88
- retries: 2
89
-
90
- diagnose:
91
- mode: compute
92
- intent: >
93
- Trace the root cause by OBSERVING actual data, not assuming.
94
- You MUST run at least one command that prints a real value at the
95
- failure point (docker exec, curl, python -c "print(type(x))").
96
- Return trace_evidence: a list of {command, actual_output, conclusion}.
97
- Also identify which layers are affected (core, service, frontend, infra).
98
- "Import OK" and "build passed" are NOT trace evidence.
99
- input:
100
- task: {type: string}
101
- output: DiagnoseResult
102
- ensure:
103
- - "result.trace_evidence != null"
104
- - "result.trace_evidence.length >= 2"
105
- - "result.root_cause != null"
106
- - "result.scope_hint in ('single', 'cross-layer', 'unknown')"
107
- retries: 2
108
-
109
- bisect:
110
- mode: compute
111
- intent: >
112
- Decide whether the bug is a regression worth bisecting; if so,
113
- classify → estimate cost → gate the human → run git bisect.
114
- The runtime helper `lib/bug-bisect.js` does the work:
115
- 1. classifyRegression(): repro test exists in main AND files in
116
- diagnosis.affected_layers were touched in the last 10 commits.
117
- 2. estimateBisectCost(): test_runs = ceil(log2(commits in range));
118
- seconds_per_run sampled by running the test once.
119
- 3. Gate: "Looks like a regression. Run git bisect? Estimate:
120
- <test_runs> runs × <seconds_per_run>s = ~<total_minutes> min.
121
- approve / skip / kill"
122
- 4. On approve: runBisect() drives `git bisect start && bad HEAD
123
- && good <baseline> && bisect run <testCmd>`, captures log to
124
- docs/bugs/<bug-code>/bisect.log, always resets in finally.
125
- 5. On skip OR not-a-regression: return {skipped: true,
126
- bisect_commit: null, estimate_minutes: 0} and continue.
127
- input:
128
- task: {type: string}
129
- diagnosis: {type: object}
130
- output: BisectResult
131
- retries: 1
132
-
133
- scope_check:
134
- mode: compute
135
- intent: >
136
- If the diagnosis shows the root cause involves a provider switch,
137
- field rename, config key change, or anything spanning multiple
138
- repos or layers: grep ALL configured project repos for every reference
139
- to the affected term. Return the full reference list grouped by repo.
140
- If the change is single-layer, return scope: 'single' and skip.
141
- This prevents incremental multi-layer discovery (fixing one layer,
142
- deploying, discovering the next layer is broken, repeat).
143
- input:
144
- task: {type: string}
145
- diagnosis: {type: object}
146
- output: ScopeResult
147
- retries: 1
148
-
149
- fix:
150
- mode: compute
151
- intent: >
152
- Implement the minimal correct fix for the diagnosed root cause.
153
- If scope_check found cross-layer references, address ALL of them
154
- in coordinated commits — do not leave any reference unaddressed.
155
- Change only what is necessary. Return a summary of changes made.
156
- input:
157
- task: {type: string}
158
- scope: {type: object}
159
- output: BugFixResult
160
- retries: 2
161
-
162
- test:
163
- mode: compute
164
- intent: >
165
- Run the full test suite. Return structured JSON:
166
- { "passing": boolean, "summary": string, "failures": string[] }.
167
- input:
168
- task: {type: string}
169
- output: TestResult
170
- ensure:
171
- - "result.passing == true"
172
- retries: 5
173
-
174
- verify:
175
- mode: compute
176
- intent: >
177
- Re-run the reproduction test from step 1. Confirm it now passes.
178
- Return a summary confirming the fix resolves the original bug.
179
- input:
180
- task: {type: string}
181
- output: BugFixResult
182
- retries: 1
183
-
184
- retro_check:
185
- mode: compute
186
- intent: >
187
- Analyze git history for this session. Detect fix chains: 2+ commits
188
- modifying the same file or function. Count total fix attempts on
189
- the target bug. For visual/CSS/layout bugs, enforce hard stop at
190
- attempt 2 and flag for cross-agent escalation.
191
- Return fix_chains (list of repeated files), attempt_count, whether
192
- escalation was triggered, and a discipline_score (0-100).
193
- input:
194
- task: {type: string}
195
- output: RetroCheckResult
196
- retries: 1
197
-
198
- ship:
199
- mode: compute
200
- intent: >
201
- Commit all changes with a descriptive message. Update CHANGELOG.md
202
- if appropriate. Return a summary of what was shipped.
203
- input:
204
- task: {type: string}
205
- output: BugFixResult
206
- retries: 1
106
+ skipped: boolean
107
+ bisect_commit: string # empty string when skipped
108
+ estimate_minutes: number
109
+ log_path: string # empty string when skipped
110
+ summary: string
207
111
 
208
112
  flows:
113
+ entry: bug_fix
209
114
  bug_fix:
210
115
  input:
211
- task: {type: string}
212
- output: BugFixResult
116
+ task: string
117
+ output:
118
+ from: "${ship.output}"
119
+ contract: ShipResult
213
120
  steps:
214
121
  - id: reproduce
215
- function: reproduce
216
- inputs:
217
- task: "$.input.task"
122
+ agent: claude
123
+ do: >
124
+ Write a failing test that demonstrates the bug: ${input.task}.
125
+ The test must fail before any fix is applied. Return a summary of the
126
+ reproduction as BugFixResult.
127
+ out: BugFixResult
128
+ ensure:
129
+ - expr: "result.outcome == 'complete'"
130
+ attempts: 3
218
131
 
219
132
  - id: diagnose
220
- function: diagnose
221
- inputs:
222
- task: "$.input.task"
223
- depends_on: [reproduce]
133
+ after: [reproduce]
134
+ agent: claude
135
+ do: >
136
+ Trace the root cause of ${input.task} by OBSERVING actual data, not
137
+ assuming. You MUST run at least two commands that print a real value at
138
+ the failure point (docker exec, curl, python -c "print(type(x))").
139
+ Return trace_evidence: a list of {command, actual_output, conclusion}.
140
+ Also identify which layers are affected (core, service, frontend, infra)
141
+ and set scope_hint. "Import OK" and "build passed" are NOT trace evidence.
142
+ out: DiagnoseResult
143
+ ensure:
144
+ # scope_hint's allowed values are enforced by the contract enum above.
145
+ - expr: "len(result.trace_evidence) >= 2"
146
+ - expr: "len(result.root_cause) > 0"
147
+ attempts: 3
224
148
 
225
149
  - id: bisect
226
- function: bisect
227
- inputs:
228
- task: "$.input.task"
229
- diagnosis: "$.steps.diagnose.output"
230
- depends_on: [diagnose]
150
+ after: [diagnose]
151
+ agent: claude
152
+ do: >
153
+ Decide whether ${input.task} is a regression worth bisecting; if so,
154
+ classify -> estimate cost -> gate the human -> run git bisect. The
155
+ root cause found by diagnose is ${diagnose.output.root_cause} and the
156
+ affected layers are ${diagnose.output.affected_layers}.
157
+ The runtime helper `lib/bug-bisect.js` does the work:
158
+ 1. classifyRegression(): repro test exists in main AND files in the
159
+ affected layers were touched in the last 10 commits.
160
+ 2. estimateBisectCost(): test_runs = ceil(log2(commits in range));
161
+ seconds_per_run sampled by running the test once.
162
+ 3. Ask the human: "Looks like a regression. Run git bisect? Estimate:
163
+ <test_runs> runs x <seconds_per_run>s = ~<total_minutes> min.
164
+ approve / skip / kill"
165
+ 4. On approve: runBisect() drives `git bisect start && bad HEAD
166
+ && good <baseline> && bisect run <testCmd>`, captures the log to
167
+ docs/bugs/<bug-code>/bisect.log, always resets in finally.
168
+ 5. On skip OR not-a-regression: return {skipped: true,
169
+ bisect_commit: "", estimate_minutes: 0, log_path: ""} and continue.
170
+ out: BisectResult
171
+ attempts: 2
231
172
 
232
173
  - id: scope_check
233
- function: scope_check
234
- inputs:
235
- task: "$.input.task"
236
- diagnosis: "$.steps.diagnose.output"
237
- depends_on: [bisect]
174
+ after: [bisect]
175
+ agent: claude
176
+ do: >
177
+ If the diagnosis of ${input.task} shows the root cause involves a
178
+ provider switch, field rename, config key change, or anything spanning
179
+ multiple repos or layers: grep ALL configured project repos for every
180
+ reference to the affected term.
181
+
182
+ The diagnosis: root cause ${diagnose.output.root_cause}; affected
183
+ layers ${diagnose.output.affected_layers}; scope hint
184
+ ${diagnose.output.scope_hint}; trace evidence
185
+ ${diagnose.output.trace_evidence}.
186
+
187
+ Return the full reference list grouped by repo in references_found —
188
+ the fix step gets its cross-layer worklist from that field and from
189
+ nothing else, so an omitted reference is a reference nobody fixes.
190
+ If the change is single-layer, return scope: 'single' and skip.
191
+ This prevents incremental multi-layer discovery (fixing one layer,
192
+ deploying, discovering the next layer is broken, repeat).
193
+ out: ScopeResult
194
+ attempts: 2
238
195
 
239
196
  - id: fix
240
- function: fix
241
- inputs:
242
- task: "$.input.task"
243
- scope: "$.steps.scope_check.output"
244
- depends_on: [scope_check]
197
+ after: [scope_check]
198
+ agent: claude
199
+ do: >
200
+ Implement the minimal correct fix for the diagnosed root cause of
201
+ ${input.task}: ${diagnose.output.root_cause}, affecting
202
+ ${diagnose.output.affected_layers}.
203
+
204
+ scope_check reported scope ${scope_check.output.scope} with
205
+ ${scope_check.output.references_count} cross-layer references. They are:
206
+ ${scope_check.output.references_found}
207
+ Address EVERY one of them in coordinated commits — do not leave any
208
+ reference unaddressed.
209
+
210
+ Change only what is necessary. Return a summary of changes made, and set
211
+ references_addressed to how many of those references you fixed.
212
+ out: BugFixResult
213
+ ensure:
214
+ - expr: "result.outcome == 'complete'"
215
+ attempts: 3
245
216
 
246
217
  - id: test
247
- function: test
248
- inputs:
249
- task: "$.input.task"
250
- depends_on: [fix]
218
+ after: [fix]
219
+ agent: claude
220
+ do: >
221
+ Run the full test suite. Return structured JSON:
222
+ { "passing": boolean, "summary": string, "failures": string[] }.
223
+ out: TestResult
224
+ ensure:
225
+ - expr: "result.passing == true"
226
+ attempts: 6
251
227
 
252
228
  - id: verify
253
- function: verify
254
- inputs:
255
- task: "$.input.task"
256
- depends_on: [test]
229
+ after: [test]
230
+ agent: claude
231
+ do: >
232
+ Re-run the reproduction test from step 1. Confirm it now passes.
233
+ Return a summary confirming the fix resolves the original bug:
234
+ ${input.task}.
235
+ out: BugFixResult
236
+ ensure:
237
+ - expr: "result.outcome == 'complete'"
238
+ attempts: 2
257
239
 
258
240
  - id: retro_check
259
- function: retro_check
260
- inputs:
261
- task: "$.input.task"
262
- depends_on: [verify]
241
+ after: [verify]
242
+ agent: claude
243
+ do: >
244
+ Analyze git history for this session. Detect fix chains: 2+ commits
245
+ modifying the same file or function. Count total fix attempts on the
246
+ target bug. For visual/CSS/layout bugs, enforce a hard stop at attempt 2
247
+ and flag for cross-agent escalation. Return fix_chains (list of repeated
248
+ files), attempt_count, whether escalation was triggered, and a
249
+ discipline_score (0-100).
250
+ out: RetroCheckResult
251
+ attempts: 2
263
252
 
264
253
  - id: ship
265
- function: ship
266
- inputs:
267
- task: "$.input.task"
268
- depends_on: [retro_check]
254
+ after: [retro_check]
255
+ agent: claude
256
+ do: >
257
+ Commit all changes with a descriptive message. Update CHANGELOG.md if
258
+ appropriate. Return a summary of what was shipped.
259
+ out: ShipResult
260
+ ensure:
261
+ - expr: "result.outcome == 'complete'"
262
+ attempts: 2
@@ -0,0 +1,12 @@
1
+ {
2
+ "_comment": "COMP-PIPELINE-QUARANTINE: compose-owned agent profiles for build-quick.stratum.yaml, derived from build.profiles.json exactly as the spec itself is derived from build.stratum.yaml. The TS engine accepts only the literal claude|codex agent, so the full profile strings (tool restrictions + model tier) that the v0.3->v1 conversion stripped live here, keyed by step id, and are applied compose-side at invocation (lib/build.js loadPipelineProfiles). Without this sidecar the quick path would silently run every step on bare defaults — notably losing the read-only-reviewer restriction that the isolation:none review_lenses fanout MUST bind. The blueprint entry is omitted because the quick path drops that step.",
3
+ "_reduceSteps": [
4
+ "review_merge"
5
+ ],
6
+ "_reduceSteps_comment": "H1: ReviewResult-out steps that MERGE/deduplicate rather than review. They get review normalization (confidence handling) but NOT the reviewer scaffold. This is python's stripped reduce_mode input, restored compose-side.",
7
+ "review_triage": "claude:orchestrator",
8
+ "review_lenses": "claude:read-only-reviewer",
9
+ "review_merge": "claude:orchestrator",
10
+ "run_tests": "claude::fast",
11
+ "ship": "claude::critical"
12
+ }