@zephyrdeng/pi-review 0.6.1 → 0.7.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 (125) hide show
  1. package/README.md +110 -13
  2. package/README.zh-CN.md +64 -3
  3. package/dist/args.d.ts +8 -0
  4. package/dist/args.d.ts.map +1 -1
  5. package/dist/args.js +147 -28
  6. package/dist/args.js.map +1 -1
  7. package/dist/args.test.d.ts +2 -0
  8. package/dist/args.test.d.ts.map +1 -0
  9. package/dist/args.test.js +115 -0
  10. package/dist/args.test.js.map +1 -0
  11. package/dist/cli-exit.test.d.ts +2 -0
  12. package/dist/cli-exit.test.d.ts.map +1 -0
  13. package/dist/cli-exit.test.js +84 -0
  14. package/dist/cli-exit.test.js.map +1 -0
  15. package/dist/cli.js +16 -2
  16. package/dist/cli.js.map +1 -1
  17. package/dist/config.d.ts +1 -0
  18. package/dist/config.d.ts.map +1 -1
  19. package/dist/config.js +1 -0
  20. package/dist/config.js.map +1 -1
  21. package/dist/extensions/review.d.ts +2 -0
  22. package/dist/extensions/review.js +22 -0
  23. package/dist/extensions/rv-prompts.d.ts +19 -0
  24. package/dist/extensions/rv-prompts.js +132 -0
  25. package/dist/index.d.ts +17 -7
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +12 -6
  28. package/dist/index.js.map +1 -1
  29. package/dist/json-events.d.ts +45 -0
  30. package/dist/json-events.d.ts.map +1 -1
  31. package/dist/json-events.js +185 -0
  32. package/dist/json-events.js.map +1 -1
  33. package/dist/json-events.test.js +64 -1
  34. package/dist/json-events.test.js.map +1 -1
  35. package/dist/loop.d.ts +36 -0
  36. package/dist/loop.d.ts.map +1 -0
  37. package/dist/loop.js +73 -0
  38. package/dist/loop.js.map +1 -0
  39. package/dist/loop.test.d.ts +2 -0
  40. package/dist/loop.test.d.ts.map +1 -0
  41. package/dist/loop.test.js +83 -0
  42. package/dist/loop.test.js.map +1 -0
  43. package/dist/matcher.d.ts +74 -0
  44. package/dist/matcher.d.ts.map +1 -0
  45. package/dist/matcher.js +202 -0
  46. package/dist/matcher.js.map +1 -0
  47. package/dist/matcher.test.d.ts +2 -0
  48. package/dist/matcher.test.d.ts.map +1 -0
  49. package/dist/matcher.test.js +161 -0
  50. package/dist/matcher.test.js.map +1 -0
  51. package/dist/meta-footer.d.ts +15 -1
  52. package/dist/meta-footer.d.ts.map +1 -1
  53. package/dist/meta-footer.js +108 -0
  54. package/dist/meta-footer.js.map +1 -1
  55. package/dist/meta-footer.test.js +43 -1
  56. package/dist/meta-footer.test.js.map +1 -1
  57. package/dist/panel-aggregate.d.ts +18 -0
  58. package/dist/panel-aggregate.d.ts.map +1 -0
  59. package/dist/panel-aggregate.js +247 -0
  60. package/dist/panel-aggregate.js.map +1 -0
  61. package/dist/panel-aggregate.test.d.ts +2 -0
  62. package/dist/panel-aggregate.test.d.ts.map +1 -0
  63. package/dist/panel-aggregate.test.js +461 -0
  64. package/dist/panel-aggregate.test.js.map +1 -0
  65. package/dist/panel-cli.test.d.ts +2 -0
  66. package/dist/panel-cli.test.d.ts.map +1 -0
  67. package/dist/panel-cli.test.js +188 -0
  68. package/dist/panel-cli.test.js.map +1 -0
  69. package/dist/panel-config.d.ts +19 -0
  70. package/dist/panel-config.d.ts.map +1 -0
  71. package/dist/panel-config.js +115 -0
  72. package/dist/panel-config.js.map +1 -0
  73. package/dist/panel-config.test.d.ts +2 -0
  74. package/dist/panel-config.test.d.ts.map +1 -0
  75. package/dist/panel-config.test.js +91 -0
  76. package/dist/panel-config.test.js.map +1 -0
  77. package/dist/panel-loop.test.d.ts +2 -0
  78. package/dist/panel-loop.test.d.ts.map +1 -0
  79. package/dist/panel-loop.test.js +118 -0
  80. package/dist/panel-loop.test.js.map +1 -0
  81. package/dist/panel.d.ts +10 -0
  82. package/dist/panel.d.ts.map +1 -0
  83. package/dist/panel.js +315 -0
  84. package/dist/panel.js.map +1 -0
  85. package/dist/presets.d.ts +2 -1
  86. package/dist/presets.d.ts.map +1 -1
  87. package/dist/presets.js +10 -0
  88. package/dist/presets.js.map +1 -1
  89. package/dist/prompt.d.ts +14 -1
  90. package/dist/prompt.d.ts.map +1 -1
  91. package/dist/prompt.js +61 -15
  92. package/dist/prompt.js.map +1 -1
  93. package/dist/prompt.test.d.ts +2 -0
  94. package/dist/prompt.test.d.ts.map +1 -0
  95. package/dist/prompt.test.js +37 -0
  96. package/dist/prompt.test.js.map +1 -0
  97. package/dist/review-result.d.ts +5 -0
  98. package/dist/review-result.d.ts.map +1 -0
  99. package/dist/review-result.js +98 -0
  100. package/dist/review-result.js.map +1 -0
  101. package/dist/review-result.test.d.ts +2 -0
  102. package/dist/review-result.test.d.ts.map +1 -0
  103. package/dist/review-result.test.js +196 -0
  104. package/dist/review-result.test.js.map +1 -0
  105. package/dist/review.d.ts +10 -4
  106. package/dist/review.d.ts.map +1 -1
  107. package/dist/review.js +82 -20
  108. package/dist/review.js.map +1 -1
  109. package/dist/review.meta.test.js +2 -2
  110. package/dist/review.meta.test.js.map +1 -1
  111. package/dist/skill-protocol.test.d.ts +2 -0
  112. package/dist/skill-protocol.test.d.ts.map +1 -0
  113. package/dist/skill-protocol.test.js +35 -0
  114. package/dist/skill-protocol.test.js.map +1 -0
  115. package/dist/types.d.ts +147 -5
  116. package/dist/types.d.ts.map +1 -1
  117. package/dist/types.js +11 -0
  118. package/dist/types.js.map +1 -1
  119. package/extensions/rv-completions.test.ts +15 -0
  120. package/extensions/rv-completions.ts +7 -1
  121. package/package.json +3 -3
  122. package/resources/panel-presets.json +21 -0
  123. package/resources/system-prompt.md +11 -1
  124. package/skills/pi-review/SKILL.md +90 -12
  125. package/skills/pi-review/references/codex-tools.md +19 -6
@@ -1,10 +1,21 @@
1
1
  import assert from "node:assert/strict";
2
2
  import { test } from "node:test";
3
- import { formatDurationMs, formatReviewMetaAscii, formatReviewMetaJsonLine } from "./meta-footer.js";
3
+ import { formatDurationMs, formatReviewMetaAscii, formatReviewMetaJsonLine, formatTokens, formatUsage } from "./meta-footer.js";
4
4
  const sample = {
5
5
  reviewMode: "code",
6
6
  verdict: "request_changes",
7
7
  verdictSource: "parsed",
8
+ status: "has_findings",
9
+ findings: [
10
+ {
11
+ id: "F1",
12
+ severity: "high",
13
+ path: "src/cli.ts",
14
+ summary: "Dirty reviews exit zero",
15
+ actionable: true,
16
+ },
17
+ ],
18
+ actionableCount: 1,
8
19
  durationMs: 383_500,
9
20
  model: "zai/glm-5.2",
10
21
  sessionHandle: "/tmp/sessions/run-abc/session.jsonl",
@@ -16,6 +27,8 @@ test("formatDurationMs formats sub-minute and minutes", () => {
16
27
  test("formatReviewMetaAscii includes verdict and session hint", () => {
17
28
  const ascii = formatReviewMetaAscii(sample);
18
29
  assert.match(ascii, /REQUEST CHANGES/);
30
+ assert.match(ascii, /HAS FINDINGS/);
31
+ assert.match(ascii, /1 actionable/);
19
32
  assert.match(ascii, /6m 24s/);
20
33
  assert.match(ascii, /session\.jsonl/);
21
34
  assert.match(ascii, /--continue/);
@@ -25,6 +38,35 @@ test("formatReviewMetaJsonLine is one JSON line", () => {
25
38
  const line = formatReviewMetaJsonLine(sample);
26
39
  assert.ok(line.startsWith("PI_REVIEW_META_JSON: "));
27
40
  const json = JSON.parse(line.slice("PI_REVIEW_META_JSON: ".length).trim());
41
+ assert.equal(json.reviewMode, "code");
28
42
  assert.equal(json.verdict, "request_changes");
43
+ assert.equal(json.verdictSource, "parsed");
44
+ assert.equal(json.durationMs, 383_500);
45
+ assert.equal(json.model, "zai/glm-5.2");
46
+ assert.equal(json.sessionHandle, "/tmp/sessions/run-abc/session.jsonl");
47
+ assert.equal(json.status, "has_findings");
48
+ assert.equal(json.actionableCount, 1);
49
+ assert.deepEqual(json.findings, sample.findings);
50
+ });
51
+ test("formatTokens scales with K/M/B units", () => {
52
+ assert.equal(formatTokens(0), "0");
53
+ assert.equal(formatTokens(512), "512");
54
+ assert.equal(formatTokens(1024), "1.0K");
55
+ assert.equal(formatTokens(18031), "17.6K");
56
+ assert.equal(formatTokens(1_500_000), "1.4M");
57
+ assert.equal(formatTokens(2_500_000_000), "2.3B");
58
+ });
59
+ test("formatUsage renders in/out/cache/reason breakdown", () => {
60
+ const text = formatUsage({ input: 1024, output: 512, cacheRead: 2048, cacheWrite: 0, reasoning: 100 });
61
+ assert.match(text, /in 1\.0K/);
62
+ assert.match(text, /out 512/);
63
+ assert.match(text, /cache 2\.0K/);
64
+ assert.match(text, /reason 100/);
65
+ });
66
+ test("ASCII footer shows thinking and tokens when present", () => {
67
+ const meta = { ...sample, thinking: "xhigh", usage: { input: 1024, output: 512, cacheRead: 2048, cacheWrite: 0, reasoning: 0, totalTokens: 3584 } };
68
+ const ascii = formatReviewMetaAscii(meta);
69
+ assert.match(ascii, /Thinking\s+xhigh/);
70
+ assert.match(ascii, /Tokens\s+in .*out .*cache/);
29
71
  });
30
72
  //# sourceMappingURL=meta-footer.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"meta-footer.test.js","sourceRoot":"","sources":["../src/meta-footer.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAGrG,MAAM,MAAM,GAAe;IACzB,UAAU,EAAE,MAAM;IAClB,OAAO,EAAE,iBAAiB;IAC1B,aAAa,EAAE,QAAQ;IACvB,UAAU,EAAE,OAAO;IACnB,KAAK,EAAE,aAAa;IACpB,aAAa,EAAE,qCAAqC;CACrD,CAAC;AAEF,IAAI,CAAC,iDAAiD,EAAE,GAAG,EAAE;IAC3D,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;IAC7C,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAC;AACpD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,yDAAyD,EAAE,GAAG,EAAE;IACnE,MAAM,KAAK,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAC5C,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,iBAAiB,CAAC,CAAC;IACvC,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAC9B,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAAC;IACtC,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;IAClC,MAAM,CAAC,YAAY,CAAC,KAAK,EAAE,qBAAqB,CAAC,CAAC;AACpD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,2CAA2C,EAAE,GAAG,EAAE;IACrD,MAAM,IAAI,GAAG,wBAAwB,CAAC,MAAM,CAAC,CAAC;IAC9C,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,uBAAuB,CAAC,CAAC,CAAC;IACpD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,uBAAuB,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IAC3E,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAC;AAChD,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"meta-footer.test.js","sourceRoot":"","sources":["../src/meta-footer.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import { type ConsensusPolicy, type PanelAggregationResult, type ReviewerSubmission } from "./types.js";
2
+ import type { FindingMatcher } from "./matcher.js";
3
+ /** Effective actionable-support threshold for a consensus policy. */
4
+ export declare function effectiveThreshold(policy: ConsensusPolicy, configuredReviewers: number, minAgree?: number): number;
5
+ export interface PanelAggregationInput {
6
+ reviewers: ReviewerSubmission[];
7
+ policy: ConsensusPolicy;
8
+ minAgree?: number;
9
+ configuredReviewers: number;
10
+ matcher: FindingMatcher;
11
+ }
12
+ /**
13
+ * Aggregate independent reviewer results into one panel result. Pure: no Pi,
14
+ * no I/O. A throwing matcher is treated as a runtime aggregation failure
15
+ * (blocked); matcher-reported errors are semantic failures (needs_human).
16
+ */
17
+ export declare function aggregatePanel(input: PanelAggregationInput): Promise<PanelAggregationResult>;
18
+ //# sourceMappingURL=panel-aggregate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"panel-aggregate.d.ts","sourceRoot":"","sources":["../src/panel-aggregate.ts"],"names":[],"mappings":"AAYA,OAAO,EAEL,KAAK,eAAe,EAEpB,KAAK,sBAAsB,EAI3B,KAAK,kBAAkB,EAIxB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnD,qEAAqE;AACrE,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,eAAe,EACvB,mBAAmB,EAAE,MAAM,EAC3B,QAAQ,CAAC,EAAE,MAAM,GAChB,MAAM,CAWR;AA0GD,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,kBAAkB,EAAE,CAAC;IAChC,MAAM,EAAE,eAAe,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,OAAO,EAAE,cAAc,CAAC;CACzB;AAMD;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAoIlG"}
@@ -0,0 +1,247 @@
1
+ // Pure panel aggregation — the primary test seam.
2
+ //
3
+ // Given reviewer submissions, a consensus policy, and an injected finding
4
+ // matcher, produce one aggregate panel result with no Pi and no I/O. Most
5
+ // consensus behaviour is deterministically testable here.
6
+ //
7
+ // Status precedence: runtime/child failure -> blocked; unsafe aggregation or
8
+ // reviewer clarification -> needs_human; confirmed actionable clusters ->
9
+ // has_findings; otherwise clean (may carry non-blocking advisories). A clean
10
+ // result is never produced silently when reviewers fail or aggregation is
11
+ // unsafe.
12
+ import { DEFAULT_PANEL_MIN_AGREE, } from "./types.js";
13
+ /** Effective actionable-support threshold for a consensus policy. */
14
+ export function effectiveThreshold(policy, configuredReviewers, minAgree) {
15
+ switch (policy) {
16
+ case "any":
17
+ return 1;
18
+ case "quorum":
19
+ return minAgree ?? DEFAULT_PANEL_MIN_AGREE;
20
+ case "majority":
21
+ return Math.floor(configuredReviewers / 2) + 1;
22
+ case "unanimous":
23
+ return configuredReviewers;
24
+ }
25
+ }
26
+ function classifyReviewer(sub) {
27
+ const { result, reviewerId, role, model, thinking, usage, durationMs } = sub;
28
+ const outcome = {
29
+ reviewerId,
30
+ ...(role ? { role } : {}),
31
+ model: model ?? null,
32
+ ...(thinking ? { thinking } : {}),
33
+ ...(usage ? { usage } : {}),
34
+ durationMs,
35
+ status: result.status,
36
+ verdict: result.verdict,
37
+ verdictSource: result.verdictSource,
38
+ contributed: false,
39
+ ...(result.verdictSource === "runtime_error" && result.parseError
40
+ ? { runtimeError: result.parseError }
41
+ : {}),
42
+ ...(result.verdictSource !== "runtime_error" && result.parseError
43
+ ? { parseError: result.parseError }
44
+ : {}),
45
+ };
46
+ if (result.verdictSource === "runtime_error" || result.status === "blocked") {
47
+ return { outcome, kind: "blocked", contributed: false };
48
+ }
49
+ if (result.verdictSource === "fallback") {
50
+ return { outcome, kind: "needs_human", contributed: false };
51
+ }
52
+ if (result.status === "needs_human") {
53
+ return { outcome, kind: "needs_human", contributed: false };
54
+ }
55
+ // A dirty verdict (has_findings) that yielded zero parseable findings is a
56
+ // malformed conclusion: the reviewer asked for changes but produced no safe
57
+ // structured finding. It must not become a clean vote (issue #2 Decision 30).
58
+ if (result.status === "has_findings" && result.findings.length === 0) {
59
+ return {
60
+ outcome: { ...outcome, parseError: [outcome.parseError, "dirty verdict with no parseable findings"].filter(Boolean).join("; ") },
61
+ kind: "needs_human",
62
+ contributed: false,
63
+ };
64
+ }
65
+ return { outcome: { ...outcome, contributed: true }, kind: "ok", contributed: true };
66
+ }
67
+ function verdictForStatus(status) {
68
+ switch (status) {
69
+ case "clean":
70
+ return "approve";
71
+ case "has_findings":
72
+ return "request_changes";
73
+ case "needs_human":
74
+ return "needs_clarification";
75
+ case "blocked":
76
+ return "blocked";
77
+ }
78
+ }
79
+ function distinctReviewerIds(sourceFindings) {
80
+ const seen = new Set();
81
+ const ordered = [];
82
+ for (const sf of sourceFindings) {
83
+ if (!seen.has(sf.reviewerId)) {
84
+ seen.add(sf.reviewerId);
85
+ ordered.push(sf.reviewerId);
86
+ }
87
+ }
88
+ return ordered.sort((a, b) => a.localeCompare(b));
89
+ }
90
+ function buildCluster(id, sourceFindings, threshold) {
91
+ const supportingReviewerIds = distinctReviewerIds(sourceFindings);
92
+ const actionableReviewers = new Set();
93
+ for (const sf of sourceFindings) {
94
+ if (sf.finding.actionable)
95
+ actionableReviewers.add(sf.reviewerId);
96
+ }
97
+ const actionableSupportCount = actionableReviewers.size;
98
+ const canonical = sourceFindings.find((sf) => sf.finding.actionable) ?? sourceFindings[0];
99
+ const firstPath = sourceFindings.map((sf) => sf.finding.path).find(Boolean);
100
+ return {
101
+ id,
102
+ summary: canonical.finding.summary,
103
+ ...(canonical.finding.severity ? { severity: canonical.finding.severity } : {}),
104
+ ...(firstPath ? { path: firstPath } : {}),
105
+ confirmed: actionableSupportCount >= threshold,
106
+ supportCount: supportingReviewerIds.length,
107
+ actionableSupportCount,
108
+ supportingReviewerIds,
109
+ sourceFindingIds: sourceFindings.map((sf) => sf.id),
110
+ };
111
+ }
112
+ function fallbackClusters(sourceFindings) {
113
+ return sourceFindings.map((sf, index) => buildCluster(`C${index + 1}`, [sf], Number.POSITIVE_INFINITY));
114
+ }
115
+ /**
116
+ * Aggregate independent reviewer results into one panel result. Pure: no Pi,
117
+ * no I/O. A throwing matcher is treated as a runtime aggregation failure
118
+ * (blocked); matcher-reported errors are semantic failures (needs_human).
119
+ */
120
+ export async function aggregatePanel(input) {
121
+ const { reviewers, policy, configuredReviewers, matcher } = input;
122
+ const threshold = effectiveThreshold(policy, configuredReviewers, input.minAgree);
123
+ const classifications = reviewers.map((sub) => classifyReviewer(sub));
124
+ const reviewerOutcomes = classifications.map((c) => c.outcome);
125
+ const anyBlocked = classifications.some((c) => c.kind === "blocked");
126
+ const anyNeedsHuman = classifications.some((c) => c.kind === "needs_human");
127
+ // Collect source findings from contributing reviewers only.
128
+ const sourceFindings = [];
129
+ for (const sub of reviewers) {
130
+ const cls = classifications.find((c) => c.outcome.reviewerId === sub.reviewerId);
131
+ if (!cls.contributed)
132
+ continue;
133
+ for (let index = 0; index < sub.result.findings.length; index += 1) {
134
+ const finding = sub.result.findings[index];
135
+ // Internal source id is unique by construction (reviewer + position),
136
+ // so a reviewer that emits duplicate finding ids cannot collide or
137
+ // silently overwrite a sibling finding (issue #2 raw-finding uniqueness).
138
+ const sourceId = `${sub.reviewerId}#F${index + 1}`;
139
+ sourceFindings.push({ id: sourceId, reviewerId: sub.reviewerId, finding });
140
+ }
141
+ }
142
+ const byId = new Map(sourceFindings.map((sf) => [sf.id, sf]));
143
+ const allSourceIds = new Set(sourceFindings.map((sf) => sf.id));
144
+ let groups = [];
145
+ let matcherErrors = [];
146
+ let adjudicationUsed = false;
147
+ let aggregationRuntimeFailure = false;
148
+ if (sourceFindings.length > 0) {
149
+ try {
150
+ const match = await matcher.match(sourceFindings);
151
+ groups = match.groups;
152
+ matcherErrors = [...(match.errors ?? [])];
153
+ adjudicationUsed = match.adjudicationUsed;
154
+ }
155
+ catch (error) {
156
+ aggregationRuntimeFailure = true;
157
+ matcherErrors = [`matcher runtime failure: ${error.message}`];
158
+ groups = [];
159
+ }
160
+ }
161
+ // Provenance invariant: every source finding must appear exactly once and no
162
+ // unknown id may be accepted.
163
+ const covered = new Set();
164
+ const membershipCount = new Map();
165
+ for (const group of groups) {
166
+ for (const id of group) {
167
+ covered.add(id);
168
+ membershipCount.set(id, (membershipCount.get(id) ?? 0) + 1);
169
+ }
170
+ }
171
+ const invented = [...covered].filter((id) => !allSourceIds.has(id));
172
+ const missing = [...allSourceIds].filter((id) => !covered.has(id));
173
+ const duplicated = [...membershipCount.entries()].filter(([, count]) => count > 1).map(([id]) => id);
174
+ if (invented.length > 0) {
175
+ matcherErrors.push(`matcher invented source finding ids: ${invented.join(", ")}`);
176
+ }
177
+ if (missing.length > 0) {
178
+ matcherErrors.push(`matcher dropped source finding ids: ${missing.join(", ")}`);
179
+ }
180
+ if (duplicated.length > 0) {
181
+ matcherErrors.push(`matcher assigned source finding ids to multiple groups: ${duplicated.join(", ")}`);
182
+ }
183
+ const aggregationSemanticFailure = matcherErrors.length > 0;
184
+ let clusters;
185
+ if (aggregationRuntimeFailure || aggregationSemanticFailure) {
186
+ // Cannot trust the clustering on any matcher failure. Fall back to one
187
+ // advisory cluster per raw source finding so no finding content is lost
188
+ // and provenance remains traceable even on the failure path.
189
+ clusters = fallbackClusters(sourceFindings);
190
+ }
191
+ else {
192
+ clusters = groups.map((group, index) => buildCluster(`C${index + 1}`, group.map((id) => byId.get(id)).filter(Boolean), threshold));
193
+ }
194
+ const confirmedClusters = clusters.filter((c) => c.confirmed);
195
+ const advisories = clusters.filter((c) => !c.confirmed);
196
+ let panelHealth;
197
+ if (anyBlocked || aggregationRuntimeFailure) {
198
+ panelHealth = "blocked";
199
+ }
200
+ else if (anyNeedsHuman || aggregationSemanticFailure) {
201
+ panelHealth = "needs_human";
202
+ }
203
+ else {
204
+ panelHealth = "healthy";
205
+ }
206
+ let status;
207
+ if (panelHealth === "blocked") {
208
+ status = "blocked";
209
+ }
210
+ else if (panelHealth === "needs_human") {
211
+ status = "needs_human";
212
+ }
213
+ else if (confirmedClusters.length > 0) {
214
+ status = "has_findings";
215
+ }
216
+ else {
217
+ status = "clean";
218
+ }
219
+ const findings = confirmedClusters.map((c) => ({
220
+ ...(c.id ? { id: c.id } : {}),
221
+ ...(c.severity ? { severity: c.severity } : {}),
222
+ ...(c.path ? { path: c.path } : {}),
223
+ summary: c.summary,
224
+ actionable: true,
225
+ }));
226
+ const successfulReviewers = reviewerOutcomes.filter((r) => r.contributed).length;
227
+ return {
228
+ verdict: verdictForStatus(status),
229
+ verdictSource: "parsed",
230
+ status,
231
+ findings,
232
+ actionableCount: findings.length,
233
+ ...(matcherErrors.length > 0 ? { parseError: matcherErrors.join("; ") } : {}),
234
+ strategy: "panel",
235
+ configuredReviewers,
236
+ successfulReviewers,
237
+ consensusPolicy: policy,
238
+ consensusThreshold: threshold,
239
+ panelHealth,
240
+ confirmedClusters,
241
+ advisories,
242
+ reviewers: reviewerOutcomes,
243
+ adjudicationUsed,
244
+ ...(matcherErrors.length > 0 ? { adjudicationErrors: matcherErrors } : {}),
245
+ };
246
+ }
247
+ //# sourceMappingURL=panel-aggregate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"panel-aggregate.js","sourceRoot":"","sources":["../src/panel-aggregate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=panel-aggregate.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"panel-aggregate.test.d.ts","sourceRoot":"","sources":["../src/panel-aggregate.test.ts"],"names":[],"mappings":""}