peaks-loop 4.0.0-beta.14 → 4.0.0-beta.16

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 (204) hide show
  1. package/CHANGELOG.md +230 -148
  2. package/README-en.md +1 -1
  3. package/README.md +32 -1
  4. package/bin/peaks.js +0 -0
  5. package/dist/cli/cli-helpers.d.ts +1 -1
  6. package/dist/cli/cli-helpers.js +1 -1
  7. package/dist/cli/commands/adapter-commands-s2a.js +1 -1
  8. package/dist/cli/commands/asset-commands.js +33 -16
  9. package/dist/cli/commands/audit-commands.js +1 -1
  10. package/dist/cli/commands/bee-commands.js +1 -1
  11. package/dist/cli/commands/capability-commands.js +1 -1
  12. package/dist/cli/commands/classify-classify-commands.js +1 -1
  13. package/dist/cli/commands/code-commands.js +1 -1
  14. package/dist/cli/commands/code-review-commands.js +1 -1
  15. package/dist/cli/commands/codegraph-commands.js +1 -1
  16. package/dist/cli/commands/compact-command.js +1 -1
  17. package/dist/cli/commands/complexity-commands.js +1 -1
  18. package/dist/cli/commands/config-commands.js +1 -1
  19. package/dist/cli/commands/context-commands.js +1 -1
  20. package/dist/cli/commands/contract-commands.js +1 -1
  21. package/dist/cli/commands/core/artifacts-command.js +1 -1
  22. package/dist/cli/commands/core/binding-commands.js +1 -1
  23. package/dist/cli/commands/core/doctor-command.js +63 -3
  24. package/dist/cli/commands/core/memory-command.js +1 -1
  25. package/dist/cli/commands/core/profile-command.js +1 -1
  26. package/dist/cli/commands/core/proxy-command.js +1 -1
  27. package/dist/cli/commands/core/session-command.js +1 -1
  28. package/dist/cli/commands/core/skill-command.js +2 -2
  29. package/dist/cli/commands/core/standards-command.js +1 -1
  30. package/dist/cli/commands/dispatch-commands.js +2 -2
  31. package/dist/cli/commands/dispatch-from-dag.js +1 -1
  32. package/dist/cli/commands/doc-commands.js +1 -1
  33. package/dist/cli/commands/ecc-commands.js +2 -2
  34. package/dist/cli/commands/evolution-commands.js +1 -1
  35. package/dist/cli/commands/feedback-commands.js +1 -1
  36. package/dist/cli/commands/final-review-commands.js +1 -1
  37. package/dist/cli/commands/fixture-commands.js +1 -1
  38. package/dist/cli/commands/fork-commands.js +1 -1
  39. package/dist/cli/commands/gate-commands.js +1 -1
  40. package/dist/cli/commands/heartbeat-commands.js +1 -1
  41. package/dist/cli/commands/hook-handle.js +1 -1
  42. package/dist/cli/commands/hooks-commands.js +1 -1
  43. package/dist/cli/commands/ide-commands.js +1 -1
  44. package/dist/cli/commands/impact-commands.js +1 -1
  45. package/dist/cli/commands/job-commands.js +1 -1
  46. package/dist/cli/commands/legacy-commands.js +1 -1
  47. package/dist/cli/commands/log-commands.js +1 -1
  48. package/dist/cli/commands/loop-commands.js +1 -1
  49. package/dist/cli/commands/loop-eval-commands.js +1 -1
  50. package/dist/cli/commands/memory-commands.js +1 -1
  51. package/dist/cli/commands/migrate-1-4-1-command.js +1 -1
  52. package/dist/cli/commands/migrate-v2-10-to-v2-11-command.js +1 -1
  53. package/dist/cli/commands/mut-commands.d.ts +1 -1
  54. package/dist/cli/commands/mut-commands.js +1 -5
  55. package/dist/cli/commands/observability-commands.js +1 -1
  56. package/dist/cli/commands/openspec-commands.js +2 -2
  57. package/dist/cli/commands/perf-audit-commands.js +2 -2
  58. package/dist/cli/commands/perf-commands.js +1 -1
  59. package/dist/cli/commands/polyrepo-commands.js +1 -1
  60. package/dist/cli/commands/prd-blocks-commands.js +1 -1
  61. package/dist/cli/commands/prd-commands.js +1 -1
  62. package/dist/cli/commands/project-commands.js +1 -1
  63. package/dist/cli/commands/qa-business-review-commands.js +1 -1
  64. package/dist/cli/commands/qa-commands.d.ts +1 -1
  65. package/dist/cli/commands/qa-commands.js +2 -2
  66. package/dist/cli/commands/release-commands.js +1 -1
  67. package/dist/cli/commands/request-commands.js +1 -1
  68. package/dist/cli/commands/retrospective-commands.js +1 -1
  69. package/dist/cli/commands/reviewer-commands.js +1 -1
  70. package/dist/cli/commands/role-commands.js +1 -1
  71. package/dist/cli/commands/runtime-commands.js +1 -2
  72. package/dist/cli/commands/sc-commands.js +1 -1
  73. package/dist/cli/commands/scan-commands.js +1 -1
  74. package/dist/cli/commands/security-audit-commands.js +2 -2
  75. package/dist/cli/commands/share-commands.d.ts +19 -0
  76. package/dist/cli/commands/share-commands.js +121 -2
  77. package/dist/cli/commands/skill-conformance-commands.js +1 -1
  78. package/dist/cli/commands/skill-loop-engineering-readiness-commands.js +1 -1
  79. package/dist/cli/commands/skill-search-commands.js +1 -1
  80. package/dist/cli/commands/slice-commands.js +1 -1
  81. package/dist/cli/commands/slice-integrate-commands.js +1 -1
  82. package/dist/cli/commands/slice-review-commands.js +1 -1
  83. package/dist/cli/commands/smoke-commands.js +1 -1
  84. package/dist/cli/commands/sop-commands.js +1 -1
  85. package/dist/cli/commands/statusline-commands.js +1 -1
  86. package/dist/cli/commands/sub-agent-commands.js +2 -1
  87. package/dist/cli/commands/understand-commands.js +1 -1
  88. package/dist/cli/commands/upgrade-commands.js +1 -1
  89. package/dist/cli/commands/user-touchpoint-commands.js +1 -1
  90. package/dist/cli/commands/verdict-aggregate-command.js +1 -1
  91. package/dist/cli/commands/workflow-commands.js +1 -1
  92. package/dist/cli/commands/workflow-plan-commands.js +1 -1
  93. package/dist/cli/commands/workspace/init-command.js +1 -1
  94. package/dist/cli/commands/workspace/migrate-command.js +1 -1
  95. package/dist/cli/commands/workspace/reconcile-command.js +1 -1
  96. package/dist/cli/index.js +1 -1
  97. package/dist/cli/program.js +2 -2
  98. package/dist/services/artifacts/artifact-prerequisites.js +1 -1
  99. package/dist/services/artifacts/request-artifact-service.js +1 -1
  100. package/dist/services/artifacts/workspace-service.js +1 -1
  101. package/dist/services/code/auto-compact-orchestrator.js +5 -2
  102. package/dist/services/code-review/ocr-service.d.ts +1 -1
  103. package/dist/services/code-review/ocr-service.js +6 -3
  104. package/dist/services/config/config-types.js +1 -1
  105. package/dist/services/dashboard/project-dashboard-service.js +2 -2
  106. package/dist/services/dispatch/batch-counter.js +1 -1
  107. package/dist/services/dispatch/dispatch-record-writer.js +1 -1
  108. package/dist/services/job/job-progress-store.d.ts +2 -2
  109. package/dist/services/job/job-types.d.ts +27 -27
  110. package/dist/services/log/retention.js +1 -1
  111. package/dist/services/openspec/openspec-archive-service.js +1 -1
  112. package/dist/services/openspec/openspec-bridge-service.js +1 -1
  113. package/dist/services/openspec/openspec-init-service.js +1 -1
  114. package/dist/services/openspec/openspec-propose-from-doctor-service.js +1 -1
  115. package/dist/services/openspec/openspec-render-service.js +1 -1
  116. package/dist/services/openspec/openspec-scan-service.js +1 -1
  117. package/dist/services/openspec/openspec-validate-service.js +1 -1
  118. package/dist/services/scan/acceptance-coverage-service.js +1 -1
  119. package/dist/services/scan/archetype-service.js +1 -1
  120. package/dist/services/scan/existing-system-service.js +1 -1
  121. package/dist/services/scan/libraries-service.js +1 -1
  122. package/dist/services/skill/skill-search-service.d.ts +5 -5
  123. package/dist/services/skill/skill-search-service.js +2 -2
  124. package/dist/services/skills/skill-registry.js +2 -2
  125. package/dist/services/skills/skill-runbook-service.js +1 -1
  126. package/dist/services/slice/slice-check-service.js +1 -1
  127. package/dist/services/understand/understand-hybrid-service.js +1 -1
  128. package/dist/services/understand/understand-scan-service.js +2 -2
  129. package/dist/services/upgrade/upgrade-service.js +4 -3
  130. package/dist/services/verdict/envelopes.d.ts +2 -2
  131. package/dist/services/verdict/envelopes.js +2 -2
  132. package/dist/services/verdict/verdict-aggregator.d.ts +3 -3
  133. package/dist/services/workflow/autonomous-resume-writer.js +1 -1
  134. package/dist/services/workflow/plan-reader.d.ts +1 -1
  135. package/dist/services/workflow/plan-reader.js +1 -1
  136. package/dist/services/workflow/plan-refresher.d.ts +1 -1
  137. package/dist/services/workflow/plan-refresher.js +1 -1
  138. package/dist/services/workflow/plan-trigger-detector.d.ts +1 -1
  139. package/dist/services/workflow/plan-trigger-detector.js +1 -1
  140. package/dist/services/workflow/workflow-router-service.js +11 -9
  141. package/dist/services/workspace/migrate-service.js +1 -1
  142. package/dist/services/workspace/workspace-service.js +1 -1
  143. package/package.json +13 -8
  144. package/scripts/sync-version.mjs +8 -1
  145. package/skills/bee/peaks-rd/SKILL.md +14 -1
  146. package/skills/peaks-code/SKILL.md +44 -0
  147. package/skills/peaks-code/references/sub-agent-dispatch.md +30 -0
  148. package/dist/services/agent/ecc-cache-service.d.ts +0 -97
  149. package/dist/services/agent/ecc-cache-service.js +0 -491
  150. package/dist/services/audit-independent/perf-audit-service.d.ts +0 -151
  151. package/dist/services/audit-independent/perf-audit-service.js +0 -316
  152. package/dist/services/audit-independent/security-audit-service.d.ts +0 -155
  153. package/dist/services/audit-independent/security-audit-service.js +0 -316
  154. package/dist/services/context/dispatch-context-guard.d.ts +0 -27
  155. package/dist/services/context/dispatch-context-guard.js +0 -192
  156. package/dist/services/context/shared-channel.d.ts +0 -93
  157. package/dist/services/context/shared-channel.js +0 -308
  158. package/dist/services/crystallization/crystallization-service.d.ts +0 -239
  159. package/dist/services/crystallization/crystallization-service.js +0 -397
  160. package/dist/services/crystallization/crystallization-store.d.ts +0 -75
  161. package/dist/services/crystallization/crystallization-store.js +0 -193
  162. package/dist/services/crystallization/crystallization-types.d.ts +0 -313
  163. package/dist/services/crystallization/crystallization-types.js +0 -299
  164. package/dist/services/crystallization/evidence-brief-builder.d.ts +0 -237
  165. package/dist/services/crystallization/evidence-brief-builder.js +0 -240
  166. package/dist/services/doctor/doctor-service.d.ts +0 -149
  167. package/dist/services/doctor/doctor-service.js +0 -929
  168. package/dist/services/filesystem/file-lock.d.ts +0 -11
  169. package/dist/services/filesystem/file-lock.js +0 -152
  170. package/dist/services/final-review/final-review-service.d.ts +0 -12
  171. package/dist/services/final-review/final-review-service.js +0 -52
  172. package/dist/services/final-review/final-review-types.d.ts +0 -42
  173. package/dist/services/final-review/final-review-types.js +0 -18
  174. package/dist/services/job/job-resource-snapshot.d.ts +0 -7
  175. package/dist/services/job/job-resource-snapshot.js +0 -75
  176. package/dist/services/mut/assert-scanner.d.ts +0 -6
  177. package/dist/services/mut/assert-scanner.js +0 -116
  178. package/dist/services/mut/index.d.ts +0 -8
  179. package/dist/services/mut/index.js +0 -7
  180. package/dist/services/mut/mut-runner.d.ts +0 -39
  181. package/dist/services/mut/mut-runner.js +0 -29
  182. package/dist/services/mut/production-stryker.d.ts +0 -2
  183. package/dist/services/mut/production-stryker.js +0 -75
  184. package/dist/services/mut/report-builder.d.ts +0 -11
  185. package/dist/services/mut/report-builder.js +0 -110
  186. package/dist/services/mut/report-loader.d.ts +0 -31
  187. package/dist/services/mut/report-loader.js +0 -78
  188. package/dist/services/mut/thresholds.d.ts +0 -21
  189. package/dist/services/mut/thresholds.js +0 -22
  190. package/dist/services/mut/types.d.ts +0 -336
  191. package/dist/services/mut/types.js +0 -59
  192. package/dist/shared/fs.d.ts +0 -4
  193. package/dist/shared/fs.js +0 -26
  194. package/dist/shared/paths.d.ts +0 -6
  195. package/dist/shared/paths.js +0 -50
  196. package/dist/shared/result.d.ts +0 -22
  197. package/dist/shared/result.js +0 -46
  198. package/dist/shared/version.d.ts +0 -1
  199. package/dist/shared/version.js +0 -1
  200. package/examples/video-demo/README.md +0 -142
  201. package/examples/video-demo/out/en-closing-960.png +0 -0
  202. package/examples/video-demo/out/zh-closing-960.png +0 -0
  203. package/examples/video-demo/preview/peaks-loop-demo-en.mp4 +0 -0
  204. package/examples/video-demo/preview/peaks-loop-demo.mp4 +0 -0
@@ -1,237 +0,0 @@
1
- import { z } from "zod";
2
- import { type EvidenceBrief } from "./crystallization-types.js";
3
- /**
4
- * EvidenceBriefBuilder — spec §4.7 / §10 RL-7.
5
- *
6
- * The brief is a 4-section natural-language projection that MUST
7
- * accompany every user-facing recommendation. The shape guard is
8
- * encoded in `EvidenceBriefSchema` (see crystallization-types.ts);
9
- * this module is the LLM-side entry point that PRODUCES the brief
10
- * from a finished trace + evaluator summary and the validator that
11
- * REFUSES to render a recommendation payload without all 4 sections.
12
- *
13
- * Hard rules (mirrored from spec):
14
- *
15
- * 1. Every section must be a non-empty NL string (1-2 sentences
16
- * for what_happened / why_it_matters / what_learned; 1
17
- * sentence for what_action). An empty section is a hard
18
- * `MISSING_BRIEF_SECTION` error.
19
- *
20
- * 2. The build path is lenient on raw prose and strict on the
21
- * final shape — `buildEvidenceBrief` calls
22
- * `EvidenceBriefSchema.parse(...)` so a partial brief throws
23
- * before reaching the database.
24
- *
25
- * 3. `renderRecommendationPayload` refuses to return a
26
- * recommendation envelope unless the brief passes the 4-section
27
- * guard. This is the CLI's single source of truth for "may I
28
- * show this to the user?".
29
- *
30
- * 4. The `evaluator_summary` is a separate field on the
31
- * crystallization_event row (spec §4.5) and is NOT part of the
32
- * brief. It feeds the broader recommendation envelope.
33
- *
34
- * Out of scope (deferred to later slices):
35
- * - LLM-authored brief generation from live trace evidence (M8 dogfood).
36
- * - brief rewrite-on-update semantics.
37
- */
38
- /**
39
- * The minimum viable trace shape that the builder needs to render
40
- * a brief. The trace is the EVIDENCE; the builder is format-stable
41
- * so a future slice can swap in a richer trace source without
42
- * editing every caller.
43
- */
44
- export declare const BriefTraceInputSchema: z.ZodObject<{
45
- trace_id: z.ZodString;
46
- /**
47
- * The full NL recap of the run. Required for what_happened.
48
- * 1-2 sentences is the spec guidance; the builder does not
49
- * truncate, but tests passing multi-paragraph input will be
50
- * warned at the Zod boundary (max 4000 chars per section).
51
- */
52
- what_happened: z.ZodString;
53
- /**
54
- * The "why this matters" recap. Required for why_it_matters.
55
- */
56
- why_it_matters: z.ZodString;
57
- /**
58
- * Failure-mode and preference-extraction recap. Required for
59
- * what_learned.
60
- */
61
- what_learned: z.ZodString;
62
- /**
63
- * The recommended action. Required for what_action (1
64
- * sentence per spec).
65
- */
66
- what_action: z.ZodString;
67
- /**
68
- * Optional structured bullets (e.g. "4 phases, 3 gates passed,
69
- * 1 evaluator verdict"). Counts are allowed at this layer; the
70
- * brief section is the NL primary (RL-7).
71
- */
72
- bullets: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
73
- /**
74
- * Source trace ids backing the brief (the column on
75
- * crystallization_event spec §4.5).
76
- */
77
- source_trace_pointers: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
78
- }, "strip", z.ZodTypeAny, {
79
- source_trace_pointers: string[];
80
- what_happened: string;
81
- why_it_matters: string;
82
- what_learned: string;
83
- what_action: string;
84
- trace_id: string;
85
- bullets: string[];
86
- }, {
87
- what_happened: string;
88
- why_it_matters: string;
89
- what_learned: string;
90
- what_action: string;
91
- trace_id: string;
92
- source_trace_pointers?: string[] | undefined;
93
- bullets?: string[] | undefined;
94
- }>;
95
- export type BriefTraceInput = z.input<typeof BriefTraceInputSchema>;
96
- /**
97
- * The summary emitted by the independent evaluators (spec §4.5
98
- * `evaluator_summary` field). Optional for the brief builder — the
99
- * brief can be built without it, but a filled evaluator_summary
100
- * flows into the recommendation envelope.
101
- */
102
- export declare const EvaluatorSummarySchema: z.ZodObject<{
103
- one_liner: z.ZodDefault<z.ZodString>;
104
- risk_tags: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
105
- }, "strip", z.ZodTypeAny, {
106
- one_liner: string;
107
- risk_tags: string[];
108
- }, {
109
- one_liner?: string | undefined;
110
- risk_tags?: string[] | undefined;
111
- }>;
112
- export type EvaluatorSummary = z.input<typeof EvaluatorSummarySchema>;
113
- export declare const RecommendationPayloadSchema: z.ZodObject<{
114
- brief: z.ZodEffects<z.ZodObject<{
115
- what_happened: z.ZodString;
116
- why_it_matters: z.ZodString;
117
- what_learned: z.ZodString;
118
- what_action: z.ZodString;
119
- }, "strict", z.ZodTypeAny, {
120
- what_happened: string;
121
- why_it_matters: string;
122
- what_learned: string;
123
- what_action: string;
124
- }, {
125
- what_happened: string;
126
- why_it_matters: string;
127
- what_learned: string;
128
- what_action: string;
129
- }>, {
130
- what_happened: string;
131
- why_it_matters: string;
132
- what_learned: string;
133
- what_action: string;
134
- }, {
135
- what_happened: string;
136
- why_it_matters: string;
137
- what_learned: string;
138
- what_action: string;
139
- }>;
140
- bullets: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
141
- source_trace_pointers: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
142
- evaluator_summary: z.ZodDefault<z.ZodObject<{
143
- one_liner: z.ZodDefault<z.ZodString>;
144
- risk_tags: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
145
- }, "strip", z.ZodTypeAny, {
146
- one_liner: string;
147
- risk_tags: string[];
148
- }, {
149
- one_liner?: string | undefined;
150
- risk_tags?: string[] | undefined;
151
- }>>;
152
- }, "strip", z.ZodTypeAny, {
153
- source_trace_pointers: string[];
154
- evaluator_summary: {
155
- one_liner: string;
156
- risk_tags: string[];
157
- };
158
- bullets: string[];
159
- brief: {
160
- what_happened: string;
161
- why_it_matters: string;
162
- what_learned: string;
163
- what_action: string;
164
- };
165
- }, {
166
- brief: {
167
- what_happened: string;
168
- why_it_matters: string;
169
- what_learned: string;
170
- what_action: string;
171
- };
172
- source_trace_pointers?: string[] | undefined;
173
- evaluator_summary?: {
174
- one_liner?: string | undefined;
175
- risk_tags?: string[] | undefined;
176
- } | undefined;
177
- bullets?: string[] | undefined;
178
- }>;
179
- export type RecommendationPayload = z.infer<typeof RecommendationPayloadSchema>;
180
- export declare class BriefSectionError extends Error {
181
- readonly code: "MISSING_BRIEF_SECTION";
182
- readonly findings: ReadonlyArray<{
183
- path: string;
184
- message: string;
185
- }>;
186
- constructor(message: string, findings?: ReadonlyArray<{
187
- path: string;
188
- message: string;
189
- }>);
190
- }
191
- /**
192
- * Build a 4-section EvidenceBrief from a finished trace recap.
193
- *
194
- * The function is STRICT: it parses the input trace through
195
- * `BriefTraceInputSchema`, then parses the assembled brief through
196
- * `EvidenceBriefSchema`. Any missing section throws
197
- * `BriefSectionError(MISSING_BRIEF_SECTION)` — the same code that
198
- * `safeParseEvidenceBrief` returns — so a single error code is the
199
- * user-facing signal for "brief incomplete, do not render".
200
- *
201
- * Brief-section related ZodErrors (e.g. `min(1)` on a section) are
202
- * translated to `BriefSectionError` so callers only handle one
203
- * shape of failure. Non-section ZodErrors (e.g. invalid `trace_id`)
204
- * are re-raised unchanged.
205
- *
206
- * NOTE: callers who already have raw NL strings can also call
207
- * `parseEvidenceBrief` directly; this function is the opinionated
208
- * shape for trace -> brief.
209
- */
210
- export declare function buildEvidenceBrief(trace: BriefTraceInput, evaluatorSummary?: EvaluatorSummary): EvidenceBrief;
211
- /**
212
- * Render the user-facing recommendation envelope (brief + bullets +
213
- * trace pointers + evaluator summary). The function refuses to
214
- * return a payload unless ALL 4 brief sections are present — this
215
- * is the single CLI-facing gate per spec §10 RL-7.
216
- *
217
- * On success, returns the validated `RecommendationPayload`. On a
218
- * missing-section brief, throws `BriefSectionError`.
219
- */
220
- export declare function renderRecommendationPayload(trace: BriefTraceInput, evaluatorSummary?: EvaluatorSummary): RecommendationPayload;
221
- /**
222
- * Convenience: validate an arbitrary unknown payload AS IF it were a
223
- * recommendation envelope. Returns a Result-like shape so the CLI can
224
- * render a structured MISSING_BRIEF_SECTION error without try/catch
225
- * noise.
226
- */
227
- export declare function safeRenderRecommendationPayload(input: unknown): {
228
- ok: true;
229
- payload: RecommendationPayload;
230
- } | {
231
- ok: false;
232
- code?: "MISSING_BRIEF_SECTION";
233
- findings: Array<{
234
- path: string;
235
- message: string;
236
- }>;
237
- };
@@ -1,240 +0,0 @@
1
- import { z } from "zod";
2
- import { EvidenceBriefSchema, } from "./crystallization-types.js";
3
- /**
4
- * EvidenceBriefBuilder — spec §4.7 / §10 RL-7.
5
- *
6
- * The brief is a 4-section natural-language projection that MUST
7
- * accompany every user-facing recommendation. The shape guard is
8
- * encoded in `EvidenceBriefSchema` (see crystallization-types.ts);
9
- * this module is the LLM-side entry point that PRODUCES the brief
10
- * from a finished trace + evaluator summary and the validator that
11
- * REFUSES to render a recommendation payload without all 4 sections.
12
- *
13
- * Hard rules (mirrored from spec):
14
- *
15
- * 1. Every section must be a non-empty NL string (1-2 sentences
16
- * for what_happened / why_it_matters / what_learned; 1
17
- * sentence for what_action). An empty section is a hard
18
- * `MISSING_BRIEF_SECTION` error.
19
- *
20
- * 2. The build path is lenient on raw prose and strict on the
21
- * final shape — `buildEvidenceBrief` calls
22
- * `EvidenceBriefSchema.parse(...)` so a partial brief throws
23
- * before reaching the database.
24
- *
25
- * 3. `renderRecommendationPayload` refuses to return a
26
- * recommendation envelope unless the brief passes the 4-section
27
- * guard. This is the CLI's single source of truth for "may I
28
- * show this to the user?".
29
- *
30
- * 4. The `evaluator_summary` is a separate field on the
31
- * crystallization_event row (spec §4.5) and is NOT part of the
32
- * brief. It feeds the broader recommendation envelope.
33
- *
34
- * Out of scope (deferred to later slices):
35
- * - LLM-authored brief generation from live trace evidence (M8 dogfood).
36
- * - brief rewrite-on-update semantics.
37
- */
38
- /* ---------------------------------------------------------------------- */
39
- /* Input shapes — the builder is the only place these normalize. */
40
- /* ---------------------------------------------------------------------- */
41
- /**
42
- * The minimum viable trace shape that the builder needs to render
43
- * a brief. The trace is the EVIDENCE; the builder is format-stable
44
- * so a future slice can swap in a richer trace source without
45
- * editing every caller.
46
- */
47
- export const BriefTraceInputSchema = z.object({
48
- trace_id: z.string().trim().min(1).max(256),
49
- /**
50
- * The full NL recap of the run. Required for what_happened.
51
- * 1-2 sentences is the spec guidance; the builder does not
52
- * truncate, but tests passing multi-paragraph input will be
53
- * warned at the Zod boundary (max 4000 chars per section).
54
- */
55
- what_happened: z.string().trim().min(1).max(4000),
56
- /**
57
- * The "why this matters" recap. Required for why_it_matters.
58
- */
59
- why_it_matters: z.string().trim().min(1).max(4000),
60
- /**
61
- * Failure-mode and preference-extraction recap. Required for
62
- * what_learned.
63
- */
64
- what_learned: z.string().trim().min(1).max(4000),
65
- /**
66
- * The recommended action. Required for what_action (1
67
- * sentence per spec).
68
- */
69
- what_action: z.string().trim().min(1).max(4000),
70
- /**
71
- * Optional structured bullets (e.g. "4 phases, 3 gates passed,
72
- * 1 evaluator verdict"). Counts are allowed at this layer; the
73
- * brief section is the NL primary (RL-7).
74
- */
75
- bullets: z.array(z.string().trim().min(1).max(1000)).default([]),
76
- /**
77
- * Source trace ids backing the brief (the column on
78
- * crystallization_event spec §4.5).
79
- */
80
- source_trace_pointers: z
81
- .array(z.string().trim().min(1).max(256))
82
- .default([]),
83
- });
84
- /**
85
- * The summary emitted by the independent evaluators (spec §4.5
86
- * `evaluator_summary` field). Optional for the brief builder — the
87
- * brief can be built without it, but a filled evaluator_summary
88
- * flows into the recommendation envelope.
89
- */
90
- export const EvaluatorSummarySchema = z.object({
91
- one_liner: z.string().trim().max(1000).default(""),
92
- risk_tags: z.array(z.string().trim().min(1).max(200)).default([]),
93
- });
94
- /* ---------------------------------------------------------------------- */
95
- /* Recommendation envelope — the CLI renders this. */
96
- /* ---------------------------------------------------------------------- */
97
- export const RecommendationPayloadSchema = z.object({
98
- brief: EvidenceBriefSchema,
99
- bullets: z.array(z.string().trim().min(1).max(1000)).default([]),
100
- source_trace_pointers: z
101
- .array(z.string().trim().min(1).max(256))
102
- .default([]),
103
- evaluator_summary: EvaluatorSummarySchema.default({
104
- one_liner: "",
105
- risk_tags: [],
106
- }),
107
- });
108
- /* ---------------------------------------------------------------------- */
109
- /* Errors */
110
- /* ---------------------------------------------------------------------- */
111
- export class BriefSectionError extends Error {
112
- code = "MISSING_BRIEF_SECTION";
113
- findings;
114
- constructor(message, findings = []) {
115
- super(message);
116
- this.name = "BriefSectionError";
117
- this.findings = findings;
118
- }
119
- }
120
- /* ---------------------------------------------------------------------- */
121
- /* Builder */
122
- /* ---------------------------------------------------------------------- */
123
- /**
124
- * Build a 4-section EvidenceBrief from a finished trace recap.
125
- *
126
- * The function is STRICT: it parses the input trace through
127
- * `BriefTraceInputSchema`, then parses the assembled brief through
128
- * `EvidenceBriefSchema`. Any missing section throws
129
- * `BriefSectionError(MISSING_BRIEF_SECTION)` — the same code that
130
- * `safeParseEvidenceBrief` returns — so a single error code is the
131
- * user-facing signal for "brief incomplete, do not render".
132
- *
133
- * Brief-section related ZodErrors (e.g. `min(1)` on a section) are
134
- * translated to `BriefSectionError` so callers only handle one
135
- * shape of failure. Non-section ZodErrors (e.g. invalid `trace_id`)
136
- * are re-raised unchanged.
137
- *
138
- * NOTE: callers who already have raw NL strings can also call
139
- * `parseEvidenceBrief` directly; this function is the opinionated
140
- * shape for trace -> brief.
141
- */
142
- export function buildEvidenceBrief(trace, evaluatorSummary) {
143
- let parsedTrace;
144
- try {
145
- parsedTrace = BriefTraceInputSchema.parse(trace);
146
- }
147
- catch (err) {
148
- throw translateBriefZodError(err);
149
- }
150
- // Assemble the 4 sections verbatim from the trace recap. The Zod
151
- // parser below re-asserts the 4-section guard.
152
- const candidate = {
153
- what_happened: parsedTrace.what_happened,
154
- why_it_matters: parsedTrace.why_it_matters,
155
- what_learned: parsedTrace.what_learned,
156
- what_action: parsedTrace.what_action,
157
- };
158
- const result = EvidenceBriefSchema.safeParse(candidate);
159
- if (!result.success) {
160
- const findings = result.error.issues.map((i) => ({
161
- path: i.path.join("."),
162
- message: i.message,
163
- }));
164
- throw new BriefSectionError("evidence_brief must contain all 4 sections (what_happened, why_it_matters, what_learned, what_action) with non-empty content (spec §4.7 / RL-7)", findings);
165
- }
166
- // Silence the unused-var lint on evaluatorSummary at this layer —
167
- // the builder currently does not consume it (the brief is NL
168
- // primary), but the surface is preserved for callers via
169
- // `renderRecommendationPayload` below.
170
- void evaluatorSummary;
171
- return result.data;
172
- }
173
- /**
174
- * Translate a ZodError raised on a brief-section path into a
175
- * `BriefSectionError`. Non-brief errors are re-raised.
176
- */
177
- function translateBriefZodError(err) {
178
- if (err instanceof z.ZodError) {
179
- const issues = err.issues;
180
- const allBrief = issues.every((i) => BRIEF_SECTION_KEYS.has(i.path.join(".")));
181
- if (allBrief) {
182
- const findings = issues.map((i) => ({
183
- path: i.path.join("."),
184
- message: i.message,
185
- }));
186
- throw new BriefSectionError("evidence_brief must contain all 4 sections (what_happened, why_it_matters, what_learned, what_action) with non-empty content (spec §4.7 / RL-7)", findings);
187
- }
188
- }
189
- throw err;
190
- }
191
- const BRIEF_SECTION_KEYS = new Set([
192
- "what_happened",
193
- "why_it_matters",
194
- "what_learned",
195
- "what_action",
196
- ]);
197
- /**
198
- * Render the user-facing recommendation envelope (brief + bullets +
199
- * trace pointers + evaluator summary). The function refuses to
200
- * return a payload unless ALL 4 brief sections are present — this
201
- * is the single CLI-facing gate per spec §10 RL-7.
202
- *
203
- * On success, returns the validated `RecommendationPayload`. On a
204
- * missing-section brief, throws `BriefSectionError`.
205
- */
206
- export function renderRecommendationPayload(trace, evaluatorSummary = { one_liner: "", risk_tags: [] }) {
207
- const brief = buildEvidenceBrief(trace, evaluatorSummary);
208
- const payload = RecommendationPayloadSchema.parse({
209
- brief,
210
- bullets: trace.bullets ?? [],
211
- source_trace_pointers: trace.source_trace_pointers ?? [],
212
- evaluator_summary: evaluatorSummary,
213
- });
214
- return payload;
215
- }
216
- /**
217
- * Convenience: validate an arbitrary unknown payload AS IF it were a
218
- * recommendation envelope. Returns a Result-like shape so the CLI can
219
- * render a structured MISSING_BRIEF_SECTION error without try/catch
220
- * noise.
221
- */
222
- export function safeRenderRecommendationPayload(input) {
223
- const r = RecommendationPayloadSchema.safeParse(input);
224
- if (r.success)
225
- return { ok: true, payload: r.data };
226
- const findings = r.error.issues.map((i) => ({
227
- path: i.path.join("."),
228
- message: i.message,
229
- }));
230
- // Map brief failures to MISSING_BRIEF_SECTION. A failure is
231
- // recognized as brief iff (a) every issue points at the brief or
232
- // its sections, OR (b) the explicit refine message is present.
233
- const isBrief = r.error.issues.every((i) => i.message.includes("evidence_brief must contain all 4 sections") ||
234
- BRIEF_SECTION_KEYS.has(i.path.join(".")) ||
235
- i.path[0] === "brief" ||
236
- (i.path.length >= 2 && i.path[0] === "brief"));
237
- return isBrief
238
- ? { ok: false, code: "MISSING_BRIEF_SECTION", findings }
239
- : { ok: false, findings };
240
- }
@@ -1,149 +0,0 @@
1
- import { type SkillPresence } from '../skills/skill-presence-service.js';
2
- export type DoctorCheck = {
3
- id: string;
4
- ok: boolean;
5
- message: string;
6
- };
7
- export type DoctorReport = {
8
- checks: DoctorCheck[];
9
- summary: {
10
- ok: boolean;
11
- passed: number;
12
- failed: number;
13
- };
14
- };
15
- export type CodegraphCapabilityProbe = {
16
- packagePath: string;
17
- version: string;
18
- binaryPath: string;
19
- binaryExists: boolean;
20
- };
21
- export type DistVersionComparison = {
22
- dist: string | null;
23
- source: string;
24
- match: boolean;
25
- distReadable: boolean;
26
- };
27
- export type DistVersionProbe = () => DistVersionComparison;
28
- export type WorkspaceLayoutInspection = {
29
- topLevelSessionDirs: string[];
30
- legacyDotfiles: string[];
31
- /**
32
- * Slice 007 — per-change-id top-level dirs (e.g. `.peaks/001-2026-06-06-.../`).
33
- * The pre-F3 canonical layout put reviewable artifacts under a
34
- * per-change-id top-level dir; the post-F3 canonical layout
35
- * consolidates them under `.peaks/_runtime/<sid>/<role>/`. Any
36
- * leftover per-change-id top-level dir is a regression to flag.
37
- * Slice 008's migration will consolidate these; until then, the
38
- * check reports them as `ok: false`.
39
- *
40
- * Optional in the type for back-compat with test probes that
41
- * pre-date the slice 007 broadening; the check itself falls back
42
- * to an empty array when the field is missing.
43
- */
44
- perChangeIdDirs?: string[];
45
- };
46
- export type WorkspaceLayoutProbe = () => WorkspaceLayoutInspection;
47
- /**
48
- * 2026-06-10 — `gateguard-fact-force` (a third-party PreToolUse hook,
49
- * NOT peaks-loop) fires on Edit / Write and demands a 4-fact questionnaire
50
- * before allowing the edit. When the LLM is in a peaks-qa flow and tries
51
- * to update `.peaks/_runtime/<sid>/qa/requests/*.md` via the Edit/Write
52
- * tool, the hook demands facts that are inapplicable to QA envelope
53
- * templates (no importers, no public API, no data files, user
54
- * instruction already in the conversation context). The check detects
55
- * this hook in the user's global and project `.claude/settings.json` and
56
- * warns when no `.peaks/**` skip is configured. The probe is injected so
57
- * tests do not depend on the real `~/.claude/settings.json` state.
58
- */
59
- export type GateguardHookLocation = {
60
- /** Source file the hook was discovered in (`global` or `project .claude/settings.json`). */
61
- source: 'global' | 'project';
62
- /** Resolved absolute path to the source file (for the message). */
63
- sourcePath: string;
64
- /** The PreToolUse entry that contains a gateguard hook command. */
65
- entry: {
66
- matcher?: string;
67
- hooks: ReadonlyArray<{
68
- type?: string;
69
- command?: string;
70
- }>;
71
- };
72
- };
73
- export type GateguardProbeResult = {
74
- /** Absolute path to `~/.claude/settings.json` (or null when the probe could not resolve it). */
75
- globalSettingsPath: string | null;
76
- /** Parsed global settings payload (or null when missing / unreadable / malformed). */
77
- globalSettings: unknown;
78
- /** Absolute path to the project `.claude/settings.json` (or null when the project root is not in a peaks project). */
79
- projectSettingsPath: string | null;
80
- /** Parsed project settings payload (or null when missing / unreadable / malformed). */
81
- projectSettings: unknown;
82
- };
83
- export type GateguardProbe = () => GateguardProbeResult;
84
- export type DoctorOptions = {
85
- schemasBaseDir?: string;
86
- skillsBaseDir?: string;
87
- codegraphProbe?: () => CodegraphCapabilityProbe;
88
- skillPresenceProbe?: () => SkillPresence | null;
89
- skillPresenceFreshnessThresholdMs?: number;
90
- statusLineInstalledProbe?: () => boolean;
91
- /** Returns true when a Peaks workspace session (.peaks/.session.json) exists. */
92
- workspaceInitializedProbe?: () => boolean;
93
- /** Platform string (defaults to process.platform); injectable for tests. */
94
- platform?: NodeJS.Platform;
95
- /** Injected for the build:dist-version-matches-source check (defaults to compareDistVersion on disk). */
96
- distVersionProbe?: DistVersionProbe;
97
- /** Injected for the build:workspace-layout-canonical check (defaults to inspectWorkspaceLayout on disk). */
98
- workspaceLayoutProbe?: WorkspaceLayoutProbe;
99
- /** Injected for the integration:gateguard-peaks-conflict check (defaults to defaultGateguardProbe on disk). */
100
- gateguardProbe?: GateguardProbe;
101
- /**
102
- * Slice 2026-06-13-repair-pre-existing-test-failures: injected
103
- * root for the L3:l3-memory-health check (defaults to
104
- * `findProjectRoot(process.cwd())`). Tests use this to point the
105
- * check at a temp dir without monkey-patching `findProjectRoot`.
106
- */
107
- l3ProjectRoot?: string;
108
- };
109
- /**
110
- * Pure helper extracted from `defaultWorkspaceInitializedProbe` so tests can
111
- * drive the filesystem check without monkey-patching `process.cwd()` or
112
- * `findProjectRoot`. Returns `true` when EITHER the canonical
113
- * `.peaks/_runtime/session.json` OR the legacy `.peaks/.session.json` exists.
114
- */
115
- export declare function isWorkspaceInitializedAt(projectRoot: string): boolean;
116
- /**
117
- * Pure helper that compares the published dist `CLI_VERSION` against the
118
- * source-of-truth `package.json#version`. Default readers fail-soft to `null`
119
- * on missing/unreadable/malformed input. Exported so tests can drive the
120
- * filesystem reads without monkey-patching `process.cwd()`.
121
- */
122
- export declare function compareDistVersion(opts: {
123
- projectRoot: string;
124
- distVersionReader?: (root: string) => string | null;
125
- sourceVersionReader?: (root: string) => string | null;
126
- }): DistVersionComparison;
127
- /**
128
- * Pure helper that inspects the on-disk workspace layout for
129
- * post-F3-canonical violations. The post-F3 canonical layout puts
130
- * session dirs under `.peaks/_runtime/<sid>/` and the runtime
131
- * binding at `.peaks/_runtime/session.json`; the legacy paths
132
- * (top-level `<YYYY-MM-DD-session-<hex>>/` dirs and the legacy
133
- * top-level `.peaks/.session.json` / `.peaks/.active-skill.json`
134
- * dotfiles) must be absent. This helper is exported so tests can
135
- * drive the filesystem walk without monkey-patching `process.cwd()`
136
- * or `findProjectRoot`.
137
- *
138
- * Both scanners fail-soft (return `[]` on read errors) so a flaky
139
- * filesystem read on a non-fatal probe path never escalates into a
140
- * doctor failure.
141
- */
142
- export declare function inspectWorkspaceLayout(opts: {
143
- projectRoot: string;
144
- topLevelScanner?: (root: string) => string[];
145
- dotfileScanner?: (root: string) => string[];
146
- perChangeIdScanner?: (root: string) => string[];
147
- }): WorkspaceLayoutInspection;
148
- export declare function collectGateguardEntries(probe: GateguardProbeResult): GateguardHookLocation[];
149
- export declare function runDoctor(options?: DoctorOptions): Promise<DoctorReport>;