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

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,316 +0,0 @@
1
- /**
2
- * peaks-perf-audit service — independent performance audit skill driver.
3
- *
4
- * Slice v2.12.0 (Group A, Tier 3). Symmetric to security-audit-service.ts:
5
- * - 5-state detection of the perf-audit runtime
6
- * - Loading + sha256 verification of the prd/handoff.md
7
- * - Loading the project-level perf-template.md
8
- * - Producing the audit envelope (verdict + violations) to write
9
- * to `.peaks/_runtime/<sid>/audit/perf-<rid>.md`
10
- *
11
- * The actual LLM-in-loop audit step is NOT in this service — the
12
- * parent LLM (peaks-perf-audit skill prompt) reads the template,
13
- * runs the audit, and returns a structured envelope. This service
14
- * is the pure I/O + validation core; the LLM is the judgement core.
15
- *
16
- * Cross-references:
17
- * - PRD: `.peaks/_runtime/<sid>/prd/handoff.md` (sha256-locked, schemaVersion: 2)
18
- * - Template: `.peaks/project-scan/perf-template.md`
19
- * - Output: `.peaks/_runtime/<sid>/audit/perf-<rid>.md`
20
- * - Schema: `.peaks/project-scan/audit-output-schema.md` (schemaVersion: 1)
21
- * - Companion: `src/services/audit-independent/security-audit-service.ts`
22
- */
23
- import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
24
- import { join, resolve, isAbsolute } from 'node:path';
25
- import { createHash } from 'node:crypto';
26
- /**
27
- * Validate a raw value as a PerfAuditEnvelope. Mirrors the
28
- * `isSecurityAuditEnvelope` strict-shape pattern.
29
- */
30
- export function isPerfAuditEnvelope(value) {
31
- if (value === null || typeof value !== 'object')
32
- return false;
33
- const obj = value;
34
- if (typeof obj.verdict !== 'string')
35
- return false;
36
- if (obj.verdict !== 'pass' && obj.verdict !== 'warn' && obj.verdict !== 'block') {
37
- return false;
38
- }
39
- if (!Array.isArray(obj.violations))
40
- return false;
41
- if (typeof obj.summary !== 'string')
42
- return false;
43
- for (const v of obj.violations) {
44
- if (v === null || typeof v !== 'object')
45
- return false;
46
- const vo = v;
47
- if (typeof vo.dimension !== 'string')
48
- return false;
49
- if (typeof vo.severity !== 'string')
50
- return false;
51
- if (vo.severity !== 'CRITICAL' && vo.severity !== 'HIGH' && vo.severity !== 'MED' && vo.severity !== 'LOW') {
52
- return false;
53
- }
54
- if (typeof vo.file !== 'string')
55
- return false;
56
- if (typeof vo.line !== 'number' || !Number.isFinite(vo.line))
57
- return false;
58
- if (typeof vo.hint !== 'string')
59
- return false;
60
- }
61
- return true;
62
- }
63
- /**
64
- * Read the peaks-prd handoff frontmatter + body, verify sha256 matches
65
- * the body. Returns null on missing file or sha256 mismatch; otherwise
66
- * returns the parsed frontmatter + body string.
67
- *
68
- * Defensive: we read frontmatter via a 1-line regex match, not via
69
- * a YAML parser. The handoff service (`src/services/prd/handoff-service.ts`)
70
- * is the canonical writer; we only consume its output here.
71
- */
72
- export function readAndVerifyHandoff(handoffPath, projectRoot) {
73
- if (!handoffPath || !isAbsolute(handoffPath)) {
74
- const absolutePath = resolve(projectRoot, handoffPath);
75
- if (!existsSync(absolutePath))
76
- return null;
77
- return readAndVerifyHandoff(absolutePath, projectRoot);
78
- }
79
- if (!existsSync(handoffPath))
80
- return null;
81
- let raw;
82
- try {
83
- raw = readFileSync(handoffPath, 'utf8');
84
- }
85
- catch { // TODO(g2): legacy silent catch — grace: 1 minor release (v2.14.0)
86
- return null;
87
- }
88
- // Frontmatter pattern: `---` line, then key: value pairs, then `---` line.
89
- const match = raw.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
90
- if (match === null)
91
- return null;
92
- const frontmatterRaw = match[1];
93
- const body = match[2];
94
- const sha256Match = frontmatterRaw.match(/^sha256:\s*([a-f0-9]{64})\s*$/m);
95
- const schemaVersionMatch = frontmatterRaw.match(/^schemaVersion:\s*(\d+)\s*$/m);
96
- if (sha256Match === null || schemaVersionMatch === null)
97
- return null;
98
- const sha256Expected = sha256Match[1];
99
- const schemaVersion = parseInt(schemaVersionMatch[1], 10);
100
- const sha256Actual = createHash('sha256').update(body, 'utf8').digest('hex');
101
- if (sha256Expected !== sha256Actual)
102
- return null;
103
- return {
104
- frontmatter: { sha256: sha256Expected, schemaVersion },
105
- body,
106
- };
107
- }
108
- /**
109
- * Read the project-level perf-template.md. Returns the body
110
- * string (with frontmatter stripped) or null if the file is absent.
111
- * Does NOT validate the template content; the parent LLM validates
112
- * by reading.
113
- */
114
- export function readPerfTemplate(projectRoot) {
115
- const templatePath = join(projectRoot, '.peaks', 'project-scan', 'perf-template.md');
116
- if (!existsSync(templatePath))
117
- return null;
118
- try {
119
- return readFileSync(templatePath, 'utf8');
120
- }
121
- catch { // TODO(g2): legacy silent catch — grace: 1 minor release (v2.14.0)
122
- return null;
123
- }
124
- }
125
- /**
126
- * 5-state detector. The parent skill inspects the state and either
127
- * proceeds (when `ready`) or records a degradation note and falls
128
- * back (when any other state).
129
- *
130
- * Soft-fail policy mirrors `detectEcc` (slice 7 Group D) and
131
- * `detectSecurityAudit`: the CLI never throws; it returns a typed
132
- * detect result.
133
- */
134
- export function detectPerfAudit(input) {
135
- const warnings = [];
136
- const nextActions = [];
137
- const handoffPath = join(input.projectRoot, '.peaks', '_runtime', input.sessionId, 'prd', 'handoff.md');
138
- const handoffPresent = existsSync(handoffPath);
139
- const templatePath = join(input.projectRoot, '.peaks', 'project-scan', 'perf-template.md');
140
- const templatePresent = existsSync(templatePath);
141
- if (!handoffPresent) {
142
- return {
143
- state: 'handoff-missing',
144
- handoffPresent: false,
145
- templatePresent,
146
- warnings: [`peaks-prd handoff not found at ${handoffPath}`],
147
- nextActions: [
148
- 'Run peaks-prd handoff init to produce a sha256-locked handoff before running peaks perf-audit.',
149
- 'Until the handoff exists, peaks-perf-audit cannot start (gate fail).'
150
- ]
151
- };
152
- }
153
- if (!templatePresent) {
154
- return {
155
- state: 'template-missing',
156
- handoffPresent: true,
157
- templatePresent: false,
158
- warnings: [`perf-template.md not found at ${templatePath}`],
159
- nextActions: [
160
- 'Run peaks project template init to bootstrap the 3 audit templates (security-template, perf-template, audit-output-schema).',
161
- 'Until the template exists, peaks-perf-audit cannot start (gate fail).'
162
- ]
163
- };
164
- }
165
- if (input.dispatchError !== undefined) {
166
- return {
167
- state: 'dispatch-failed',
168
- handoffPresent: true,
169
- templatePresent: true,
170
- warnings: [
171
- `Audit dispatch failed: ${input.dispatchError instanceof Error ? input.dispatchError.message : String(input.dispatchError)}`
172
- ],
173
- nextActions: [
174
- 'Inspect the audit prompt template for the failure cause.',
175
- 'peaks-perf-audit falls back to inline LLM review (degradation note: perf-audit-dispatch-failed).'
176
- ]
177
- };
178
- }
179
- if (input.envelope !== undefined && !isPerfAuditEnvelope(input.envelope)) {
180
- return {
181
- state: 'envelope-malformed',
182
- handoffPresent: true,
183
- templatePresent: true,
184
- warnings: [
185
- 'Perf-audit returned a value that failed envelope validation (expected { verdict, violations, summary }).'
186
- ],
187
- nextActions: [
188
- 'Verify the perf-audit skill prompt matches PRD AC-3.x output shape.',
189
- 'If the envelope shape is intentionally different, file a bug at the peaks-loop repo.'
190
- ]
191
- };
192
- }
193
- return {
194
- state: 'ready',
195
- handoffPresent: true,
196
- templatePresent: true,
197
- warnings,
198
- nextActions
199
- };
200
- }
201
- /**
202
- * Render a PerfAuditEnvelope to the canonical audit artifact body
203
- * (markdown). Mirrors `renderSecurityAuditArtifact` in
204
- * `security-audit-service.ts` and `adaptEccEnvelopeToRdCodeReview`
205
- * in ecc-bridge.ts: produce a markdown body with all required
206
- * sections, ready to write to
207
- * `.peaks/_runtime/<sid>/audit/perf-<rid>.md`.
208
- */
209
- export function renderPerfAuditArtifact(env, opts) {
210
- const counts = {};
211
- for (const v of env.violations) {
212
- counts[v.severity] = (counts[v.severity] ?? 0) + 1;
213
- }
214
- const criticalCount = counts['CRITICAL'] ?? 0;
215
- const findingsBullets = env.violations.length === 0
216
- ? '- (none)'
217
- : env.violations.map((v) => `- [${v.severity}] ${v.dimension} @ ${v.file}:${v.line} — ${v.hint}`).join('\n');
218
- const requiredFixes = env.violations.length === 0
219
- ? ''
220
- : [
221
- '## Required fixes',
222
- '',
223
- ...env.violations.map((v) => `- [${v.severity}] ${v.file}:${v.line} — ${v.hint}`),
224
- ''
225
- ].join('\n');
226
- const body = [
227
- '## Summary',
228
- '',
229
- env.summary,
230
- '',
231
- '## Baseline reference',
232
- '',
233
- 'N/A — no prior baseline (slice v2.12.0 first-run bootstrap)',
234
- `audited at: ${opts.generatedAt}`,
235
- `verdict: ${env.verdict}`,
236
- `handoffHash: ${opts.handoffHash}`,
237
- '',
238
- '## Measurement result',
239
- '',
240
- '(see Findings; per-dimension method declared in template)',
241
- '',
242
- '## Threshold check',
243
- '',
244
- '(see Findings; per-dimension threshold table declared in template)',
245
- '',
246
- '## Findings',
247
- '',
248
- findingsBullets,
249
- '',
250
- requiredFixes,
251
- '## Verdict',
252
- '',
253
- `verdict: ${env.verdict}`,
254
- `CRITICAL: ${criticalCount}`,
255
- ''
256
- ].filter((s) => s.length > 0).join('\n');
257
- return {
258
- body,
259
- violationsCount: env.violations.length,
260
- verdict: env.verdict,
261
- };
262
- }
263
- /**
264
- * Write the rendered audit artifact to
265
- * `.peaks/_runtime/<sid>/audit/perf-<rid>.md`.
266
- *
267
- * Atomic write (tmp + rename) to avoid partial writes on crash.
268
- * Returns the absolute path on success.
269
- */
270
- export function writePerfAuditArtifact(projectRoot, sessionId, rid, body) {
271
- const targetDir = join(projectRoot, '.peaks', '_runtime', sessionId, 'audit');
272
- mkdirSync(targetDir, { recursive: true });
273
- const targetPath = join(targetDir, `perf-${rid}.md`);
274
- // tmp + rename for atomicity
275
- const tmpPath = `${targetPath}.tmp`;
276
- writeFileSync(tmpPath, body, 'utf8');
277
- // Sync rename: on Windows, fs.renameSync overwrites if target exists (Node 22+)
278
- const { renameSync } = require('node:fs');
279
- renameSync(tmpPath, targetPath);
280
- return targetPath;
281
- }
282
- /**
283
- * Convenience: run `detectPerfAudit` + `renderPerfAuditArtifact`
284
- * + `writePerfAuditArtifact` in one call.
285
- *
286
- * Returns `{ detect, artifactPath, violationsCount, verdict }` or
287
- * `{ detect, artifactPath: null, ... }` when not ready.
288
- */
289
- export function runPerfAudit(input) {
290
- const detect = detectPerfAudit({
291
- projectRoot: input.projectRoot,
292
- sessionId: input.sessionId,
293
- ...(input.dispatchError !== undefined ? { dispatchError: input.dispatchError } : {}),
294
- ...(input.envelope !== undefined ? { envelope: input.envelope } : {})
295
- });
296
- if (detect.state !== 'ready' || input.envelope === undefined) {
297
- return { detect, artifactPath: null, violationsCount: 0, verdict: null };
298
- }
299
- // detect.state === 'ready' implies input.envelope passed isPerfAuditEnvelope.
300
- const env = input.envelope;
301
- const handoffPath = join(input.projectRoot, '.peaks', '_runtime', input.sessionId, 'prd', 'handoff.md');
302
- const verified = readAndVerifyHandoff(handoffPath, input.projectRoot);
303
- const handoffHash = verified?.frontmatter.sha256 ?? 'unknown';
304
- const rendered = renderPerfAuditArtifact(env, {
305
- rid: input.rid,
306
- handoffHash,
307
- generatedAt: input.generatedAt
308
- });
309
- const artifactPath = writePerfAuditArtifact(input.projectRoot, input.sessionId, input.rid, rendered.body);
310
- return {
311
- detect,
312
- artifactPath,
313
- violationsCount: rendered.violationsCount,
314
- verdict: rendered.verdict
315
- };
316
- }
@@ -1,155 +0,0 @@
1
- /**
2
- * peaks-security-audit service — independent security audit skill driver.
3
- *
4
- * Slice v2.12.0 (Group A, Tier 2). The skill is decoupled from the
5
- * peaks-rd 5-way fan-out (per PRD AC-2.x) and lives as a standalone
6
- * CLI surface: `peaks security-audit run --rid <id> ...`.
7
- *
8
- * The service owns:
9
- * - 5-state detection of the security-audit runtime
10
- * (handoff-missing / template-missing / dispatch-failed / template-malformed / ready)
11
- * - Loading + sha256 verification of the prd/handoff.md
12
- * - Loading the project-level security-template.md
13
- * - Producing the audit envelope (verdict + violations) to write
14
- * to `.peaks/_runtime/<sid>/audit/security-<rid>.md`
15
- *
16
- * The actual LLM-in-loop audit step is NOT in this service — the
17
- * parent LLM (peaks-security-audit skill prompt) reads the template,
18
- * runs the audit, and returns a structured envelope. This service
19
- * is the pure I/O + validation core; the LLM is the judgement core.
20
- *
21
- * Why a service (not inlined in the CLI):
22
- * - Unit-testable in isolation (6 case per PRD AC-2.8)
23
- * - The 5-state detector mirrors the ecc-bridge detectEcc pattern
24
- * (slice 7 Group D), keeping the surface uniform
25
- * - Future migration to peaks sub-agent dispatch (peaks-rd main
26
- * loop can opt to call this service directly without re-implementing
27
- * the handoff verification)
28
- *
29
- * Cross-references:
30
- * - PRD: `.peaks/_runtime/<sid>/prd/handoff.md` (sha256-locked, schemaVersion: 2)
31
- * - Template: `.peaks/project-scan/security-template.md`
32
- * - Output: `.peaks/_runtime/<sid>/audit/security-<rid>.md`
33
- * - Schema: `.peaks/project-scan/audit-output-schema.md` (schemaVersion: 1)
34
- */
35
- /**
36
- * 5-state detection result. Mirrors `detectEcc` in `services/code-review/ecc-bridge.ts`.
37
- *
38
- * - `ready` — handoff + template + project all present
39
- * - `handoff-missing` — `.peaks/_runtime/<sid>/prd/handoff.md` absent
40
- * - `template-missing` — `.peaks/project-scan/security-template.md` absent
41
- * - `dispatch-failed` — parent LLM threw before returning the audit envelope
42
- * - `envelope-malformed` — parent LLM returned a value that fails `isSecurityAuditEnvelope`
43
- */
44
- export type SecurityAuditDetectState = 'ready' | 'handoff-missing' | 'template-missing' | 'dispatch-failed' | 'envelope-malformed';
45
- export interface SecurityAuditDetectResult {
46
- readonly state: SecurityAuditDetectState;
47
- readonly handoffPresent: boolean;
48
- readonly templatePresent: boolean;
49
- readonly warnings: readonly string[];
50
- readonly nextActions: readonly string[];
51
- }
52
- export type SecurityAuditVerdict = 'pass' | 'warn' | 'block';
53
- export interface SecurityAuditViolation {
54
- readonly dimension: string;
55
- readonly severity: 'CRITICAL' | 'HIGH' | 'MED' | 'LOW';
56
- readonly file: string;
57
- readonly line: number;
58
- readonly hint: string;
59
- }
60
- export interface SecurityAuditEnvelope {
61
- readonly verdict: SecurityAuditVerdict;
62
- readonly violations: ReadonlyArray<SecurityAuditViolation>;
63
- readonly summary: string;
64
- }
65
- /**
66
- * Validate a raw value as a SecurityAuditEnvelope. Mirrors the
67
- * `isEccEnvelope` strict-shape pattern.
68
- */
69
- export declare function isSecurityAuditEnvelope(value: unknown): value is SecurityAuditEnvelope;
70
- /**
71
- * Handoff frontmatter — minimal projection of peaks-prd v2.11.0 handoff
72
- * frontmatter. We only need sha256 for verification; the rest of the
73
- * handoff body is consumed by the parent LLM, not by this service.
74
- */
75
- export interface HandoffFrontmatter {
76
- readonly sha256: string;
77
- readonly schemaVersion: number;
78
- }
79
- /**
80
- * Read the peaks-prd handoff frontmatter + body, verify sha256 matches
81
- * the body. Returns null on missing file or sha256 mismatch; otherwise
82
- * returns the parsed frontmatter + body string.
83
- *
84
- * Defensive: we read frontmatter via a 1-line regex match, not via
85
- * a YAML parser. The handoff service (`src/services/prd/handoff-service.ts`)
86
- * is the canonical writer; we only consume its output here.
87
- */
88
- export declare function readAndVerifyHandoff(handoffPath: string, projectRoot: string): {
89
- frontmatter: HandoffFrontmatter;
90
- body: string;
91
- } | null;
92
- /**
93
- * Read the project-level security-template.md. Returns the body
94
- * string (with frontmatter stripped) or null if the file is absent.
95
- * Does NOT validate the template content; the parent LLM validates
96
- * by reading.
97
- */
98
- export declare function readSecurityTemplate(projectRoot: string): string | null;
99
- /**
100
- * 5-state detector. The parent skill inspects the state and either
101
- * proceeds (when `ready`) or records a degradation note and falls
102
- * back (when any other state).
103
- *
104
- * Soft-fail policy mirrors `detectEcc` (slice 7 Group D): the CLI
105
- * never throws; it returns a typed detect result.
106
- */
107
- export declare function detectSecurityAudit(input: {
108
- readonly projectRoot: string;
109
- readonly sessionId: string;
110
- readonly dispatchError?: unknown;
111
- readonly envelope?: unknown;
112
- }): SecurityAuditDetectResult;
113
- /**
114
- * Render a SecurityAuditEnvelope to the canonical audit artifact body
115
- * (markdown). Mirrors `adaptEccEnvelopeToRdCodeReview` in ecc-bridge.ts:
116
- * produce a markdown body with all required sections, ready to write
117
- * to `.peaks/_runtime/<sid>/audit/security-<rid>.md`.
118
- */
119
- export declare function renderSecurityAuditArtifact(env: SecurityAuditEnvelope, opts: {
120
- rid: string;
121
- handoffHash: string;
122
- generatedAt: string;
123
- }): {
124
- body: string;
125
- violationsCount: number;
126
- verdict: SecurityAuditVerdict;
127
- };
128
- /**
129
- * Write the rendered audit artifact to
130
- * `.peaks/_runtime/<sid>/audit/security-<rid>.md`.
131
- *
132
- * Atomic write (tmp + rename) to avoid partial writes on crash.
133
- * Returns the absolute path on success.
134
- */
135
- export declare function writeSecurityAuditArtifact(projectRoot: string, sessionId: string, rid: string, body: string): string;
136
- /**
137
- * Convenience: run `detectSecurityAudit` + `renderSecurityAuditArtifact`
138
- * + `writeSecurityAuditArtifact` in one call.
139
- *
140
- * Returns `{ detect, artifactPath, violationsCount, verdict }` or
141
- * `{ detect, artifactPath: null, ... }` when not ready.
142
- */
143
- export declare function runSecurityAudit(input: {
144
- readonly projectRoot: string;
145
- readonly sessionId: string;
146
- readonly rid: string;
147
- readonly generatedAt: string;
148
- readonly dispatchError?: unknown;
149
- readonly envelope?: unknown;
150
- }): {
151
- detect: SecurityAuditDetectResult;
152
- artifactPath: string | null;
153
- violationsCount: number;
154
- verdict: SecurityAuditVerdict | null;
155
- };