@adversarylabs/sdk 0.1.8 → 0.1.10

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/README.md CHANGED
@@ -135,6 +135,40 @@ app.rule("scoped", async (ctx) => {
135
135
  });
136
136
  ```
137
137
 
138
+ ### Opinion framing (`formatOpinion`)
139
+
140
+ Do not hardcode "before merging" (or similar decision language) in domain adversaries.
141
+ The runner already resolved the review posture; the SDK turns a ship decision and domain
142
+ concern into posture-aware prose:
143
+
144
+ | Posture | When | Deadline language |
145
+ | --- | --- | --- |
146
+ | `repository` | `change === null` or `scanMode: "all"` (for example `--all-files`) | before shipping |
147
+ | `change` | committed range (`scanMode: "changed"`, not worktree) | before merging |
148
+ | `worktree` | uncommitted local changes (`headRef` is `WORKTREE`) | before committing |
149
+
150
+ ```ts
151
+ import { formatOpinion } from "@adversarylabs/sdk";
152
+
153
+ ctx.review.opinion(
154
+ formatOpinion({
155
+ ship: false,
156
+ // Prefer a noun phrase. Full clauses are normalized for grammar.
157
+ concern: "direct process termination below the application boundary",
158
+ change: ctx.change,
159
+ }),
160
+ );
161
+ ```
162
+
163
+ Helpers:
164
+
165
+ - `resolveReviewPosture(change)` — map `ctx.change` to `repository` | `change` | `worktree`
166
+ - `normalizeOpinionConcern(concern)` — normalize titles/clauses for "address …" sentences
167
+ - `formatOpinion({ ship, concern?, remainingCount?, change?, posture? })` — build `{ ship, summary }`
168
+
169
+ When an adversary omits `ctx.review.opinion(...)`, the SDK synthesizes an opinion from residual
170
+ findings using the same posture rules.
171
+
138
172
  ### `app.defineRule(definition)`
139
173
 
140
174
  Registers domain-specific aggregation for a stable rule id. The SDK still owns grouping,
@@ -315,10 +349,15 @@ ctx.review.observe({
315
349
  summary: "Some comments are written as complete sentences."
316
350
  });
317
351
 
318
- ctx.review.opinion({
319
- ship: true,
320
- summary: "Comment sentence style does not block shipping."
321
- });
352
+ ctx.review.opinion(
353
+ formatOpinion({
354
+ ship: true,
355
+ concern: "comment sentence style cleanup",
356
+ change: ctx.change,
357
+ }),
358
+ );
359
+ // Or set a fully custom summary when domain voice must differ:
360
+ // ctx.review.opinion({ ship: true, summary: "Comment sentence style does not block shipping." });
322
361
 
323
362
  ctx.review.score({
324
363
  key: "production-readiness",
@@ -385,6 +424,16 @@ new TerminalRenderer().render(result);
385
424
  new JsonRenderer().render(result);
386
425
  ```
387
426
 
427
+ `TerminalRenderer` uses the same product layout as the adversary CLI text
428
+ report: header (adversary, shortened repository, files scanned) → overall
429
+ assessment → finding index → finding detail (evidence capped) → suppressed
430
+ findings (when requested) → positives → scores → observations → overall
431
+ opinion → findings footer. Active `Findings: N` counts only non-suppressed
432
+ findings; suppressed details use a separate section and footer count.
433
+ Prep/context notes (keys ending in `.analysis` or `metadata.role: "context"`)
434
+ are omitted from the Observations section. JSON output remains the full
435
+ structured result.
436
+
388
437
  Adversary implementations should not manually format review output.
389
438
 
390
439
  ### Canonical wire evidence
package/dist/index.d.ts CHANGED
@@ -140,6 +140,34 @@ export interface ReviewOpinion {
140
140
  ship?: boolean;
141
141
  summary: string;
142
142
  }
143
+ /**
144
+ * Decision context for opinion framing. Derived from the runner-resolved change
145
+ * scope so adversaries do not invent merge/commit language for whole-target audits.
146
+ *
147
+ * - `repository` — entire target (`change === null` or `scanMode: "all"`)
148
+ * - `change` — committed range (branch comparison, PR, or explicit base/head)
149
+ * - `worktree` — uncommitted local changes (`headRef` is the WORKTREE sentinel)
150
+ */
151
+ export type ReviewPosture = "repository" | "change" | "worktree";
152
+ export interface FormatOpinionOptions {
153
+ /** Whether the reviewer would accept the current target as-is enough to proceed. */
154
+ ship: boolean;
155
+ /**
156
+ * What should be fixed. Prefer a short noun phrase
157
+ * ("direct process termination below the application boundary").
158
+ * Full clauses are normalized for "address …" sentences.
159
+ */
160
+ concern?: string;
161
+ /**
162
+ * When greater than 1, use plural "remaining findings" framing and ignore
163
+ * `concern` for the primary sentence.
164
+ */
165
+ remainingCount?: number;
166
+ /** Runner-resolved change scope; used when `posture` is omitted. */
167
+ change?: ChangeContext | null;
168
+ /** Explicit posture override. */
169
+ posture?: ReviewPosture;
170
+ }
143
171
  export interface ReviewScore {
144
172
  key: string;
145
173
  label?: string;
@@ -350,7 +378,40 @@ export declare class JsonRenderer implements ReviewRenderer {
350
378
  export declare class TerminalRenderer implements ReviewRenderer {
351
379
  private readonly write;
352
380
  constructor(write?: (text: string) => void);
381
+ /**
382
+ * Product text report layout (aligned with the adversary CLI renderer):
383
+ * header → assessment → finding index → finding detail → positives →
384
+ * scores → observations → opinion → stats footer.
385
+ */
353
386
  render(result: ReviewResult): void;
354
387
  }
355
388
  export declare function normalizeChangeContext(change: RuntimeChange | null | undefined): ChangeContext | null;
389
+ /**
390
+ * Resolve the decision posture from the runner-provided change scope.
391
+ * Adversaries should prefer this (or `formatOpinion`) over hardcoding merge language.
392
+ */
393
+ export declare function resolveReviewPosture(change: ChangeContext | null | undefined): ReviewPosture;
394
+ /**
395
+ * Normalize a concern for use after "address …". Noun phrases pass through;
396
+ * full clauses become "that …" so rule titles remain grammatical.
397
+ */
398
+ export declare function normalizeOpinionConcern(concern: string): string;
399
+ /**
400
+ * Build a posture-aware review opinion from a ship decision and optional concern.
401
+ *
402
+ * Domain adversaries should pass judgment (ship + concern phrase) and let the SDK
403
+ * choose merge/commit/shipping language from the runner-resolved change scope.
404
+ *
405
+ * @example
406
+ * ```ts
407
+ * ctx.review.opinion(
408
+ * formatOpinion({
409
+ * ship: false,
410
+ * concern: "direct process termination below the application boundary",
411
+ * change: ctx.change,
412
+ * }),
413
+ * );
414
+ * ```
415
+ */
416
+ export declare function formatOpinion(options: FormatOpinionOptions): ReviewOpinion;
356
417
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -171,7 +171,8 @@ export class Adversary {
171
171
  const cache = new Map();
172
172
  const collector = createReviewCollector();
173
173
  const registry = this.ruleDefinitions.snapshot();
174
- const context = createRuleContext(repoPath, normalizeChangeContext(options.input.change), summary, cache, collector, registry);
174
+ const change = normalizeChangeContext(options.input.change);
175
+ const context = createRuleContext(repoPath, change, summary, cache, collector, registry);
175
176
  const includeSuppressed = options.includeSuppressed;
176
177
  for (const rule of this.rules) {
177
178
  log.debug(`running rule ${rule.id}`);
@@ -184,6 +185,7 @@ export class Adversary {
184
185
  collector,
185
186
  policy: cloneReviewPolicy({ ...this.reviewPolicy, ...options.review }),
186
187
  registry,
188
+ change,
187
189
  includeSuppressed,
188
190
  includeRawObservations: options.includeRawObservations,
189
191
  timing: options.includeTiming
@@ -361,16 +363,26 @@ export class JsonRenderer {
361
363
  this.write(`${JSON.stringify(toWireReviewResult(result), null, 2)}\n`);
362
364
  }
363
365
  }
366
+ /** Maximum evidence items shown per finding in text mode. JSON keeps the full list. */
367
+ const TERMINAL_MAX_EVIDENCE = 5;
364
368
  export class TerminalRenderer {
365
369
  write;
366
370
  constructor(write = (text) => process.stdout.write(text)) {
367
371
  this.write = write;
368
372
  }
373
+ /**
374
+ * Product text report layout (aligned with the adversary CLI renderer):
375
+ * header → assessment → finding index → finding detail → positives →
376
+ * scores → observations → opinion → stats footer.
377
+ */
369
378
  render(result) {
370
379
  const lines = [];
371
380
  lines.push(`Adversary: ${result.adversary.name}`);
372
381
  if (result.target.repository !== undefined) {
373
- lines.push(`Repository: ${result.target.repository}`);
382
+ lines.push(`Repository: ${shortenRepositoryPath(result.target.repository)}`);
383
+ }
384
+ if (result.target.filesScanned !== undefined) {
385
+ lines.push(`Files scanned: ${result.target.filesScanned}`);
374
386
  }
375
387
  lines.push("");
376
388
  if (result.assessment !== undefined) {
@@ -380,14 +392,35 @@ export class TerminalRenderer {
380
392
  lines.push(normalizeParagraph(result.assessment.summary), "");
381
393
  }
382
394
  }
383
- const scoreNotes = result.observations.filter(isScoreReviewNote);
384
- const additionalObservations = result.observations.filter((note) => !isScoreReviewNote(note));
385
- if (scoreNotes.length > 0) {
386
- lines.push("Scores", "");
387
- for (const note of scoreNotes) {
388
- lines.push(note.summary);
395
+ if (result.findings.length > 0) {
396
+ lines.push(`Findings (${result.findings.length})`, "");
397
+ for (const finding of result.findings) {
398
+ const sites = finding.evidence.length;
399
+ lines.push(sites > 0
400
+ ? `- [${finding.severity}] ${finding.title} (${evidenceCountLabel(sites)})`
401
+ : `- [${finding.severity}] ${finding.title}`);
402
+ }
403
+ lines.push("");
404
+ }
405
+ for (const finding of result.findings) {
406
+ appendTerminalFinding(lines, finding);
407
+ }
408
+ // Suppressed details are separate from the active findings index/total.
409
+ // The active count remains result.findings.length; suppressed details and
410
+ // the suppressed footer count are reported explicitly.
411
+ const suppressedFindings = result.suppressedFindings ?? [];
412
+ if (suppressedFindings.length > 0) {
413
+ lines.push(`Suppressed findings (${suppressedFindings.length})`, "");
414
+ for (const finding of suppressedFindings) {
415
+ const sites = finding.evidence.length;
416
+ lines.push(sites > 0
417
+ ? `- [${finding.severity}] ${finding.title} (${evidenceCountLabel(sites)})`
418
+ : `- [${finding.severity}] ${finding.title}`);
389
419
  }
390
420
  lines.push("");
421
+ for (const finding of suppressedFindings) {
422
+ appendTerminalFinding(lines, finding, "suppressed; reason unavailable");
423
+ }
391
424
  }
392
425
  if (result.positives.length > 0) {
393
426
  lines.push("Positive signals", "");
@@ -396,56 +429,98 @@ export class TerminalRenderer {
396
429
  }
397
430
  lines.push("");
398
431
  }
432
+ const scoreNotes = result.observations.filter(isScoreReviewNote);
433
+ const additionalObservations = reviewObservationsForTerminal(result.observations.filter((note) => !isScoreReviewNote(note)));
434
+ if (scoreNotes.length > 0) {
435
+ lines.push("Scores", "");
436
+ for (const note of scoreNotes) {
437
+ lines.push(note.summary);
438
+ }
439
+ lines.push("");
440
+ }
399
441
  if (additionalObservations.length > 0) {
400
- lines.push("Additional observations", "");
442
+ lines.push("Observations", "");
401
443
  for (const observation of additionalObservations) {
402
444
  lines.push(`- ${normalizeParagraph(observation.summary)}`);
403
445
  }
404
446
  lines.push("");
405
447
  }
406
- const primary = result.findings[0];
407
- if (primary !== undefined) {
408
- lines.push("Primary opportunity", "");
409
- lines.push(`- ${primary.title.endsWith(".") ? primary.title : `${primary.title}.`}`, "");
410
- }
411
448
  if (result.opinion !== undefined) {
412
449
  lines.push("Overall opinion", "", normalizeParagraph(result.opinion.summary), "");
413
450
  }
414
- lines.push("Scan complete", "");
415
- if (result.target.filesScanned !== undefined) {
416
- lines.push(`Files scanned: ${result.target.filesScanned}`);
451
+ // Active findings only in the primary total; suppressed counts are separate.
452
+ lines.push(`Findings: ${result.findings.length}`);
453
+ if (result.suppressed.observations > 0) {
454
+ lines.push(`Suppressed observations: ${result.suppressed.observations}`);
417
455
  }
418
- lines.push(`Findings: ${result.findings.length}`, "");
419
- for (const finding of result.findings) {
420
- lines.push(`[${finding.severity}] ${finding.title}`);
421
- const firstEvidence = finding.evidence.find((item) => item.location?.file !== undefined);
422
- if (firstEvidence?.location?.file !== undefined) {
423
- lines.push(formatEvidenceLocation(firstEvidence));
424
- }
425
- lines.push("");
426
- lines.push(`Category: ${finding.category}`);
427
- lines.push(`Confidence: ${finding.confidence}`, "");
428
- lines.push("Summary", "", finding.summary, "");
429
- if (finding.whyItMatters !== undefined) {
430
- lines.push("Why it matters", "", finding.whyItMatters, "");
431
- }
432
- if (finding.impact !== undefined) {
433
- lines.push("Impact", "", finding.impact, "");
434
- }
435
- if (finding.evidence.length > 0) {
436
- lines.push("Evidence", "");
437
- for (const evidence of finding.evidence) {
438
- lines.push(...formatEvidenceLines(evidence));
439
- }
440
- lines.push("");
441
- }
442
- if (finding.recommendation !== undefined) {
443
- lines.push("Recommendation", "", normalizeParagraph(finding.recommendation), "");
444
- }
456
+ const suppressedFindingCount = Math.max(result.suppressed.findings, suppressedFindings.length);
457
+ if (suppressedFindingCount > 0) {
458
+ lines.push(`Suppressed findings: ${suppressedFindingCount}`);
445
459
  }
446
460
  this.write(`${lines.join("\n").trimEnd()}\n`);
447
461
  }
448
462
  }
463
+ function appendTerminalFinding(lines, finding, qualifier) {
464
+ const label = qualifier === undefined ? finding.severity : `${finding.severity}; ${qualifier}`;
465
+ lines.push(`[${label}] ${finding.title}`);
466
+ const firstEvidence = finding.evidence.find((item) => item.location?.file !== undefined);
467
+ if (firstEvidence?.location?.file !== undefined) {
468
+ lines.push(formatEvidenceLocation(firstEvidence));
469
+ }
470
+ lines.push("");
471
+ lines.push(`Category: ${finding.category}`);
472
+ lines.push(`Confidence: ${finding.confidence}`, "");
473
+ lines.push("Summary", "", finding.summary, "");
474
+ if (finding.whyItMatters !== undefined) {
475
+ lines.push("Why it matters", "", finding.whyItMatters, "");
476
+ }
477
+ if (finding.impact !== undefined) {
478
+ lines.push("Impact", "", finding.impact, "");
479
+ }
480
+ if (finding.evidence.length > 0) {
481
+ lines.push("Evidence", "");
482
+ const shown = finding.evidence.slice(0, TERMINAL_MAX_EVIDENCE);
483
+ const remaining = finding.evidence.length - shown.length;
484
+ for (const evidence of shown) {
485
+ lines.push(...formatEvidenceLines(evidence));
486
+ }
487
+ if (remaining > 0) {
488
+ lines.push(`- … and ${remaining} more`);
489
+ }
490
+ lines.push("");
491
+ }
492
+ if (finding.recommendation !== undefined) {
493
+ lines.push("Recommendation", "", normalizeParagraph(finding.recommendation), "");
494
+ }
495
+ }
496
+ function reviewObservationsForTerminal(notes) {
497
+ return notes.filter((note) => !isContextObservation(note));
498
+ }
499
+ function isContextObservation(note) {
500
+ // Prefer explicit markers only. Free-text heuristics like "Prepared … file"
501
+ // drop legitimate review notes (e.g. "Prepared migration file has syntax errors").
502
+ const key = note.key.trim().toLowerCase();
503
+ if (key.endsWith(".analysis") || key === "analysis") {
504
+ return true;
505
+ }
506
+ const role = note.metadata?.role;
507
+ return typeof role === "string" && role.toLowerCase() === "context";
508
+ }
509
+ function shortenRepositoryPath(path) {
510
+ const trimmed = path.trim();
511
+ if (trimmed.length === 0) {
512
+ return trimmed;
513
+ }
514
+ const normalized = trimmed.replaceAll("\\", "/");
515
+ const segments = normalized.split("/").filter((part) => part.length > 0);
516
+ if (segments.length <= 2) {
517
+ return trimmed;
518
+ }
519
+ return `${segments[segments.length - 2]}/${segments[segments.length - 1]}`;
520
+ }
521
+ function evidenceCountLabel(n) {
522
+ return n === 1 ? "1 site" : `${n} sites`;
523
+ }
449
524
  export function normalizeChangeContext(change) {
450
525
  if (change === undefined || change === null) {
451
526
  return null;
@@ -601,7 +676,7 @@ function buildReviewResult(input) {
601
676
  positives,
602
677
  observations: reviewObservations,
603
678
  findings: eligible,
604
- opinion: input.collector.opinion ?? synthesizeOpinion(eligible),
679
+ opinion: input.collector.opinion ?? synthesizeOpinion(eligible, input.change ?? null),
605
680
  suppressed: {
606
681
  observations: synthesis.suppressedObservations,
607
682
  findings: suppressedFindings.length,
@@ -843,7 +918,10 @@ function assessmentConcern(finding) {
843
918
  return concernClause(lowercaseFirst(trimTrailingSentencePunctuation(summary ?? findingConcern(finding))));
844
919
  }
845
920
  function concernClause(concern) {
846
- const isClause = /\b(?:allows|are|builds|can|contains|copies|could|did|do|does|exposes|has|have|includes|installs|is|lacks|may|might|must|reads|references|relies|requires|runs|uses|was|were|writes)\b/i.test(concern);
921
+ // Finite verbs with a following complement/object. Requiring a trailing token
922
+ // keeps noun phrases such as "memory leaks", "stale reads", and "concurrent
923
+ // writes" from being rewritten as broken "that the …" clauses.
924
+ const isClause = /\b(?:allows|are|binds|blocks|builds|bypasses|calls|can|closes|contains|copies|could|creates|detaches|did|discards|do|does|exits|exposes|fails|forks|has|have|ignores|includes|installs|is|kills|lacks|leaks|leaves|logs|maps|may|might|must|opens|panics|prints|reads|references|relies|replaces|requires|returns|runs|skips|spawns|starts|terminates|throws|uses|was|were|writes)\b\s+\S+/i.test(concern);
847
925
  if (!isClause) {
848
926
  return concern;
849
927
  }
@@ -853,28 +931,151 @@ function concernClause(concern) {
853
931
  function joinSentences(...sentences) {
854
932
  return sentences.filter(isNonEmptyString).join(" ");
855
933
  }
856
- function synthesizeOpinion(findings) {
857
- if (findings.length === 0) {
934
+ /**
935
+ * Resolve the decision posture from the runner-provided change scope.
936
+ * Adversaries should prefer this (or `formatOpinion`) over hardcoding merge language.
937
+ */
938
+ export function resolveReviewPosture(change) {
939
+ if (change === null || change === undefined || change.scanMode === "all") {
940
+ return "repository";
941
+ }
942
+ if (change.worktree) {
943
+ return "worktree";
944
+ }
945
+ return "change";
946
+ }
947
+ /**
948
+ * Normalize a concern for use after "address …". Noun phrases pass through;
949
+ * full clauses become "that …" so rule titles remain grammatical.
950
+ */
951
+ export function normalizeOpinionConcern(concern) {
952
+ const normalized = lowercaseFirst(trimTrailingSentencePunctuation(normalizeParagraph(concern)));
953
+ if (!isNonEmptyString(normalized)) {
954
+ throw new Error("opinion concern must be a non-empty string.");
955
+ }
956
+ return concernClause(normalized);
957
+ }
958
+ /**
959
+ * Build a posture-aware review opinion from a ship decision and optional concern.
960
+ *
961
+ * Domain adversaries should pass judgment (ship + concern phrase) and let the SDK
962
+ * choose merge/commit/shipping language from the runner-resolved change scope.
963
+ *
964
+ * @example
965
+ * ```ts
966
+ * ctx.review.opinion(
967
+ * formatOpinion({
968
+ * ship: false,
969
+ * concern: "direct process termination below the application boundary",
970
+ * change: ctx.change,
971
+ * }),
972
+ * );
973
+ * ```
974
+ */
975
+ export function formatOpinion(options) {
976
+ if (typeof options.ship !== "boolean") {
977
+ throw new Error("formatOpinion requires a boolean ship decision.");
978
+ }
979
+ const posture = options.posture === undefined
980
+ ? resolveReviewPosture(options.change ?? null)
981
+ : parseReviewPosture(options.posture, "formatOpinion posture");
982
+ const deadline = opinionDeadline(posture);
983
+ const remainingCount = options.remainingCount ?? 0;
984
+ if (remainingCount > 1) {
985
+ return {
986
+ ship: options.ship,
987
+ summary: `I would address the remaining findings ${deadline}.`,
988
+ };
989
+ }
990
+ const concern = options.concern === undefined || options.concern.trim() === ""
991
+ ? undefined
992
+ : normalizeOpinionConcern(options.concern);
993
+ if (options.ship) {
994
+ if (concern === undefined) {
995
+ return { ship: true, summary: opinionApproveAsIs(posture) };
996
+ }
858
997
  return {
859
998
  ship: true,
860
- summary: "I would ship this as-is.",
999
+ summary: opinionApproveWithFollowUp(posture, concern),
861
1000
  };
862
1001
  }
1002
+ if (concern === undefined) {
1003
+ return {
1004
+ ship: false,
1005
+ summary: `I would address the remaining findings ${deadline}.`,
1006
+ };
1007
+ }
1008
+ return {
1009
+ ship: false,
1010
+ summary: `I would address ${concern} ${deadline}.`,
1011
+ };
1012
+ }
1013
+ function parseReviewPosture(value, label) {
1014
+ if (value === "repository" || value === "change" || value === "worktree") {
1015
+ return value;
1016
+ }
1017
+ throw new Error(`${label} must be one of repository, change, or worktree.`);
1018
+ }
1019
+ function opinionDeadline(posture) {
1020
+ switch (posture) {
1021
+ case "worktree":
1022
+ return "before committing";
1023
+ case "change":
1024
+ return "before merging";
1025
+ case "repository":
1026
+ return "before shipping";
1027
+ default: {
1028
+ const _exhaustive = posture;
1029
+ throw new Error(`unsupported review posture: ${String(_exhaustive)}`);
1030
+ }
1031
+ }
1032
+ }
1033
+ function opinionApproveAsIs(posture) {
1034
+ switch (posture) {
1035
+ case "worktree":
1036
+ return "I would land these local changes as-is.";
1037
+ case "change":
1038
+ return "I would merge this change as-is.";
1039
+ case "repository":
1040
+ return "I would ship this as-is.";
1041
+ default: {
1042
+ const _exhaustive = posture;
1043
+ throw new Error(`unsupported review posture: ${String(_exhaustive)}`);
1044
+ }
1045
+ }
1046
+ }
1047
+ function opinionApproveWithFollowUp(posture, concern) {
1048
+ switch (posture) {
1049
+ case "worktree":
1050
+ return `I would land these local changes and address ${concern} as follow-up hardening.`;
1051
+ case "change":
1052
+ return `I would merge this change and address ${concern} as follow-up hardening.`;
1053
+ case "repository":
1054
+ return `I would ship this as-is. Addressing ${concern} is the only improvement I would recommend before shipping.`;
1055
+ default: {
1056
+ const _exhaustive = posture;
1057
+ throw new Error(`unsupported review posture: ${String(_exhaustive)}`);
1058
+ }
1059
+ }
1060
+ }
1061
+ function synthesizeOpinion(findings, change) {
1062
+ const posture = resolveReviewPosture(change);
1063
+ const deadline = opinionDeadline(posture);
1064
+ if (findings.length === 0) {
1065
+ return formatOpinion({ ship: true, posture });
1066
+ }
863
1067
  const highestSeverity = highestFindingSeverity(findings);
864
1068
  const ship = severityWeight(highestSeverity) < severityWeight(Severity.High);
865
1069
  if (findings.length > 1) {
866
- return {
867
- ship,
868
- summary: "I would address the remaining findings before production.",
869
- };
1070
+ return formatOpinion({ ship, remainingCount: findings.length, posture });
870
1071
  }
871
1072
  const finding = findings[0];
872
1073
  const improvement = finding === undefined ? "Addressing the finding" : improvementPhrase(finding);
873
1074
  return {
874
1075
  ship,
875
1076
  summary: ship
876
- ? `I would ship this as-is. ${improvement} is the only improvement I would recommend before production.`
877
- : `${improvement} is the most important improvement to address before production.`,
1077
+ ? `${opinionApproveAsIs(posture)} ${improvement} is the only improvement I would recommend ${deadline}.`
1078
+ : `${improvement} is the most important improvement to address ${deadline}.`,
878
1079
  };
879
1080
  }
880
1081
  function deduplicateScores(scores) {