@mmnto/cli 1.16.1 → 1.17.1

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 (40) hide show
  1. package/dist/adapters/github-cli-pr.d.ts +13 -1
  2. package/dist/adapters/github-cli-pr.d.ts.map +1 -1
  3. package/dist/adapters/github-cli-pr.js +60 -2
  4. package/dist/adapters/github-cli-pr.js.map +1 -1
  5. package/dist/adapters/github-cli-pr.test.js +67 -0
  6. package/dist/adapters/github-cli-pr.test.js.map +1 -1
  7. package/dist/adapters/pr-adapter.d.ts +25 -0
  8. package/dist/adapters/pr-adapter.d.ts.map +1 -1
  9. package/dist/commands/retrospect.d.ts +37 -0
  10. package/dist/commands/retrospect.d.ts.map +1 -0
  11. package/dist/commands/retrospect.js +461 -0
  12. package/dist/commands/retrospect.js.map +1 -0
  13. package/dist/commands/retrospect.test.d.ts +2 -0
  14. package/dist/commands/retrospect.test.d.ts.map +1 -0
  15. package/dist/commands/retrospect.test.js +703 -0
  16. package/dist/commands/retrospect.test.js.map +1 -0
  17. package/dist/commands/shield-estimate.d.ts +8 -0
  18. package/dist/commands/shield-estimate.d.ts.map +1 -1
  19. package/dist/commands/shield-estimate.js +224 -0
  20. package/dist/commands/shield-estimate.js.map +1 -1
  21. package/dist/commands/shield-estimate.test.js +570 -0
  22. package/dist/commands/shield-estimate.test.js.map +1 -1
  23. package/dist/commands/shield.d.ts +8 -0
  24. package/dist/commands/shield.d.ts.map +1 -1
  25. package/dist/commands/shield.js.map +1 -1
  26. package/dist/index.js +64 -0
  27. package/dist/index.js.map +1 -1
  28. package/dist/terminal-sanitize.d.ts +28 -0
  29. package/dist/terminal-sanitize.d.ts.map +1 -0
  30. package/dist/terminal-sanitize.js +36 -0
  31. package/dist/terminal-sanitize.js.map +1 -0
  32. package/dist/terminal-sanitize.test.d.ts +2 -0
  33. package/dist/terminal-sanitize.test.d.ts.map +1 -0
  34. package/dist/terminal-sanitize.test.js +46 -0
  35. package/dist/terminal-sanitize.test.js.map +1 -0
  36. package/dist/utils.d.ts +1 -0
  37. package/dist/utils.d.ts.map +1 -1
  38. package/dist/utils.js +6 -0
  39. package/dist/utils.js.map +1 -1
  40. package/package.json +2 -2
@@ -0,0 +1,461 @@
1
+ /**
2
+ * `totem retrospect <pr>` — bot-tax circuit-breaker (mmnto-ai/totem#1713).
3
+ *
4
+ * Reads a PR's bot-review history live, groups findings into push-based
5
+ * rounds via the per-submission `commit_id` field, enriches each finding
6
+ * with cross-PR-recurrence flags from `.totem/recurrence-stats.json`
7
+ * (read-only) plus rule-coverage flags from `compiled-rules.json`, and
8
+ * emits a console report classifying findings as `route-out`,
9
+ * `in-pr-fix`, or `undetermined` via a deterministic table-driven
10
+ * heuristic.
11
+ *
12
+ * Substrate of the bot-tax cluster (#1715 + #1714 + #1713). Reuses the
13
+ * `recurrence-stats.ts` signature + severity vocabulary so the cluster
14
+ * has a single source of truth.
15
+ *
16
+ * No LLM. No GitHub API writes. Read-only outside the optional
17
+ * `--out <path>` JSON write.
18
+ *
19
+ * NOTE on `--auto-file`: the auto-spec proposed shelling out to
20
+ * `gh issue create` for every route-out candidate. The locked design
21
+ * (see `.totem/specs/1713.md` Q2) defers `--auto-file` to a follow-up
22
+ * ticket because mass-filing issues is irreversible and the v0.1
23
+ * surface emits suggested titles + bodies that the human can copy-paste.
24
+ */
25
+ // totem-context: type-only imports above are erased at compile time and don't
26
+ // violate the lazy-import command policy (mmnto-ai/totem#1729 CR R1). All
27
+ // runtime imports (node:fs, node:path, zod, @mmnto/totem, helpers, adapters)
28
+ // are dynamic — see runRetrospect body.
29
+ // ─── Constants ───────────────────────────────────────
30
+ export const RETROSPECT_DISPLAY_TAG = 'Retrospect';
31
+ const TAG = RETROSPECT_DISPLAY_TAG;
32
+ const DEFAULT_THRESHOLD = 5;
33
+ const BODY_EXCERPT_MAX = 280;
34
+ /** Jaccard similarity above which a finding signature is treated as covered by an existing compiled rule. Mirrors `recurrence-stats.ts` `COVERAGE_JACCARD_THRESHOLD`. */
35
+ const RULE_COVERAGE_JACCARD_THRESHOLD = 0.6;
36
+ /** Max chars rendered for a finding's body excerpt in the console report. */
37
+ const RENDER_SNIPPET_MAX = 80;
38
+ // ─── Main entrypoint ────────────────────────────────
39
+ export async function runRetrospect(options) {
40
+ // Dynamic imports per `packages/cli/src/commands/**` lazy-import policy
41
+ // (mmnto-ai/totem#1729 CR R1).
42
+ const fs = await import('node:fs');
43
+ const path = await import('node:path');
44
+ const { z } = await import('zod');
45
+ const { GitHubCliPrAdapter } = await import('../adapters/github-cli-pr.js');
46
+ const { log } = await import('../ui.js');
47
+ const { isBotComment, detectBot, parseCRSeverity, parseGCASeverity, stripHtmlWrappers, extractReviewBodyFindings, } = await import('../parsers/bot-review-parser.js');
48
+ const { buildStopConditions, classifyFinding, computeDedupRate, computeSignature, groupFindingsByRound, jaccard, loadCompiledRules, normalizeFindingBody, readLedgerEvents, RetrospectReportSchema, toSeverityBucket, tokenizeForJaccard, } = await import('@mmnto/totem');
49
+ // `sanitizeForTerminal` is re-exported from `../utils.js` (canonical
50
+ // location: `./terminal-sanitize.ts` — see CR mmnto-ai/totem#1739 R2).
51
+ // Routing it through `terminal-sanitize.js` would NOT save load cost
52
+ // here because utils.js is already in this command's lazy-import set
53
+ // for `loadConfig` + `resolveConfigPath`; the orchestrator graph is
54
+ // already in. The dep-light routing matters for `shield-estimate.ts`'s
55
+ // pattern-history overlay (which doesn't otherwise load utils).
56
+ const { loadConfig, resolveConfigPath, sanitizeForTerminal } = await import('../utils.js');
57
+ // Local schema — the recurrence-stats file shape is defined in core,
58
+ // but reading it here keeps the zod import lazy.
59
+ const RecurrenceStatsFileSchema = z.object({
60
+ version: z.literal(1),
61
+ patterns: z.array(z.object({
62
+ signature: z.string(),
63
+ prs: z.array(z.string()),
64
+ })),
65
+ coveredPatterns: z
66
+ .array(z.object({
67
+ signature: z.string(),
68
+ prs: z.array(z.string()),
69
+ }))
70
+ .optional(),
71
+ });
72
+ const cwd = process.cwd();
73
+ const threshold = clampThreshold(options.threshold);
74
+ const prNumber = options.prNumber;
75
+ // Strict integer parse (reject "5foo", "5.2", " 5 ") — `Number.parseInt`
76
+ // silently accepts trailing non-numerics; per CR/GCA mmnto-ai/totem#1734
77
+ // review-1 we use `Number()` + `Number.isInteger` for CLI inputs.
78
+ const prNumberInt = Number(prNumber);
79
+ if (!Number.isInteger(prNumberInt) || prNumberInt <= 0) {
80
+ const { TotemConfigError } = await import('@mmnto/totem');
81
+ throw new TotemConfigError(`Invalid PR number: ${prNumber}`, "Pass a positive integer (e.g. 'totem retrospect 1734').", 'CONFIG_INVALID');
82
+ }
83
+ log.info(TAG, `Retrospect on PR #${prNumber} (threshold=${threshold}).`);
84
+ // 1. Live-fetch PR + reviews + comments.
85
+ const adapter = new GitHubCliPrAdapter(cwd);
86
+ const prData = adapter.fetchPr(prNumberInt);
87
+ const reviewSubmissions = adapter.fetchReviews(prNumberInt);
88
+ const reviewComments = adapter.fetchReviewComments(prNumberInt);
89
+ // 2. Round-grouping. Build a SHA → finding-count map by joining inline
90
+ // comments back to the closest preceding review submission via
91
+ // timestamp. We only consider BOT submissions because the round
92
+ // count is a measure of bot-driven feedback waves.
93
+ // Null-guard before isBotComment — GitHub API permits null `user`
94
+ // (deleted/ghost accounts). Without the guard, `isBotComment(null)`
95
+ // would silently exclude bot rounds. Per CR mmnto-ai/totem#1734 review-1.
96
+ const botSubmissions = reviewSubmissions
97
+ .filter((r) => r.user_login !== null && isBotComment(r.user_login))
98
+ .map((r) => ({
99
+ id: r.id,
100
+ commit_id: r.commit_id ?? null,
101
+ submitted_at: r.submitted_at ?? null,
102
+ user_login: r.user_login,
103
+ }));
104
+ // Bucket each finding by the parent review submission's commit_id.
105
+ // Per CR mmnto-ai/totem#1734 round-2: `created_at` can predate
106
+ // `submitted_at` for pending/draft reviews, so a timestamp join
107
+ // mis-attributes the head SHA. The GitHub API exposes
108
+ // `pull_request_review_id` on each review comment as the stable
109
+ // foreign key back to its parent submission — we use that.
110
+ const sortedSubs = [...botSubmissions].sort((a, b) => {
111
+ const at = a.submitted_at ?? '';
112
+ const bt = b.submitted_at ?? '';
113
+ if (at < bt)
114
+ return -1;
115
+ if (at > bt)
116
+ return 1;
117
+ return 0;
118
+ });
119
+ /** review_id → commit_id lookup over bot-authored submissions only. */
120
+ const reviewIdToSha = new Map();
121
+ for (const s of botSubmissions) {
122
+ if (typeof s.commit_id === 'string')
123
+ reviewIdToSha.set(s.id, s.commit_id);
124
+ }
125
+ function shaForInlineComment(reviewId) {
126
+ if (typeof reviewId !== 'number')
127
+ return '';
128
+ return reviewIdToSha.get(reviewId) ?? '';
129
+ }
130
+ // 3. Inline + review-body bot finding extraction.
131
+ const inlineBotComments = reviewComments.filter((c) => isBotComment(c.author));
132
+ const inlineFindings = [];
133
+ for (const c of inlineBotComments) {
134
+ const tool = detectBot(c.author);
135
+ const severity = tool === 'coderabbit'
136
+ ? parseCRSeverity(c.body)
137
+ : tool === 'gca'
138
+ ? parseGCASeverity(c.body)
139
+ : 'info';
140
+ const body = stripHtmlWrappers(c.body);
141
+ const hunkMatch = c.diffHunk.match(/@@ .+?\+(\d+)/);
142
+ const line = hunkMatch ? Number.parseInt(hunkMatch[1], 10) : undefined;
143
+ inlineFindings.push({
144
+ finding: {
145
+ tool,
146
+ severity,
147
+ file: c.path,
148
+ line,
149
+ body,
150
+ resolutionSignal: 'none',
151
+ rootCommentId: c.id,
152
+ },
153
+ sha: shaForInlineComment(c.pullRequestReviewId),
154
+ observedAt: c.createdAt ?? '',
155
+ });
156
+ }
157
+ // CR review-body findings (outside-diff + nits) — bucket into the SHA
158
+ // of the review submission that carried them.
159
+ const reviewBodyFindings = [];
160
+ for (const r of reviewSubmissions) {
161
+ // Null-guard: deleted/ghost accounts skip this branch — same rationale as the bot-submissions filter above.
162
+ if (r.user_login === null || !isBotComment(r.user_login))
163
+ continue;
164
+ const synthesized = extractReviewBodyFindings([{ author: r.user_login, body: r.body ?? '' }]);
165
+ const sha = typeof r.commit_id === 'string' ? r.commit_id : '';
166
+ const observedAt = r.submitted_at ?? '';
167
+ for (const f of synthesized) {
168
+ reviewBodyFindings.push({ finding: f, sha, observedAt });
169
+ }
170
+ }
171
+ const allFindings = [...inlineFindings, ...reviewBodyFindings];
172
+ // SHA → finding count.
173
+ const findingsPerSha = new Map();
174
+ for (const f of allFindings) {
175
+ findingsPerSha.set(f.sha, (findingsPerSha.get(f.sha) ?? 0) + 1);
176
+ }
177
+ // Compute rounds via the pure helper.
178
+ const rounds = groupFindingsByRound(sortedSubs, findingsPerSha);
179
+ // SHA → roundNumber lookup so we can stamp each finding.
180
+ const shaToRoundNumber = new Map();
181
+ for (const r of rounds) {
182
+ shaToRoundNumber.set(r.headSha ?? '', r.roundNumber);
183
+ }
184
+ // 4. Substrate read — recurrence-stats (graceful degrade if missing).
185
+ const config = await loadConfig(resolveConfigPath(cwd));
186
+ const totemDir = path.join(cwd, config.totemDir);
187
+ const substratePath = path.join(totemDir, 'recurrence-stats.json');
188
+ let substrateAvailable = false;
189
+ /** signature → list of OTHER PRs sharing this signature (target excluded). */
190
+ const crossPrIndex = new Map();
191
+ if (fs.existsSync(substratePath)) {
192
+ try {
193
+ const raw = fs.readFileSync(substratePath, 'utf-8');
194
+ const parsed = JSON.parse(raw);
195
+ const validated = RecurrenceStatsFileSchema.parse(parsed);
196
+ substrateAvailable = true;
197
+ const allEntries = [...(validated.patterns ?? []), ...(validated.coveredPatterns ?? [])];
198
+ for (const entry of allEntries) {
199
+ const others = entry.prs.filter((p) => p !== prNumber);
200
+ const set = crossPrIndex.get(entry.signature) ?? new Set();
201
+ for (const pr of others)
202
+ set.add(pr);
203
+ crossPrIndex.set(entry.signature, set);
204
+ }
205
+ // totem-context: malformed substrate is a graceful-degrade path per the mmnto-ai/totem#1713 failure-mode table — log + continue with `crossPrRecurrence: 0` for every finding; `substrateAvailable: false` surfaces the degradation in the report so the consumer can see it explicitly. Hard-erroring would block the circuit-breaker the user invoked retrospect to run.
206
+ }
207
+ catch (err) {
208
+ const msg = err instanceof Error ? err.message : String(err);
209
+ log.warn(TAG, `Could not parse ${substratePath}: ${msg} — running without cross-PR recurrence enrichment.`);
210
+ }
211
+ }
212
+ else {
213
+ log.warn(TAG, `${substratePath} not found — run 'totem stats --pattern-recurrence' first to enable cross-PR enrichment.`);
214
+ }
215
+ // 5. Compiled-rules read — graceful degrade if missing.
216
+ // `loadCompiledRules` is intentionally `[]`-returning on ENOENT so a
217
+ // sync-after-fresh-clone doesn't crash; we can't tell "missing" from
218
+ // "empty manifest" by return value alone. Gate on file existence
219
+ // first so the report's `compiledRulesAvailable` flag matches the
220
+ // user's mental model: if the file isn't there, the coverage check
221
+ // is structurally unavailable.
222
+ const rulesPath = path.join(totemDir, 'compiled-rules.json');
223
+ let compiledRulesAvailable = false;
224
+ let ruleTokenSets = [];
225
+ if (fs.existsSync(rulesPath)) {
226
+ try {
227
+ const compiledRules = loadCompiledRules(rulesPath);
228
+ compiledRulesAvailable = true;
229
+ ruleTokenSets = compiledRules.map((r) => tokenizeForJaccard(r.message ?? ''));
230
+ // totem-context: malformed compiled-rules.json is a graceful-degrade path per the mmnto-ai/totem#1713 failure-mode table — log + continue with `coveredByRule: false` for every finding; `compiledRulesAvailable: false` surfaces the degradation. Mirrors the pattern in `runRecurrenceStats` step 6 ("missing/malformed compiled-rules.json disables coverage routing only").
231
+ }
232
+ catch (err) {
233
+ const msg = err instanceof Error ? err.message : String(err);
234
+ log.warn(TAG, `Could not load compiled rules: ${msg} — coverage check disabled.`);
235
+ }
236
+ }
237
+ else {
238
+ log.warn(TAG, `${rulesPath} not found — run 'totem lesson compile' first to enable rule-coverage enrichment.`);
239
+ }
240
+ // 6. Trap-ledger override events (read-only, count only). Today the
241
+ // LedgerEventSchema does NOT carry a `prNumber` field, so we cannot
242
+ // actually scope the count to the target PR — every event passes
243
+ // the predicate. The cast-based predicate below is a forward-compat
244
+ // scaffold: when a future ticket adds `prNumber` to LedgerEvent
245
+ // (filed as the mmnto-ai/totem#1734-CR-7 follow-up), the predicate
246
+ // will start filtering automatically with no command-side change.
247
+ // Per CR mmnto-ai/totem#1734 review-1.
248
+ const ledgerEvents = readLedgerEvents(totemDir, (msg) => log.warn(TAG, msg));
249
+ const overrideEventsObserved = ledgerEvents.filter((e) => {
250
+ if (e.type !== 'override')
251
+ return false;
252
+ const eventPr = e.prNumber;
253
+ return eventPr === undefined || String(eventPr) === prNumber;
254
+ }).length;
255
+ // 7. Annotate every finding: signature, classification, recurrence, coverage.
256
+ const annotated = allFindings.map((f) => ({
257
+ finding: f.finding,
258
+ roundNumber: shaToRoundNumber.get(f.sha) ?? 0,
259
+ observedAt: f.observedAt,
260
+ }));
261
+ // Per discriminated union (CR mmnto-ai/totem#1734 round-2): `routeOutReason`
262
+ // is present iff `classification === 'route-out'`; the schema infers
263
+ // `RetrospectFinding` accordingly.
264
+ const enriched = [];
265
+ for (const a of annotated) {
266
+ const normalized = normalizeFindingBody(a.finding.body);
267
+ if (normalized.length === 0)
268
+ continue;
269
+ const signature = computeSignature(normalized);
270
+ const tool = a.finding.tool === 'coderabbit' ? 'coderabbit' : a.finding.tool === 'gca' ? 'gca' : 'unknown';
271
+ const severityBucket = toSeverityBucket(tool, a.finding.severity);
272
+ // Cross-PR recurrence — count of OTHER PRs (target excluded by construction).
273
+ const crossPrRecurrence = crossPrIndex.get(signature)?.size ?? 0;
274
+ // Coverage check — Jaccard 0.6 against any rule message.
275
+ let coveredByRule = false;
276
+ if (compiledRulesAvailable && ruleTokenSets.length > 0) {
277
+ const findingTokens = tokenizeForJaccard(normalized);
278
+ let maxJ = 0;
279
+ for (const ruleTokens of ruleTokenSets) {
280
+ const v = jaccard(findingTokens, ruleTokens);
281
+ if (v > maxJ)
282
+ maxJ = v;
283
+ }
284
+ coveredByRule = maxJ >= RULE_COVERAGE_JACCARD_THRESHOLD;
285
+ }
286
+ const verdict = classifyFinding({
287
+ severityBucket,
288
+ roundNumber: a.roundNumber > 0 ? a.roundNumber : 1,
289
+ crossPrRecurrence,
290
+ coveredByRule,
291
+ });
292
+ const base = {
293
+ signature,
294
+ tool,
295
+ severityBucket,
296
+ bodyExcerpt: a.finding.body.slice(0, BODY_EXCERPT_MAX),
297
+ file: a.finding.file,
298
+ line: a.finding.line,
299
+ roundNumber: a.roundNumber > 0 ? a.roundNumber : 1,
300
+ crossPrRecurrence,
301
+ coveredByRule,
302
+ };
303
+ if (verdict.classification === 'route-out' && verdict.routeOutReason !== undefined) {
304
+ enriched.push({
305
+ ...base,
306
+ classification: 'route-out',
307
+ routeOutReason: verdict.routeOutReason,
308
+ });
309
+ }
310
+ else if (verdict.classification === 'route-out') {
311
+ // Defensive: classifier returned 'route-out' without a reason — should
312
+ // be unreachable per the table. Fail loud (Tenet 4) so the missing
313
+ // catalog entry surfaces immediately.
314
+ throw new Error(`[Totem Error] classifier returned route-out without routeOutReason for signature ${signature}`);
315
+ }
316
+ else {
317
+ enriched.push({ ...base, classification: verdict.classification });
318
+ }
319
+ }
320
+ // 8. Distribution counts.
321
+ const byTool = {};
322
+ const bySeverity = {};
323
+ const byClassification = {};
324
+ for (const f of enriched) {
325
+ byTool[f.tool] = (byTool[f.tool] ?? 0) + 1;
326
+ bySeverity[f.severityBucket] = (bySeverity[f.severityBucket] ?? 0) + 1;
327
+ byClassification[f.classification] = (byClassification[f.classification] ?? 0) + 1;
328
+ }
329
+ // Sort buckets — primary by roundNumber asc; tie-break: numeric PR
330
+ // sort is on `prs[]` arrays (lesson-26935d32 applies in
331
+ // `recurrence-stats`); here we stay deterministic via signature.
332
+ const sortByRoundThenSig = (a, b) => {
333
+ if (a.roundNumber !== b.roundNumber)
334
+ return a.roundNumber - b.roundNumber;
335
+ return a.signature.localeCompare(b.signature);
336
+ };
337
+ const routeOutCandidates = enriched
338
+ .filter((f) => f.classification === 'route-out')
339
+ .sort(sortByRoundThenSig);
340
+ const inPrFixes = enriched
341
+ .filter((f) => f.classification === 'in-pr-fix')
342
+ .sort(sortByRoundThenSig);
343
+ const undetermined = enriched
344
+ .filter((f) => f.classification === 'undetermined')
345
+ .sort(sortByRoundThenSig);
346
+ const dedupRate = computeDedupRate(enriched);
347
+ // 9. Build report.
348
+ const report = {
349
+ version: 1,
350
+ prNumber,
351
+ prState: prData.state,
352
+ generatedAt: new Date().toISOString(),
353
+ threshold,
354
+ substrateAvailable,
355
+ compiledRulesAvailable,
356
+ rounds,
357
+ totalFindings: enriched.length,
358
+ dedupRate,
359
+ findingDistribution: { byTool, bySeverity, byClassification },
360
+ routeOutCandidates,
361
+ inPrFixes,
362
+ undetermined,
363
+ stopConditions: [],
364
+ overrideEventsObserved,
365
+ };
366
+ report.stopConditions = buildStopConditions(report);
367
+ // Validate the assembled report shape — fail-loud on schema drift.
368
+ RetrospectReportSchema.parse(report);
369
+ // 10. Threshold gate.
370
+ if (rounds.length < threshold && !options.force) {
371
+ log.info(TAG, `PR #${prNumber} has ${rounds.length} bot-review round(s); below threshold ${threshold}. Skipping (pass --force to inspect anyway).`);
372
+ return;
373
+ }
374
+ // 11. Render console report.
375
+ renderReport(report, log, sanitizeForTerminal);
376
+ // 12. Optional --out write (deterministic two-space JSON).
377
+ if (options.out) {
378
+ const outPath = path.isAbsolute(options.out) ? options.out : path.join(cwd, options.out);
379
+ fs.mkdirSync(path.dirname(outPath), { recursive: true });
380
+ fs.writeFileSync(outPath, JSON.stringify(report, null, 2) + '\n', 'utf-8');
381
+ log.info(TAG, `Wrote report → ${outPath}`);
382
+ }
383
+ }
384
+ function renderReport(report, log, sanitizeForTerminal) {
385
+ log.info(TAG, `PR #${report.prNumber} (${report.prState}) — ${report.rounds.length} round(s), ${report.totalFindings} bot finding(s).`);
386
+ log.dim(TAG, ` substrate=${report.substrateAvailable ? 'available' : 'absent'}, compiled-rules=${report.compiledRulesAvailable ? 'available' : 'absent'}, dedup-rate=${(report.dedupRate * 100).toFixed(0)}%`);
387
+ // Distribution
388
+ const tools = Object.entries(report.findingDistribution.byTool)
389
+ .sort((a, b) => b[1] - a[1])
390
+ .map(([k, v]) => `${k}:${v}`)
391
+ .join(' ');
392
+ const severities = Object.entries(report.findingDistribution.bySeverity)
393
+ .sort((a, b) => b[1] - a[1])
394
+ .map(([k, v]) => `${k}:${v}`)
395
+ .join(' ');
396
+ const classifications = Object.entries(report.findingDistribution.byClassification)
397
+ .sort((a, b) => b[1] - a[1])
398
+ .map(([k, v]) => `${k}:${v}`)
399
+ .join(' ');
400
+ if (tools)
401
+ log.dim(TAG, ` tool: ${tools}`);
402
+ if (severities)
403
+ log.dim(TAG, ` severity: ${severities}`);
404
+ if (classifications)
405
+ log.dim(TAG, ` classification: ${classifications}`);
406
+ // Route-out candidates.
407
+ if (report.routeOutCandidates.length > 0) {
408
+ log.info(TAG, `Route-out candidates (${report.routeOutCandidates.length}):`);
409
+ for (const f of report.routeOutCandidates) {
410
+ const snippet = sanitizeForTerminal(f.bodyExcerpt)
411
+ .replace(/\s+/g, ' ')
412
+ .slice(0, RENDER_SNIPPET_MAX);
413
+ // Schema discriminates: `f.classification === 'route-out'` guarantees `routeOutReason`.
414
+ const reason = f.routeOutReason;
415
+ log.dim(TAG, ` [r${f.roundNumber}] ${f.severityBucket} ${f.signature} — ${snippet} (${reason})`);
416
+ }
417
+ }
418
+ else {
419
+ log.dim(TAG, 'Route-out candidates: (none)');
420
+ }
421
+ // In-PR fixes.
422
+ if (report.inPrFixes.length > 0) {
423
+ log.info(TAG, `In-PR fixes (${report.inPrFixes.length}):`);
424
+ for (const f of report.inPrFixes) {
425
+ const snippet = sanitizeForTerminal(f.bodyExcerpt)
426
+ .replace(/\s+/g, ' ')
427
+ .slice(0, RENDER_SNIPPET_MAX);
428
+ log.dim(TAG, ` [r${f.roundNumber}] ${f.severityBucket} ${f.signature} — ${snippet}`);
429
+ }
430
+ }
431
+ else {
432
+ log.dim(TAG, 'In-PR fixes: (none)');
433
+ }
434
+ // Undetermined.
435
+ if (report.undetermined.length > 0) {
436
+ log.info(TAG, `Undetermined (${report.undetermined.length}):`);
437
+ for (const f of report.undetermined) {
438
+ const snippet = sanitizeForTerminal(f.bodyExcerpt)
439
+ .replace(/\s+/g, ' ')
440
+ .slice(0, RENDER_SNIPPET_MAX);
441
+ log.dim(TAG, ` [r${f.roundNumber}] ${f.severityBucket} ${f.signature} — ${snippet}`);
442
+ }
443
+ }
444
+ // Stop conditions.
445
+ if (report.stopConditions.length > 0) {
446
+ log.info(TAG, 'Stop conditions:');
447
+ for (const cond of report.stopConditions) {
448
+ log.dim(TAG, ` • ${cond}`);
449
+ }
450
+ }
451
+ if (report.overrideEventsObserved > 0) {
452
+ log.dim(TAG, `Trap ledger: ${report.overrideEventsObserved} override event(s) observed.`);
453
+ }
454
+ }
455
+ // ─── Helpers ────────────────────────────────────────
456
+ function clampThreshold(input) {
457
+ if (input === undefined || !Number.isFinite(input) || input < 1)
458
+ return DEFAULT_THRESHOLD;
459
+ return Math.floor(input);
460
+ }
461
+ //# sourceMappingURL=retrospect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retrospect.js","sourceRoot":"","sources":["../../src/commands/retrospect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=retrospect.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retrospect.test.d.ts","sourceRoot":"","sources":["../../src/commands/retrospect.test.ts"],"names":[],"mappings":""}