@mmnto/totem 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.
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/recurrence-stats.d.ts +19 -0
- package/dist/recurrence-stats.d.ts.map +1 -1
- package/dist/recurrence-stats.js +49 -0
- package/dist/recurrence-stats.js.map +1 -1
- package/dist/retrospect.d.ts +1022 -0
- package/dist/retrospect.d.ts.map +1 -0
- package/dist/retrospect.js +368 -0
- package/dist/retrospect.js.map +1 -0
- package/dist/retrospect.test.d.ts +2 -0
- package/dist/retrospect.test.d.ts.map +1 -0
- package/dist/retrospect.test.js +572 -0
- package/dist/retrospect.test.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retrospect.d.ts","sourceRoot":"","sources":["../src/retrospect.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Retrospect schemas + pure helpers for `totem retrospect <pr>`
|
|
3
|
+
* (mmnto-ai/totem#1713).
|
|
4
|
+
*
|
|
5
|
+
* Substrate of the bot-tax cluster — the deterministic circuit-breaker
|
|
6
|
+
* that fires when a PR has accumulated enough bot-review rounds to
|
|
7
|
+
* suggest the loop has stalled. Reuses `recurrence-stats.ts` primitives
|
|
8
|
+
* (`computeSignature`, `normalizeFindingBody`, `toSeverityBucket`) so
|
|
9
|
+
* the bot-tax cluster (#1715 / #1714 / #1713) has a single severity +
|
|
10
|
+
* signature vocabulary.
|
|
11
|
+
*
|
|
12
|
+
* Everything in this file is pure: Zod schemas + deterministic helpers.
|
|
13
|
+
* No I/O, no command logic. No LLM. No GitHub API writes.
|
|
14
|
+
*/
|
|
15
|
+
import { z } from 'zod';
|
|
16
|
+
import { computeSignature, normalizeFindingBody } from './recurrence-stats.js';
|
|
17
|
+
import { RecurrenceSeverityBucketSchema } from './recurrence-stats.js';
|
|
18
|
+
// ─── Zod schemas ────────────────────────────────────
|
|
19
|
+
/** A push-grouped review round on the target PR. */
|
|
20
|
+
export const RetrospectRoundSchema = z.object({
|
|
21
|
+
/** 1-based, monotonically increasing in submission order. */
|
|
22
|
+
roundNumber: z.number().int().min(1),
|
|
23
|
+
/** ISO 8601 timestamp of the earliest review submission for this round. */
|
|
24
|
+
submittedAt: z.string(),
|
|
25
|
+
/** PR head SHA at review time; absent when the upstream review record lacks `commit_id`. */
|
|
26
|
+
headSha: z.string().optional(),
|
|
27
|
+
/** Number of bot findings tied to this round. */
|
|
28
|
+
findingCount: z.number().int().min(0),
|
|
29
|
+
});
|
|
30
|
+
/**
|
|
31
|
+
* Classification verdict for a single bot finding.
|
|
32
|
+
*
|
|
33
|
+
* - `route-out` — finding is better tracked as a follow-up issue than blocking the current PR.
|
|
34
|
+
* - `in-pr-fix` — finding should be addressed before merge.
|
|
35
|
+
* - `undetermined` — no heuristic signal fired; contributor judgment.
|
|
36
|
+
*/
|
|
37
|
+
export const RetrospectClassificationSchema = z.enum(['route-out', 'in-pr-fix', 'undetermined']);
|
|
38
|
+
/** Source classification of a finding (mirror of `RecurrenceTool` minus `'mixed'`). */
|
|
39
|
+
const RetrospectFindingToolSchema = z.enum(['coderabbit', 'gca', 'sarif', 'override', 'unknown']);
|
|
40
|
+
/**
|
|
41
|
+
* Closed catalog of `route-out` reasons. The Zod-side mirror of
|
|
42
|
+
* `RETROSPECT_ROUTE_OUT_REASONS` (defined later in the file). Used by the
|
|
43
|
+
* discriminated `RetrospectFindingSchema` to enforce the deterministic
|
|
44
|
+
* contract: every `route-out` finding carries a reason from this enum, and
|
|
45
|
+
* non-route-out findings forbid the field entirely. Per CR mmnto-ai/totem#1734
|
|
46
|
+
* round-2.
|
|
47
|
+
*/
|
|
48
|
+
export const RetrospectRouteOutReasonSchema = z.enum([
|
|
49
|
+
'covered by existing compiled rule',
|
|
50
|
+
'rule-covered class flagged late — retroactive shouldn’t block ship',
|
|
51
|
+
'frequent across other PRs — file follow-up to compile into a rule',
|
|
52
|
+
'low/nit severity flagged late in the bot-review loop',
|
|
53
|
+
]);
|
|
54
|
+
const RetrospectFindingBaseSchema = z.object({
|
|
55
|
+
/** Stable signature hash (16-char) — matches the recurrence-stats vocabulary. */
|
|
56
|
+
signature: z.string().min(1),
|
|
57
|
+
/** Source bot/tool. */
|
|
58
|
+
tool: RetrospectFindingToolSchema,
|
|
59
|
+
/** Normalized severity bucket. */
|
|
60
|
+
severityBucket: RecurrenceSeverityBucketSchema,
|
|
61
|
+
/** First 280 chars of the raw body (for human triage). */
|
|
62
|
+
bodyExcerpt: z.string(),
|
|
63
|
+
/** File path attached to the finding (`(review body)` for CR outside-diff/nits). */
|
|
64
|
+
file: z.string(),
|
|
65
|
+
/** Best-effort line number. */
|
|
66
|
+
line: z.number().int().positive().optional(),
|
|
67
|
+
/** Round number assigned by `groupFindingsByRound`. */
|
|
68
|
+
roundNumber: z.number().int().min(1),
|
|
69
|
+
/** Count of OTHER PRs sharing this signature (target PR excluded). */
|
|
70
|
+
crossPrRecurrence: z.number().int().min(0),
|
|
71
|
+
/** True if the signature heuristically maps to an existing compiled rule (Jaccard ≥ 0.6). */
|
|
72
|
+
coveredByRule: z.boolean(),
|
|
73
|
+
});
|
|
74
|
+
/**
|
|
75
|
+
* Discriminated union on `classification`: `route-out` requires a reason from
|
|
76
|
+
* the closed catalog; `in-pr-fix` and `undetermined` forbid the field entirely.
|
|
77
|
+
* Per CR mmnto-ai/totem#1734 round-2 — the prior `routeOutReason: z.string().optional()`
|
|
78
|
+
* leaked the deterministic contract.
|
|
79
|
+
*/
|
|
80
|
+
export const RetrospectFindingSchema = z.discriminatedUnion('classification', [
|
|
81
|
+
RetrospectFindingBaseSchema.extend({
|
|
82
|
+
classification: z.literal('route-out'),
|
|
83
|
+
/** Reason from the closed catalog (`RETROSPECT_ROUTE_OUT_REASONS`). */
|
|
84
|
+
routeOutReason: RetrospectRouteOutReasonSchema,
|
|
85
|
+
}),
|
|
86
|
+
// `.strict()` so a stray `routeOutReason` on a non-route-out finding fails
|
|
87
|
+
// the schema instead of being silently stripped — the deterministic
|
|
88
|
+
// contract is "reason iff route-out", and silent-strip would hide a bug.
|
|
89
|
+
RetrospectFindingBaseSchema.extend({
|
|
90
|
+
classification: z.literal('in-pr-fix'),
|
|
91
|
+
}).strict(),
|
|
92
|
+
RetrospectFindingBaseSchema.extend({
|
|
93
|
+
classification: z.literal('undetermined'),
|
|
94
|
+
}).strict(),
|
|
95
|
+
]);
|
|
96
|
+
const RetrospectFindingDistributionSchema = z.object({
|
|
97
|
+
byTool: z.record(z.string(), z.number().int().min(0)),
|
|
98
|
+
bySeverity: z.record(z.string(), z.number().int().min(0)),
|
|
99
|
+
byClassification: z.record(z.string(), z.number().int().min(0)),
|
|
100
|
+
});
|
|
101
|
+
/** Top-level shape emitted by `runRetrospect` and optionally written via `--out`. */
|
|
102
|
+
export const RetrospectReportSchema = z.object({
|
|
103
|
+
/** Schema version for forward-compat. */
|
|
104
|
+
version: z.literal(1),
|
|
105
|
+
/** Target PR number (string for parity with recurrence-stats prsScanned). */
|
|
106
|
+
prNumber: z.string(),
|
|
107
|
+
/** Open / closed / merged at fetch time. */
|
|
108
|
+
prState: z.string(),
|
|
109
|
+
/** ISO 8601 generation timestamp. */
|
|
110
|
+
generatedAt: z.string(),
|
|
111
|
+
/** Resolved threshold (after option clamping). */
|
|
112
|
+
threshold: z.number().int().min(1),
|
|
113
|
+
/** True iff `.totem/recurrence-stats.json` was loaded successfully. */
|
|
114
|
+
substrateAvailable: z.boolean(),
|
|
115
|
+
/** True iff `compiled-rules.json` was loaded successfully. */
|
|
116
|
+
compiledRulesAvailable: z.boolean(),
|
|
117
|
+
/** Push-grouped rounds (ordered by earliest submittedAt per head_sha). */
|
|
118
|
+
rounds: z.array(RetrospectRoundSchema),
|
|
119
|
+
/** Total bot findings (inline + review-body). */
|
|
120
|
+
totalFindings: z.number().int().min(0),
|
|
121
|
+
/** `1 - uniqueSignatures/totalFindings`, clamped to [0,1]; 0 when totalFindings == 0. */
|
|
122
|
+
dedupRate: z.number().min(0).max(1),
|
|
123
|
+
/** Distribution counts. */
|
|
124
|
+
findingDistribution: RetrospectFindingDistributionSchema,
|
|
125
|
+
/** Findings classified as `route-out`. */
|
|
126
|
+
routeOutCandidates: z.array(RetrospectFindingSchema),
|
|
127
|
+
/** Findings classified as `in-pr-fix`. */
|
|
128
|
+
inPrFixes: z.array(RetrospectFindingSchema),
|
|
129
|
+
/** Findings classified as `undetermined`. */
|
|
130
|
+
undetermined: z.array(RetrospectFindingSchema),
|
|
131
|
+
/** Deterministic stop-condition templates (no prose generation). */
|
|
132
|
+
stopConditions: z.array(z.string()),
|
|
133
|
+
/** Trap-ledger override events read for this PR (read-only count). */
|
|
134
|
+
overrideEventsObserved: z.number().int().min(0),
|
|
135
|
+
});
|
|
136
|
+
/**
|
|
137
|
+
* Group bot review submissions by `commit_id` (head SHA).
|
|
138
|
+
*
|
|
139
|
+
* - Two reviews on the same `commit_id` → same round.
|
|
140
|
+
* - Reviews missing `commit_id` are bucketed into a single synthetic
|
|
141
|
+
* round (head SHA `undefined`) so they don't double-count as N rounds.
|
|
142
|
+
* - Round ordering is by EARLIEST `submitted_at` within each SHA bucket.
|
|
143
|
+
* - Round numbers are 1-based.
|
|
144
|
+
*
|
|
145
|
+
* `findingCount` requires `groupFindingsByRound` to receive the corresponding
|
|
146
|
+
* inline-comment list keyed by SHA via `findingShaBySubmissionId`. The mapping
|
|
147
|
+
* is computed by the caller because `pulls/N/comments` and `pulls/N/reviews`
|
|
148
|
+
* are separate GH endpoints and the join is push-based, not in-memory native.
|
|
149
|
+
*
|
|
150
|
+
* To keep the helper pure, this function returns the round index ONLY.
|
|
151
|
+
* Callers walk findings + assign each to a round by submission timestamp.
|
|
152
|
+
*/
|
|
153
|
+
export function groupFindingsByRound(reviewSubmissions, findingsPerRoundCount) {
|
|
154
|
+
// Bucket submissions by commit_id (treating null/undefined as the same key).
|
|
155
|
+
const bySha = new Map();
|
|
156
|
+
for (const sub of reviewSubmissions) {
|
|
157
|
+
const key = typeof sub.commit_id === 'string' && sub.commit_id.length > 0 ? sub.commit_id : '';
|
|
158
|
+
let bucket = bySha.get(key);
|
|
159
|
+
if (!bucket) {
|
|
160
|
+
bucket = [];
|
|
161
|
+
bySha.set(key, bucket);
|
|
162
|
+
}
|
|
163
|
+
bucket.push(sub);
|
|
164
|
+
}
|
|
165
|
+
const buckets = [];
|
|
166
|
+
for (const [sha, subs] of bySha) {
|
|
167
|
+
let earliest = '';
|
|
168
|
+
for (const s of subs) {
|
|
169
|
+
const t = typeof s.submitted_at === 'string' ? s.submitted_at : '';
|
|
170
|
+
if (t.length === 0)
|
|
171
|
+
continue;
|
|
172
|
+
if (earliest.length === 0 || t < earliest)
|
|
173
|
+
earliest = t;
|
|
174
|
+
}
|
|
175
|
+
buckets.push({ sha, earliest });
|
|
176
|
+
}
|
|
177
|
+
// Stable sort by earliest timestamp ascending; missing timestamp sinks last.
|
|
178
|
+
buckets.sort((a, b) => {
|
|
179
|
+
if (a.earliest === '' && b.earliest !== '')
|
|
180
|
+
return 1;
|
|
181
|
+
if (a.earliest !== '' && b.earliest === '')
|
|
182
|
+
return -1;
|
|
183
|
+
if (a.earliest < b.earliest)
|
|
184
|
+
return -1;
|
|
185
|
+
if (a.earliest > b.earliest)
|
|
186
|
+
return 1;
|
|
187
|
+
return 0;
|
|
188
|
+
});
|
|
189
|
+
const rounds = [];
|
|
190
|
+
let roundNumber = 1;
|
|
191
|
+
for (const bucket of buckets) {
|
|
192
|
+
rounds.push({
|
|
193
|
+
roundNumber,
|
|
194
|
+
submittedAt: bucket.earliest,
|
|
195
|
+
headSha: bucket.sha.length > 0 ? bucket.sha : undefined,
|
|
196
|
+
findingCount: findingsPerRoundCount.get(bucket.sha) ?? 0,
|
|
197
|
+
});
|
|
198
|
+
roundNumber += 1;
|
|
199
|
+
}
|
|
200
|
+
return rounds;
|
|
201
|
+
}
|
|
202
|
+
export function toRoundPosition(roundNumber) {
|
|
203
|
+
if (roundNumber <= 3)
|
|
204
|
+
return 'early';
|
|
205
|
+
if (roundNumber <= 9)
|
|
206
|
+
return 'mid';
|
|
207
|
+
return 'late';
|
|
208
|
+
}
|
|
209
|
+
export function toCrossPrBucket(crossPrRecurrence) {
|
|
210
|
+
if (crossPrRecurrence <= 0)
|
|
211
|
+
return 'none';
|
|
212
|
+
if (crossPrRecurrence <= 2)
|
|
213
|
+
return 'some';
|
|
214
|
+
return 'frequent';
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Fixed catalog of route-out reasons. Keep deterministic — every reason
|
|
218
|
+
* a classifier emits MUST come from this catalog so the report doesn't
|
|
219
|
+
* accumulate a long-tail of one-off prose strings.
|
|
220
|
+
*/
|
|
221
|
+
export const RETROSPECT_ROUTE_OUT_REASONS = {
|
|
222
|
+
COVERED_BY_RULE: 'covered by existing compiled rule',
|
|
223
|
+
RULE_COVERED_LATE: 'rule-covered class flagged late — retroactive shouldn’t block ship',
|
|
224
|
+
FREQUENT_CROSS_PR: 'frequent across other PRs — file follow-up to compile into a rule',
|
|
225
|
+
LOW_NIT_LATE: 'low/nit severity flagged late in the bot-review loop',
|
|
226
|
+
};
|
|
227
|
+
/**
|
|
228
|
+
* Deterministic, table-driven classifier. Same inputs → same outputs across
|
|
229
|
+
* invocations. Reason strings are drawn exclusively from
|
|
230
|
+
* `RETROSPECT_ROUTE_OUT_REASONS` so consumers can treat them as a closed set.
|
|
231
|
+
*
|
|
232
|
+
* Heuristic intent (v0.1):
|
|
233
|
+
* - `critical` or `high` at any round → `in-pr-fix` (regardless of recurrence/coverage)
|
|
234
|
+
* - `low`/`nit` late + (`coveredByRule` OR `crossPrRecurrence frequent`) → `route-out`
|
|
235
|
+
* - `medium` late + `coveredByRule` → `route-out`
|
|
236
|
+
* - `medium` early/mid → `in-pr-fix`
|
|
237
|
+
* - `nit` early/mid → `in-pr-fix`
|
|
238
|
+
* - else → `undetermined`
|
|
239
|
+
*/
|
|
240
|
+
export function classifyFinding(input) {
|
|
241
|
+
const { severityBucket, coveredByRule } = input;
|
|
242
|
+
const position = toRoundPosition(input.roundNumber);
|
|
243
|
+
const recurrence = toCrossPrBucket(input.crossPrRecurrence);
|
|
244
|
+
// Critical / high — always block the PR.
|
|
245
|
+
if (severityBucket === 'critical' || severityBucket === 'high') {
|
|
246
|
+
return { classification: 'in-pr-fix' };
|
|
247
|
+
}
|
|
248
|
+
// Late-round low/nit — route out when covered or frequent.
|
|
249
|
+
if (severityBucket === 'low' || severityBucket === 'nit') {
|
|
250
|
+
if (position === 'late') {
|
|
251
|
+
if (coveredByRule) {
|
|
252
|
+
return {
|
|
253
|
+
classification: 'route-out',
|
|
254
|
+
routeOutReason: RETROSPECT_ROUTE_OUT_REASONS.COVERED_BY_RULE,
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
if (recurrence === 'frequent') {
|
|
258
|
+
return {
|
|
259
|
+
classification: 'route-out',
|
|
260
|
+
routeOutReason: RETROSPECT_ROUTE_OUT_REASONS.FREQUENT_CROSS_PR,
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
return {
|
|
264
|
+
classification: 'route-out',
|
|
265
|
+
routeOutReason: RETROSPECT_ROUTE_OUT_REASONS.LOW_NIT_LATE,
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
// Cheap to fix inline early/mid.
|
|
269
|
+
if (severityBucket === 'nit')
|
|
270
|
+
return { classification: 'in-pr-fix' };
|
|
271
|
+
// low at early/mid: default to in-pr-fix unless rule-covered (then route-out).
|
|
272
|
+
if (coveredByRule) {
|
|
273
|
+
return {
|
|
274
|
+
classification: 'route-out',
|
|
275
|
+
routeOutReason: RETROSPECT_ROUTE_OUT_REASONS.COVERED_BY_RULE,
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
return { classification: 'in-pr-fix' };
|
|
279
|
+
}
|
|
280
|
+
// Medium severity.
|
|
281
|
+
if (severityBucket === 'medium') {
|
|
282
|
+
if (position === 'late' && coveredByRule) {
|
|
283
|
+
return {
|
|
284
|
+
classification: 'route-out',
|
|
285
|
+
routeOutReason: RETROSPECT_ROUTE_OUT_REASONS.RULE_COVERED_LATE,
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
return { classification: 'in-pr-fix' };
|
|
289
|
+
}
|
|
290
|
+
// Should be unreachable given the enum, but kept for total-function hygiene.
|
|
291
|
+
return { classification: 'undetermined' };
|
|
292
|
+
}
|
|
293
|
+
// ─── Stop-conditions ────────────────────────────────
|
|
294
|
+
/**
|
|
295
|
+
* Deterministic stop-condition templates keyed off the report shape. No
|
|
296
|
+
* prose generation; only integer substitution. Returns the catalog
|
|
297
|
+
* filtered to entries whose triggering condition fires for the given
|
|
298
|
+
* report.
|
|
299
|
+
*/
|
|
300
|
+
export function buildStopConditions(report) {
|
|
301
|
+
const out = [];
|
|
302
|
+
const lastRound = report.rounds[report.rounds.length - 1];
|
|
303
|
+
const roundCount = report.rounds.length;
|
|
304
|
+
// 1. Route-out candidates exist → "ship + file N follow-up issue(s)".
|
|
305
|
+
if (report.routeOutCandidates.length > 0) {
|
|
306
|
+
const n = report.routeOutCandidates.length;
|
|
307
|
+
out.push(`If next round contains only nit-severity findings, ship + file ${n} follow-up issue(s) for the route-out candidates above.`);
|
|
308
|
+
}
|
|
309
|
+
// 2. ≥ 50% of LAST round's findings are rule-covered → consider shipping.
|
|
310
|
+
// Denominator must include `undetermined` so uncovered findings without
|
|
311
|
+
// a verdict don't get hidden from the ratio (CR mmnto-ai/totem#1734
|
|
312
|
+
// round-2). Otherwise the stop condition can fire early when a chunk
|
|
313
|
+
// of the round is undetermined-uncovered.
|
|
314
|
+
if (lastRound && lastRound.findingCount > 0) {
|
|
315
|
+
const lastRoundFindings = report.routeOutCandidates
|
|
316
|
+
.concat(report.inPrFixes, report.undetermined)
|
|
317
|
+
.filter((f) => f.roundNumber === lastRound.roundNumber);
|
|
318
|
+
const ruleCovered = lastRoundFindings.filter((f) => f.coveredByRule).length;
|
|
319
|
+
const ratio = ruleCovered / Math.max(1, lastRoundFindings.length);
|
|
320
|
+
if (ratio >= 0.5) {
|
|
321
|
+
const pct = Math.round(ratio * 100);
|
|
322
|
+
out.push(`Round count ${roundCount} exceeds threshold; ${pct}% of round-${lastRound.roundNumber} findings are already covered by compiled rules — consider shipping.`);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
// 3. Frequent-recurrence route-out subset is non-empty.
|
|
326
|
+
const frequentRouteOuts = report.routeOutCandidates.filter((f) => toCrossPrBucket(f.crossPrRecurrence) === 'frequent');
|
|
327
|
+
if (frequentRouteOuts.length > 0) {
|
|
328
|
+
out.push(`${frequentRouteOuts.length} finding(s) recur across other PRs; if not addressed inline, file follow-up issues to add them to the compiled-rules manifest.`);
|
|
329
|
+
}
|
|
330
|
+
// 4. High dedup rate → comment-drift suspicion.
|
|
331
|
+
if (report.dedupRate >= 0.4) {
|
|
332
|
+
const uniquePct = Math.round((1 - report.dedupRate) * 100);
|
|
333
|
+
out.push(`PR has ${roundCount} round(s) with ${uniquePct}% unique signatures; high dedup rate suggests comment-drift — consider squashing finding-fix commits before re-pushing to reduce bot re-review surface area.`);
|
|
334
|
+
}
|
|
335
|
+
return out;
|
|
336
|
+
}
|
|
337
|
+
// ─── Dedup math ─────────────────────────────────────
|
|
338
|
+
/**
|
|
339
|
+
* Compute `1 - uniqueSignatures / totalFindings`, clamped to [0, 1].
|
|
340
|
+
*
|
|
341
|
+
* - 0 findings → 0 (no findings, no dedup pressure).
|
|
342
|
+
* - All unique → 0.
|
|
343
|
+
* - All duplicates of one signature → close to 1 (`1 - 1/N`).
|
|
344
|
+
*/
|
|
345
|
+
export function computeDedupRate(findings) {
|
|
346
|
+
if (findings.length === 0)
|
|
347
|
+
return 0;
|
|
348
|
+
const seen = new Set();
|
|
349
|
+
for (const f of findings)
|
|
350
|
+
seen.add(f.signature);
|
|
351
|
+
const rate = 1 - seen.size / findings.length;
|
|
352
|
+
if (rate < 0)
|
|
353
|
+
return 0;
|
|
354
|
+
if (rate > 1)
|
|
355
|
+
return 1;
|
|
356
|
+
return rate;
|
|
357
|
+
}
|
|
358
|
+
// ─── Convenience signature helper ───────────────────
|
|
359
|
+
/**
|
|
360
|
+
* Compute a stable signature for a finding body using the
|
|
361
|
+
* recurrence-stats normalization pipeline. Re-exported here so callers
|
|
362
|
+
* outside the cli package don't need to call `normalizeFindingBody +
|
|
363
|
+
* computeSignature` separately.
|
|
364
|
+
*/
|
|
365
|
+
export function signatureOfBody(body) {
|
|
366
|
+
return computeSignature(normalizeFindingBody(body));
|
|
367
|
+
}
|
|
368
|
+
//# sourceMappingURL=retrospect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retrospect.js","sourceRoot":"","sources":["../src/retrospect.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retrospect.test.d.ts","sourceRoot":"","sources":["../src/retrospect.test.ts"],"names":[],"mappings":""}
|