@zhixuan92/multi-model-agent-core 4.0.2 → 4.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (263) hide show
  1. package/README.md +20 -6
  2. package/dist/bounded-execution/activity-tracker-types.d.ts +2 -2
  3. package/dist/bounded-execution/activity-tracker-types.d.ts.map +1 -1
  4. package/dist/bounded-execution/activity-tracker.d.ts +3 -3
  5. package/dist/bounded-execution/activity-tracker.d.ts.map +1 -1
  6. package/dist/bounded-execution/activity-tracker.js +15 -15
  7. package/dist/bounded-execution/activity-tracker.js.map +1 -1
  8. package/dist/config/model-profile-registry.d.ts +0 -10
  9. package/dist/config/model-profile-registry.d.ts.map +1 -1
  10. package/dist/config/model-profile-registry.js +126 -8
  11. package/dist/config/model-profile-registry.js.map +1 -1
  12. package/dist/config/schema.d.ts +0 -1
  13. package/dist/config/schema.d.ts.map +1 -1
  14. package/dist/config/schema.js +3 -1
  15. package/dist/config/schema.js.map +1 -1
  16. package/dist/escalation/delegate-with-escalation.d.ts +24 -0
  17. package/dist/escalation/delegate-with-escalation.d.ts.map +1 -1
  18. package/dist/escalation/delegate-with-escalation.js +5 -0
  19. package/dist/escalation/delegate-with-escalation.js.map +1 -1
  20. package/dist/escalation/fallback-types.d.ts +1 -1
  21. package/dist/escalation/fallback-types.d.ts.map +1 -1
  22. package/dist/escalation/fallback.js +2 -2
  23. package/dist/escalation/fallback.js.map +1 -1
  24. package/dist/events/cloud-events.d.ts +3 -4
  25. package/dist/events/cloud-events.d.ts.map +1 -1
  26. package/dist/events/cloud-events.js +0 -1
  27. package/dist/events/cloud-events.js.map +1 -1
  28. package/dist/events/event-builder.d.ts +4 -2
  29. package/dist/events/event-builder.d.ts.map +1 -1
  30. package/dist/events/event-builder.js +47 -45
  31. package/dist/events/event-builder.js.map +1 -1
  32. package/dist/events/observability-events.d.ts +7 -8
  33. package/dist/events/observability-events.d.ts.map +1 -1
  34. package/dist/events/running-headline-sink.d.ts +26 -0
  35. package/dist/events/running-headline-sink.d.ts.map +1 -0
  36. package/dist/events/running-headline-sink.js +116 -0
  37. package/dist/events/running-headline-sink.js.map +1 -0
  38. package/dist/events/telemetry-types.d.ts +20 -20
  39. package/dist/events/telemetry-types.js +8 -8
  40. package/dist/events/telemetry-types.js.map +1 -1
  41. package/dist/events/verbose-log-channel.d.ts +22 -2
  42. package/dist/events/verbose-log-channel.d.ts.map +1 -1
  43. package/dist/events/verbose-log-channel.js +46 -9
  44. package/dist/events/verbose-log-channel.js.map +1 -1
  45. package/dist/index.d.ts +4 -1
  46. package/dist/index.d.ts.map +1 -1
  47. package/dist/index.js +4 -1
  48. package/dist/index.js.map +1 -1
  49. package/dist/intake/brief-compiler-slots/delegate.d.ts +1 -0
  50. package/dist/intake/brief-compiler-slots/delegate.d.ts.map +1 -1
  51. package/dist/intake/brief-compiler-slots/delegate.js +17 -2
  52. package/dist/intake/brief-compiler-slots/delegate.js.map +1 -1
  53. package/dist/lifecycle/diff-tracker.d.ts +72 -0
  54. package/dist/lifecycle/diff-tracker.d.ts.map +1 -0
  55. package/dist/lifecycle/diff-tracker.js +316 -0
  56. package/dist/lifecycle/diff-tracker.js.map +1 -0
  57. package/dist/lifecycle/executor-output-types.d.ts +2 -2
  58. package/dist/lifecycle/executor-output-types.d.ts.map +1 -1
  59. package/dist/lifecycle/handlers/baseline-handlers.d.ts.map +1 -1
  60. package/dist/lifecycle/handlers/baseline-handlers.js +48 -1
  61. package/dist/lifecycle/handlers/baseline-handlers.js.map +1 -1
  62. package/dist/lifecycle/handlers/prepare-execution-context-handler.d.ts +1 -1
  63. package/dist/lifecycle/handlers/prepare-execution-context-handler.d.ts.map +1 -1
  64. package/dist/lifecycle/handlers/prepare-execution-context-handler.js +23 -1
  65. package/dist/lifecycle/handlers/prepare-execution-context-handler.js.map +1 -1
  66. package/dist/lifecycle/handlers/quality-chain-handlers.d.ts.map +1 -1
  67. package/dist/lifecycle/handlers/quality-chain-handlers.js +177 -6
  68. package/dist/lifecycle/handlers/quality-chain-handlers.js.map +1 -1
  69. package/dist/lifecycle/handlers/review-diff-handler.d.ts.map +1 -1
  70. package/dist/lifecycle/handlers/review-diff-handler.js +74 -13
  71. package/dist/lifecycle/handlers/review-diff-handler.js.map +1 -1
  72. package/dist/lifecycle/handlers/run-verify-command-handler.js +11 -2
  73. package/dist/lifecycle/handlers/run-verify-command-handler.js.map +1 -1
  74. package/dist/lifecycle/handlers/spec-chain-handlers.d.ts.map +1 -1
  75. package/dist/lifecycle/handlers/spec-chain-handlers.js +135 -6
  76. package/dist/lifecycle/handlers/spec-chain-handlers.js.map +1 -1
  77. package/dist/lifecycle/handlers/terminal-handlers.d.ts +8 -0
  78. package/dist/lifecycle/handlers/terminal-handlers.d.ts.map +1 -1
  79. package/dist/lifecycle/handlers/terminal-handlers.js +168 -11
  80. package/dist/lifecycle/handlers/terminal-handlers.js.map +1 -1
  81. package/dist/lifecycle/lifecycle-context.d.ts +0 -2
  82. package/dist/lifecycle/lifecycle-context.d.ts.map +1 -1
  83. package/dist/lifecycle/merge-stage-stats.d.ts +58 -0
  84. package/dist/lifecycle/merge-stage-stats.d.ts.map +1 -0
  85. package/dist/lifecycle/merge-stage-stats.js +120 -0
  86. package/dist/lifecycle/merge-stage-stats.js.map +1 -0
  87. package/dist/lifecycle/shared-compute.js +4 -4
  88. package/dist/lifecycle/shared-compute.js.map +1 -1
  89. package/dist/lifecycle/stage-plan-builder.d.ts.map +1 -1
  90. package/dist/lifecycle/stage-plan-builder.js +6 -0
  91. package/dist/lifecycle/stage-plan-builder.js.map +1 -1
  92. package/dist/lifecycle/stage-plan-types.d.ts +18 -0
  93. package/dist/lifecycle/stage-plan-types.d.ts.map +1 -1
  94. package/dist/lifecycle/stage-progression.d.ts +20 -0
  95. package/dist/lifecycle/stage-progression.d.ts.map +1 -0
  96. package/dist/lifecycle/stage-progression.js +165 -0
  97. package/dist/lifecycle/stage-progression.js.map +1 -0
  98. package/dist/lifecycle/task-executor.d.ts.map +1 -1
  99. package/dist/lifecycle/task-executor.js +55 -10
  100. package/dist/lifecycle/task-executor.js.map +1 -1
  101. package/dist/lifecycle/task-runner.d.ts +7 -3
  102. package/dist/lifecycle/task-runner.d.ts.map +1 -1
  103. package/dist/lifecycle/task-runner.js +43 -7
  104. package/dist/lifecycle/task-runner.js.map +1 -1
  105. package/dist/providers/anthropic-messages-adapter.d.ts.map +1 -1
  106. package/dist/providers/anthropic-messages-adapter.js +25 -1
  107. package/dist/providers/anthropic-messages-adapter.js.map +1 -1
  108. package/dist/providers/base/result-builders.d.ts +1 -1
  109. package/dist/providers/base/result-builders.d.ts.map +1 -1
  110. package/dist/providers/base/result-builders.js +4 -4
  111. package/dist/providers/base/result-builders.js.map +1 -1
  112. package/dist/providers/make-runner-shell.d.ts.map +1 -1
  113. package/dist/providers/make-runner-shell.js +6 -5
  114. package/dist/providers/make-runner-shell.js.map +1 -1
  115. package/dist/providers/openai-chat-adapter.d.ts +0 -2
  116. package/dist/providers/openai-chat-adapter.d.ts.map +1 -1
  117. package/dist/providers/openai-chat-adapter.js +2 -3
  118. package/dist/providers/openai-chat-adapter.js.map +1 -1
  119. package/dist/providers/openai-responses-adapter.d.ts +1 -2
  120. package/dist/providers/openai-responses-adapter.d.ts.map +1 -1
  121. package/dist/providers/openai-responses-adapter.js +67 -39
  122. package/dist/providers/openai-responses-adapter.js.map +1 -1
  123. package/dist/providers/provider-factory.d.ts.map +1 -1
  124. package/dist/providers/provider-factory.js +51 -9
  125. package/dist/providers/provider-factory.js.map +1 -1
  126. package/dist/providers/runner-adapter.d.ts +10 -0
  127. package/dist/providers/runner-adapter.d.ts.map +1 -1
  128. package/dist/providers/runner-shell-types.d.ts +33 -0
  129. package/dist/providers/runner-shell-types.d.ts.map +1 -1
  130. package/dist/providers/runner-shell.d.ts +10 -1
  131. package/dist/providers/runner-shell.d.ts.map +1 -1
  132. package/dist/providers/runner-shell.js +251 -18
  133. package/dist/providers/runner-shell.js.map +1 -1
  134. package/dist/providers/runner-types.d.ts +21 -2
  135. package/dist/providers/runner-types.d.ts.map +1 -1
  136. package/dist/providers/tool-name-sets.d.ts +29 -0
  137. package/dist/providers/tool-name-sets.d.ts.map +1 -0
  138. package/dist/providers/tool-name-sets.js +41 -0
  139. package/dist/providers/tool-name-sets.js.map +1 -0
  140. package/dist/reporting/headline-composer.d.ts +12 -0
  141. package/dist/reporting/headline-composer.d.ts.map +1 -1
  142. package/dist/reporting/headline-composer.js.map +1 -1
  143. package/dist/reporting/headline-templates/audit.d.ts.map +1 -1
  144. package/dist/reporting/headline-templates/audit.js +35 -6
  145. package/dist/reporting/headline-templates/audit.js.map +1 -1
  146. package/dist/reporting/headline-templates/debug.d.ts +22 -3
  147. package/dist/reporting/headline-templates/debug.d.ts.map +1 -1
  148. package/dist/reporting/headline-templates/debug.js +38 -8
  149. package/dist/reporting/headline-templates/debug.js.map +1 -1
  150. package/dist/reporting/headline-templates/delegate.d.ts.map +1 -1
  151. package/dist/reporting/headline-templates/delegate.js +36 -6
  152. package/dist/reporting/headline-templates/delegate.js.map +1 -1
  153. package/dist/reporting/headline-templates/execute-plan.d.ts.map +1 -1
  154. package/dist/reporting/headline-templates/execute-plan.js +18 -6
  155. package/dist/reporting/headline-templates/execute-plan.js.map +1 -1
  156. package/dist/reporting/headline-templates/review.d.ts.map +1 -1
  157. package/dist/reporting/headline-templates/review.js +32 -8
  158. package/dist/reporting/headline-templates/review.js.map +1 -1
  159. package/dist/reporting/headline-templates/verify.d.ts.map +1 -1
  160. package/dist/reporting/headline-templates/verify.js +23 -6
  161. package/dist/reporting/headline-templates/verify.js.map +1 -1
  162. package/dist/reporting/headline-text.d.ts +36 -0
  163. package/dist/reporting/headline-text.d.ts.map +1 -0
  164. package/dist/reporting/headline-text.js +73 -0
  165. package/dist/reporting/headline-text.js.map +1 -0
  166. package/dist/reporting/report-parser-slots/verify-report.d.ts +17 -0
  167. package/dist/reporting/report-parser-slots/verify-report.d.ts.map +1 -1
  168. package/dist/reporting/report-parser-slots/verify-report.js +45 -3
  169. package/dist/reporting/report-parser-slots/verify-report.js.map +1 -1
  170. package/dist/reporting/severity.d.ts +62 -0
  171. package/dist/reporting/severity.d.ts.map +1 -0
  172. package/dist/reporting/severity.js +93 -0
  173. package/dist/reporting/severity.js.map +1 -0
  174. package/dist/reporting/structured-report.d.ts +3 -3
  175. package/dist/research/explore-orchestrator.d.ts.map +1 -1
  176. package/dist/research/explore-orchestrator.js +4 -5
  177. package/dist/research/explore-orchestrator.js.map +1 -1
  178. package/dist/review/annotator-engine.d.ts +8 -0
  179. package/dist/review/annotator-engine.d.ts.map +1 -1
  180. package/dist/review/annotator-engine.js +7 -1
  181. package/dist/review/annotator-engine.js.map +1 -1
  182. package/dist/review/annotator-output-parser.d.ts.map +1 -1
  183. package/dist/review/annotator-output-parser.js +94 -14
  184. package/dist/review/annotator-output-parser.js.map +1 -1
  185. package/dist/review/annotator-prompt-builder.d.ts +20 -0
  186. package/dist/review/annotator-prompt-builder.d.ts.map +1 -1
  187. package/dist/review/annotator-prompt-builder.js +52 -1
  188. package/dist/review/annotator-prompt-builder.js.map +1 -1
  189. package/dist/review/review-types.d.ts +6 -2
  190. package/dist/review/review-types.d.ts.map +1 -1
  191. package/dist/review/reviewer-engine.d.ts +25 -0
  192. package/dist/review/reviewer-engine.d.ts.map +1 -1
  193. package/dist/review/reviewer-engine.js +18 -1
  194. package/dist/review/reviewer-engine.js.map +1 -1
  195. package/dist/review/reviewer-output-parser.d.ts.map +1 -1
  196. package/dist/review/reviewer-output-parser.js +190 -13
  197. package/dist/review/reviewer-output-parser.js.map +1 -1
  198. package/dist/review/reviewer-prompt-builder.d.ts +4 -12
  199. package/dist/review/reviewer-prompt-builder.d.ts.map +1 -1
  200. package/dist/review/reviewer-prompt-builder.js.map +1 -1
  201. package/dist/review/templates/diff-review.d.ts +8 -0
  202. package/dist/review/templates/diff-review.d.ts.map +1 -1
  203. package/dist/review/templates/diff-review.js +34 -2
  204. package/dist/review/templates/diff-review.js.map +1 -1
  205. package/dist/review/templates/finding-criteria.d.ts +39 -0
  206. package/dist/review/templates/finding-criteria.d.ts.map +1 -0
  207. package/dist/review/templates/finding-criteria.js +80 -0
  208. package/dist/review/templates/finding-criteria.js.map +1 -0
  209. package/dist/review/templates/quality-review-artifact.d.ts +13 -0
  210. package/dist/review/templates/quality-review-artifact.d.ts.map +1 -1
  211. package/dist/review/templates/quality-review-artifact.js +41 -3
  212. package/dist/review/templates/quality-review-artifact.js.map +1 -1
  213. package/dist/review/templates/shared.d.ts +22 -5
  214. package/dist/review/templates/shared.d.ts.map +1 -1
  215. package/dist/review/templates/spec-review.d.ts +15 -0
  216. package/dist/review/templates/spec-review.d.ts.map +1 -1
  217. package/dist/review/templates/spec-review.js +43 -3
  218. package/dist/review/templates/spec-review.js.map +1 -1
  219. package/dist/stores/batch-registry.d.ts +18 -0
  220. package/dist/stores/batch-registry.d.ts.map +1 -1
  221. package/dist/stores/batch-registry.js +10 -0
  222. package/dist/stores/batch-registry.js.map +1 -1
  223. package/dist/stores/context-block-tool.d.ts +14 -0
  224. package/dist/stores/context-block-tool.d.ts.map +1 -1
  225. package/dist/stores/context-block-tool.js.map +1 -1
  226. package/dist/stores/file-backed-context-block-store.d.ts +63 -0
  227. package/dist/stores/file-backed-context-block-store.d.ts.map +1 -0
  228. package/dist/stores/file-backed-context-block-store.js +293 -0
  229. package/dist/stores/file-backed-context-block-store.js.map +1 -0
  230. package/dist/stores/project-context-registry.d.ts +16 -3
  231. package/dist/stores/project-context-registry.d.ts.map +1 -1
  232. package/dist/stores/project-context-registry.js +9 -2
  233. package/dist/stores/project-context-registry.js.map +1 -1
  234. package/dist/tools/audit/schema.d.ts +2 -2
  235. package/dist/tools/audit/tool-config.d.ts.map +1 -1
  236. package/dist/tools/audit/tool-config.js +23 -6
  237. package/dist/tools/audit/tool-config.js.map +1 -1
  238. package/dist/tools/debug/tool-config.d.ts.map +1 -1
  239. package/dist/tools/debug/tool-config.js +17 -4
  240. package/dist/tools/debug/tool-config.js.map +1 -1
  241. package/dist/tools/execute-plan/tool-config.d.ts.map +1 -1
  242. package/dist/tools/execute-plan/tool-config.js +5 -1
  243. package/dist/tools/execute-plan/tool-config.js.map +1 -1
  244. package/dist/tools/investigate/tool-config.d.ts +13 -1
  245. package/dist/tools/investigate/tool-config.d.ts.map +1 -1
  246. package/dist/tools/investigate/tool-config.js +34 -4
  247. package/dist/tools/investigate/tool-config.js.map +1 -1
  248. package/dist/tools/retry/tool-config.d.ts.map +1 -1
  249. package/dist/tools/retry/tool-config.js +28 -5
  250. package/dist/tools/retry/tool-config.js.map +1 -1
  251. package/dist/tools/review/schema.d.ts +1 -1
  252. package/dist/tools/review/tool-config.d.ts.map +1 -1
  253. package/dist/tools/review/tool-config.js +19 -4
  254. package/dist/tools/review/tool-config.js.map +1 -1
  255. package/dist/tools/verify/tool-config.d.ts.map +1 -1
  256. package/dist/tools/verify/tool-config.js +17 -4
  257. package/dist/tools/verify/tool-config.js.map +1 -1
  258. package/dist/types/enums.d.ts +10 -10
  259. package/package.json +5 -1
  260. package/dist/intake/brief-compiler-slots/investigate.d.ts +0 -26
  261. package/dist/intake/brief-compiler-slots/investigate.d.ts.map +0 -1
  262. package/dist/intake/brief-compiler-slots/investigate.js +0 -42
  263. package/dist/intake/brief-compiler-slots/investigate.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"debug.d.ts","sourceRoot":"","sources":["../../../src/reporting/headline-templates/debug.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEhE;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,EAAE,gBAQnC,CAAC"}
1
+ {"version":3,"file":"debug.d.ts","sourceRoot":"","sources":["../../../src/reporting/headline-templates/debug.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAGhE;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,qBAAqB,EAAE,gBAsBnC,CAAC"}
@@ -1,15 +1,45 @@
1
+ import { countHighOrCritical, parseNarrativeFindings } from '../severity.js';
1
2
  /**
2
- * Compose a terminal headline for debug. Matches the composeTerminalHeadline
3
- * format that the legacy executor produced: "debug: 1/1 tasks complete".
4
- * Debug always dispatches exactly 1 task.
3
+ * Compose a terminal headline for debug.
4
+ *
5
+ * Tool sweep #4 rewrite: bring debug into the same shape as audit and
6
+ * review/verify so operator-facing logs stay consistent across tools:
7
+ *
8
+ * [ok] debug <path>: 3 findings (0 high)
9
+ * [error] debug: 1 findings (1 high)
10
+ * [ok] debug completed
11
+ *
12
+ * Previously emitted "debug: 1/1 tasks complete" with no status prefix
13
+ * and no findings count — operator could not tell ok from error and
14
+ * had no signal about how many real findings landed.
15
+ *
16
+ * Source priority for findings (parallel to audit):
17
+ * 1. runResult.annotatedFindings (canonical — annotator's structured
18
+ * output when verdict='annotated').
19
+ * 2. parseNarrativeFindings(runResult.output) — recovers `## Finding N:`
20
+ * blocks from the implementer's narrative when the annotator errored.
21
+ *
22
+ * Note: debug's reportSchema.parse is intentionally a thrower (the tool
23
+ * doesn't emit a structured report), so `report` is always notApplicable
24
+ * here — there's no `report.findings` source to read.
5
25
  */
6
26
  export const debugHeadlineTemplate = {
7
- compose({ report }) {
8
- const r = report;
9
- if (r && typeof r.rootCause === 'string' && r.rootCause.length > 0) {
10
- return `debug: root cause ${r.rootCause}`;
27
+ compose({ status, runResult, task }) {
28
+ const annotated = runResult?.annotatedFindings ?? [];
29
+ let findings = annotated;
30
+ if (findings.length === 0 && typeof runResult?.output === 'string') {
31
+ const narrative = parseNarrativeFindings(runResult.output);
32
+ if (narrative.length > 0)
33
+ findings = narrative;
11
34
  }
12
- return 'debug: 1/1 tasks complete';
35
+ const path = task?.filePaths?.[0] || '';
36
+ if (findings.length === 0 && !path) {
37
+ return `[${status}] debug completed`;
38
+ }
39
+ const high = countHighOrCritical(findings);
40
+ return path
41
+ ? `[${status}] debug ${path}: ${findings.length} findings (${high} high)`
42
+ : `[${status}] debug: ${findings.length} findings (${high} high)`;
13
43
  },
14
44
  };
15
45
  //# sourceMappingURL=debug.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"debug.js","sourceRoot":"","sources":["../../../src/reporting/headline-templates/debug.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAqB;IACrD,OAAO,CAAC,EAAE,MAAM,EAAE;QAChB,MAAM,CAAC,GAAG,MAA6C,CAAC;QACxD,IAAI,CAAC,IAAI,OAAO,CAAC,CAAC,SAAS,KAAK,QAAQ,IAAI,CAAC,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACnE,OAAO,uBAAuB,CAAC,CAAC,SAAS,EAAE,CAAC;QAC9C,CAAC;QACD,OAAO,2BAA2B,CAAC;IACrC,CAAC;CACF,CAAC"}
1
+ {"version":3,"file":"debug.js","sourceRoot":"","sources":["../../../src/reporting/headline-templates/debug.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAE7E;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAqB;IACrD,OAAO,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE;QACjC,MAAM,SAAS,GAAG,SAAS,EAAE,iBAAiB,IAAI,EAAE,CAAC;QACrD,IAAI,QAAQ,GACV,SAA0C,CAAC;QAC7C,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,SAAS,EAAE,MAAM,KAAK,QAAQ,EAAE,CAAC;YACnE,MAAM,SAAS,GAAG,sBAAsB,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YAC3D,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC;gBAAE,QAAQ,GAAG,SAAS,CAAC;QACjD,CAAC;QAED,MAAM,IAAI,GACP,IAA6C,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAEvE,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YACnC,OAAO,IAAI,MAAM,mBAAmB,CAAC;QACvC,CAAC;QAED,MAAM,IAAI,GAAG,mBAAmB,CAAC,QAAQ,CAAC,CAAC;QAC3C,OAAO,IAAI;YACT,CAAC,CAAC,IAAI,MAAM,WAAW,IAAI,KAAK,QAAQ,CAAC,MAAM,cAAc,IAAI,QAAQ;YACzE,CAAC,CAAC,IAAI,MAAM,YAAY,QAAQ,CAAC,MAAM,cAAc,IAAI,QAAQ,CAAC;IACtE,CAAC;CACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"delegate.d.ts","sourceRoot":"","sources":["../../../src/reporting/headline-templates/delegate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAIhE,eAAO,MAAM,wBAAwB,EAAE,gBAQtC,CAAC"}
1
+ {"version":3,"file":"delegate.d.ts","sourceRoot":"","sources":["../../../src/reporting/headline-templates/delegate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAKhE,eAAO,MAAM,wBAAwB,EAAE,gBA0CtC,CAAC"}
@@ -1,12 +1,42 @@
1
1
  import { isNotApplicable } from '../not-applicable.js';
2
+ import { firstSentenceOrTruncate } from '../headline-text.js';
2
3
  export const delegateHeadlineTemplate = {
3
- compose({ report, status }) {
4
- if (!report || isNotApplicable(report))
5
- return `[${status}] no structured report available`;
4
+ compose({ report, status, runResult }) {
6
5
  const r = report;
7
- const files = Array.isArray(r.filesChanged) ? r.filesChanged : [];
8
- const summary = typeof r.summary === 'string' ? r.summary : '';
9
- return `[${status}] ${summary} (${files.length} file${files.length === 1 ? '' : 's'})`;
6
+ const reportInapplicable = !r || isNotApplicable(r);
7
+ // Gap 13 fix (4.0.3+): file count source priority is
8
+ // `report.filesChanged` (rare only when the worker emits proper
9
+ // structured output) → `runResult.filesWritten` (canonical
10
+ // runner-shell signal that always reflects reality, including
11
+ // synthetic `shell:<cmd>` entries from Gap 11). Pre-fix, the
12
+ // composer only read report.filesChanged and reported "(0 files)"
13
+ // even when the worker had successfully edited files via
14
+ // edit_file or run_shell.
15
+ const reportFiles = !reportInapplicable && Array.isArray(r?.filesChanged) ? r.filesChanged : [];
16
+ const runFiles = Array.isArray(runResult?.filesWritten) ? runResult.filesWritten : [];
17
+ const fileCount = reportFiles.length > 0 ? reportFiles.length : runFiles.length;
18
+ if (reportInapplicable && fileCount === 0) {
19
+ return `[${status}] delegate: no structured report available`;
20
+ }
21
+ // Gap 12 fix (4.0.3+): trim worker's narrative `summary` to first
22
+ // sentence (or 80-char truncate). Pre-fix, the entire summary —
23
+ // sometimes multi-sentence prose ending mid-thought — was inlined
24
+ // into the headline.
25
+ //
26
+ // Tool sweep #6 follow-up: when the structured report carries no
27
+ // summary, fall back to the worker's `output` text (also trimmed to
28
+ // first sentence) so the headline is informative even on no-op /
29
+ // 0-file outcomes. Pre-fix, those collapsed to `[incomplete] (0
30
+ // files)` with NO clue why.
31
+ const rawSummary = (!reportInapplicable && typeof r?.summary === 'string' && r.summary.length > 0)
32
+ ? r.summary
33
+ : (typeof runResult?.output === 'string' ? runResult.output : '');
34
+ const summary = firstSentenceOrTruncate(rawSummary);
35
+ const summaryClause = summary.length > 0 ? ` ${summary}` : '';
36
+ // Tool sweep #6 follow-up: prefix with `delegate:` for parity with
37
+ // audit / review / verify / debug / investigate headlines so the
38
+ // operator can tell the route at a glance.
39
+ return `[${status}] delegate:${summaryClause} (${fileCount} file${fileCount === 1 ? '' : 's'})`;
10
40
  },
11
41
  };
12
42
  //# sourceMappingURL=delegate.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"delegate.js","sourceRoot":"","sources":["../../../src/reporting/headline-templates/delegate.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,MAAM,CAAC,MAAM,wBAAwB,GAAqB;IACxD,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE;QACxB,IAAI,CAAC,MAAM,IAAI,eAAe,CAAC,MAAM,CAAC;YAAE,OAAO,IAAI,MAAM,kCAAkC,CAAC;QAC5F,MAAM,CAAC,GAAG,MAAkC,CAAC;QAC7C,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;QAClE,MAAM,OAAO,GAAG,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/D,OAAO,IAAI,MAAM,KAAK,OAAO,KAAK,KAAK,CAAC,MAAM,QAAQ,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;IACzF,CAAC;CACF,CAAC"}
1
+ {"version":3,"file":"delegate.js","sourceRoot":"","sources":["../../../src/reporting/headline-templates/delegate.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAE9D,MAAM,CAAC,MAAM,wBAAwB,GAAqB;IACxD,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE;QACnC,MAAM,CAAC,GAAG,MAA8D,CAAC;QACzE,MAAM,kBAAkB,GAAG,CAAC,CAAC,IAAI,eAAe,CAAC,CAAC,CAAC,CAAC;QAEpD,qDAAqD;QACrD,kEAAkE;QAClE,2DAA2D;QAC3D,8DAA8D;QAC9D,6DAA6D;QAC7D,kEAAkE;QAClE,yDAAyD;QACzD,0BAA0B;QAC1B,MAAM,WAAW,GAAG,CAAC,kBAAkB,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;QACjG,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,SAAU,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;QACvF,MAAM,SAAS,GAAG,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC;QAEhF,IAAI,kBAAkB,IAAI,SAAS,KAAK,CAAC,EAAE,CAAC;YAC1C,OAAO,IAAI,MAAM,4CAA4C,CAAC;QAChE,CAAC;QAED,kEAAkE;QAClE,gEAAgE;QAChE,kEAAkE;QAClE,qBAAqB;QACrB,EAAE;QACF,iEAAiE;QACjE,oEAAoE;QACpE,iEAAiE;QACjE,gEAAgE;QAChE,4BAA4B;QAC5B,MAAM,UAAU,GAAG,CAAC,CAAC,kBAAkB,IAAI,OAAO,CAAC,EAAE,OAAO,KAAK,QAAQ,IAAI,CAAC,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;YAChG,CAAC,CAAC,CAAC,CAAC,OAAO;YACX,CAAC,CAAC,CAAC,OAAO,SAAS,EAAE,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACpE,MAAM,OAAO,GAAG,uBAAuB,CAAC,UAAU,CAAC,CAAC;QAEpD,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9D,mEAAmE;QACnE,iEAAiE;QACjE,2CAA2C;QAC3C,OAAO,IAAI,MAAM,cAAc,aAAa,KAAK,SAAS,QAAQ,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;IAClG,CAAC;CACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"execute-plan.d.ts","sourceRoot":"","sources":["../../../src/reporting/headline-templates/execute-plan.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAYhE,eAAO,MAAM,2BAA2B,EAAE,gBAczC,CAAC"}
1
+ {"version":3,"file":"execute-plan.d.ts","sourceRoot":"","sources":["../../../src/reporting/headline-templates/execute-plan.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAahE,eAAO,MAAM,2BAA2B,EAAE,gBAyBzC,CAAC"}
@@ -1,14 +1,26 @@
1
+ import { firstSentenceOrTruncate } from '../headline-text.js';
1
2
  export const executePlanHeadlineTemplate = {
2
- compose({ report, status }) {
3
+ compose({ report, status, runResult }) {
3
4
  const r = report;
5
+ // Tool sweep #7 (execute-plan): use the dash-cased route name
6
+ // `execute-plan` to match the HTTP path + envelope shapes (the
7
+ // pre-fix `execute_plan` underscore was the only tool diverging
8
+ // from kebab-case in operator-facing output) and ALWAYS include
9
+ // the [<status>] prefix for parity with audit/review/verify/debug/
10
+ // delegate.
4
11
  if (r?.taskOutcomes && Array.isArray(r.taskOutcomes) && r.taskOutcomes.length > 0) {
5
12
  const completed = r.taskOutcomes.filter((t) => t.status === 'completed' || t.status === 'success').length;
6
- return `execute_plan: ${completed}/${r.taskOutcomes.length} tasks complete`;
13
+ return `[${status}] execute-plan: ${completed}/${r.taskOutcomes.length} tasks complete`;
7
14
  }
8
- if (r?.summary && typeof r.summary === 'string') {
9
- return `[${status}] execute_plan: ${r.summary}`;
10
- }
11
- return `[${status}] execute_plan`;
15
+ // Tool sweep #7: fall back to runResult.output when report has no
16
+ // summary. Mirrors the delegate fix — operator gets a meaningful
17
+ // reason on no-op outcomes instead of a bare `[<status>] execute-plan`.
18
+ const fallbackSrc = (r?.summary && typeof r.summary === 'string' && r.summary.length > 0)
19
+ ? r.summary
20
+ : (typeof runResult?.output === 'string' ? runResult.output : '');
21
+ const summary = firstSentenceOrTruncate(fallbackSrc);
22
+ const summaryClause = summary.length > 0 ? ` ${summary}` : '';
23
+ return `[${status}] execute-plan:${summaryClause}`;
12
24
  },
13
25
  };
14
26
  //# sourceMappingURL=execute-plan.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"execute-plan.js","sourceRoot":"","sources":["../../../src/reporting/headline-templates/execute-plan.ts"],"names":[],"mappings":"AAYA,MAAM,CAAC,MAAM,2BAA2B,GAAqB;IAC3D,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE;QACxB,MAAM,CAAC,GAAG,MAA2C,CAAC;QACtD,IAAI,CAAC,EAAE,YAAY,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClF,MAAM,SAAS,GAAG,CAAC,CAAC,YAAY,CAAC,MAAM,CACrC,CAAC,CAAc,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS,CACvE,CAAC,MAAM,CAAC;YACT,OAAO,iBAAiB,SAAS,IAAI,CAAC,CAAC,YAAY,CAAC,MAAM,iBAAiB,CAAC;QAC9E,CAAC;QACD,IAAI,CAAC,EAAE,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;YAChD,OAAO,IAAI,MAAM,mBAAmB,CAAC,CAAC,OAAO,EAAE,CAAC;QAClD,CAAC;QACD,OAAO,IAAI,MAAM,gBAAgB,CAAC;IACpC,CAAC;CACF,CAAC"}
1
+ {"version":3,"file":"execute-plan.js","sourceRoot":"","sources":["../../../src/reporting/headline-templates/execute-plan.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAY9D,MAAM,CAAC,MAAM,2BAA2B,GAAqB;IAC3D,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE;QACnC,MAAM,CAAC,GAAG,MAA2C,CAAC;QACtD,8DAA8D;QAC9D,+DAA+D;QAC/D,gEAAgE;QAChE,gEAAgE;QAChE,mEAAmE;QACnE,YAAY;QACZ,IAAI,CAAC,EAAE,YAAY,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClF,MAAM,SAAS,GAAG,CAAC,CAAC,YAAY,CAAC,MAAM,CACrC,CAAC,CAAc,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS,CACvE,CAAC,MAAM,CAAC;YACT,OAAO,IAAI,MAAM,mBAAmB,SAAS,IAAI,CAAC,CAAC,YAAY,CAAC,MAAM,iBAAiB,CAAC;QAC1F,CAAC;QACD,kEAAkE;QAClE,iEAAiE;QACjE,wEAAwE;QACxE,MAAM,WAAW,GAAG,CAAC,CAAC,EAAE,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,IAAI,CAAC,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;YACvF,CAAC,CAAC,CAAC,CAAC,OAAO;YACX,CAAC,CAAC,CAAC,OAAO,SAAS,EAAE,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACpE,MAAM,OAAO,GAAG,uBAAuB,CAAC,WAAW,CAAC,CAAC;QACrD,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9D,OAAO,IAAI,MAAM,kBAAkB,aAAa,EAAE,CAAC;IACrD,CAAC;CACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"review.d.ts","sourceRoot":"","sources":["../../../src/reporting/headline-templates/review.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAIhE,eAAO,MAAM,sBAAsB,EAAE,gBAYpC,CAAC"}
1
+ {"version":3,"file":"review.d.ts","sourceRoot":"","sources":["../../../src/reporting/headline-templates/review.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAKhE,eAAO,MAAM,sBAAsB,EAAE,gBAwCpC,CAAC"}
@@ -1,15 +1,39 @@
1
1
  import { isNotApplicable } from '../not-applicable.js';
2
+ import { countHighOrCritical, parseNarrativeFindings } from '../severity.js';
2
3
  export const reviewHeadlineTemplate = {
3
- compose({ report, status, taskBrief }) {
4
- if (isNotApplicable(report)) {
5
- return `[${status}] review: ${taskBrief}`;
6
- }
4
+ compose({ report, status, taskBrief, runResult, task }) {
7
5
  const r = report;
8
- if (!r?.findings) {
9
- return `[${status}] review: ${taskBrief}`;
6
+ const reportInapplicable = !r || isNotApplicable(r);
7
+ // Source priority (4.0.3+, parallel to audit):
8
+ // 1. report.findings (structured)
9
+ // 2. runResult.annotatedFindings (annotator success path)
10
+ // 3. parseNarrativeFindings(runResult.output) (annotator error
11
+ // fallback — recover from implementer's `## Finding N:` blocks)
12
+ const reportFindings = !reportInapplicable && Array.isArray(r?.findings) ? r.findings : [];
13
+ const annotated = runResult?.annotatedFindings ?? [];
14
+ let findings = reportFindings.length > 0
15
+ ? reportFindings
16
+ : annotated;
17
+ if (findings.length === 0 && typeof runResult?.output === 'string') {
18
+ const narrative = parseNarrativeFindings(runResult.output);
19
+ if (narrative.length > 0)
20
+ findings = narrative;
21
+ }
22
+ const blocking = countHighOrCritical(findings);
23
+ const path = (!reportInapplicable && typeof r?.filePath === 'string' ? r.filePath : '')
24
+ || task?.filePaths?.[0]
25
+ || '';
26
+ // Mirror audit's gap-A fix: only collapse to "review completed"
27
+ // when we have no path AND no findings. With a path, always emit
28
+ // the structured form so a clean review still names the file:
29
+ // [ok] review packages/foo.ts: 0 findings (0 blocking)
30
+ // Previously this branch fell back to `${taskBrief}` which the
31
+ // brief compiler reduces to the route name, producing the
32
+ // operator-useless headline "[ok] review: review".
33
+ if (findings.length === 0 && !path) {
34
+ return `[${status}] review completed`;
10
35
  }
11
- const blocking = r.findings.filter(f => f.severity === 'high').length;
12
- return `[${status}] review ${r.filePath}: ${r.findings.length} findings (${blocking} blocking)`;
36
+ return `[${status}] review ${path}: ${findings.length} findings (${blocking} blocking)`;
13
37
  },
14
38
  };
15
39
  //# sourceMappingURL=review.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"review.js","sourceRoot":"","sources":["../../../src/reporting/headline-templates/review.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,MAAM,CAAC,MAAM,sBAAsB,GAAqB;IACtD,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE;QACnC,IAAI,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC;YAC5B,OAAO,IAAI,MAAM,aAAa,SAAS,EAAE,CAAC;QAC5C,CAAC;QACD,MAAM,CAAC,GAAG,MAAsB,CAAC;QACjC,IAAI,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC;YACjB,OAAO,IAAI,MAAM,aAAa,SAAS,EAAE,CAAC;QAC5C,CAAC;QACD,MAAM,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;QACtE,OAAO,IAAI,MAAM,YAAY,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,QAAQ,CAAC,MAAM,cAAc,QAAQ,YAAY,CAAC;IAClG,CAAC;CACF,CAAC"}
1
+ {"version":3,"file":"review.js","sourceRoot":"","sources":["../../../src/reporting/headline-templates/review.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAE7E,MAAM,CAAC,MAAM,sBAAsB,GAAqB;IACtD,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE;QACpD,MAAM,CAAC,GAAG,MAAkD,CAAC;QAC7D,MAAM,kBAAkB,GAAG,CAAC,CAAC,IAAI,eAAe,CAAC,CAAC,CAAC,CAAC;QAEpD,+CAA+C;QAC/C,oCAAoC;QACpC,4DAA4D;QAC5D,iEAAiE;QACjE,qEAAqE;QACrE,MAAM,cAAc,GAAG,CAAC,kBAAkB,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5F,MAAM,SAAS,GAAG,SAAS,EAAE,iBAAiB,IAAI,EAAE,CAAC;QACrD,IAAI,QAAQ,GACV,cAAc,CAAC,MAAM,GAAG,CAAC;YACvB,CAAC,CAAE,cAAgD;YACnD,CAAC,CAAE,SAA2C,CAAC;QACnD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,SAAS,EAAE,MAAM,KAAK,QAAQ,EAAE,CAAC;YACnE,MAAM,SAAS,GAAG,sBAAsB,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YAC3D,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC;gBAAE,QAAQ,GAAG,SAAS,CAAC;QACjD,CAAC;QAED,MAAM,QAAQ,GAAG,mBAAmB,CAAC,QAAQ,CAAC,CAAC;QAC/C,MAAM,IAAI,GACR,CAAC,CAAC,kBAAkB,IAAI,OAAO,CAAC,EAAE,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;eACvE,IAA6C,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;eAC9D,EAAE,CAAC;QAER,gEAAgE;QAChE,iEAAiE;QACjE,8DAA8D;QAC9D,yDAAyD;QACzD,+DAA+D;QAC/D,0DAA0D;QAC1D,mDAAmD;QACnD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YACnC,OAAO,IAAI,MAAM,oBAAoB,CAAC;QACxC,CAAC;QAED,OAAO,IAAI,MAAM,YAAY,IAAI,KAAK,QAAQ,CAAC,MAAM,cAAc,QAAQ,YAAY,CAAC;IAC1F,CAAC;CACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../../src/reporting/headline-templates/verify.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAIhE,eAAO,MAAM,sBAAsB,EAAE,gBAQpC,CAAC"}
1
+ {"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../../src/reporting/headline-templates/verify.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAIhE,eAAO,MAAM,sBAAsB,EAAE,gBA8BpC,CAAC"}
@@ -1,12 +1,29 @@
1
+ import { parseVerifyResults } from '../report-parser-slots/verify-report.js';
1
2
  import { isNotApplicable } from '../not-applicable.js';
2
3
  export const verifyHeadlineTemplate = {
3
- compose({ report, status }) {
4
- if (!report || isNotApplicable(report))
5
- return `[${status}] verify: no structured report available`;
4
+ compose({ report, status, runResult, task }) {
6
5
  const r = report;
7
- const items = Array.isArray(r.results) ? r.results : [];
8
- const passed = items.filter((x) => x?.pass).length;
9
- return `[${status}] verify: ${passed}/${items.length} pass`;
6
+ const reportInapplicable = !r || isNotApplicable(r);
7
+ // Source priority (parallel to audit + review):
8
+ // 1. report.results (structured path; the primary parser now handles
9
+ // both JSON and narrative).
10
+ // 2. parseVerifyResults(runResult.output) (defensive fallback when the
11
+ // structured parser ran a non-verify schema and stripped the
12
+ // narrative — same Gap-A pattern surfaced on review #2).
13
+ let results = !reportInapplicable && Array.isArray(r?.results) ? r.results : [];
14
+ if (results.length === 0 && typeof runResult?.output === 'string') {
15
+ const narrative = parseVerifyResults(runResult.output);
16
+ if (narrative.length > 0)
17
+ results = narrative;
18
+ }
19
+ const path = task?.filePaths?.[0] || '';
20
+ if (results.length === 0 && !path) {
21
+ return `[${status}] verify completed`;
22
+ }
23
+ const passed = results.filter((x) => x?.pass).length;
24
+ return path
25
+ ? `[${status}] verify ${path}: ${passed}/${results.length} pass`
26
+ : `[${status}] verify: ${passed}/${results.length} pass`;
10
27
  },
11
28
  };
12
29
  //# sourceMappingURL=verify.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"verify.js","sourceRoot":"","sources":["../../../src/reporting/headline-templates/verify.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,MAAM,CAAC,MAAM,sBAAsB,GAAqB;IACtD,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE;QACxB,IAAI,CAAC,MAAM,IAAI,eAAe,CAAC,MAAM,CAAC;YAAE,OAAO,IAAI,MAAM,0CAA0C,CAAC;QACpG,MAAM,CAAC,GAAG,MAAsB,CAAC;QACjC,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;QACxD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,MAAM,CAAC;QACnD,OAAO,IAAI,MAAM,aAAa,MAAM,IAAI,KAAK,CAAC,MAAM,OAAO,CAAC;IAC9D,CAAC;CACF,CAAC"}
1
+ {"version":3,"file":"verify.js","sourceRoot":"","sources":["../../../src/reporting/headline-templates/verify.ts"],"names":[],"mappings":"AACA,OAAO,EAAqB,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAChG,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,MAAM,CAAC,MAAM,sBAAsB,GAAqB;IACtD,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE;QACzC,MAAM,CAAC,GAAG,MAAkD,CAAC;QAC7D,MAAM,kBAAkB,GAAG,CAAC,CAAC,IAAI,eAAe,CAAC,CAAC,CAAC,CAAC;QAEpD,gDAAgD;QAChD,uEAAuE;QACvE,iCAAiC;QACjC,yEAAyE;QACzE,kEAAkE;QAClE,8DAA8D;QAC9D,IAAI,OAAO,GACT,CAAC,kBAAkB,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;QACrE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,SAAS,EAAE,MAAM,KAAK,QAAQ,EAAE,CAAC;YAClE,MAAM,SAAS,GAAG,kBAAkB,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YACvD,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC;gBAAE,OAAO,GAAG,SAAS,CAAC;QAChD,CAAC;QAED,MAAM,IAAI,GACP,IAA6C,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAEvE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YAClC,OAAO,IAAI,MAAM,oBAAoB,CAAC;QACxC,CAAC;QAED,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,MAAM,CAAC;QACrD,OAAO,IAAI;YACT,CAAC,CAAC,IAAI,MAAM,YAAY,IAAI,KAAK,MAAM,IAAI,OAAO,CAAC,MAAM,OAAO;YAChE,CAAC,CAAC,IAAI,MAAM,aAAa,MAAM,IAAI,OAAO,CAAC,MAAM,OAAO,CAAC;IAC7D,CAAC;CACF,CAAC"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Helpers for headline text shaping.
3
+ *
4
+ * Headlines are operator-facing single-line strings that appear in
5
+ * polling output and the terminal envelope. They MUST stay short and
6
+ * structured — workers' free-form `summary` fields can be paragraphs
7
+ * long and end mid-sentence (the v4.0.3 Gap 12 case: "...now ends
8
+ * with:" cut off because the worker meant to put a code excerpt
9
+ * after the colon).
10
+ *
11
+ * `firstSentenceOrTruncate` is the single helper composers use to
12
+ * sanitize narrative text for headline display.
13
+ */
14
+ /**
15
+ * Return the first sentence of `s`, or a hard-truncated form with
16
+ * trailing ellipsis when no sentence boundary exists in the first
17
+ * `max` characters.
18
+ *
19
+ * Why first-sentence? Worker summaries follow a "headline sentence,
20
+ * then details" pattern; the first sentence carries the operator-
21
+ * relevant signal. Truncating mid-sentence (the prior bug) loses
22
+ * that signal AND looks broken.
23
+ *
24
+ * Sentence-end heuristic: a `.!?` followed by whitespace OR end-of-
25
+ * string. The match is non-greedy and ranges over `max` characters,
26
+ * so internal punctuation (version numbers like `v4.0.3`, decimals
27
+ * like `1.5`, filenames like `auth.ts`) does NOT block the scan.
28
+ *
29
+ * @param s raw text (may be empty / whitespace-only)
30
+ * @param max hard truncation cap when no sentence break is found.
31
+ * 80 keeps headlines well under the typical 120-char
32
+ * terminal-line target after the bracket prefix +
33
+ * file-count suffix are added.
34
+ */
35
+ export declare function firstSentenceOrTruncate(s: string, max?: number): string;
36
+ //# sourceMappingURL=headline-text.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"headline-text.d.ts","sourceRoot":"","sources":["../../src/reporting/headline-text.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,SAAK,GAAG,MAAM,CAkCnE"}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Helpers for headline text shaping.
3
+ *
4
+ * Headlines are operator-facing single-line strings that appear in
5
+ * polling output and the terminal envelope. They MUST stay short and
6
+ * structured — workers' free-form `summary` fields can be paragraphs
7
+ * long and end mid-sentence (the v4.0.3 Gap 12 case: "...now ends
8
+ * with:" cut off because the worker meant to put a code excerpt
9
+ * after the colon).
10
+ *
11
+ * `firstSentenceOrTruncate` is the single helper composers use to
12
+ * sanitize narrative text for headline display.
13
+ */
14
+ /**
15
+ * Return the first sentence of `s`, or a hard-truncated form with
16
+ * trailing ellipsis when no sentence boundary exists in the first
17
+ * `max` characters.
18
+ *
19
+ * Why first-sentence? Worker summaries follow a "headline sentence,
20
+ * then details" pattern; the first sentence carries the operator-
21
+ * relevant signal. Truncating mid-sentence (the prior bug) loses
22
+ * that signal AND looks broken.
23
+ *
24
+ * Sentence-end heuristic: a `.!?` followed by whitespace OR end-of-
25
+ * string. The match is non-greedy and ranges over `max` characters,
26
+ * so internal punctuation (version numbers like `v4.0.3`, decimals
27
+ * like `1.5`, filenames like `auth.ts`) does NOT block the scan.
28
+ *
29
+ * @param s raw text (may be empty / whitespace-only)
30
+ * @param max hard truncation cap when no sentence break is found.
31
+ * 80 keeps headlines well under the typical 120-char
32
+ * terminal-line target after the bracket prefix +
33
+ * file-count suffix are added.
34
+ */
35
+ export function firstSentenceOrTruncate(s, max = 80) {
36
+ if (!s || typeof s !== 'string')
37
+ return '';
38
+ const trimmed = s.trim();
39
+ if (trimmed.length === 0)
40
+ return '';
41
+ // F2 fix (audit, low): defend against invalid `max` values. Headlines
42
+ // are single-line operator-facing strings; a buggy caller passing
43
+ // `max=0`, negative, `NaN`, or `Infinity` shouldn't make the regex
44
+ // throw or overrun. Coerce to a sane bound: integer in [1, 2000].
45
+ const safeMax = Number.isFinite(max) && max >= 1
46
+ ? Math.min(Math.floor(max), 2000)
47
+ : 80;
48
+ // N2 fix (audit-2, low): collapse whitespace BEFORE sentence detection.
49
+ // Doing it after meant a sentence wrapping across a newline before
50
+ // its terminator (e.g., "Fixed auth\nissue. More") never matched the
51
+ // boundary regex and fell through to a generic truncate.
52
+ const oneLine = collapseNewlines(trimmed);
53
+ // N1 fix (audit-2, low): cap the captured sentence at exactly `safeMax`
54
+ // chars including the terminating punctuation. The leading run is
55
+ // therefore at most `safeMax - 1` chars. Skip sentence detection
56
+ // entirely when there's no room for even "X." (safeMax < 2).
57
+ // Lazy quantifier `{1,N}?` lets internal `.!?` characters pass
58
+ // through (version numbers, decimals, filenames) until we hit one
59
+ // followed by whitespace or end-of-string — the real sentence boundary.
60
+ if (safeMax >= 2) {
61
+ const sentenceEnd = new RegExp(`^(.{1,${safeMax - 1}}?[.!?])(\\s|$)`);
62
+ const m = oneLine.match(sentenceEnd);
63
+ if (m)
64
+ return m[1];
65
+ }
66
+ return oneLine.length > safeMax ? oneLine.slice(0, safeMax - 1) + '…' : oneLine;
67
+ }
68
+ /** Replace any whitespace run (including newlines, tabs, and CRs) with
69
+ * a single space so the returned headline stays on one line. */
70
+ function collapseNewlines(s) {
71
+ return s.replace(/\s+/g, ' ').trim();
72
+ }
73
+ //# sourceMappingURL=headline-text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"headline-text.js","sourceRoot":"","sources":["../../src/reporting/headline-text.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,uBAAuB,CAAC,CAAS,EAAE,GAAG,GAAG,EAAE;IACzD,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,EAAE,CAAC;IAC3C,MAAM,OAAO,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACzB,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAEpC,sEAAsE;IACtE,kEAAkE;IAClE,mEAAmE;IACnE,kEAAkE;IAClE,MAAM,OAAO,GACX,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC;QAC9B,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC;QACjC,CAAC,CAAC,EAAE,CAAC;IAET,wEAAwE;IACxE,mEAAmE;IACnE,qEAAqE;IACrE,yDAAyD;IACzD,MAAM,OAAO,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAE1C,wEAAwE;IACxE,kEAAkE;IAClE,iEAAiE;IACjE,6DAA6D;IAC7D,+DAA+D;IAC/D,kEAAkE;IAClE,wEAAwE;IACxE,IAAI,OAAO,IAAI,CAAC,EAAE,CAAC;QACjB,MAAM,WAAW,GAAG,IAAI,MAAM,CAAC,SAAS,OAAO,GAAG,CAAC,iBAAiB,CAAC,CAAC;QACtE,MAAM,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QACrC,IAAI,CAAC;YAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IACrB,CAAC;IAED,OAAO,OAAO,CAAC,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC;AAClF,CAAC;AAED;iEACiE;AACjE,SAAS,gBAAgB,CAAC,CAAS;IACjC,OAAO,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AACvC,CAAC"}
@@ -6,5 +6,22 @@ export interface VerifyReport {
6
6
  evidence: string;
7
7
  }>;
8
8
  }
9
+ /**
10
+ * Extract verify checklist results from `## Finding N:` narrative blocks.
11
+ *
12
+ * The verify tool prompt instructs workers to emit results in this exact
13
+ * format (and explicitly NOT JSON):
14
+ *
15
+ * ## Finding 1: <title>
16
+ * - Severity: low|high|...
17
+ * - Item: <criterion text>
18
+ * - Result: PASS | FAIL
19
+ * - Evidence: <evidence>
20
+ *
21
+ * Returns one entry per finding block. `pass` is true iff the Result line
22
+ * normalizes to "pass" (case-insensitive). Missing labels become empty
23
+ * strings / false (matches the schema's required-field shape).
24
+ */
25
+ export declare function parseVerifyResults(output: string): VerifyReport['results'];
9
26
  export declare const verifyReportSchema: ReportSchema<VerifyReport>;
10
27
  //# sourceMappingURL=verify-report.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"verify-report.d.ts","sourceRoot":"","sources":["../../../src/reporting/report-parser-slots/verify-report.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAEnE,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACnE;AAED,eAAO,MAAM,kBAAkB,EAAE,YAAY,CAAC,YAAY,CAMzD,CAAC"}
1
+ {"version":3,"file":"verify-report.d.ts","sourceRoot":"","sources":["../../../src/reporting/report-parser-slots/verify-report.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAEnE,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACnE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,GACb,YAAY,CAAC,SAAS,CAAC,CAezB;AAED,eAAO,MAAM,kBAAkB,EAAE,YAAY,CAAC,YAAY,CAezD,CAAC"}
@@ -1,9 +1,51 @@
1
+ /**
2
+ * Extract verify checklist results from `## Finding N:` narrative blocks.
3
+ *
4
+ * The verify tool prompt instructs workers to emit results in this exact
5
+ * format (and explicitly NOT JSON):
6
+ *
7
+ * ## Finding 1: <title>
8
+ * - Severity: low|high|...
9
+ * - Item: <criterion text>
10
+ * - Result: PASS | FAIL
11
+ * - Evidence: <evidence>
12
+ *
13
+ * Returns one entry per finding block. `pass` is true iff the Result line
14
+ * normalizes to "pass" (case-insensitive). Missing labels become empty
15
+ * strings / false (matches the schema's required-field shape).
16
+ */
17
+ export function parseVerifyResults(output) {
18
+ if (!output || typeof output !== 'string')
19
+ return [];
20
+ const blocks = output.split(/^##\s+Finding\s+\d+\s*:?/im);
21
+ const out = [];
22
+ for (let i = 1; i < blocks.length; i++) {
23
+ const block = blocks[i];
24
+ const itemMatch = block.match(/^\s*[-*]?\s*Item\s*:\s*(.+?)\s*$/im);
25
+ const resultMatch = block.match(/^\s*[-*]?\s*Result\s*:\s*(\w+)/im);
26
+ const evidenceMatch = block.match(/^\s*[-*]?\s*Evidence\s*:\s*([\s\S]+?)(?=\n\s*[-*]\s|\n##|$)/im);
27
+ const item = itemMatch ? itemMatch[1].trim() : '';
28
+ const pass = resultMatch ? /^pass$/i.test(resultMatch[1].trim()) : false;
29
+ const evidence = evidenceMatch ? evidenceMatch[1].trim() : '';
30
+ out.push({ item, pass, evidence });
31
+ }
32
+ return out;
33
+ }
1
34
  export const verifyReportSchema = {
2
35
  parse(text) {
36
+ // Primary path: JSON block (legacy; some workers may still emit it).
3
37
  const m = text.match(/```json\n([\s\S]+?)\n```/);
4
- if (!m)
5
- throw new Error('verify report missing JSON block');
6
- return JSON.parse(m[1]);
38
+ if (m)
39
+ return JSON.parse(m[1]);
40
+ // Narrative path (the actual prompt format — the verify prompt
41
+ // explicitly says "Do NOT emit JSON"). Recover one result per
42
+ // `## Finding N:` block. If neither path produced anything,
43
+ // throw so the parent falls back to notApplicable.
44
+ const narrative = parseVerifyResults(text);
45
+ if (narrative.length === 0) {
46
+ throw new Error('verify report missing JSON block and no `## Finding N:` narrative results');
47
+ }
48
+ return { results: narrative };
7
49
  },
8
50
  };
9
51
  //# sourceMappingURL=verify-report.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"verify-report.js","sourceRoot":"","sources":["../../../src/reporting/report-parser-slots/verify-report.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,MAAM,kBAAkB,GAA+B;IAC5D,KAAK,CAAC,IAAY;QAChB,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;QACjD,IAAI,CAAC,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;QAC5D,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1B,CAAC;CACF,CAAC"}
1
+ {"version":3,"file":"verify-report.js","sourceRoot":"","sources":["../../../src/reporting/report-parser-slots/verify-report.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,kBAAkB,CAChC,MAAc;IAEd,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,EAAE,CAAC;IACrD,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAC1D,MAAM,GAAG,GAA4B,EAAE,CAAC;IACxC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACxB,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;QACpE,MAAM,WAAW,GAAG,KAAK,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;QACpE,MAAM,aAAa,GAAG,KAAK,CAAC,KAAK,CAAC,+DAA+D,CAAC,CAAC;QACnG,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAClD,MAAM,IAAI,GAAG,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QACzE,MAAM,QAAQ,GAAG,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9D,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;IACrC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,CAAC,MAAM,kBAAkB,GAA+B;IAC5D,KAAK,CAAC,IAAY;QAChB,qEAAqE;QACrE,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;QACjD,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/B,+DAA+D;QAC/D,8DAA8D;QAC9D,4DAA4D;QAC5D,mDAAmD;QACnD,MAAM,SAAS,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;QAC3C,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,2EAA2E,CAAC,CAAC;QAC/F,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;IAChC,CAAC;CACF,CAAC"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Severity helpers shared across headline composers and telemetry
3
+ * event-builder. Per the wire-telemetry-gaps plan (Gap 2 + round-2 F1):
4
+ * THREE distinct helpers, NOT one — conflating headline counting with
5
+ * telemetry bucketing would corrupt the wire's findings_critical /
6
+ * findings_high columns.
7
+ */
8
+ export type FindingSeverity = 'critical' | 'high' | 'medium' | 'low';
9
+ /**
10
+ * Normalize a raw severity string to the canonical lowercase enum.
11
+ * Returns null for unknown / unparseable values.
12
+ *
13
+ * Used by both headline counting and telemetry bucketing — single
14
+ * source of truth for "what's the severity of this finding".
15
+ */
16
+ export declare function normalizeSeverity(raw: unknown): FindingSeverity | null;
17
+ /**
18
+ * Headline-only helper. Counts findings whose normalized severity is
19
+ * 'high' OR 'critical'. Used by audit + review headline composers to
20
+ * surface the "(N high)" annotation.
21
+ *
22
+ * MUST NOT be used for telemetry bucketing — see
23
+ * `bucketFindingsBySeverity` for that.
24
+ */
25
+ export declare function countHighOrCritical(findings: ReadonlyArray<{
26
+ severity?: unknown;
27
+ }>): number;
28
+ /**
29
+ * Telemetry-only helper. Returns separate per-severity buckets:
30
+ * `{ critical, high, medium, low }`. Used by event-builder so the
31
+ * wire's findings_critical / findings_high / findings_medium /
32
+ * findings_low DB columns each carry exact counts.
33
+ *
34
+ * MUST NOT be replaced by countHighOrCritical — that conflates
35
+ * critical and high into one count.
36
+ */
37
+ export declare function bucketFindingsBySeverity(findings: ReadonlyArray<{
38
+ severity?: unknown;
39
+ }>): Record<FindingSeverity, number>;
40
+ /**
41
+ * Extract findings from an implementer's narrative `## Finding N:` output
42
+ * block-by-block. The audit / review / verify / debug / investigate
43
+ * tool prompts instruct workers to emit findings in this exact format:
44
+ *
45
+ * ## Finding 1: <title>
46
+ * - Severity: critical | high | medium | low
47
+ * - Location: file:line
48
+ * - Issue: ...
49
+ * - Suggestion: ...
50
+ *
51
+ * The annotator normally consumes that narrative and emits a structured
52
+ * JSON array. When the annotator errors (parse failure, exhaustion
53
+ * mid-block, etc.), this helper recovers the findings from the
54
+ * implementer's output so the headline + envelope still report the
55
+ * correct count. Returns one entry per finding with the parsed severity
56
+ * (lowercase canonical, or null if no severity line was found).
57
+ */
58
+ export declare function parseNarrativeFindings(output: string): Array<{
59
+ severity: FindingSeverity | null;
60
+ claim: string;
61
+ }>;
62
+ //# sourceMappingURL=severity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"severity.d.ts","sourceRoot":"","sources":["../../src/reporting/severity.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;AAIrE;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG,eAAe,GAAG,IAAI,CAItE;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,aAAa,CAAC;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,GAAG,MAAM,CAO3F;AAED;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,aAAa,CAAC;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,GAC9C,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC,CAOjC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,MAAM,GACb,KAAK,CAAC;IAAE,QAAQ,EAAE,eAAe,GAAG,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAgB5D"}