@secureport/core 0.2.0 → 0.3.0

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 (60) hide show
  1. package/README.md +67 -31
  2. package/dist/coverage.d.ts +21 -0
  3. package/dist/coverage.d.ts.map +1 -0
  4. package/dist/coverage.js +65 -0
  5. package/dist/coverage.js.map +1 -0
  6. package/dist/finding.d.ts +89 -0
  7. package/dist/finding.d.ts.map +1 -0
  8. package/dist/finding.js +2 -0
  9. package/dist/finding.js.map +1 -0
  10. package/dist/fingerprint.d.ts +185 -0
  11. package/dist/fingerprint.d.ts.map +1 -0
  12. package/dist/fingerprint.js +247 -0
  13. package/dist/fingerprint.js.map +1 -0
  14. package/dist/import/nuclei.d.ts +39 -0
  15. package/dist/import/nuclei.d.ts.map +1 -0
  16. package/dist/import/nuclei.js +115 -0
  17. package/dist/import/nuclei.js.map +1 -0
  18. package/dist/import/zap.d.ts +26 -0
  19. package/dist/import/zap.d.ts.map +1 -0
  20. package/dist/import/zap.js +119 -0
  21. package/dist/import/zap.js.map +1 -0
  22. package/dist/index.d.ts +31 -2
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +22 -2
  25. package/dist/index.js.map +1 -1
  26. package/dist/issue.d.ts +190 -11
  27. package/dist/issue.d.ts.map +1 -1
  28. package/dist/reconcile.d.ts +115 -10
  29. package/dist/reconcile.d.ts.map +1 -1
  30. package/dist/reconcile.js +306 -12
  31. package/dist/reconcile.js.map +1 -1
  32. package/dist/run.d.ts +134 -0
  33. package/dist/run.d.ts.map +1 -0
  34. package/dist/run.js +2 -0
  35. package/dist/run.js.map +1 -0
  36. package/dist/severity.d.ts +191 -0
  37. package/dist/severity.d.ts.map +1 -0
  38. package/dist/severity.js +171 -0
  39. package/dist/severity.js.map +1 -0
  40. package/dist/snapshot-builder.d.ts +70 -0
  41. package/dist/snapshot-builder.d.ts.map +1 -0
  42. package/dist/snapshot-builder.js +148 -0
  43. package/dist/snapshot-builder.js.map +1 -0
  44. package/dist/snapshot.d.ts +125 -0
  45. package/dist/snapshot.d.ts.map +1 -0
  46. package/dist/snapshot.js +2 -0
  47. package/dist/snapshot.js.map +1 -0
  48. package/package.json +23 -2
  49. package/src/coverage.ts +65 -0
  50. package/src/finding.ts +112 -0
  51. package/src/fingerprint.ts +315 -0
  52. package/src/import/nuclei.ts +173 -0
  53. package/src/import/zap.ts +161 -0
  54. package/src/index.ts +56 -2
  55. package/src/issue.ts +244 -11
  56. package/src/reconcile.ts +421 -17
  57. package/src/run.ts +163 -0
  58. package/src/severity.ts +250 -0
  59. package/src/snapshot-builder.ts +199 -0
  60. package/src/snapshot.ts +146 -0
package/dist/reconcile.js CHANGED
@@ -1,23 +1,317 @@
1
+ import { DEFAULT_SLA_POLICY, SEVERITY_ORDER, SEVERITY_WEIGHTS, severityRank, slaDueAt, } from './severity.js';
2
+ import { coversLocation } from './coverage.js';
1
3
  /**
2
- * Merges incoming findings into the tracked issue set. A finding whose title
3
- * matches an open issue is folded into it; anything new opens an issue.
4
+ * The key an issue and a finding must share to be the same issue.
4
5
  *
5
- * Pure: no I/O, no clock, no randomness. Callers supply the id for any issue
6
- * this opens via `nextId`.
6
+ * **The fingerprint version is part of it, not decoration.** A fingerprint means
7
+ * nothing without the algorithm that produced it, so an `fp_v1` finding must
8
+ * never match an `fp_v2` issue — reconciling across versions would silently
9
+ * merge two things that were never computed the same way. Crossing a version is
10
+ * what a re-fingerprint migration is for.
11
+ *
12
+ * The separator is an escape rather than a literal control character, so the
13
+ * source stays plain text: an invisible NUL here once passed prettier, eslint,
14
+ * tsc and the whole test suite, and was only caught because `grep` went quiet
15
+ * on a file it could no longer read.
7
16
  */
8
- export function reconcile(findings, openIssues, nextId) {
9
- const byTitle = new Map(openIssues.map((issue) => [issue.title, issue]));
17
+ function issueKey(of) {
18
+ return `${of.fingerprintVersion}\u0000${of.fingerprint}`;
19
+ }
20
+ /** Groups this run's findings by the issue they belong to. */
21
+ function groupByFingerprint(findings) {
22
+ const groups = new Map();
10
23
  for (const finding of findings) {
11
- const existing = byTitle.get(finding.title);
24
+ // The version is part of the key. A fingerprint means nothing without the
25
+ // algorithm that produced it, so a `fp_v1` finding must never match a
26
+ // `fp_v2` issue — that is what a re-fingerprint migration is for.
27
+ const key = issueKey(finding);
28
+ const existing = groups.get(key);
29
+ if (existing)
30
+ existing.push(finding);
31
+ else
32
+ groups.set(key, [finding]);
33
+ }
34
+ return groups;
35
+ }
36
+ /** The most urgent severity among a group of findings for one issue. */
37
+ function highestSeverity(findings) {
38
+ return findings.reduce((worst, candidate) => severityRank(candidate.detectedSeverity) > severityRank(worst.detectedSeverity)
39
+ ? candidate
40
+ : worst);
41
+ }
42
+ /** The default flapping guard for a run kind. */
43
+ function defaultThreshold(kind) {
44
+ // An upload asserts a complete result, so one miss is enough. A scan can miss
45
+ // for reasons that say nothing about the issue.
46
+ return kind === 'upload' ? 1 : 2;
47
+ }
48
+ /** An all-zero count, so a report never has to decide what a missing key means. */
49
+ function emptyCounts() {
50
+ return Object.fromEntries(SEVERITY_ORDER.map((s) => [s, 0]));
51
+ }
52
+ /** Whole days between two moments, floored. */
53
+ function daysBetween(from, to) {
54
+ return Math.max(0, Math.floor((to.getTime() - from.getTime()) / 86_400_000));
55
+ }
56
+ /**
57
+ * Turns a run's findings into issue state.
58
+ *
59
+ * **The only writer of issue state, and a pure function.** Given the same
60
+ * issues, findings, run and clock it produces the same result every time. It
61
+ * performs no I/O, reads no clock and generates no randomness; the caller
62
+ * supplies `now` and `newId` and persists what comes back.
63
+ *
64
+ * This half handles everything a **present** finding causes:
65
+ *
66
+ * - a fingerprint that matches nothing opens an issue (`created`);
67
+ * - a fingerprint that matches attaches evidence and refreshes `lastSeen`,
68
+ * clearing the miss counter (`seen`);
69
+ * - a `resolved` issue seen again becomes `regressed` (`reopened`) — a returning
70
+ * problem is a different and more interesting event than a new one;
71
+ * - a changed detected severity updates the issue, and updates the *effective*
72
+ * severity and the SLA deadline only where nobody has overridden it
73
+ * (`severity_detected_changed`);
74
+ * - an `ignored` issue whose detected severity has risen above what was
75
+ * accepted comes back (`unignored`) — accepting the risk of a medium is not
76
+ * accepting the risk of the critical it turned out to be.
77
+ *
78
+ * And everything an **absent** finding causes:
79
+ *
80
+ * - an issue the run covered but did not see takes a miss, and resolves once it
81
+ * has missed enough consecutive covering runs (`resolved`);
82
+ * - an issue **outside** the run's coverage is untouched — not resolved, and not
83
+ * even counted as a miss, so a sequence of narrow scans cannot accumulate
84
+ * misses against a path none of them looked at (invariant 5);
85
+ * - a **manual-origin** issue never auto-resolves; a human closes what a human
86
+ * opened (invariant 6);
87
+ * - a suppression whose expiry has passed lapses (`unignored`), regardless of
88
+ * coverage — an ignore expiring is a decision timing out, not an observation.
89
+ *
90
+ * Finally it computes the {@link RunSummary}: counts by severity for new, still
91
+ * open, resolved, regressed and ignored, plus the exposure score. Ignored issues
92
+ * are excluded from every count but their own, and from exposure, and never from
93
+ * the suppressed appendix (invariant 7).
94
+ *
95
+ * `firstSeen` is never reset, by anything here (invariant 4).
96
+ *
97
+ * @param input - Issues, findings, the run, the clock and an id source.
98
+ * @returns Every issue for the target, plus the events that explain the changes.
99
+ */
100
+ export function reconcile(input) {
101
+ const { issues, findings, run, now, newId } = input;
102
+ const actor = input.actor ?? 'reconciler';
103
+ const slaPolicy = input.slaPolicy ?? DEFAULT_SLA_POLICY;
104
+ const events = [];
105
+ const emit = (issueId, type, payload) => {
106
+ events.push({
107
+ id: newId(),
108
+ orgId: run.orgId,
109
+ issueId,
110
+ runId: run.id,
111
+ type,
112
+ actor,
113
+ ...(payload === undefined ? {} : { payload }),
114
+ createdAt: now,
115
+ });
116
+ };
117
+ const byKey = new Map(issues.map((i) => [issueKey(i), i]));
118
+ const updated = new Map();
119
+ for (const [key, group] of groupByFingerprint(findings)) {
120
+ const existing = byKey.get(key);
121
+ const worst = highestSeverity(group);
122
+ const findingIds = group.map((f) => f.id);
12
123
  if (!existing) {
13
- byTitle.set(finding.title, {
14
- id: nextId(),
15
- title: finding.title,
16
- severity: finding.severity,
124
+ const id = newId();
125
+ const issue = {
126
+ id,
127
+ orgId: run.orgId,
128
+ targetId: run.targetId,
129
+ fingerprint: worst.fingerprint,
130
+ fingerprintVersion: worst.fingerprintVersion,
131
+ title: worst.title,
132
+ vulnKey: worst.vulnKey,
133
+ ...(worst.cwe === undefined ? {} : { cwe: worst.cwe }),
134
+ location: worst.location,
135
+ ...(worst.parameter === undefined ? {} : { parameter: worst.parameter }),
17
136
  status: 'open',
137
+ detectedSeverity: worst.detectedSeverity,
138
+ effectiveSeverity: worst.detectedSeverity,
139
+ firstSeen: now,
140
+ lastSeen: now,
141
+ consecutiveMisses: 0,
142
+ origin: run.kind,
143
+ slaDueAt: slaDueAt(worst.detectedSeverity, now, slaPolicy),
144
+ };
145
+ updated.set(key, issue);
146
+ emit(id, 'created', { findingIds, severity: worst.detectedSeverity });
147
+ continue;
148
+ }
149
+ // One `seen` per issue per run, not one per finding. `issue_events` is what
150
+ // every analytic counts, and a weakness two engines both detected would
151
+ // otherwise register as two sightings of one issue.
152
+ let issue = { ...existing, lastSeen: now, consecutiveMisses: 0 };
153
+ emit(issue.id, 'seen', { findingIds });
154
+ if (issue.status === 'resolved') {
155
+ issue = { ...issue, status: 'regressed', reopenedAt: now };
156
+ emit(issue.id, 'reopened', { resolvedAt: existing.resolvedAt?.toISOString() });
157
+ }
158
+ if (worst.detectedSeverity !== issue.detectedSeverity) {
159
+ const overridden = issue.severityOverriddenAt !== undefined;
160
+ const raisedAboveOverride = overridden && severityRank(worst.detectedSeverity) > severityRank(issue.effectiveSeverity);
161
+ emit(issue.id, 'severity_detected_changed', {
162
+ from: issue.detectedSeverity,
163
+ to: worst.detectedSeverity,
164
+ // "Flag for review" in the spec, which names no column to flag it in.
165
+ // Recorded on the event rather than invented as a field: the detected
166
+ // severity has risen above a human's override, and somebody should look.
167
+ needsReview: raisedAboveOverride,
168
+ });
169
+ issue = overridden
170
+ ? { ...issue, detectedSeverity: worst.detectedSeverity }
171
+ : {
172
+ ...issue,
173
+ detectedSeverity: worst.detectedSeverity,
174
+ effectiveSeverity: worst.detectedSeverity,
175
+ slaDueAt: slaDueAt(worst.detectedSeverity, issue.firstSeen, slaPolicy),
176
+ };
177
+ }
178
+ if (issue.status === 'ignored' &&
179
+ issue.severityAtIgnore !== undefined &&
180
+ severityRank(worst.detectedSeverity) > severityRank(issue.severityAtIgnore)) {
181
+ emit(issue.id, 'unignored', {
182
+ reason: 'severity increased',
183
+ from: issue.severityAtIgnore,
184
+ to: worst.detectedSeverity,
18
185
  });
186
+ issue = {
187
+ ...issue,
188
+ status: 'open',
189
+ ignoreReason: undefined,
190
+ ignoreComment: undefined,
191
+ ignoreScope: undefined,
192
+ ignoreExpiresAt: undefined,
193
+ ignoredBy: undefined,
194
+ severityAtIgnore: undefined,
195
+ };
196
+ }
197
+ updated.set(key, issue);
198
+ }
199
+ const created = new Set([...updated.keys()].filter((k) => !byKey.has(k)));
200
+ const regressedNow = new Set([...updated].filter(([k, i]) => !created.has(k) && i.status === 'regressed').map(([k]) => k));
201
+ const resolvedNow = new Set();
202
+ // ---- what an absent finding causes -------------------------------------
203
+ //
204
+ // A run resolves only what it could have found. An issue outside coverage is
205
+ // left entirely alone: not resolved, and not counted as a miss either, so a
206
+ // sequence of narrow scans cannot accumulate misses against a path none of
207
+ // them looked at.
208
+ const threshold = input.autoResolveThreshold ?? defaultThreshold(run.kind);
209
+ for (const original of issues) {
210
+ const key = issueKey(original);
211
+ if (updated.has(key))
212
+ continue; // seen this run
213
+ if (original.status !== 'open' && original.status !== 'regressed')
214
+ continue;
215
+ // A human closes what a human opened (invariant 6).
216
+ if (original.origin === 'manual')
217
+ continue;
218
+ if (!coversLocation(original.location, run.coverage))
219
+ continue;
220
+ const misses = original.consecutiveMisses + 1;
221
+ if (misses < threshold) {
222
+ updated.set(key, { ...original, consecutiveMisses: misses });
223
+ continue;
224
+ }
225
+ updated.set(key, {
226
+ ...original,
227
+ consecutiveMisses: misses,
228
+ status: 'resolved',
229
+ resolvedAt: now,
230
+ });
231
+ resolvedNow.add(key);
232
+ emit(original.id, 'resolved', { consecutiveMisses: misses, threshold });
233
+ }
234
+ // ---- suppressions that have lapsed --------------------------------------
235
+ //
236
+ // Independent of coverage and of whether the issue was seen: an ignore
237
+ // expiring is a decision timing out, not an observation.
238
+ for (const original of issues) {
239
+ const key = issueKey(original);
240
+ const current = updated.get(key) ?? original;
241
+ if (current.status !== 'ignored')
242
+ continue;
243
+ if (current.ignoreExpiresAt === undefined)
244
+ continue;
245
+ if (current.ignoreExpiresAt.getTime() > now.getTime())
246
+ continue;
247
+ emit(current.id, 'unignored', {
248
+ reason: 'expired',
249
+ expiredAt: current.ignoreExpiresAt.toISOString(),
250
+ });
251
+ updated.set(key, {
252
+ ...current,
253
+ status: 'open',
254
+ ignoreReason: undefined,
255
+ ignoreComment: undefined,
256
+ ignoreScope: undefined,
257
+ ignoreExpiresAt: undefined,
258
+ ignoredBy: undefined,
259
+ severityAtIgnore: undefined,
260
+ });
261
+ }
262
+ // Untouched issues are returned unchanged, in their original order, so a
263
+ // caller can write the whole set back without diffing.
264
+ const result = issues.map((i) => updated.get(issueKey(i)) ?? i);
265
+ for (const [key, issue] of updated)
266
+ if (!byKey.has(key))
267
+ result.push(issue);
268
+ // ---- the summary --------------------------------------------------------
269
+ const counts = {
270
+ new: emptyCounts(),
271
+ stillOpen: emptyCounts(),
272
+ resolved: emptyCounts(),
273
+ regressed: emptyCounts(),
274
+ ignored: emptyCounts(),
275
+ };
276
+ let exposureScore = 0;
277
+ for (const issue of result) {
278
+ const key = issueKey(issue);
279
+ const severity = issue.effectiveSeverity;
280
+ if (issue.status === 'ignored') {
281
+ // Excluded from every other count and from exposure, never from the
282
+ // suppressed appendix (invariant 7).
283
+ counts.ignored[severity]++;
284
+ continue;
285
+ }
286
+ if (created.has(key))
287
+ counts.new[severity]++;
288
+ else if (resolvedNow.has(key))
289
+ counts.resolved[severity]++;
290
+ else if (regressedNow.has(key))
291
+ counts.regressed[severity]++;
292
+ else if (updated.has(key))
293
+ counts.stillOpen[severity]++;
294
+ if (issue.status === 'open' || issue.status === 'regressed') {
295
+ exposureScore += SEVERITY_WEIGHTS[severity] * Math.min(daysBetween(issue.firstSeen, now), 90);
19
296
  }
20
297
  }
21
- return [...byTitle.values()];
298
+ const summary = {
299
+ runId: run.id,
300
+ orgId: run.orgId,
301
+ targetId: run.targetId,
302
+ kind: run.kind,
303
+ trigger: run.trigger,
304
+ engines: run.coverage.engines,
305
+ coverage: run.coverage,
306
+ durationMs: input.durationMs ?? 0,
307
+ new: counts.new,
308
+ stillOpen: counts.stillOpen,
309
+ resolved: counts.resolved,
310
+ regressed: counts.regressed,
311
+ ignored: counts.ignored,
312
+ exposureScore,
313
+ createdAt: now,
314
+ };
315
+ return { issues: result, events, summary };
22
316
  }
23
317
  //# sourceMappingURL=reconcile.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"reconcile.js","sourceRoot":"","sources":["../src/reconcile.ts"],"names":[],"mappings":"AAQA;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAAC,QAAmB,EAAE,UAAmB,EAAE,MAAoB;IACtF,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IAEzE,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAC5C,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE;gBACzB,EAAE,EAAE,MAAM,EAAE;gBACZ,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,MAAM,EAAE,MAAM;aACf,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;AAC/B,CAAC"}
1
+ {"version":3,"file":"reconcile.js","sourceRoot":"","sources":["../src/reconcile.ts"],"names":[],"mappings":"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"}
package/dist/run.d.ts ADDED
@@ -0,0 +1,134 @@
1
+ import type { Severity } from './severity.js';
2
+ /**
3
+ * What kind of run this was.
4
+ *
5
+ * - `scan` — Secureport originated the traffic.
6
+ * - `upload` — someone brought results from elsewhere.
7
+ * - `manual` — a human recorded a finding directly.
8
+ *
9
+ * **An upload is first-class, not a lesser scan.** Much of the value is in
10
+ * tracking results a customer already has, and a model that treated uploads as
11
+ * second-class would make that path feel second-class too.
12
+ */
13
+ export type RunKind = 'scan' | 'upload' | 'manual';
14
+ /**
15
+ * What set the run going.
16
+ *
17
+ * Recorded on every run from the first line of code, because it is what lets
18
+ * you say "the Action ran 340 times this quarter" — the sentence that shows
19
+ * automation is actually being used rather than merely installed.
20
+ */
21
+ export type RunTrigger = 'github_action' | 'cli' | 'api' | 'scheduled' | 'web';
22
+ /**
23
+ * What a run actually exercised.
24
+ *
25
+ * The reason auto-resolution is safe. **A run only resolves what it could have
26
+ * found** (invariant 5): a quick profile that skipped `/admin` must not close
27
+ * an `/admin` issue, because not looking is not the same as not finding.
28
+ *
29
+ * Scan runs record what they genuinely reached. Upload runs take a declared
30
+ * scope, defaulting to the whole target — the person uploading is asserting
31
+ * what their results cover.
32
+ */
33
+ export interface Coverage {
34
+ /**
35
+ * Location patterns the run covered, as globs, e.g.
36
+ * `https://app.example.com/**`.
37
+ *
38
+ * An issue whose location matches none of these is untouched by this run,
39
+ * whatever else happened.
40
+ */
41
+ readonly paths: readonly string[];
42
+ /** Ports exercised, where the run was port-aware. */
43
+ readonly ports?: readonly number[];
44
+ /** Engines that took part. */
45
+ readonly engines: readonly string[];
46
+ }
47
+ /**
48
+ * One execution against a target.
49
+ */
50
+ export interface Run {
51
+ /** Unique id. */
52
+ readonly id: string;
53
+ /** Organisation this run belongs to. */
54
+ readonly orgId: string;
55
+ /** Target it ran against. */
56
+ readonly targetId: string;
57
+ /** What kind of run it was. */
58
+ readonly kind: RunKind;
59
+ /** What set it going. */
60
+ readonly trigger: RunTrigger;
61
+ /** What it exercised. */
62
+ readonly coverage: Coverage;
63
+ /**
64
+ * The verification this run relied on, for runs that originate traffic.
65
+ *
66
+ * Recorded per run rather than per organisation, because verification
67
+ * belongs to a target: verifying production must never authorise scanning
68
+ * staging, even on the same wildcard domain (invariant 11).
69
+ */
70
+ readonly verificationId?: string;
71
+ /** When it started. */
72
+ readonly startedAt: Date;
73
+ /** When it finished. */
74
+ readonly finishedAt?: Date;
75
+ }
76
+ /**
77
+ * A count of issues per {@link Severity}.
78
+ *
79
+ * Every severity is present, including zeroes, so a report renders a complete
80
+ * table without deciding what a missing key means.
81
+ */
82
+ export type SeverityCounts = Readonly<Record<Severity, number>>;
83
+ /**
84
+ * What a run did, in the terms a reader cares about.
85
+ *
86
+ * The change summary every report opens with, and the row analytics aggregate.
87
+ * Computed once by reconciliation and stored, so no report has to recount
88
+ * findings at render time.
89
+ */
90
+ export interface RunSummary {
91
+ /** The run this summarises. */
92
+ readonly runId: string;
93
+ /** Organisation it belongs to. */
94
+ readonly orgId: string;
95
+ /** Target it ran against. */
96
+ readonly targetId: string;
97
+ /** What kind of run it was. */
98
+ readonly kind: RunKind;
99
+ /** What set it going. */
100
+ readonly trigger: RunTrigger;
101
+ /** Engines that took part. */
102
+ readonly engines: readonly string[];
103
+ /** What the run exercised. */
104
+ readonly coverage: Coverage;
105
+ /** How long it took. */
106
+ readonly durationMs: number;
107
+ /** Issues opened for the first time by this run. */
108
+ readonly new: SeverityCounts;
109
+ /** Issues already open that this run saw again. */
110
+ readonly stillOpen: SeverityCounts;
111
+ /** Issues this run resolved. */
112
+ readonly resolved: SeverityCounts;
113
+ /** Issues that were resolved and that this run found again. */
114
+ readonly regressed: SeverityCounts;
115
+ /**
116
+ * Issues currently suppressed.
117
+ *
118
+ * Reported separately and **never folded into the other counts**: an ignored
119
+ * issue is excluded from metrics but never from the suppressed appendix
120
+ * (invariant 7).
121
+ */
122
+ readonly ignored: SeverityCounts;
123
+ /**
124
+ * Exposure at the end of this run.
125
+ *
126
+ * `Σ over open issues of severityWeight × min(daysOpen, 90)`. Simple,
127
+ * explainable and monotone — it can only fall by fixing things or by time not
128
+ * passing.
129
+ */
130
+ readonly exposureScore: number;
131
+ /** When the summary was computed. */
132
+ readonly createdAt: Date;
133
+ }
134
+ //# sourceMappingURL=run.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C;;;;;;;;;;GAUG;AACH,MAAM,MAAM,OAAO,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEnD;;;;;;GAMG;AACH,MAAM,MAAM,UAAU,GAAG,eAAe,GAAG,KAAK,GAAG,KAAK,GAAG,WAAW,GAAG,KAAK,CAAC;AAE/E;;;;;;;;;;GAUG;AACH,MAAM,WAAW,QAAQ;IACvB;;;;;;OAMG;IACH,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAElC,qDAAqD;IACrD,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAEnC,8BAA8B;IAC9B,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC;AAED;;GAEG;AACH,MAAM,WAAW,GAAG;IAClB,iBAAiB;IACjB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB,wCAAwC;IACxC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEvB,6BAA6B;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B,+BAA+B;IAC/B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAEvB,yBAAyB;IACzB,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;IAE7B,yBAAyB;IACzB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAE5B;;;;;;OAMG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IAEjC,uBAAuB;IACvB,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;IAEzB,wBAAwB;IACxB,QAAQ,CAAC,UAAU,CAAC,EAAE,IAAI,CAAC;CAC5B;AAED;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;AAEhE;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IACzB,+BAA+B;IAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEvB,kCAAkC;IAClC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEvB,6BAA6B;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B,+BAA+B;IAC/B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAEvB,yBAAyB;IACzB,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;IAE7B,8BAA8B;IAC9B,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAEpC,8BAA8B;IAC9B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAE5B,wBAAwB;IACxB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAE5B,oDAAoD;IACpD,QAAQ,CAAC,GAAG,EAAE,cAAc,CAAC;IAE7B,mDAAmD;IACnD,QAAQ,CAAC,SAAS,EAAE,cAAc,CAAC;IAEnC,gCAAgC;IAChC,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAElC,+DAA+D;IAC/D,QAAQ,CAAC,SAAS,EAAE,cAAc,CAAC;IAEnC;;;;;;OAMG;IACH,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IAEjC;;;;;;OAMG;IACH,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAE/B,qCAAqC;IACrC,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;CAC1B"}
package/dist/run.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":""}