@jphutchins/code-review 0.1.0-alpha.61 → 0.1.0-alpha.62

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.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/util.ts","../src/schema.ts","../src/cost.ts","../src/patch.ts","../src/surface.ts","../src/comment-chain.ts","../src/transcript.ts","../src/answered.ts","../src/render.ts","../src/diff.ts","../src/inline.ts","../src/validate.ts","../src/stop-gate.ts","../src/budget.ts","../src/format.ts","../src/notice.ts","../src/registry.ts","../src/exec.ts","../src/gh.ts","../src/artifact.ts","../src/pr.ts","../src/checkrun.ts","../src/post.ts","../src/command.ts","../src/react.ts","../src/ci.ts","../src/gather.ts","../src/extract.ts","../src/adapt.ts","../src/settings.ts","../src/sandbox.ts","../src/scope.ts","../src/index.ts"],"names":["identity","record","key","run","t","t2","type","answeredNote","Eta","readFileSync","basename","join","dirname","resolvePath","resolve","execFile","findings","stampedFindings","reviewUrl","unanchoredCount","t3","t4","t5","t6","writeFileSync","scanLine","t7","output"],"mappings":"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","file":"index.js","sourcesContent":["import { readFileSync } from \"node:fs\";\n\nexport const asRecord = (u: unknown): Record<string, unknown> | null =>\n typeof u === \"object\" && u !== null && !Array.isArray(u) ? (u as Record<string, unknown>) : null;\n\nexport const errMsg = (e: unknown): string => (e instanceof Error ? e.message : String(e));\n\n// A GitHub Actions workflow command (`::warning::…`) is single-line: a CR/LF in the message ends the\n// annotation early, and a following `::…::` in the remainder would be parsed as another command.\n// Collapse line breaks so an untrusted interpolation (e.g. `gh` stderr) can't break out of one.\nexport const annotationSafe = (msg: string): string => msg.replaceAll(/[\\r\\n]+/g, \" \");\n\n// A caller declares a model's real context window to the agent CLI by suffixing the id it configures\n// (`deepseek-v4-pro[1m]`). The CLI strips that before the request and it is absent from the price\n// map, so it is a directive rather than part of the model's identity — but the CLI does key its own\n// usage telemetry by the configured id. Every ingress that reads a model id from the agent\n// canonicalizes it here: carried through, it misses the price map, prices the run at $0, and voids\n// the spend clamp that steers off those same entries.\nexport const modelIdentity = (configuredModelId: string): string =>\n configuredModelId.replace(/\\[[12]m\\]$/i, \"\");\n\nexport type ParseResult = { readonly ok: true; readonly value: unknown } | { readonly ok: false };\n\n// Clip a body to `max` chars without splitting a code point (a lone high surrogate at the cut is\n// dropped so the kept prefix stays well-formed UTF-16). Shared by gather's conversation bodies and\n// the answered-registry reply excerpts.\nexport const clipText = (body: string, max: number): string => {\n if (body.length <= max) return body;\n const cut = body.slice(0, max);\n const safe = /[\\uD800-\\uDBFF]$/.test(cut) ? cut.slice(0, -1) : cut;\n return `${safe}\\n… [truncated]`;\n};\n\n// The shared clip cap for bodies that travel whole: gather clips each conversation body to it, and\n// render clips each carried suppressed-nit field to it. One constant so the two caps cannot drift\n// (the carried clip must match the conversation clip the seeded agent already saw, issue #217\n// review r7).\nexport const BODY_CLIP_CHARS = 4000;\n\nexport const tryParseJson = (text: string): ParseResult => {\n try {\n return { ok: true, value: JSON.parse(text) as unknown };\n } catch {\n return { ok: false };\n }\n};\n\nexport const readFileOrNull = (path: string): string | null => {\n try {\n return readFileSync(path, \"utf-8\");\n } catch {\n return null;\n }\n};\n","// These codecs ARE the source of truth for the data shapes (types via t.TypeOf<>); no hand-written\n// DTO types exist elsewhere — import types from here.\n\nimport * as t from \"io-ts\";\nimport { createHash } from \"node:crypto\";\n\nconst SeverityCodec = t.union([\n t.literal(\"critical\"),\n t.literal(\"major\"),\n t.literal(\"minor\"),\n t.literal(\"nit\"),\n]);\n\nconst SideCodec = t.union([t.literal(\"RIGHT\"), t.literal(\"LEFT\")]);\n\nconst VerdictCodec = t.union([\n t.literal(\"approve\"),\n t.literal(\"comment\"),\n t.literal(\"changes\"),\n t.literal(\"error\"),\n]);\n\nconst LineNumber = t.refinement(\n t.number,\n (n): n is number => Number.isInteger(n) && n >= 1,\n \"LineNumber\",\n);\n\nconst Confidence = t.refinement(t.number, (n): n is number => n >= 0 && n <= 1, \"Confidence\");\nconst Likelihood = t.refinement(t.number, (n): n is number => n >= 0 && n <= 1, \"Likelihood\");\n\n// A convergence score/threshold must be FINITE: io-ts's t.number accepts Infinity/NaN (JSON.parse(\"1e400\")\n// yields Infinity), which JSON.stringify then coerces to null — silently dropping the carried convergence\n// on the next hop. parseSurfaceSignal guards the same vector; the convergence codec must too.\nconst FiniteNumber = t.refinement(t.number, (n): n is number => Number.isFinite(n), \"FiniteNumber\");\n\n// A non-negative price (USD per 1M tokens). Mirrors prices.schema.json's `minimum: 0` so the codec\n// gate rejects a negative rate exactly as the ajv gate does — else a negative price prices negative cost.\nconst NonNegativePrice = t.refinement(t.number, (n): n is number => n >= 0, \"NonNegativePrice\");\n\n// Mirrors findings.schema.json's schema_version.pattern exactly, so resolve() never accepts a value\n// the ajv gate would reject (e.g. a truncated \"0.2\" or an over-long \"0.2.0.0\").\nconst SEMVER_SUFFIX =\n \"(?:-[0-9A-Za-z-]+(?:\\\\.[0-9A-Za-z-]+)*)?(?:\\\\+[0-9A-Za-z-]+(?:\\\\.[0-9A-Za-z-]+)*)?\";\nconst SCHEMA_VERSION_RE = new RegExp(`^(0|[1-9]\\\\d*)\\\\.(\\\\d+)\\\\.(\\\\d+)${SEMVER_SUFFIX}$`);\n\n// The enforcement copy printableSchema injects: the general pattern narrowed to the in-force minor,\n// admitting exactly the stamps (patch, prerelease, build) the registry dispatches to the live entry.\nexport const anchoredSchemaVersionPattern = (version: string): string =>\n `^${version.split(\".\").slice(0, 2).join(\"\\\\.\")}\\\\.[0-9]+${SEMVER_SUFFIX}$`;\n\nconst SchemaVersion = t.refinement(\n t.string,\n (s): s is string => SCHEMA_VERSION_RE.test(s),\n \"SchemaVersion\",\n);\n\n// Mirrors ajv-formats' `uri` format (an absolute, RFC 3986 URI) so the codec gate and the ajv gate\n// agree on code_url — the extraction ladder runs both gates, and post's decode-only path must not\n// accept what ajv rejects. Verified against ajv-formats over the URI corpus; the whitespace check\n// closes the one divergence (URL() auto-encodes raw spaces that a URI cannot contain).\nconst UriString = t.refinement(\n t.string,\n (s): s is string => !/\\s/.test(s) && URL.canParse(s),\n \"UriString\",\n);\n\n// The ONE strict+exact discipline shared by every strict-keyed codec in this file: the ajv gate\n// rejects unknown keys (additionalProperties: false), while t.exact strips them SILENTLY on both\n// encode and decode — so without the refinement the codec gate would accept-and-drop exactly what\n// the ajv gate rejects. The refinement makes the codec gate reject instead, with the key set derived\n// from the passed members. `members` MUST be exactly the shape's prop-bearing leaves (each shape's\n// own component codecs): an omitted leaf would silently reject that leaf's fields on every decode —\n// the key set cannot drift only if the list cannot.\nconst strictExact = <C extends t.HasProps>(\n name: string,\n shape: C,\n members: readonly { props: t.Props }[],\n): t.ExactC<t.RefinementC<C>> => {\n const keys = new Set(members.flatMap((m) => Object.keys(m.props)));\n return t.exact(\n t.refinement(shape, (x): x is t.TypeOf<C> => Object.keys(x).every((k) => keys.has(k)), name),\n );\n};\n\n// The stable mechanism identifier pair, shared by findings and systemic problems so the two shapes\n// can never diverge on it. The `id` itself is REQUIRED on a finding (trackability across rounds and\n// discussions); the optional half of the pair is the URL documenting the rule it names.\nconst RuleUrlCodec = t.partial({\n code_url: UriString,\n});\n\n// The finding's REQUIRED fields minus its identity, shared by BOTH suites: the 0.10 shape adds\n// `id` required (FindingIdRequired), the legacy shape adds the tolerant LegacyRuleCodec instead.\nconst FindingCoreRequired = t.type({\n path: t.string,\n start_line: LineNumber,\n end_line: LineNumber,\n severity: SeverityCodec,\n title: t.string,\n description: t.string,\n reasoning: t.string,\n confidence: Confidence,\n likelihood: Likelihood,\n});\n\nconst FindingIdRequired = t.type({ id: t.string });\n\nconst FindingOptional = t.partial({\n side: SideCodec,\n recommendation: t.string,\n patch: t.string,\n});\n\n// ONE line-anchor gate shared by BOTH finding shapes — they differ only in their identity field.\n// Applied as a WRAPPER refinement around each shape (not an intersection member), so an inner shape\n// failure short-circuits with the outer context (`0.findings.0`) — an intersection member would fail\n// under a bare numeric index and dump the whole finding into the stop-gate message the next-round\n// agent reads.\nconst EndGeStart = <C extends t.HasProps>(shape: C): t.RefinementC<C> =>\n t.refinement(shape, (f): f is t.TypeOf<C> => f.end_line >= f.start_line, \"EndGeStart\");\n\n// Strict-key refinement (see strictExact): t.exact would silently strip unknown keys, so the\n// codec gate must reject exactly what ajv rejects instead of accepting-and-dropping — a removed\n// `code` key must not pass one gate and fail the other.\nconst FindingShape = t.intersection([\n FindingCoreRequired,\n FindingIdRequired,\n RuleUrlCodec,\n FindingOptional,\n]);\n\nexport const FindingCodec = strictExact(\"FindingStrict\", EndGeStart(FindingShape), [\n FindingCoreRequired,\n FindingIdRequired,\n RuleUrlCodec,\n FindingOptional,\n]);\n\n// Cross-cutting observations that tie findings together, with no required line anchor — mirrors\n// findings.schema.json's systemic_problems items exactly, reusing the shared rule-identifier pair.\n// severity/reasoning/confidence are required (owner direction on #134).\nconst SystemicRequired = t.type({\n title: t.string,\n description: t.string,\n severity: SeverityCodec,\n reasoning: t.string,\n confidence: Confidence,\n likelihood: Likelihood,\n});\n\nconst SystemicOptional = t.partial({\n id: t.string,\n finding_ids: t.array(t.string),\n paths: t.array(t.string),\n});\n\nconst SystemicProblemShape = t.intersection([SystemicRequired, RuleUrlCodec, SystemicOptional]);\n\n// The schema declares additionalProperties: false; strictExact makes the codec gate reject exactly\n// what the ajv gate rejects instead of silently stripping (the extraction ladder runs both gates).\nexport const SystemicProblemCodec = strictExact(\"SystemicProblemStrict\", SystemicProblemShape, [\n SystemicRequired,\n RuleUrlCodec,\n SystemicOptional,\n]);\n\n// Shared by BOTH suites' recurring items (issue #150): the 0.10 shape requires `id`, the legacy\n// shape swaps it for the tolerant code/id pair.\nconst ConsecutiveRounds = t.refinement(\n t.number,\n (n): n is number => Number.isSafeInteger(n) && n >= 1,\n \"ConsecutiveRounds\",\n);\nconst StartRound = t.refinement(\n t.number,\n (n): n is number => Number.isSafeInteger(n) && n >= 1,\n \"StartRound\",\n);\n\nconst RecurringShape = t.type({\n id: t.string,\n consecutive_rounds: ConsecutiveRounds,\n start_round: StartRound,\n});\n\n// The schema declares additionalProperties: false on recurring items; strictExact makes the codec\n// gate reject exactly what the ajv gate rejects instead of silently stripping (a seed-echoing draft\n// smuggling an extra key into a recurring item must not pass one gate and fail the other).\nconst RecurringCodec = strictExact(\"RecurringStrict\", RecurringShape, [RecurringShape]);\n\n// The scope-metastasis entry (issue #150): per-code consecutive-round recurrence counts plus the\n// decision prompt, computed from the rounds history. The agent never writes it — the re-review seed\n// re-derives it from the carried convergence trajectory and delivers it to the next-round agent — but\n// the draft schema tolerates it so a seed-echoing agent's draft still validates.\nconst ScopeMetastasisShape = t.type({\n decision_prompt: t.string,\n recurring: t.array(RecurringCodec),\n});\n\nexport const ScopeMetastasisCodec = strictExact(\"ScopeMetastasisStrict\", ScopeMetastasisShape, [\n ScopeMetastasisShape,\n]);\n\n// One round's trajectory entry (issue #174): the round number and its convergence score, plus the\n// mechanism-frequency map and reviewed head SHA the recurrence signals read. Prior rounds are carried\n// verbatim, so a threshold change never rewrites a past score.\nconst RoundNumber = t.refinement(\n t.number,\n (n): n is number => Number.isSafeInteger(n) && n >= 1,\n \"RoundNumber\",\n);\n\n// t.record decodes by plain assignment into a fresh object, and assigning a number to `__proto__`\n// hits the inherited accessor and silently no-ops — a reviewer-supplied `__proto__` id (which every\n// writer-side map preserves via Object.fromEntries) would vanish on the round-trip. The custom codec\n// rebuilds the map with Object.fromEntries, so the decode preserves exactly the keys the writer wrote.\n// Values: negative counts are REJECTED (the ajv gates carry minimum: 0, and the codec gate mirrors\n// them), while a 0-valued entry is DROPPED — 0 means \"no findings this round\" and every round reader\n// treats it as absence, so the decode and the readers agree without rejecting the whole document.\nconst idFrequencyCodec = (\n name: string,\n): t.Type<Readonly<Record<string, number>>, Readonly<Record<string, number>>> =>\n new t.Type<Readonly<Record<string, number>>, Readonly<Record<string, number>>>(\n name,\n (u): u is Readonly<Record<string, number>> =>\n typeof u === \"object\" && u !== null && !Array.isArray(u),\n (u, c) => {\n if (typeof u !== \"object\" || u === null || Array.isArray(u)) return t.failure(u, c);\n const entries: [string, number][] = [];\n for (const [k, v] of Object.entries(u as Record<string, unknown>)) {\n if (typeof v !== \"number\" || !Number.isSafeInteger(v) || v < 0) return t.failure(v, c);\n if (v === 0) continue;\n entries.push([k, v]);\n }\n return t.success(Object.fromEntries(entries));\n },\n (a) => a,\n );\n\nconst IdFrequency = idFrequencyCodec(\"IdFrequency\");\n\nconst ConvergenceRoundRequired = t.type({ round: RoundNumber });\nconst ConvergenceRoundOptional = t.partial({\n score: FiniteNumber,\n ids: IdFrequency,\n sha: t.string,\n});\nconst ConvergenceRoundShape = t.intersection([ConvergenceRoundRequired, ConvergenceRoundOptional]);\n\nexport const ConvergenceRoundCodec = strictExact(\"ConvergenceRoundStrict\", ConvergenceRoundShape, [\n ConvergenceRoundRequired,\n ConvergenceRoundOptional,\n]);\n\n// The convergence signal (issue #174): the current round's score, the threshold it is judged against,\n// whether it converged, and the per-round trajectory. Pipeline-stamped like scope_metastasis — the\n// agent never writes it; the pipeline computes the score deterministically from the findings and stamps\n// it so the JSON document is the sole source of the convergence data a decoding agent reads, no\n// side-channel marker. score AND threshold are both carried so the number is interpretable on its own.\nconst ConvergenceCoreShape = t.type({\n score: FiniteNumber,\n threshold: FiniteNumber,\n converged: t.boolean,\n});\n\nconst ConvergenceOptional = t.partial({ rounds: t.array(ConvergenceRoundCodec) });\nconst ConvergenceShape = t.intersection([ConvergenceCoreShape, ConvergenceOptional]);\n\nexport const ConvergenceCodec = strictExact(\"ConvergenceStrict\", ConvergenceShape, [\n ConvergenceCoreShape,\n ConvergenceOptional,\n]);\n\n// The change-size breakdown (issue #182): per-role added/removed line counts. UNLIKE\n// convergence/scope_metastasis (pipeline-stamped), this IS the agent's own judgment — a LOW-effort\n// path bucketing of the diff into code / tests / docs (a tests dir / *.test.* is tests, *.md / docs/\n// is docs, everything else is code; no file introspection). All roles optional and best-effort; an\n// absent role renders nothing. The deterministic cloc table beside it is pipeline-seeded, not here.\nconst LineDelta = t.refinement(\n t.number,\n (n): n is number => Number.isInteger(n) && n >= 0,\n \"LineDelta\",\n);\nconst ChangeLinesCodec = t.exact(t.type({ added: LineDelta, removed: LineDelta }));\nexport const ChangeSizeCodec = t.exact(\n t.partial({ code: ChangeLinesCodec, tests: ChangeLinesCodec, docs: ChangeLinesCodec }),\n);\n\nexport const FindingsCodec = t.exact(\n t.intersection([\n t.type({\n schema_version: SchemaVersion,\n summary: t.string,\n verdict: VerdictCodec,\n findings: t.array(FindingCodec),\n }),\n t.partial({\n systemic_problems: t.array(SystemicProblemCodec),\n // Pipeline-stamped only (issue #150); see ScopeMetastasisCodec.\n scope_metastasis: ScopeMetastasisCodec,\n // Pipeline-stamped only (issue #174); see ConvergenceCodec.\n convergence: ConvergenceCodec,\n // Agent-written best-effort (issue #182); see ChangeSizeCodec.\n change_size: ChangeSizeCodec,\n }),\n ]),\n);\n\n// The optional document fields safe to strip to RECOVER a findings doc when the in-force schema or the\n// codec rejects it — rather than lose the whole review (post's loadFindings) or all prior seed context\n// (the seed's barePrior fallback). PIPELINE_STAMPED_FIELDS are re-derived/re-stamped after load; the\n// agent's best-effort chrome (change_size, issue #182) is dropped because it never affects the verdict.\n// ONE definition so the two recovery sites can never diverge on the key set (issue #182 review r2).\nexport const PIPELINE_STAMPED_FIELDS: ReadonlySet<string> = new Set([\n \"convergence\",\n \"scope_metastasis\",\n]);\nexport const RECOVERABLE_OPTIONAL_FIELDS: ReadonlySet<string> = new Set([\n ...PIPELINE_STAMPED_FIELDS,\n \"change_size\",\n]);\n\n// The content-derived identity a finding WITHOUT an id resolves to: deterministic across rounds (the\n// same path + title always synthesizes the same id), so a pre-id finding re-raised next round keys to\n// the same ledger entry. A systemic problem has no path; its synthesized id keys on the title alone.\nconst synthesizedId = (parts: readonly string[], prefix: string): string =>\n `${prefix}${createHash(\"sha256\").update(parts.join(\"\\u0000\")).digest(\"base64url\").slice(0, 12)}`;\n\nexport const synthesizedFindingId = (path: string, title: string): string =>\n synthesizedId([path, title], \"f-\");\n\nexport const synthesizedSystemicId = (title: string): string => synthesizedId([title], \"s-\");\n\n// Exactly the shape synthesizedFindingId emits (`f-` + 12 base64url chars) — the answered matcher's\n// title second chance applies ONLY to entries whose code was synthesized (the pre-0.10 codeless\n// pair), so a reviewer-supplied id that merely starts with `f-` can never open the fallback.\nexport const isSynthesizedFindingId = (id: string): boolean => /^f-[A-Za-z0-9_-]{12}$/.test(id);\n\n// The ONE resolution a finding's id goes through: an explicit id wins, and an empty one resolves to\n// the same synthesized id the legacy upcast derives — shared by the answered-registry builder and the\n// answered match, so the two sides can never disagree on what an empty id means.\nexport const resolveFindingId = (f: { id: string; path: string; title: string }): string =>\n f.id !== \"\" ? f.id : synthesizedFindingId(f.path, f.title);\n\n// The ONE legacy-spelling precedence for a RAW record (id → code → synthesized when a path exists):\n// shared by the legacy upcast, the answered-registry marker reader, and the below-floor nit reader,\n// so the three raw-document sites can never drift on which spelling wins. undefined only when the\n// record carries no usable spelling AND no path to synthesize from (a systemic's shape).\nexport const resolveRuleId = (rec: {\n readonly id?: string;\n readonly code?: string;\n readonly path?: string;\n readonly title: string;\n}): string | undefined =>\n rec.id !== undefined && rec.id !== \"\"\n ? rec.id\n : rec.code !== undefined && rec.code !== \"\"\n ? rec.code\n : rec.path !== undefined\n ? synthesizedFindingId(rec.path, rec.title)\n : undefined;\n\n// The ONE \"usable counts map\" predicate every round reader shares: every entry a positive safe\n// integer — a present-but-malformed/empty/all-zero map is absence, so a valid legacy `codes` map\n// sitting beside a bad `ids` takes over wherever a round's mechanism map is read (the round readers\n// and the legacy upcast both apply it, so they can never disagree on what a usable map is).\nexport const usableCountsMap = (v: unknown): Readonly<Record<string, number>> | undefined => {\n if (typeof v !== \"object\" || v === null || Array.isArray(v)) return undefined;\n const entries = Object.entries(v as Record<string, unknown>).filter(\n (e): e is [string, number] =>\n typeof e[1] === \"number\" && Number.isSafeInteger(e[1]) && e[1] > 0,\n );\n return entries.length === 0 ? undefined : Object.fromEntries(entries);\n};\n\n// The ONE dual-spelling resolution for a round's mechanism map: when BOTH spellings carry usable\n// maps, their entries MERGE — the current `ids` spelling wins every shared key (the writer stopped\n// emitting `codes`, so a stale legacy count must never displace the current one), and `codes`\n// supplies only the keys `ids` lacks, so a merely-usable `ids` cannot discard a more complete\n// legacy map's names. Shared by the legacy upcast, the surface convergence migration, and\n// parseRounds so the dual-spelling readers can never drift.\nexport const mergedCountsMaps = (\n ids: unknown,\n codes: unknown,\n): Readonly<Record<string, number>> | undefined => {\n const idsMap = usableCountsMap(ids);\n const codesMap = usableCountsMap(codes);\n if (idsMap === undefined) return codesMap;\n if (codesMap === undefined) return idsMap;\n // Object spread defines `__proto__` as an OWN data property (CreateDataProperty), the same\n // prototype-pollution invariant the idFrequencyCodec's fromEntries rebuild holds.\n return { ...codesMap, ...idsMap };\n};\n\n// The pre-0.10 shape (schema/v0.9/findings.schema.json): findings carried an OPTIONAL `code` and no\n// `id`. Decoded only as a migration input — the registry's pre-0.10 entries normalize it to the 0.10\n// shape (code → id, or the synthesized content-derived id when a finding carried none). `id` is\n// accepted too: the legacy route is tolerant-in/strict-out, so a doc that already carries one passes\n// it through untouched.\nconst LegacyRuleCodec = t.partial({\n code: t.string,\n id: t.string,\n code_url: UriString,\n});\n\nconst FindingShapeV09 = t.intersection([FindingCoreRequired, LegacyRuleCodec, FindingOptional]);\n\n// The legacy finding stays tolerant-in on KEYS — no strict-key gate, unlike its 0.10 counterpart —\n// because the legacy route's contract is tolerant-in/strict-out (normalizeV09 rewrites to the strict\n// 0.10 shape); only the end>=start anchor and the exact-strip run here.\nconst FindingCodecV09 = t.exact(EndGeStart(FindingShapeV09));\n\nconst SystemicV09Optional = t.partial({\n finding_codes: t.array(t.string),\n finding_ids: t.array(t.string),\n paths: t.array(t.string),\n});\n\nconst SystemicV09Shape = t.intersection([SystemicRequired, LegacyRuleCodec, SystemicV09Optional]);\n\nconst SystemicProblemCodecV09 = strictExact(\"SystemicV09Strict\", SystemicV09Shape, [\n SystemicRequired,\n LegacyRuleCodec,\n SystemicV09Optional,\n]);\n\n// The legacy recurring item stays tolerant-in on KEYS — like the legacy finding, no strict-key\n// gate — because the legacy route's contract is tolerant-in/strict-out (normalizeV09 rewrites the\n// items to the strict 0.10 shape, dropping a code/id-less item entirely).\nconst RecurringV09Identity = t.partial({ code: t.string, id: t.string });\nconst RecurringV09Counts = t.type({\n consecutive_rounds: ConsecutiveRounds,\n start_round: StartRound,\n});\nconst RecurringV09Shape = t.intersection([RecurringV09Identity, RecurringV09Counts]);\n\nconst ScopeMetastasisV09Shape = t.type({\n decision_prompt: t.string,\n recurring: t.array(RecurringV09Shape),\n});\n\nconst ScopeMetastasisCodecV09 = strictExact(\"ScopeMetastasisV09Strict\", ScopeMetastasisV09Shape, [\n ScopeMetastasisV09Shape,\n]);\n\nconst CodeFrequencyV09 = idFrequencyCodec(\"CodeFrequencyV09\");\n\nconst ConvergenceRoundV09Optional = t.partial({\n score: FiniteNumber,\n codes: CodeFrequencyV09,\n ids: CodeFrequencyV09,\n sha: t.string,\n});\n\nconst ConvergenceRoundV09Shape = t.intersection([\n ConvergenceRoundRequired,\n ConvergenceRoundV09Optional,\n]);\n\nconst ConvergenceRoundCodecV09 = strictExact(\n \"ConvergenceRoundV09Strict\",\n ConvergenceRoundV09Shape,\n [ConvergenceRoundRequired, ConvergenceRoundV09Optional],\n);\n\nconst ConvergenceV09Optional = t.partial({ rounds: t.array(ConvergenceRoundCodecV09) });\nconst ConvergenceV09Shape = t.intersection([ConvergenceCoreShape, ConvergenceV09Optional]);\n\nconst ConvergenceCodecV09 = strictExact(\"ConvergenceV09Strict\", ConvergenceV09Shape, [\n ConvergenceCoreShape,\n ConvergenceV09Optional,\n]);\n\nconst FindingsV09Shape = t.intersection([\n t.type({\n // Any pre-0.10 minor — the registry dispatches on major.minor before decoding, so the codec\n // accepts every legacy patch version (0.4.x through 0.9.x) through the one tolerant shape.\n // SchemaVersion keeps the F3 strictness: a patch-less \"0.4\" or over-long \"0.4.0.0\" still fails\n // the codec gate exactly as the ajv gate rejects it.\n schema_version: SchemaVersion,\n summary: t.string,\n verdict: VerdictCodec,\n findings: t.array(FindingCodecV09),\n }),\n t.partial({\n systemic_problems: t.array(SystemicProblemCodecV09),\n scope_metastasis: ScopeMetastasisCodecV09,\n convergence: ConvergenceCodecV09,\n change_size: ChangeSizeCodec,\n }),\n]);\n\nexport const FindingsCodecV09 = t.exact(FindingsV09Shape);\n\n// The registry's 0.9 upcast: a 0.9 document becomes a valid 0.10 document. `code` maps to `id`; a\n// finding (or systemic) without one gains the synthesized content-derived id, so pre-id findings\n// stay trackable across the migration boundary.\nexport const normalizeV09 = (doc: t.TypeOf<typeof FindingsCodecV09>): Findings => {\n const findings = doc.findings.map(({ code, id, ...f }) => ({\n ...f,\n id:\n resolveRuleId({ id, code, path: f.path, title: f.title }) ??\n synthesizedFindingId(f.path, f.title),\n }));\n const systemic_problems = doc.systemic_problems?.map(\n ({ code, id, finding_codes, finding_ids, ...s }) => ({\n ...s,\n id: resolveRuleId({ id, code, title: s.title }) ?? synthesizedSystemicId(s.title),\n ...(finding_ids !== undefined && finding_ids.length > 0\n ? { finding_ids }\n : finding_codes !== undefined\n ? { finding_ids: finding_codes }\n : {}),\n }),\n );\n const scope_metastasis =\n doc.scope_metastasis === undefined\n ? undefined\n : {\n decision_prompt: doc.scope_metastasis.decision_prompt,\n // A legacy recurring item carrying neither code nor id names nothing — drop it rather than\n // synthesize an id with nothing to key it on.\n recurring: doc.scope_metastasis.recurring.flatMap((r) => {\n const carried = r.id !== undefined && r.id !== \"\" ? r.id : r.code;\n return carried === undefined || carried === \"\"\n ? []\n : [\n {\n id: carried,\n consecutive_rounds: r.consecutive_rounds,\n start_round: r.start_round,\n },\n ];\n }),\n };\n const convergence =\n doc.convergence === undefined\n ? undefined\n : {\n score: doc.convergence.score,\n threshold: doc.convergence.threshold,\n converged: doc.convergence.converged,\n ...(doc.convergence.rounds !== undefined\n ? {\n rounds: doc.convergence.rounds.map((r) => {\n // mergedCountsMaps: the upcast, the surface migration, and parseRounds\n // share ONE dual-spelling resolution, so a merely-usable new spelling can never\n // discard a more complete legacy one (or diverge from the marker channel).\n const ids = mergedCountsMaps(r.ids, r.codes);\n return {\n round: r.round,\n ...(r.score !== undefined ? { score: r.score } : {}),\n ...(ids !== undefined ? { ids } : {}),\n ...(r.sha !== undefined ? { sha: r.sha } : {}),\n };\n }),\n }\n : {}),\n };\n return {\n schema_version: DEFAULT_SCHEMA_VERSION,\n summary: doc.summary,\n verdict: doc.verdict,\n findings,\n ...(systemic_problems !== undefined ? { systemic_problems } : {}),\n ...(scope_metastasis !== undefined ? { scope_metastasis } : {}),\n ...(convergence !== undefined ? { convergence } : {}),\n ...(doc.change_size !== undefined ? { change_size: doc.change_size } : {}),\n };\n};\n\nexport const TriageCodec = t.type({\n safe: t.boolean,\n reasons: t.string,\n});\n\n// Abstract, vendor-neutral result envelope (SPEC §6.1) — not any adapter's native shape.\nconst TokenCount = t.refinement(\n t.number,\n (n): n is number => Number.isInteger(n) && n >= 0,\n \"TokenCount\",\n);\n\nexport const ModelUsageEntryCodec = t.intersection([\n t.type({\n model: t.string,\n input_tokens: TokenCount,\n output_tokens: TokenCount,\n }),\n t.partial({\n cache_read_tokens: TokenCount,\n cache_write_tokens: TokenCount,\n }),\n]);\n\nexport const ResultEnvelopeCodec = t.intersection([\n t.type({\n schema_version: t.string,\n findings: FindingsCodec,\n models: t.array(ModelUsageEntryCodec),\n turns: TokenCount,\n duration_ms: TokenCount,\n }),\n t.partial({\n vendor_cost_usd: t.union([t.number, t.null]),\n route: t.string,\n effort: t.string,\n // The ISO-8601 UTC instant the run completed (stamped by `adapt` when it built this envelope, issue\n // #170). Cost recomputation prices a time-slotted model at THIS instant, so the same envelope prices\n // to the same slot deterministically wherever it is re-rendered — not at each command's wall clock.\n // Absent on a pre-#170 envelope (cost then falls back to the caller's instant).\n generated_at: t.string,\n // The run produced a notice rather than a completed review (security-gate block, agent kill, no\n // recoverable findings). An empty `findings` array alone can't say this — a genuine clean review\n // is also empty — so the render suppresses \"clean review\" and the sticky precedence guard refuses\n // to bury a completed review under it. Absent ⇒ a completed review.\n incomplete: t.boolean,\n }),\n]);\n\nconst FlatModelPricesShape = t.type({\n in: NonNegativePrice,\n out: NonNegativePrice,\n cache_read: NonNegativePrice,\n cache_write: NonNegativePrice,\n});\n\n// The prices codecs mirror the ajv gate exactly, the same two-gates-agree discipline as the rest of\n// this file's strictExact codecs (issue #170 review): a key-set refinement rejects unknown keys on\n// DECODE (ajv's additionalProperties:false) — so a hybrid entry that carries BOTH flat fields and\n// `slots` is rejected by both variants and the union never ambiguates, rather than decoding as flat\n// while being priced as slotted.\nconst FlatModelPricesCodec = strictExact(\"FlatModelPricesStrict\", FlatModelPricesShape, [\n FlatModelPricesShape,\n]);\n\n// HH:MM in UTC (00:00–23:59). The pattern string is byte-identical to prices.schema.json's slot-time\n// pattern so the codec + ajv gates cannot silently disagree (issue #170 review).\nconst UTC_HHMM_RE = /^([01][0-9]|2[0-3]):[0-5][0-9]$/;\nconst UtcHHMM = t.refinement(t.string, (s): s is string => UTC_HHMM_RE.test(s), \"UtcHHMM\");\n\n// One UTC time-of-day slot (issue #170): a [utc_from, utc_to) half-open window — wrapping past midnight\n// when utc_to <= utc_from — carrying the same per-token fields as the flat shape. cost.ts selects the\n// slot covering the run's UTC instant; a model's slots must partition the 24h day with no gap or overlap.\nconst PriceSlotAnchor = t.type({ utc_from: UtcHHMM, utc_to: UtcHHMM });\nconst PriceSlotShape = t.intersection([PriceSlotAnchor, FlatModelPricesShape]);\nconst PriceSlotCodec = strictExact(\"PriceSlotStrict\", PriceSlotShape, [\n PriceSlotAnchor,\n FlatModelPricesShape,\n]);\n\n// `slots` must be non-empty (the ajv gate's minItems: 1) — an empty array is a misconfiguration, not a\n// zero-cost model.\nconst NonEmptyPriceSlots = t.refinement(\n t.array(PriceSlotCodec),\n (a): a is t.TypeOf<typeof PriceSlotCodec>[] => a.length >= 1,\n \"NonEmptyPriceSlots\",\n);\n// `weekend_slots` overrides `slots` on Saturdays and Sundays, BEIJING time — DeepSeek bills off-peak\n// all weekend from 2026-08-23 (issue #216). Optional and additive: a map without it behaves exactly as\n// before. Two arrays rather than a weekday field on a slot, because that shape would make a\n// partition-with-a-Saturday-gap newly expressible. Each array is independently a 24h partition and the\n// existing \"exactly one covering slot\" check applies unchanged — but only to whichever array a given\n// run selects, so a broken `weekend_slots` stays quiet until a weekend run reaches it. The warning\n// names the array it consulted for that reason.\nconst SlottedRequired = t.type({ slots: NonEmptyPriceSlots });\nconst SlottedOptional = t.partial({ weekend_slots: NonEmptyPriceSlots });\nconst SlottedShape = t.intersection([SlottedRequired, SlottedOptional]);\nconst SlottedModelPricesCodec = strictExact(\"SlottedModelPricesStrict\", SlottedShape, [\n SlottedRequired,\n SlottedOptional,\n]);\n\n// A model's price is EITHER flat (one all-day rate — unchanged, fully backward-compatible) OR a set of\n// UTC time-of-day slots (issue #170), for a provider with peak/off-peak rates (DeepSeek). Both variants\n// are strict-keyed (above), so the union rejects a hybrid entry instead of silently resolving it to one.\nexport const ModelPricesCodec = t.union([FlatModelPricesCodec, SlottedModelPricesCodec]);\n\nexport const PriceMapCodec = t.type({\n _updated: t.string,\n _unit: t.string,\n models: t.record(t.string, ModelPricesCodec),\n});\n\n// Format-agnostic test summary (SPEC §5.1 item 4, REQ-CO-9) — any conforming test report shape.\nexport const TestFailureCodec = t.intersection([\n t.type({ name: t.string }),\n t.partial({ message: t.string }),\n]);\n\nexport const TestSummaryCodec = t.intersection([\n t.type({\n passed: t.number,\n failed: t.number,\n total: t.number,\n }),\n t.partial({\n failures: t.array(TestFailureCodec),\n }),\n]);\n\n// Used when an adapter's native output omits schema_version; the registry sources its findings\n// defaultVersion from this.\nexport const DEFAULT_SCHEMA_VERSION = \"0.10.0\";\n\nexport type Finding = t.TypeOf<typeof FindingCodec>;\nexport type SystemicProblem = t.TypeOf<typeof SystemicProblemCodec>;\nexport type Findings = t.TypeOf<typeof FindingsCodec>;\nexport type ScopeMetastasis = t.TypeOf<typeof ScopeMetastasisCodec>;\nexport type Convergence = t.TypeOf<typeof ConvergenceCodec>;\nexport type ChangeSize = t.TypeOf<typeof ChangeSizeCodec>;\nexport type ConvergenceRound = t.TypeOf<typeof ConvergenceRoundCodec>;\nexport type ConvergenceCore = t.TypeOf<typeof ConvergenceCoreShape>;\nexport type Verdict = t.TypeOf<typeof VerdictCodec>;\n\n// The findings shape for a run that produced no code-review verdict — an operational failure, a\n// security refusal, or an empty diff with nothing to review. `verdict: \"error\"` is the machine-readable\n// signal that the blob a consumer decodes is NOT a clean pass (verdict \"comment\", findings []), so an\n// agent following the decode-the-JSON contract cannot mistake \"no verdict was produced\" for \"nothing\n// found\". A completed review carries approve/comment/changes.\nexport const incompleteFindings = (summary: string): Findings => ({\n schema_version: DEFAULT_SCHEMA_VERSION,\n summary,\n verdict: \"error\",\n findings: [],\n});\n\n// The one predicate for \"this findings doc is a no-verdict notice, not a completed review\", shared by\n// render and the sticky-precedence guard so the rule lives in a single place. Requires an EMPTY\n// findings array: a doc that carries real findings is a real review whatever its verdict says, so a\n// spurious \"error\" verdict alongside findings can never silently suppress them.\nexport const isIncompleteFindings = (findings: Findings): boolean =>\n findings.verdict === \"error\" && findings.findings.length === 0;\nexport type Triage = t.TypeOf<typeof TriageCodec>;\nexport type Severity = t.TypeOf<typeof SeverityCodec>;\nexport type Side = t.TypeOf<typeof SideCodec>;\nexport type ModelUsageEntry = t.TypeOf<typeof ModelUsageEntryCodec>;\nexport type ResultEnvelope = t.TypeOf<typeof ResultEnvelopeCodec>;\nexport type FlatModelPrices = t.TypeOf<typeof FlatModelPricesCodec>;\nexport type PriceSlot = t.TypeOf<typeof PriceSlotCodec>;\nexport type ModelPrices = t.TypeOf<typeof ModelPricesCodec>;\nexport type PriceMap = t.TypeOf<typeof PriceMapCodec>;\nexport type TestFailure = t.TypeOf<typeof TestFailureCodec>;\nexport type TestSummary = t.TypeOf<typeof TestSummaryCodec>;\n","// Recomputes USD (the CLI's vendor_cost_usd is vendor-priced); warnings threaded via a `warn` sink.\n\nimport type {\n PriceMap,\n ModelUsageEntry,\n ModelPrices,\n FlatModelPrices,\n PriceSlot,\n} from \"./schema.js\";\n\nexport interface CostLine {\n readonly model: string;\n readonly inputTokens: number;\n readonly outputTokens: number;\n readonly cacheReadTokens: number;\n readonly cacheWriteTokens: number;\n readonly costUSD: number;\n}\n\nexport interface CostReport {\n readonly lines: readonly CostLine[];\n readonly totalInputTokens: number;\n readonly totalOutputTokens: number;\n readonly totalCacheReadTokens: number;\n readonly totalCacheWriteTokens: number;\n readonly totalCostUSD: number;\n}\n\nexport type Warn = (message: string) => void;\n\nconst defaultWarn: Warn = (message) => {\n process.stderr.write(`${message}\\n`);\n};\n\n// A parseable UTC instant from an ISO string, or undefined — so an unparseable/no-offset generated_at\n// (issue #170 review r2) falls back to the caller's instant rather than pricing at an Invalid Date.\nexport const parseInstant = (iso: string | undefined): Date | undefined => {\n if (iso === undefined) return undefined;\n // A date-TIME with no UTC designator (Z or ±offset) is parsed as LOCAL time by Date — ambiguous and\n // slot-wrong. Reject a T-bearing instant that lacks an explicit offset (adapt stamps toISOString(),\n // always Z; a date-only value is unambiguous UTC midnight and is allowed).\n if (iso.includes(\"T\") && !/(Z|[+-]\\d{2}:?\\d{2})$/.test(iso)) return undefined;\n const d = new Date(iso);\n return Number.isNaN(d.getTime()) ? undefined : d;\n};\n\nconst utcMinuteOfDay = (at: Date): number => at.getUTCHours() * 60 + at.getUTCMinutes();\n\nconst hhmmToMinutes = (hhmm: string): number => {\n const [h, m] = hhmm.split(\":\");\n return Number(h) * 60 + Number(m);\n};\n\nconst hhmmOf = (minute: number): string =>\n `${String(Math.floor(minute / 60)).padStart(2, \"0\")}:${String(minute % 60).padStart(2, \"0\")}`;\n\n// A [utc_from, utc_to) half-open UTC window contains `minute`; when utc_to <= utc_from the window wraps\n// past midnight (e.g. 22:00→02:00 covers the late night and early morning). A degenerate utc_from ==\n// utc_to therefore covers the FULL day (wrap branch), matching the schema's \"utc_to <= utc_from wraps\".\nconst slotCovers = (slot: PriceSlot, minute: number): boolean => {\n const from = hhmmToMinutes(slot.utc_from);\n const to = hhmmToMinutes(slot.utc_to);\n return from < to ? minute >= from && minute < to : minute >= from || minute < to;\n};\n\n// The flat per-token rate for a model at the run's UTC instant (issue #170): a flat entry as-is; a\n// slotted entry's covering slot. A slotted map that leaves the instant uncovered (a gap) or double-\n// covers it (an overlap) — or a slotted model priced with no instant supplied — is a misconfiguration:\n// warn LOUDLY (like the unknown-model path) and return null so cost falls back to $0 for that model,\n// never crashing and never silently mis-pricing.\n// Weekend-ness is a property of the BEIJING date, not the UTC one — the provider states the rule in\n// Beijing time (see the schema's weekend_slots description, which is the spec). Beijing keeps no\n// daylight saving, so a fixed +8 is exact rather than an approximation (issue #216).\nconst BEIJING_OFFSET_MINUTES = 8 * 60;\n\nconst isBeijingWeekend = (instant: Date): boolean => {\n const day = new Date(instant.getTime() + BEIJING_OFFSET_MINUTES * 60_000).getUTCDay();\n return day === 0 || day === 6;\n};\n\nconst resolveFlatPrices = (\n model: string,\n p: ModelPrices,\n pricedAt: Date | undefined,\n warn: Warn,\n): FlatModelPrices | null => {\n if (!(\"slots\" in p)) return p;\n if (pricedAt === undefined) {\n warn(\n `code-review cost: model \"${model}\" has time-slotted prices but no run instant was supplied to select a slot; cost for this model set to $0`,\n );\n return null;\n }\n const minute = utcMinuteOfDay(pricedAt);\n const weekendSlots = p.weekend_slots;\n const useWeekend = weekendSlots != null && isBeijingWeekend(pricedAt);\n const slots = useWeekend ? weekendSlots : p.slots;\n const covering = slots.filter((s) => slotCovers(s, minute));\n if (covering.length === 1) return covering[0] ?? null;\n warn(\n `code-review cost: model \"${model}\" — ${String(covering.length)} price slots in \\`${useWeekend ? \"weekend_slots\" : \"slots\"}\\` cover ${hhmmOf(minute)} UTC (expected exactly 1); that array must partition the 24h day with no gap or overlap; cost for this model set to $0`,\n );\n return null;\n};\n\nconst computeModelCost = (\n entry: ModelUsageEntry,\n prices: PriceMap,\n pricedAt: Date | undefined,\n warn: Warn,\n): CostLine => {\n const p = prices.models[entry.model];\n const cacheRead = entry.cache_read_tokens ?? 0;\n const cacheWrite = entry.cache_write_tokens ?? 0;\n const zero: CostLine = {\n model: entry.model,\n inputTokens: entry.input_tokens,\n outputTokens: entry.output_tokens,\n cacheReadTokens: cacheRead,\n cacheWriteTokens: cacheWrite,\n costUSD: 0,\n };\n if (!p) {\n warn(\n `code-review cost: unknown model \"${entry.model}\" — no entry in price map; cost for this model set to $0`,\n );\n return zero;\n }\n const rate = resolveFlatPrices(entry.model, p, pricedAt, warn);\n if (rate === null) return zero;\n const costUSD =\n (entry.input_tokens * rate.in +\n entry.output_tokens * rate.out +\n cacheRead * rate.cache_read +\n cacheWrite * rate.cache_write) /\n 1_000_000;\n return { ...zero, costUSD };\n};\n\nexport const computeCost = (\n models: readonly ModelUsageEntry[],\n prices: PriceMap,\n // The run's UTC instant, used to select a time-slotted model's rate (issue #170). Undefined is fine\n // for a flat price map (ignored); a slotted model priced without it degrades to $0 with a warning.\n pricedAt?: Date,\n warn: Warn = defaultWarn,\n): CostReport => {\n const lines = models.map((entry) => computeModelCost(entry, prices, pricedAt, warn));\n\n return {\n lines,\n totalInputTokens: lines.reduce((s, l) => s + l.inputTokens, 0),\n totalOutputTokens: lines.reduce((s, l) => s + l.outputTokens, 0),\n totalCacheReadTokens: lines.reduce((s, l) => s + l.cacheReadTokens, 0),\n totalCacheWriteTokens: lines.reduce((s, l) => s + l.cacheWriteTokens, 0),\n totalCostUSD: lines.reduce((s, l) => s + l.costUSD, 0),\n };\n};\n","// A review agent's own unified-diff patch is either validated against the real PR-head file (to\n// align a finding's range and confirm it still applies) or projected into a GitHub suggestion — two\n// pure functions over one shared hunk parser (SSOT). Assumes LF line endings (the review runs on\n// Linux); CRLF is out of scope.\n\nexport type ValidateResult =\n | { readonly kind: \"anchored\"; readonly startLine: number; readonly endLine: number }\n | { readonly kind: \"keep\"; readonly reason: string }\n | { readonly kind: \"drop\"; readonly reason: string };\n\nexport type SuggestionResult = string | { readonly kind: \"drop\"; readonly reason: string };\n\ntype BodyLine =\n | { readonly kind: \"context\"; readonly text: string }\n | { readonly kind: \"removed\"; readonly text: string }\n | { readonly kind: \"added\"; readonly text: string };\n\nconst HUNK_HEADER_RE = /^@@ -(\\d+)(?:,\\d+)? \\+\\d+(?:,\\d+)? @@/;\n\nconst hunkOldStart = (line: string): number | null => {\n const raw = HUNK_HEADER_RE.exec(line)?.[1];\n return raw !== undefined ? Number(raw) : null;\n};\n\nconst classifyBodyLine = (line: string): BodyLine | null => {\n if (line.startsWith(\" \")) return { kind: \"context\", text: line.slice(1) };\n if (line.startsWith(\"-\")) return { kind: \"removed\", text: line.slice(1) };\n if (line.startsWith(\"+\")) return { kind: \"added\", text: line.slice(1) };\n return null;\n};\n\nconst trimmedMiddle = (body: readonly BodyLine[]): readonly BodyLine[] => {\n const first = body.findIndex((l) => l.kind !== \"context\");\n if (first === -1) return [];\n const last = body.findLastIndex((l) => l.kind !== \"context\");\n return body.slice(first, last + 1);\n};\n\n// Zero-or-more removed then zero-or-more added, no context, no interleaving.\nconst isContiguousChange = (middle: readonly BodyLine[]): boolean => {\n if (middle.some((l) => l.kind === \"context\")) return false;\n const firstAdded = middle.findIndex((l) => l.kind === \"added\");\n if (firstAdded === -1) return true;\n return (\n middle.slice(0, firstAdded).every((l) => l.kind === \"removed\") &&\n middle.slice(firstAdded).every((l) => l.kind === \"added\")\n );\n};\n\ninterface RemovedRange {\n readonly lineNumber: number;\n readonly firstRemoved: number | null;\n readonly lastRemoved: number | null;\n}\n\n// The old-side line number advances on context and removed lines, not added ones.\nconst removedRange = (body: readonly BodyLine[], oldStart: number): RemovedRange =>\n body.reduce<RemovedRange>(\n (acc, line) =>\n line.kind === \"added\"\n ? acc\n : {\n lineNumber: acc.lineNumber + 1,\n firstRemoved:\n line.kind === \"removed\" && acc.firstRemoved === null\n ? acc.lineNumber\n : acc.firstRemoved,\n lastRemoved: line.kind === \"removed\" ? acc.lineNumber : acc.lastRemoved,\n },\n { lineNumber: oldStart, firstRemoved: null, lastRemoved: null },\n );\n\nconst drop = (reason: string): { readonly kind: \"drop\"; readonly reason: string } => ({\n kind: \"drop\",\n reason,\n});\n\nconst keep = (reason: string): { readonly kind: \"keep\"; readonly reason: string } => ({\n kind: \"keep\",\n reason,\n});\n\ntype ParsedHunk =\n | { readonly kind: \"ok\"; readonly oldStart: number; readonly body: readonly BodyLine[] }\n | { readonly kind: \"drop\"; readonly reason: string };\n\n// SSOT shared by validatePatch and patchToSuggestion; drops on != 1 hunk or a malformed body line.\nconst parseHunk = (patch: string): ParsedHunk => {\n const rawLines = patch.split(\"\\n\");\n // A trailing newline splits into a trailing \"\" element — not a line of content.\n const lines =\n rawLines.length > 0 && rawLines[rawLines.length - 1] === \"\" ? rawLines.slice(0, -1) : rawLines;\n\n const headerHits = lines.reduce<readonly { readonly index: number; readonly oldStart: number }[]>(\n (acc, line, index) => {\n const oldStart = hunkOldStart(line);\n return oldStart !== null ? [...acc, { index, oldStart }] : acc;\n },\n [],\n );\n if (headerHits.length !== 1) {\n return drop(`expected exactly one hunk, got ${String(headerHits.length)}`);\n }\n const hit = headerHits[0];\n if (hit === undefined) return drop(\"malformed hunk header\");\n\n // Header-preceding lines (diff --git/index/---/+++) are never examined; a trailing\n // \"\\" marker carries no content.\n const bodyRaw = lines.slice(hit.index + 1).filter((line) => !line.startsWith(\"\\\\\"));\n const classified = bodyRaw.map(classifyBodyLine);\n if (classified.some((line) => line === null)) return drop(\"malformed hunk body line\");\n const body = classified.filter((line): line is BodyLine => line !== null);\n\n return { kind: \"ok\", oldStart: hit.oldStart, body };\n};\n\n// fileLines are 0-indexed and WITHOUT trailing newlines. Anchors when the removed lines give a range,\n// keeps a pure insertion (no range) for the renderer's ```patch fallback, drops on a context mismatch.\nexport const validatePatch = (patch: string, fileLines: readonly string[]): ValidateResult => {\n const parsed = parseHunk(patch);\n if (parsed.kind === \"drop\") return parsed;\n const { oldStart, body } = parsed;\n\n const oldSideTexts = body.filter((l) => l.kind !== \"added\").map((l) => l.text);\n const expected = fileLines.slice(oldStart - 1, oldStart - 1 + oldSideTexts.length);\n const oldSideMatches =\n expected.length === oldSideTexts.length &&\n expected.every((line, i) => line === oldSideTexts[i]);\n if (!oldSideMatches) {\n return drop(\n `patch context does not match the file at lines ${String(oldStart)}..${String(oldStart + oldSideTexts.length - 1)}`,\n );\n }\n\n if (!isContiguousChange(trimmedMiddle(body))) {\n return drop(\"change is not a single contiguous block\");\n }\n\n const removedCount = body.filter((l) => l.kind === \"removed\").length;\n const addedCount = body.filter((l) => l.kind === \"added\").length;\n if (removedCount === 0 && addedCount === 0) return drop(\"hunk contains no changes\");\n if (removedCount === 0) {\n return keep(\"pure insertion applies cleanly but has no removed range to anchor a suggestion\");\n }\n\n const { firstRemoved, lastRemoved } = removedRange(body, oldStart);\n if (firstRemoved === null || lastRemoved === null) return drop(\"malformed hunk body\");\n\n return { kind: \"anchored\", startLine: firstRemoved, endLine: lastRemoved };\n};\n\n// The added lines alone (no file needed). An all-deletion hunk yields \"\" (delete the range); a pure\n// insertion has nothing to replace.\nexport const patchToSuggestion = (patch: string): SuggestionResult => {\n const parsed = parseHunk(patch);\n if (parsed.kind === \"drop\") return parsed;\n const { body } = parsed;\n\n if (!isContiguousChange(trimmedMiddle(body))) {\n return drop(\"change is not a single contiguous block\");\n }\n\n const removedCount = body.filter((l) => l.kind === \"removed\").length;\n const addedLines = body.filter((l) => l.kind === \"added\");\n if (removedCount === 0 && addedLines.length === 0) return drop(\"hunk contains no changes\");\n if (removedCount === 0) return drop(\"pure insertion can't be expressed as a suggestion\");\n\n return addedLines.map((l) => l.text).join(\"\\n\");\n};\n","// Single source of truth for the bits every render surface (sticky, inline comment, review body)\n// must agree on: severity→emoji, the machine-readable findings-json marker, and patch→suggestion\n// projection. Pure.\n\nimport {\n ConvergenceCodec,\n DEFAULT_SCHEMA_VERSION,\n mergedCountsMaps,\n resolveFindingId,\n resolveRuleId,\n usableCountsMap,\n} from \"./schema.js\";\nimport type {\n ChangeSize,\n Convergence,\n ConvergenceCore,\n ConvergenceRound,\n Finding,\n Findings,\n ScopeMetastasis,\n Severity,\n SystemicProblem,\n} from \"./schema.js\";\nimport type { IdCounts, IdStreak, RoundRecord, SeverityCounts } from \"./types.js\";\nimport { patchToSuggestion } from \"./patch.js\";\n\n// The recurrence signals (streaks, scope metastasis, same-root) read only a round's mechanism map,\n// head SHA, and round number — never its score or severity counts — so this structural shape lets both\n// the JSON trajectory (ConvergenceRound) and a legacy parsed rounds marker (RoundRecord) flow through\n// the same detectors without an adapter.\ntype RecurrenceRound = {\n readonly ids?: IdCounts;\n readonly sha?: string;\n readonly round?: number;\n};\n\nexport const severityEmoji = (s: string): string => {\n switch (s) {\n case \"critical\":\n return \"🔴\";\n case \"major\":\n return \"🟠\";\n case \"minor\":\n return \"🔵\";\n case \"nit\":\n return \"⚪\";\n default:\n return \"❓\";\n }\n};\n\n// The canonical location of the findings schema — the moving `main` ref (mirrors findings.schema.json's\n// own $id). No version tag is cut yet; a tagged schema pins its own $id (schema/VERSIONING.md), so a\n// decoding agent starts here and, if its document's schema_version names a different version, fetches\n// that one — the URL below is NOT version-pinned.\nconst FINDINGS_SCHEMA_URL =\n \"https://raw.githubusercontent.com/JPHutchins/code-review/main/schema/findings.schema.json\";\n\n// One constant, carried onto every surface: a rendered review, a status notice, one inline comment.\n// It says nothing about what either side CONTAINS because that varies by route, envelope and round,\n// and three rounds of review found each such claim false somewhere (issues #171, #217). Read the\n// text; do not paraphrase it here. Uses em dashes, never \"--\", so the HTML comment\n// stays well-formed. Exported so the surfaces and their tests share one SSOT for the text (it is\n// carried forward verbatim by carryForwardMarkers) — the text below is that SSOT; do not restate it\n// here.\nexport const AGENTS_STOP_DIRECTIVE = `<!-- AGENTS: STOP — this comment names a code-review findings document in the marker, and usually renders that same review as prose. Read the prose when it is there: it is the cheaper read. Fetch the document when the prose is not the review (this comment may be a status notice), when the prose is only part of it (findings anchored to diff lines, and those threads carry their own finding rather than a link — the workflow run's summary renders the review whole), or when you need a field the prose does not render — decode the marker where the comment carries it instead (an inline thread's finding, or a pre-#217 sticky). Read the document's schema_version and fetch the schema for THAT version before acting — a schema's own $id is its canonical URL, and the URL below is the current version, not a pinned one: ${FINDINGS_SCHEMA_URL} — then parse the WHOLE findings document, not only the fields you recognize. -->`;\n\n// The marker names the findings artifact; it never carries the document. The embedded base64 form is\n// still READ (parseFindingsMarker) because every sticky written before this change holds one; a\n// carried pre-#217 marker may also be re-emitted verbatim by a notice path, never freshly written:\n// the blob was ~50% of a sticky's bytes and the size branch it needed was what made an oversized\n// review silently lose its re-review seed (issue #217).\nconst encodeMarker = (jsonUrl: string): string =>\n `${AGENTS_STOP_DIRECTIVE}\\n<!-- code-review:findings-json ${jsonUrl} -->`;\n\n// Decode a base64-in-HTML-comment marker payload, shared by the findings + rounds markers; undefined\n// on any malformed input so callers degrade rather than throw on the render path.\nconst decodeBase64Json = (b64: string): unknown => {\n try {\n return JSON.parse(Buffer.from(b64, \"base64\").toString(\"utf-8\"));\n } catch {\n return undefined;\n }\n};\n\nexport const findingsPointer = (jsonUrl: string): string => encodeMarker(jsonUrl);\n\n// Per-finding counterpart, and the ONE place a payload still travels in a comment. The answered\n// registry (issue #151) identifies a thread by decoding the finding out of its root comment, and it\n// must keep working across rounds: an answer given in round 1 still closes a verbatim re-raise in\n// round 8. A link cannot do that — this round's artifact does not contain round 1's finding — so the\n// thread carries its own finding, self-contained, exactly as before. It is one finding (~1KB), not the\n// whole document, and only on the opt-in inline surface (issue #217).\n//\n// Two thresholds, one valve. The inline template re-renders the SAME fields as prose, so the comment\n// holds the payload AND roughly the payload again — past the SOFT bound the inline renderer clips\n// that prose (marked, never silent) while the marker keeps embedding the WHOLE finding, which is\n// what keeps the answered registry working (issue #233 r1 + r2). Past the HARD bound (the\n// whole-document embed's old EMBED_LIMIT) no embed fits at all, so the marker names the artifact\n// instead — and only THAT band breaks the registry, for a finding pathological enough that no\n// comment could hold it. With no URL there is nothing to name, so the embed stays the only channel.\n// Dedupes the hard-valve warning per finding identity within one process (issue #236 r3).\nconst warnedValveFindings = new Set<string>();\n\nexport const INLINE_PROSE_CLIP_THRESHOLD_CHARS = 30_000;\n// The hard valve sits below the whole-document embed's old EMBED_LIMIT: the inline body is payload\n// + directive + clipped prose, and the clipped reasoning gains a `> ` prefix per rendered line — the\n// worst RENDERED case must stay under the comment limit, not just the raw parts (issue #235).\nexport const INLINE_EMBED_LIMIT_CHARS = 38_000;\nexport const findingPayload = (finding: Finding, schemaVersion: string): string =>\n Buffer.from(\n JSON.stringify({ schema_version: schemaVersion, findings: [finding] }),\n \"utf-8\",\n ).toString(\"base64\");\n\n// The heading and the permalink render the same line range with different separators (an en dash\n// for display, \"-L\" for the URL anchor) — ONE collapse decision shared by both, so the two\n// surfaces cannot drift (issue #231 r1).\nexport const lineRange = (startLine: number, endLine: number, separator: string): string =>\n startLine === endLine ? String(startLine) : `${String(startLine)}${separator}${String(endLine)}`;\n\nexport const findingPointer = (\n finding: Finding,\n schemaVersion: string,\n jsonUrl?: string,\n): string => {\n const payload = findingPayload(finding, schemaVersion);\n if (payload.length > INLINE_EMBED_LIMIT_CHARS) {\n if (jsonUrl !== undefined) {\n return `${AGENTS_STOP_DIRECTIVE}\\n<!-- code-review:findings-json ${jsonUrl} -->`;\n }\n // No URL to name and the payload cannot fit: omit the marker entirely — the pre-#217 behavior —\n // with a loud warning naming the finding, rather than embedding a comment GitHub is guaranteed\n // to reject (the 422 aborts the inline post; issue #235). Deduped per finding identity — a\n // fan-out round hits the valve once per comment, and the log must stay readable (issue #236 r3).\n const identity = `${finding.path}:${String(finding.start_line)}`;\n if (!warnedValveFindings.has(identity)) {\n warnedValveFindings.add(identity);\n process.stderr.write(\n `::warning::the finding at ${identity} has a payload past the inline comment limit and no --json-url was supplied to name the artifact — the comment carries no findings marker\\n`,\n );\n }\n return \"\";\n }\n return `${AGENTS_STOP_DIRECTIVE}\\n<!-- code-review:findings-json;base64 ${payload} -->`;\n};\n\n// null when the marker is absent or holds the all-zeros placeholder (no head SHA was stamped),\n// so callers treat an unknown prior commit as a new-commit re-review rather than asserting a match.\nconst ZERO_SHA = \"0000000000000000000000000000000000000000\";\nexport const parseReviewedSha = (body: string): string | null => {\n const sha = /<!-- reviewed-sha: ([0-9a-fA-F]{40}) -->/.exec(body)?.[1]?.toLowerCase();\n return sha && sha !== ZERO_SHA ? sha : null;\n};\n\n// The route of the COMPLETED review that stamped the sticky (\"full review\" | \"mechanic\"; absent on\n// notices and on pre-route-marker stickies). The seed chain is route-aware on it: a CI-fix mechanic\n// pass must not seed a later full review as if it were the previous full review (issue #127).\nconst ROUTE_RE = /<!-- reviewed-route: ([^>]*) -->/;\nexport const parseReviewedRoute = (body: string): string | null => ROUTE_RE.exec(body)?.[1] || null;\n\n// Post's empty-mechanic guard predicate: \"does this sticky record a completed FULL review as its\n// last completed review?\" The route marker wins — a mechanic sticky carries a prior full review's\n// round history forward, so round history alone can't distinguish it — and round history is the\n// fallback for pre-route-marker stickies (only a completed full review ever APPENDS a round; a\n// mechanic can only carry one). With no signal at all the review is not classified as full here;\n// post adds its own completed-review fallbacks (review-complete, or the placeholder's\n// completed-ancestor marker) for the pre-rounds era. seed-draft deliberately does NOT use this\n// predicate: for seeding, a no-route prior is unknown (a pre-route mechanic that carried rounds\n// looks identical to a pre-route full review), and the false-prior direction is worse than one cold\n// review, so it requires the route marker outright.\nexport const isFullReviewSticky = (body: string): boolean => {\n const route = parseReviewedRoute(body);\n if (route === \"full review\") return true;\n if (route === \"mechanic\" || parseMechanicAncestor(body)) return false;\n // Round history means a completed full review — whether it rides the new convergence field/marker or a\n // legacy rounds marker (issue #185 review). A post-#174 notice carries its trajectory in the\n // document's convergence or the compact marker, and this predicate gates the empty-mechanic guard\n // that must not bury that completed review.\n return priorTrajectory(parseFindingsMarker(body), body).length > 0;\n};\n\n// Carried by a body that replaces a MECHANIC sticky: a notice over a mechanic-origin prior must\n// not stamp the reviewed-route marker (its contract is the COMPLETED review's route, and a\n// stamped route would make the next round read the notice as a completed full review) — the\n// mechanic provenance rides this dedicated ancestry marker instead.\nexport const MECHANIC_ANCESTOR_MARKER = \"<!-- review-mechanic-ancestor -->\";\n// Anchored to a standalone comment LINE: the sticky body embeds reviewer prose and patch fences,\n// and a finding quoting this literal must not gate the next round as mechanic ancestry.\nexport const parseMechanicAncestor = (body: string): boolean =>\n new RegExp(`(^|\\n)${MECHANIC_ANCESTOR_MARKER}(\\n|$)`).test(body);\n\n// Carried by the announce placeholder when the sticky it replaced was a COMPLETED review: the\n// placeholder strips review-complete (it must not read as a finished review of the new head), yet\n// the empty-mechanic guard needs to know the placeholder descends from a completed review to\n// protect a pre-route/pre-rounds full review that would otherwise lose every signal (issue #127\n// round-2). Only ever carried — never emitted by a completed render, which has review-complete.\nexport const COMPLETED_ANCESTOR_MARKER = \"<!-- review-complete-ancestor -->\";\n// Anchored to a standalone comment LINE like its mechanic sibling: the sticky embeds reviewer\n// prose, and a finding quoting this literal must not gate as full-review ancestry.\nexport const parseCompletedAncestor = (body: string): boolean =>\n new RegExp(`(^|\\n)${COMPLETED_ANCESTOR_MARKER}(\\n|$)`).test(body);\n\n// A POSITIVE marker: present only in a sticky the commenter wrote for a COMPLETED review. It is\n// absent from an incomplete notice AND from an in-progress placeholder (which carries forward a prior\n// review's reviewed-sha yet is not itself a completed review) — so a precedence check can tell those\n// apart, which reviewed-sha alone (stamped on notices too) cannot. Re-emitted by the template each\n// write from the render's `incomplete` flag, never carried forward.\nexport const REVIEW_COMPLETE_MARKER = \"<!-- review-complete -->\";\nexport const parseReviewComplete = (body: string): boolean => body.includes(REVIEW_COMPLETE_MARKER);\n\n// null when the body carries no base64 marker — the link form is what every post writes now; the\n// embedded form is read-only legacy that only a carried pre-#217 marker can re-emit verbatim.\n// Every sticky written before the link form holds one, and each PR only rewrites its own on its\n// next round. Also null when the payload isn't valid JSON. Callers validate the result — a prior\n// run may predate the shape.\nexport const parseFindingsMarker = (body: string): unknown => {\n const b64 = /<!-- code-review:findings-json;base64 ([A-Za-z0-9+/=]+) -->/.exec(body)?.[1];\n if (b64 === undefined) return null;\n return decodeBase64Json(b64) ?? null;\n};\n\n// Per-full-review-round records (severity counts + mechanism-frequency map), carried in a base64\n// marker so each completed full review appends its own and the sticky renders the convergence\n// trajectory and the advisory scope-metastasis note. A CI-fix mechanic pass carries it forward\n// unchanged (it is not a review round). Best-effort like the findings marker: any non-conforming\n// shape decodes to no history rather than throwing on this render path.\nconst ROUNDS_RE = /<!-- code-review:rounds;base64 ([A-Za-z0-9+/=]+) -->/;\n\n// The severity keys in descending weight/emphasis order, so every surface (counts validation, chips)\n// iterates them the same way from one source.\nconst SEVERITIES = [\"critical\", \"major\", \"minor\", \"nit\"] as const;\n\n// Non-negative integers only: a crafted/corrupted marker with a negative count would render as a\n// false \"clean\" chip (filtered by `> 0`), and a fractional/huge one as a garbage chip. Rejecting them\n// here drops the bad round instead of carrying it forward on every re-serialize.\nconst isSeverityCounts = (u: unknown): u is SeverityCounts =>\n typeof u === \"object\" &&\n u !== null &&\n SEVERITIES.every((k) => {\n const v = (u as Record<string, unknown>)[k];\n // isSafeInteger (not isInteger): a huge integer-valued float like 1e308 is an integer per\n // Number.isInteger, and would render a garbage `🔴1e+308` chip and re-serialize forward.\n return typeof v === \"number\" && Number.isSafeInteger(v) && v >= 0;\n });\n\n// How many distinct mechanisms (codes) a round's marker may record — a per-round top-N by count, so a\n// finding-heavy round can't grow the carried marker without bound. Recurring mechanisms are typically\n// among a round's most-counted codes, so the streak signal survives the cap.\nexport const MAX_IDS_PER_ROUND = 8;\n\n// Own-property presence of a code in a frequency map. Reviewer-supplied codes are used as plain-object\n// keys, so a code like \"constructor\" or \"__proto__\" must never read an inherited Object.prototype\n// member (which would count a function as a recurrence). Maps are built via Object.fromEntries\n// (CreateDataProperty), so the own property is what every consumer should read.\nconst hasId = (ids: IdCounts | undefined, code: string): boolean =>\n ids !== undefined && Object.prototype.hasOwnProperty.call(ids, code);\n\n// Codes render inside backticks in the advisory notes; a backtick inside a (reviewer-supplied) code\n// would break the span, and a newline would break out of the note's blockquote, so both are escaped\n// (newlines collapse to a space). Shared with render.ts (which escapes paths into backtick spans) so\n// the escaping rule lives in one place.\nexport const escapeCodeBackticks = (code: string): string =>\n code.replace(/`/g, \"-\").replace(/\\r?\\n/g, \" \");\n\n// The codes field of a round record, validated and capped: string → positive safe-integer counts only\n// (a count-0 entry means \"no findings this round\" and is not recorded — every consumer agrees that 0\n// is absence), kept sorted by preferredKeys first (a dual-spelling round's current ids keys, so a\n// stale legacy count can never evict them from the cap), then count descending with ties preferring\n// codes that recurred in the previous round (so the per-round top-N cap can't silently drop the\n// exact mechanism the streak detector is watching), then alphabetically for a stable order.\n// Malformed (or absent) codes decode to undefined so the round's severity counts still stand — a\n// crafted marker can't smuggle a bad codes shape into the streak/note renderers.\n// The bounded form for the ROUNDS marker (the carrier with the top-N cap): the shared\n// usableCountsMap validation (schema.ts — the one definition every round reader shares), then the\n// cap + prior-preference.\nconst normalizeIdCounts = (\n ids: unknown,\n priorCodes?: IdCounts,\n preferredKeys?: ReadonlySet<string>,\n preValidated = false,\n): IdCounts | undefined => {\n const entries = Object.entries((preValidated ? (ids as IdCounts) : usableCountsMap(ids)) ?? {});\n if (entries.length === 0) return undefined;\n const sorted = entries.sort((a, b) => {\n const aPreferred = preferredKeys?.has(a[0]) === true ? 1 : 0;\n const bPreferred = preferredKeys?.has(b[0]) === true ? 1 : 0;\n if (aPreferred !== bPreferred) return bPreferred - aPreferred;\n if (b[1] !== a[1]) return b[1] - a[1];\n const aPrior = hasId(priorCodes, a[0]) ? 1 : 0;\n const bPrior = hasId(priorCodes, b[0]) ? 1 : 0;\n if (aPrior !== bPrior) return bPrior - aPrior;\n return a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0;\n });\n // The base cap is the top-N by (count, prior-preference). A mechanism the streak detector is\n // watching (it recurred in the previous round) is never dropped by a finding-heavy round even when\n // its count is low — any such code cut by the cap is appended after the base (bounded by a second\n // cap), so a recurrence can't silently end.\n const base = sorted.slice(0, MAX_IDS_PER_ROUND);\n const priorKept = sorted\n .slice(MAX_IDS_PER_ROUND)\n .filter(([code]) => hasId(priorCodes, code))\n .slice(0, MAX_IDS_PER_ROUND);\n return Object.fromEntries([...base, ...priorKept]);\n};\n\nexport const parseRounds = (body: string): readonly RoundRecord[] => {\n const b64 = ROUNDS_RE.exec(body)?.[1];\n if (b64 === undefined) return [];\n const decoded = decodeBase64Json(b64);\n // Filter, not all-or-nothing: one future-shaped or corrupted round drops only itself rather than\n // erasing the whole trajectory (post re-serializes the parsed array on every write). The ids\n // field is normalized independently — a bad ids shape strips just that field, never the round.\n // A legacy marker's `codes` field reads identically (0.10 renamed it to `ids`).\n if (!Array.isArray(decoded)) return [];\n // SEQUENTIAL normalization: each round's ids are re-normalized with the PRECEDING round's\n // normalized ids as priorCodes, so the up-to-8 prior-kept ids of a finding-heavy round survive\n // the marker round-trip (without it, the re-parse collapses every round to its top-8 base and the\n // re-attached scope_metastasis under-reports mechanisms post() would have flagged, issue #150 review r2).\n const kept: RoundRecord[] = [];\n let priorCodes: IdCounts | undefined;\n for (const u of (decoded as readonly unknown[]).filter(isSeverityCounts)) {\n const rec = u as Record<string, unknown>;\n // mergedCountsMaps first (the ONE dual-spelling resolution, shared with the convergence\n // migration and the legacy upcast): a round carrying BOTH spellings merges their entries with\n // the current `ids` spelling winning every shared key, and a malformed/empty `ids` must not\n // lose its mechanism map while a valid legacy `codes` sits beside it. normalizeIdCounts then\n // applies the top-N cap.\n // The cap prefers the current ids keys (preferredKeys) so a high-count legacy codes-only key\n // can never evict a current mechanism from the capped trajectory — the merge's stated rationale.\n const codes = normalizeIdCounts(\n mergedCountsMaps(rec[\"ids\"], rec[\"codes\"]),\n priorCodes,\n new Set(Object.keys(usableCountsMap(rec[\"ids\"]) ?? {})),\n true,\n );\n priorCodes = codes;\n const sha = rec[\"sha\"];\n const shaStr = typeof sha === \"string\" && sha !== \"\" ? sha : undefined;\n const round = rec[\"round\"];\n const roundNum =\n typeof round === \"number\" && Number.isSafeInteger(round) && round >= 1 ? round : undefined;\n const base =\n codes === undefined\n ? { critical: u.critical, major: u.major, minor: u.minor, nit: u.nit }\n : { critical: u.critical, major: u.major, minor: u.minor, nit: u.nit, ids: codes };\n const record = shaStr === undefined ? base : { ...base, sha: shaStr };\n kept.push(roundNum === undefined ? record : { ...record, round: roundNum });\n }\n return kept;\n};\n\n// A convergence score for display: the same fixed-2-decimal formatting as formatConfidence (a descent\n// reads cleanly — 2.40 → 1.10 → 0.42 — and the badge and the trajectory's last entry print identically).\n// Delegates so a future change to the 2-decimal rule lands in one place.\nexport const formatScore = (score: number): string => formatConfidence(score);\n\n// The convergence trajectory (issue #174): \"**Round 3** · 2.40 → 1.10 → 0.42\"; \"\" when there is no\n// round history. Each entry is a round's stored convergence score; a round with no stored score (a\n// legacy rounds marker predating this feature) renders \"—\" rather than a severity chip, so the line\n// never mixes units. The round number is always the true count; only the most recent entries show\n// (with a leading \"…\" when older ones are elided) so a long-running PR's line stays bounded.\nconst TRAJECTORY_SCORES = 8;\nexport const roundsSummary = (\n rounds: readonly { readonly round?: number; readonly score?: number }[],\n count: number = rounds.length,\n): string => {\n if (count === 0) return \"\";\n const cells = rounds\n .slice(-TRAJECTORY_SCORES)\n .map((r) => (typeof r.score === \"number\" ? formatScore(r.score) : \"—\"));\n const trajectory =\n cells.length === 0\n ? \"\"\n : rounds.length > TRAJECTORY_SCORES\n ? `… → ${cells.join(\" → \")}`\n : cells.join(\" → \");\n return trajectory === \"\"\n ? `**Round ${String(count)}**`\n : `**Round ${String(count)}** · ${trajectory}`;\n};\n\n// The per-round mechanism-frequency map: each finding carrying a `code` counts once toward that\n// mechanism, as does each code a systemic problem ties together via `finding_ids` — so a structural\n// mechanism surfaced as a systemic problem is visible to the same-root note and the streak detector,\n// not just one surfaced on a finding. Findings without a `code` are mechanism-unknown and uncounted.\n// Built via Object.fromEntries so reviewer-supplied keys like \"__proto__\" or \"constructor\" become own\n// data properties rather than mutating the map's prototype or reading inherited members.\nexport const computeIdCounts = (\n findings: readonly Finding[],\n systemic: readonly SystemicProblem[] = [],\n): IdCounts => {\n // A single Map pass — one increment per code — then Object.fromEntries so a reviewer-supplied\n // key like \"__proto__\" becomes an own property, never the map's prototype.\n const counts = new Map<string, number>();\n for (const code of [\n // resolveFindingId: an EMPTY id counts under the same synthesized key the answered match uses —\n // one finding can never be simultaneously tracked (dropped-by-synthesis) and uncounted.\n ...findings.map((f) => resolveFindingId(f)),\n ...systemic.flatMap((s) => [s.id, ...(s.finding_ids ?? [])]),\n ]) {\n if (code === undefined || code === \"\") continue;\n counts.set(code, (counts.get(code) ?? 0) + 1);\n }\n return Object.fromEntries(counts);\n};\n\n// Per code, how many consecutive rounds (ending at the last recorded round) carried a finding with\n// that code, and the 1-indexed round where the streak began. A round with no codes record (pre-feature\n// or a round with no coded findings) ENDS every streak — absence of data cannot evidence recurrence.\nexport const consecutiveIdStreaks = (\n rounds: readonly RecurrenceRound[],\n): Readonly<Record<string, IdStreak>> => {\n const entries: [string, IdStreak][] = [];\n if (rounds.length === 0) return {};\n const lastCodes = rounds[rounds.length - 1]?.ids;\n if (lastCodes === undefined) return {};\n for (const code of Object.keys(lastCodes)) {\n let streak = 0;\n let startIndex = rounds.length;\n for (let i = rounds.length - 1; i >= 0; i--) {\n const codes = rounds[i]?.ids;\n if (codes === undefined || !hasId(codes, code)) break;\n // A same-head CI retry appends a round with the same sha as the round before it — the same\n // review iteration re-examined, not new evidence of recurrence — so it neither advances nor\n // breaks the streak. Only when the code ALSO appeared in the previous (same-sha) round is the\n // evidence genuinely repeated; a code NEW in the retry round is fresh and counts.\n if (\n i > 0 &&\n rounds[i]?.sha !== undefined &&\n rounds[i]?.sha === rounds[i - 1]?.sha &&\n hasId(rounds[i - 1]?.ids, code)\n ) {\n continue;\n }\n streak += 1;\n startIndex = i;\n }\n if (streak > 0) {\n entries.push([code, { streak, startRound: rounds[startIndex]?.round ?? startIndex + 1 }]);\n }\n }\n // Object.fromEntries so a reviewer-supplied code like \"__proto__\" becomes an own key, never the\n // map's prototype (which would corrupt the result and render [object Object] in the note).\n return Object.fromEntries(entries);\n};\n\n// The minimum consecutive-round recurrence that triggers the advisory scope-metastasis note.\nexport const DEFAULT_METASTASIS_STREAK = 3;\n\n// The decision prompt the structured scope-metastasis entry carries (issue #150): a DECISION, not a\n// directive — the issue's author-agent found \"narrow the scope\" would have been the wrong instruction\n// on salix#100 (the metastasis converged to the correct end state), so the prompt must force an\n// explicit choice, not steer one. Shared by the structured entry; the prose note paraphrases it\n// (advisory-only wording, no imperative).\nexport const SCOPE_METASTASIS_DECISION_PROMPT =\n \"Findings keep recurring in the same mechanism across consecutive rounds — each fix keeps enabling the next finding in that machinery. This is a decision, not a directive: state in your summary whether you are committing to the expanding scope (plan the remaining facets of the recurring mechanism(s) above as one unit) or narrowing the scope so the recurrence stops.\";\n\n// The codes whose consecutive-round streak meets the threshold, sorted by streak descending — the\n// single computation both the advisory prose note and the structured scope-metastasis entry derive\n// from, so the two surfaces can never disagree on what is flagged.\nconst flaggedIdStreaks = (\n rounds: readonly RecurrenceRound[],\n minStreak: number,\n): ReadonlyArray<{ readonly id: string; readonly streak: IdStreak }> =>\n Object.entries(consecutiveIdStreaks(rounds))\n .filter(([, s]) => s.streak >= minStreak)\n .sort((a, b) => b[1].streak - a[1].streak)\n .map(([id, streak]) => ({ id, streak }));\n\n// The advisory scope-metastasis note for the sticky's convergence area: \"\" when no code has recurred\n// in `minStreak` or more consecutive rounds. Names the mechanism by its code (the pipeline cannot\n// paraphrase it — that needs the finding text) and the round range it streaked over. ADVISORY ONLY —\n// mirrors the convergence badge's posture: derives from the reviewer's own codes and never alters any\n// finding's severity or the verdict.\nexport const metastasisNote = (\n rounds: readonly RecurrenceRound[],\n minStreak: number = DEFAULT_METASTASIS_STREAK,\n): string => {\n const flagged = flaggedIdStreaks(rounds, minStreak);\n if (flagged.length === 0) return \"\";\n // The note only fires at minStreak ≥ 3 (the default), so \"consecutive rounds\" is always plural.\n // The round range is deliberately omitted: the history may contain same-sha retries that the\n // streak detector de-duplicates, so any X–Y range would contradict the streak count.\n const lines = flagged.map(\n ({ id, streak }) =>\n `> **\\`${escapeCodeBackticks(id)}\\`** — findings in ${String(streak.streak)} consecutive rounds.`,\n );\n return [\n \"> [!WARNING]\",\n \"> **Scope metastasis** — findings keep recurring in the same mechanism across consecutive rounds; each fix keeps enabling the next finding in that machinery. Consider whether a structural fix (change the shape, not the edge case) or a scope narrowing would converge this faster.\",\n ...lines,\n ].join(\"\\n\");\n};\n\n// The structured counterpart of the prose note (issue #150): the per-code consecutive-round counts\n// plus the decision prompt. The re-review seed re-derives this from the carried rounds history and\n// delivers it to the next-round agent (it is NOT embedded in the findings blob), so the machine\n// channel and the sticky's prose carry the same recurrence signal. null when nothing is flagged, so a\n// clean history carries no signal (the same omission semantics as the prose note's \"\"). The\n// structured entry carries the RAW reviewer-supplied code (the identifier consumers match on); the\n// prose note renders the SANITIZED form (escapeCodeBackticks) — the flagged SET is identical, only\n// the representation differs (a backtick/newline code is escaped for the markdown surface, raw in\n// the JSON).\nexport const computeScopeMetastasis = (\n rounds: readonly RecurrenceRound[],\n minStreak: number = DEFAULT_METASTASIS_STREAK,\n): ScopeMetastasis | null => {\n const flagged = flaggedIdStreaks(rounds, minStreak);\n if (flagged.length === 0) return null;\n return {\n decision_prompt: SCOPE_METASTASIS_DECISION_PROMPT,\n recurring: flagged.map(({ id, streak }) => ({\n id,\n consecutive_rounds: streak.streak,\n start_round: streak.startRound,\n })),\n };\n};\n\n// Code → \"same mechanism as round N\" for findings whose mechanism recurred in a PRIOR round: the most\n// recent prior round that carried a finding with the same code. The deterministic backstop to the\n// reviewer's own prose — the pipeline can't name the mechanism (that needs the finding text), but it\n// can name the round the code last appeared in. Empty when nothing recurs.\nexport const computeSameRootNotes = (\n priorRounds: readonly RecurrenceRound[],\n findings: readonly Finding[],\n currentSha?: string,\n): Readonly<Record<string, string>> => {\n const codes = findings.map((f) => resolveFindingId(f));\n const entries: [string, string][] = [];\n for (const code of codes) {\n let lastRound = 0;\n for (let i = priorRounds.length - 1; i >= 0; i--) {\n // A same-sha prior round is the same commit re-reviewed (a CI retry) — its findings are the\n // same evidence, not a prior fix that re-opened the mechanism, so it must not be named. A\n // retry deeper in the history (a round that merely re-examines the commit before it) is\n // collapsed the same way consecutiveIdStreaks collapses it, so both advisory signals agree.\n if (currentSha !== undefined && priorRounds[i]?.sha === currentSha) continue;\n // Collapse a same-sha retry exactly like consecutiveIdStreaks does: only when the code ALSO\n // appeared in the retried round is the evidence genuinely repeated — a code NEW in the retry\n // round is fresh and is named here (the two advisory signals agree).\n if (\n i > 0 &&\n priorRounds[i]?.sha !== undefined &&\n priorRounds[i]?.sha === priorRounds[i - 1]?.sha &&\n hasId(priorRounds[i - 1]?.ids, code)\n )\n continue;\n const count = priorRounds[i]?.ids?.[code];\n if (count !== undefined && count > 0) {\n lastRound = priorRounds[i]?.round ?? i + 1;\n break;\n }\n }\n if (lastRound > 0) {\n entries.push([\n code,\n `Same mechanism as round ${String(lastRound)} (\\`${escapeCodeBackticks(code)}\\`) — the prior fix in this area re-opened it; consider a structural fix or a scope narrowing.`,\n ]);\n }\n }\n // Object.fromEntries so a reviewer-supplied code like \"__proto__\" becomes an own key.\n return Object.fromEntries(entries);\n};\n\n// The convergence score and its advisory badge (score ≤ threshold), per finding/systemic problem:\n// floor(severity) + max(0, ceiling − floor) × confidence × likelihood. The floor is the weight the\n// modulation cannot erode; critical's is threshold-relative (CRITICAL_FLOOR_MARGIN) so an open critical\n// is never converged at any practical threshold (the margin degrades only where FP precision drops\n// 0.01, i.e. thresholds ≳ 1e14). ADVISORY ONLY: never alters the verdict.\nconst CONVERGENCE_CEILINGS: SeverityCounts = { critical: 4, major: 2, minor: 1, nit: 0 };\n// > 0 so a lone critical fails `score ≤ threshold`; 0.01 survives round2 (a coarser round would erase it).\nconst CRITICAL_FLOOR_MARGIN = 0.01;\n// A minor's floor (issue #178): the weight the modulation cannot erode, so a PILE of low-likelihood\n// minors resists convergence even when each is individually unlikely — count matters, not only\n// per-finding likelihood. A single solid minor still converges (0.1 + 0.9 × conf × like ≤ 1).\nconst MINOR_FLOOR = 0.1;\nexport const DEFAULT_CONVERGENCE_THRESHOLD = 1;\n\nconst convergenceFloor = (severity: Severity, threshold: number): number =>\n severity === \"critical\"\n ? threshold + CRITICAL_FLOOR_MARGIN\n : severity === \"major\"\n ? 0.5\n : severity === \"minor\"\n ? MINOR_FLOOR\n : 0;\n\n// A mechanic (CI-fix) pass stamps a never-converged convergence over the prior trajectory: CI\n// failed, so whatever the prior round said, this run's stamp must not read \"converged\". The score is\n// the THRESHOLD-RELATIVE critical floor (threshold + CRITICAL_FLOOR_MARGIN) — the same guarantee\n// convergenceFloor gives an open critical — so the score ≤ threshold triple buildConvergence\n// documents stays consistent at every threshold the CLI accepts. null when no prior round exists: a\n// stamp without a trajectory is one the reader gate (validStampedConvergence) rejects, and no marker\n// is the honest form of \"nothing to carry\" (issue #224).\nexport const mechanicConvergence = (\n prior: Convergence | null,\n threshold: number,\n): Convergence | null =>\n prior === null\n ? null\n : {\n score: convergenceFloor(\"critical\", threshold),\n threshold,\n converged: false,\n rounds: prior.rounds,\n };\n\nconst round2 = (n: number): number => Math.round((n + Number.EPSILON) * 100) / 100;\n\n// One finding/systemic-problem's contribution: floor(severity) + confidence-and-likelihood-weighted\n// headroom. The interlocks live HERE so both reducers below share them: max(0, …) can't invert when\n// threshold ≥ ceiling, and the critical margin + round2 preserve an open critical's `> threshold`\n// guarantee.\nconst contribution = (\n severity: Severity,\n confidence: number,\n likelihood: number,\n threshold: number,\n): number => {\n const floor = convergenceFloor(severity, threshold);\n return floor + Math.max(0, CONVERGENCE_CEILINGS[severity] - floor) * confidence * likelihood;\n};\n\n// Findings AND systemic problems (issue #134 scope), rounded to 2 decimals. A systemic problem is\n// scored with likelihood 1, NEVER its written value (issue #178): `likelihood` measures how routinely a\n// triggering input/state occurs, but a structural/cross-cutting observation has no single triggering\n// input — it is definitionally always present — so discounting it by likelihood is a category error\n// that under-weights exactly the findings that tie a review together. The field stays on the schema\n// (removing it would invalidate blobs already posted) but the score does not read it for systemic.\nexport const convergenceScore = (doc: Findings, threshold: number): number =>\n round2(\n doc.findings.reduce(\n (sum, { severity, confidence, likelihood }) =>\n sum + contribution(severity, confidence, likelihood, threshold),\n 0,\n ) +\n (doc.systemic_problems ?? []).reduce(\n (sum, { severity, confidence }) => sum + contribution(severity, confidence, 1, threshold),\n 0,\n ),\n );\n\n// The pipeline-stamped convergence field (issue #174): this round's score/threshold/converged plus the\n// per-round trajectory. Prior rounds are carried VERBATIM — their scores are historical snapshots, and\n// recomputing at a changed threshold would rewrite the past — while THIS round is appended with its\n// score and the mechanism map + head SHA the recurrence signals read. The trajectory keeps only the\n// most recent CONVERGENCE_TRAJECTORY_LIMIT rounds — a COUNT bound (not a byte cap), which keeps the blob\n// growth bounded in the common case (a round record is compact) and caps the same-root memory at that\n// many rounds; the recurrence detectors read only the recent tail, so bounding never ends a live streak.\nexport const CONVERGENCE_TRAJECTORY_LIMIT = 64;\nexport const buildConvergence = (\n doc: Findings,\n threshold: number = DEFAULT_CONVERGENCE_THRESHOLD,\n priorRounds: readonly ConvergenceRound[] = [],\n round: number = 1,\n ids: IdCounts = {},\n sha?: string,\n): Convergence => {\n const score = convergenceScore(doc, threshold);\n const normalized = normalizeIdCounts(ids, priorRounds[priorRounds.length - 1]?.ids);\n const current: ConvergenceRound = {\n round,\n score,\n ...(normalized !== undefined ? { ids: { ...normalized } } : {}),\n ...(sha !== undefined ? { sha } : {}),\n };\n const rounds = [...priorRounds, current].slice(-CONVERGENCE_TRAJECTORY_LIMIT);\n return { score, threshold, converged: score <= threshold, rounds };\n};\n\n// ── Nit visibility floor (issue #164) ───────────────────────────────────────────────────────────\n// A nit whose confidence × likelihood falls below this is below the noise floor: KEPT in the machine\n// blob (so the next-round seed reads it as already adjudicated and never re-raises it as fresh) but\n// hidden from the HUMAN surfaces (no inline comment; a collapsed aside in the sticky). Nit-only, and\n// orthogonal to the convergence score — a nit's ceiling is 0, so it contributes 0 whether shown or\n// hidden. Scoped to findings only; a nit-severity systemic problem is never floored here (hiding a\n// cross-cutting observation is a heavier call than hiding a per-line nit).\nexport const DEFAULT_NIT_VISIBILITY_FLOOR = 0.25;\n\n// True when a finding is a nit below the visibility floor. Accepts a loose shape so it serves both a\n// validated current Finding (confidence/likelihood are always numbers) and a hand-parsed prior-blob\n// finding: a non-numeric confidence or likelihood — a pre-0.9 blob predates likelihood — makes this\n// FALSE, so a finding is never hidden on missing data; suppression fails OPEN to visible.\nexport const isBelowVisibilityFloor = (\n f: { readonly severity?: unknown; readonly confidence?: unknown; readonly likelihood?: unknown },\n floor: number = DEFAULT_NIT_VISIBILITY_FLOOR,\n): boolean =>\n f.severity === \"nit\" &&\n typeof f.confidence === \"number\" &&\n typeof f.likelihood === \"number\" &&\n f.confidence * f.likelihood < floor;\n\n// The identifying bits of a prior round's below-floor nit, hand-parsed from a decoded prior findings\n// blob (parseFindingsMarker output) — the one-round suppression memory. post derives its stickiness\n// key from these (a still-nit matching one stays hidden even if its score wobbled up); the seed\n// delivers them as adjudicated context. Defensive/best-effort like parseRounds: a non-object, an old\n// blob without likelihood, or a malformed entry contributes nothing.\nexport interface PriorSuppressedNit {\n readonly title: string;\n readonly id?: string;\n readonly path?: string;\n}\nexport const priorBelowFloorNits = (\n priorDoc: unknown,\n floor: number = DEFAULT_NIT_VISIBILITY_FLOOR,\n): readonly PriorSuppressedNit[] => {\n if (typeof priorDoc !== \"object\" || priorDoc === null) return [];\n const arr = (priorDoc as Record<string, unknown>)[\"findings\"];\n if (!Array.isArray(arr)) return [];\n const nits: PriorSuppressedNit[] = [];\n for (const f of arr) {\n if (typeof f !== \"object\" || f === null) continue;\n const rec = f as Record<string, unknown>;\n if (!isBelowVisibilityFloor(rec, floor)) continue;\n const title = rec[\"title\"];\n if (typeof title !== \"string\") continue;\n const path = typeof rec[\"path\"] === \"string\" ? rec[\"path\"] : undefined;\n // resolveRuleId: the raw marker doc may predate id (a legacy `code`), and a CODELESS pre-id nit\n // resolves to the same synthesized id the upcast derives — so post's stickiness key matches the\n // 0.10 re-raise of the same claim instead of resetting on the migration round.\n const id = resolveRuleId({\n id: typeof rec[\"id\"] === \"string\" ? rec[\"id\"] : undefined,\n code: typeof rec[\"code\"] === \"string\" ? rec[\"code\"] : undefined,\n path,\n title,\n });\n nits.push({\n title,\n ...(id !== undefined ? { id } : {}),\n ...(path !== undefined ? { path } : {}),\n });\n }\n return nits;\n};\n\n// The convergence badge from a stored or freshly-computed signal: \"**Convergence** 🏁 0.42 ≤ 1 —\n// converged\" / \"**Convergence** 🔄 2.40 > 1 — iterating\". The score prints 2-decimal (formatScore) so it\n// matches the trajectory's last entry; the converged glyph is a checkered flag, NOT the verdict badge's\n// ✅, so a reader (or the author-agent this steers) can't skim the line as an approval. `converged` is\n// read from the signal, never recomputed here, so the shown inequality can't contradict the stored\n// decision.\nexport const convergenceBadge = (c: ConvergenceCore): string =>\n c.converged\n ? `**Convergence** 🏁 ${formatScore(c.score)} ≤ ${String(c.threshold)} — converged`\n : `**Convergence** 🔄 ${formatScore(c.score)} > ${String(c.threshold)} — iterating`;\n\n// The badge computed fresh from a document — the standalone `render` command and any legacy sticky with\n// no stored convergence. The post path reads the stamped signal via convergenceBadge, so its shown\n// score is the verbatim historical value.\nexport const convergenceSummary = (\n doc: Findings,\n threshold: number = DEFAULT_CONVERGENCE_THRESHOLD,\n): string => convergenceBadge(convergenceSignal(doc, threshold));\n\n// The change-size breakdown line (issue #182): \"+240 / −80 code · +120 / −10 tests · +30 / −0 docs\",\n// dropping a role the agent left absent. \"\" when the field or every role is absent. The agent's\n// best-effort role split (chrome); the per-language cloc table rides its own collapsible beside it.\nexport const changeSizeSummary = (changeSize: ChangeSize | undefined): string => {\n if (changeSize === undefined) return \"\";\n const cell = (\n label: string,\n d: { readonly added: number; readonly removed: number } | undefined,\n ): string | null =>\n d === undefined ? null : `+${String(d.added)} / −${String(d.removed)} ${label}`;\n return [\n cell(\"code\", changeSize.code),\n cell(\"tests\", changeSize.tests),\n cell(\"docs\", changeSize.docs),\n ]\n .filter((c): c is string => c !== null)\n .join(\" · \");\n};\n\n// The round number the NEXT completed full review will stamp, from a prior sticky's parsed state: the\n// max of the trajectory and the carried convergence's last round (never regresses across a legacy\n// signal/marker split), + 1. post numbers its appended round with it and announce labels the in-progress\n// trajectory with it, so the placeholder's round and post's stamp are ONE derivation, not copy-paste.\nexport const nextRoundNumber = (\n priorTraj: readonly ConvergenceRound[],\n priorConvRounds: readonly ConvergenceRound[],\n): number => {\n const last = (rounds: readonly ConvergenceRound[]): number =>\n rounds.length > 0 ? (rounds[rounds.length - 1]?.round ?? rounds.length) : 0;\n return Math.max(last(priorTraj), last(priorConvRounds)) + 1;\n};\n\n// The in-progress trajectory line for the announce placeholder (issue #180): the completed rounds'\n// scores plus a pending \"⏳\" cell for the round now running. The caller passes the running round from\n// nextRoundNumber, so the label and the pending cell agree with what post will stamp — by construction,\n// not by re-derivation here. NO badge: a carried \"converged\" above a running round would read as \"done,\n// ignore this.\" \"\" when the prior carries no completed round.\nexport const inProgressConvergence = (prior: Convergence, runningRound: number): string => {\n const rounds = prior.rounds ?? [];\n return rounds.length === 0 ? \"\" : `${roundsSummary(rounds, runningRound)} → ⏳`;\n};\n\n// The version a LEGACY compact stop-signal marker declared, and the version a LEGACY surfaced blob\n// declared before issue #156 deleted the surfacing transform. Its writer is retired (issue #186); the\n// version survives so the migration readers recognize a pre-#185 marker. DISTINCT from the draft axis\n// (DEFAULT_SCHEMA_VERSION is 0.9.0 after issue #163) so the surface channel can never be mistaken for\n// the agent's own document: parseSurfaceSignal accepts a signal marker only at a surface version, and\n// stripSurfaceFields recognizes a legacy surfaced blob by it to peel that blob back to a draft.\nexport const SURFACE_SCHEMA_VERSION = \"0.8.0\";\n\n// The stop signal's convergence core is the schema's ConvergenceCore — one definition shared by the\n// JSON convergence field and the legacy compact signal marker's reader.\nexport type ConvergenceSignal = ConvergenceCore;\n\n// The shape parseSignalMarker / parseSurfaceSignal return from a LEGACY compact signal marker or\n// surfaced blob: the round number + that round's score/threshold/converged. Its writer is retired\n// (issue #186); post now carries convergence forward via the stamped field (carriedConvergence), and a\n// stored `converged` is never re-derived — re-deriving at a changed convergence_threshold would flip a\n// prior round's decision.\nexport interface SurfaceSignal {\n readonly round: number;\n readonly convergence: ConvergenceSignal;\n}\n\n// The pure findings→signal computation, shared by post (a completing round) and render's fallback.\nexport const convergenceSignal = (\n doc: Findings,\n threshold: number = DEFAULT_CONVERGENCE_THRESHOLD,\n): ConvergenceSignal => {\n const score = convergenceScore(doc, threshold);\n return { score, threshold, converged: score <= threshold };\n};\n\nconst SIGNAL_RE = /<!-- code-review:signal;base64 ([A-Za-z0-9+/=]+) -->/;\n\n// Decodes a LEGACY compact signal marker (writer retired, issue #186) — a read-only fallback in the\n// carry chain: carriedConvergence reads the stamped convergence field, then the code-review:convergence\n// marker, and only then this. parseSurfaceSignal below is the older fallback for pre-#156 stickies whose\n// signal rode inside the blob.\nexport const parseSignalMarker = (body: string): SurfaceSignal | null => {\n const b64 = SIGNAL_RE.exec(body)?.[1];\n if (b64 === undefined) return null;\n return parseSurfaceSignal(decodeBase64Json(b64));\n};\n\n// Best-effort like parseRounds: the carried stop signal read back from a LEGACY (pre-#156) surfaced\n// blob whose signal rode inside the findings JSON — null on any malformed shape, a pre-surface blob,\n// or a doc that does not declare a surfaced version, so a draft or foreign document carrying\n// round/convergence keys can never be treated as the commenter's stop signal (the same version gate\n// stripSurfaceFields applies to the seed channel). Nothing writes this anymore (issue #186); it is the\n// last fallback in carriedConvergence's carry chain, reached only for an older sticky.\nexport const parseSurfaceSignal = (doc: unknown): SurfaceSignal | null => {\n if (typeof doc !== \"object\" || doc === null || Array.isArray(doc)) return null;\n const o = doc as Record<string, unknown>;\n if (!isSurfaceVersion(o[\"schema_version\"])) return null;\n const round = o[\"round\"];\n const convergence = o[\"convergence\"];\n if (typeof round !== \"number\" || !Number.isSafeInteger(round) || round < 1) return null;\n if (typeof convergence !== \"object\" || convergence === null) return null;\n const c = convergence as Record<string, unknown>;\n // isFinite (not just typeof): JSON.parse(\"1e400\") yields Infinity, which typeof says is a number\n // but JSON.stringify coerces to null — a non-finite score would survive one hop and then silently\n // drop the whole carried signal on the next.\n if (\n typeof c[\"score\"] !== \"number\" ||\n !Number.isFinite(c[\"score\"]) ||\n typeof c[\"threshold\"] !== \"number\" ||\n !Number.isFinite(c[\"threshold\"]) ||\n typeof c[\"converged\"] !== \"boolean\"\n ) {\n return null;\n }\n return {\n round,\n convergence: { score: c[\"score\"], threshold: c[\"threshold\"], converged: c[\"converged\"] },\n };\n};\n\n// Decode-tolerant read of the pipeline-stamped convergence field from a prior findings blob (the raw\n// parseFindingsMarker output): the convergence when the blob carries a valid one, else null.\n// Best-effort like parseRounds — a malformed or absent field yields null, never a throw.\n// A #174 pipeline stamp always carries a NON-EMPTY trajectory. A convergence that decodes but has no\n// `rounds` (or an empty one) is either a legacy pre-#156 surface blob's embedded stop signal or a\n// crafted/reset value — treat it as absent so the marker/legacy fallbacks reconstruct the whole thing,\n// and an empty trajectory can never silently reset the round count to 0 (issue #185 review).\n// A pre-0.10 sticky's compact convergence marker carries rounds whose mechanism maps use the legacy\n// `codes` spelling (0.10 renamed it to `ids`). Map the legacy rounds before the strict codec gate\n// with the SAME resolution parseRounds applies (mergedCountsMaps: usable maps merge, the current\n// `ids` spelling winning shared keys) — a round carrying both with a malformed `ids` must not\n// lose its mechanism map. The winner maps to `ids` verbatim minus the entries usableCounts itself\n// rejects (this carrier was never capped, unlike the rounds marker).\nconst withLegacyConvergenceIds = (raw: unknown): unknown => {\n if (typeof raw !== \"object\" || raw === null || Array.isArray(raw)) return raw;\n const rec = raw as Record<string, unknown>;\n const rounds = rec[\"rounds\"];\n if (!Array.isArray(rounds)) return raw;\n const needsMigration = (r: unknown): boolean => {\n if (typeof r !== \"object\" || r === null) return false;\n const round = r as Record<string, unknown>;\n return round[\"codes\"] !== undefined || usableCountsMap(round[\"ids\"]) === undefined;\n };\n // Fast path: a current 0.10 doc whose rounds all carry usable ids maps needs no migration — the\n // mapper runs on EVERY convergence decode, so the common case must not pay per-round rebuilds.\n if (!rounds.some(needsMigration)) return raw;\n const mapped: unknown[] = rounds.map((r) => {\n if (typeof r !== \"object\" || r === null) return r as unknown;\n const round = r as Record<string, unknown>;\n const ids = mergedCountsMaps(round[\"ids\"], round[\"codes\"]);\n if (ids === undefined) {\n // Neither spelling usable: strip BOTH map fields (like parseRounds strips a bad map) rather\n // than leaving the legacy `codes` key for the strict round gate to reject — a corrupted map\n // must cost the round its mechanism data, never the whole trajectory.\n return round[\"ids\"] !== undefined || round[\"codes\"] !== undefined\n ? Object.fromEntries(Object.entries(round).filter(([k]) => k !== \"ids\" && k !== \"codes\"))\n : round;\n }\n const rest = Object.fromEntries(\n Object.entries(round).filter(([k]) => k !== \"ids\" && k !== \"codes\"),\n );\n return { ...rest, ids };\n });\n return { ...rec, rounds: mapped };\n};\n\nconst validStampedConvergence = (raw: unknown): Convergence | null => {\n const decoded = ConvergenceCodec.decode(withLegacyConvergenceIds(raw));\n return decoded._tag === \"Right\" &&\n decoded.right.rounds !== undefined &&\n decoded.right.rounds.length > 0\n ? decoded.right\n : null;\n};\n\nexport const parseConvergence = (priorDoc: unknown): Convergence | null => {\n if (typeof priorDoc !== \"object\" || priorDoc === null) return null;\n const raw = (priorDoc as Record<string, unknown>)[\"convergence\"];\n return raw === undefined ? null : validStampedConvergence(raw);\n};\n\nconst CONVERGENCE_RE = /<!-- code-review:convergence;base64 ([A-Za-z0-9+/=]+) -->/;\n\n// The compact convergence marker (issue #185): the document left the comment (issue #217), so\n// convergence no longer rides inside it — the marker carries the SAME stamped convergence object\n// compactly beside the link, on EVERY post that has a convergence to carry (a completed round, or one\n// carried forward by a notice or a CI-fix pass). Its size-fallback role is over: it is how a reader of\n// the comment reaches the trajectory and the stop signal without a fetch.\nexport const convergenceMarker = (convergence: Convergence): string =>\n `<!-- code-review:convergence;base64 ${Buffer.from(JSON.stringify(convergence), \"utf-8\").toString(\n \"base64\",\n )} -->`;\n\n// The marker pair every surface writes: the artifact link, and the compact convergence beside it. They\n// travel together because the document left the comment (issue #217) — a link alone would put a\n// trajectory and a stop signal behind a fetch. Built here rather than at each caller: post and render\n// each had their own copy, and a test had to catch one of them emitting a link with the convergence\n// missing.\nexport const findingsMarkerPair = (\n jsonUrl: string | undefined,\n convergence: Convergence | undefined,\n): string => {\n const marker = jsonUrl !== undefined ? findingsPointer(jsonUrl) : \"\";\n if (convergence === undefined) return marker;\n const conv = convergenceMarker(convergence);\n return marker === \"\" ? conv : `${marker}\\n${conv}`;\n};\n\nexport const parseConvergenceMarker = (body: string): Convergence | null => {\n const b64 = CONVERGENCE_RE.exec(body)?.[1];\n return b64 === undefined ? null : validStampedConvergence(decodeBase64Json(b64));\n};\n\n// A legacy parsed rounds marker mapped into the trajectory shape: codes/sha/round survive (the\n// recurrence detectors read them), score is absent (a legacy round stored no score, so the trajectory\n// renders \"—\" for it). The one-time bridge across the upgrade to the JSON convergence field.\nexport const roundRecordsToConvergenceRounds = (\n records: readonly RoundRecord[],\n): ConvergenceRound[] =>\n records.map((r, i) => ({\n round: r.round ?? i + 1,\n ...(r.ids !== undefined ? { ids: { ...r.ids } } : {}),\n ...(r.sha !== undefined ? { sha: r.sha } : {}),\n }));\n\n// The prior round trajectory for post + seed: the JSON convergence field's rounds when the prior blob\n// carries it, else the legacy rounds marker mapped forward. Empty on a first review.\nexport const priorTrajectory = (\n priorDoc: unknown,\n priorBody: string,\n): readonly ConvergenceRound[] =>\n parseConvergence(priorDoc)?.rounds ??\n parseConvergenceMarker(priorBody)?.rounds ??\n roundRecordsToConvergenceRounds(parseRounds(priorBody));\n\n// The prior completed round's convergence, carried VERBATIM into a notice or CI-fix pass so the JSON\n// keeps the trajectory + last score across a non-round post: the stamped convergence field if present,\n// else reconstructed from a legacy sticky's compact signal marker (the core) + rounds marker (the\n// trajectory, scoreless). null when no round has completed — a first-run notice stamps no convergence.\nexport const carriedConvergence = (priorDoc: unknown, priorBody: string): Convergence | null => {\n const stamped = parseConvergence(priorDoc) ?? parseConvergenceMarker(priorBody);\n if (stamped !== null) return stamped;\n const signal = parseSignalMarker(priorBody) ?? parseSurfaceSignal(priorDoc);\n if (signal === null) return null;\n const legacy = roundRecordsToConvergenceRounds(parseRounds(priorBody));\n // The legacy signal's round is the authoritative completed-round count; if a corrupt round was\n // filtered from the rounds marker, keep that count on the trajectory's last entry so the next round\n // never regresses (issue #141). An empty marker beside a signal becomes a single scoreless round.\n const last = legacy[legacy.length - 1];\n const rounds =\n last === undefined\n ? [{ round: signal.round }]\n : last.round < signal.round\n ? [...legacy.slice(0, -1), { ...last, round: signal.round }]\n : legacy;\n return { ...signal.convergence, rounds };\n};\n\n// Every surface-channel version this CLI recognizes: the versions a LEGACY surfaced blob declared\n// (which stripSurfaceFields peels back to the agent document, so a sticky written before issue #156\n// still seeds) plus the version a legacy compact signal marker declared. Both are read-only now (the\n// writers are retired, issue #186). A dedicated list, deliberately distinct from the draft-version\n// registry axis: only these versions declare the surface channel, so a draft bump can never be\n// mistaken for one. A future surface bump appends the superseded version(s) here alongside the new one.\nexport const SURFACE_SCHEMA_VERSIONS: readonly string[] = [\"0.7.0\", SURFACE_SCHEMA_VERSION];\n\n// Does a value declare one of the surface-channel versions? The single gate the surface channel\n// applies wherever it must tell a commenter-side surface artifact from the agent's own draft — the\n// stop-signal read-back (parseSurfaceSignal), the legacy-blob peel-back (stripSurfaceFields), and the\n// seed's authoritative-vs-echoed scope_metastasis decision all share it.\nexport const isSurfaceVersion = (version: unknown): boolean =>\n typeof version === \"string\" && SURFACE_SCHEMA_VERSIONS.includes(version);\n\n// Peels a LEGACY surfaced blob (pre-#156) back to the agent's own document for the re-review seed —\n// post-#156 a fresh blob is already the agent's draft and passes through untouched. Version-gated,\n// not key-gated: a doc declaring a known SURFACE version has its pipeline-stamped convergence/round\n// dropped and its version restored to the current draft default, so the seeded draft still validates;\n// anything else (a draft version, an unknown future version, a malformed version) passes through\n// untouched and fails or passes schema validation downstream on its own merits — never silently\n// rewritten. A non-object stays as-is. A legacy blob's `scope_metastasis` (issue #150) is NOT dropped\n// here: on a 0.8.0 surfaced blob it was pipeline-stamped and authoritative, so it must reach the\n// next-round agent (a 0.7.0 blob predates the field; the draft schema tolerates it so the seeded doc\n// validates); a draft blob's echoed entry is dropped upstream in the seed, before this runs.\nexport const stripSurfaceFields = (doc: unknown): unknown => {\n if (typeof doc !== \"object\" || doc === null || Array.isArray(doc)) return doc;\n const o = doc as Record<string, unknown>;\n if (!isSurfaceVersion(o[\"schema_version\"])) return doc;\n const rest = Object.fromEntries(\n Object.entries(o).filter(([key]) => key !== \"convergence\" && key !== \"round\"),\n );\n return { ...rest, schema_version: DEFAULT_SCHEMA_VERSION };\n};\n\n// The machine-readable markers to carry forward when a comment's PROSE is replaced but its data must\n// survive — the \"review in progress\" placeholder swaps the visible summary yet must not clobber the\n// re-review seed the review job reads back from the sticky (the embedded findings + reviewed-sha),\n// the route that made the seed chain route-aware, nor the round-history trajectory. The findings\n// marker is extracted verbatim so both its base64 and jsonUrl-link forms survive; base64 (A–Z a–z\n// 0–9 + / =) and URLs never contain '>', so `[^>]*` stops at its closing `-->`. The STOP directive\n// that always precedes it is re-emitted from AGENTS_STOP_DIRECTIVE (its SSOT above) rather than\n// re-matched, so a future edit to that constant can't silently desync a parallel regex. Returns \"\"\n// when the body carries none of them.\n// The prior sticky's findings marker, whatever form it rides (the artifact link OR the pre-#217\n// embedded base64). Shared by carryForwardMarkers and the notice paths, so both preserves of the\n// prior pointer can never diverge on which form survives.\nexport const carriedFindingsMarker = (body: string): string | null =>\n /<!-- code-review:findings-json[^>]*-->/.exec(body)?.[0] ?? null;\n\n// The pointer a body emits when it carries a PRIOR sticky's findings marker forward instead of\n// naming its own: the carried marker verbatim (link OR embedded base64 form) with this body's own\n// convergence stamp beside it. Shared by the notice paths and the no-json-url main path, so the\n// two carries can never diverge on form or layout.\nexport const carriedMarkerPointer = (\n carried: string,\n convergence: Convergence | undefined,\n): string =>\n [\n `${AGENTS_STOP_DIRECTIVE}\\n${carried}`,\n ...(convergence !== undefined ? [convergenceMarker(convergence)] : []),\n ].join(\"\\n\");\n\n// The provenance markers a replacing sticky must preserve. The reviewed-sha is deliberately NOT\n// here — a new write stamps its own head.\nconst completedAncestryMarker = (body: string): string | undefined =>\n parseReviewComplete(body) || parseCompletedAncestor(body) ? COMPLETED_ANCESTOR_MARKER : undefined;\n\nexport const carriedProvenanceMarkers = (body: string): string =>\n [\n // The placeholder keeps the REAL route marker: the seed chain requires it outright to stay\n // route-aware across the prose swap.\n ROUTE_RE.exec(body)?.[0],\n parseMechanicAncestor(body) ? MECHANIC_ANCESTOR_MARKER : undefined,\n completedAncestryMarker(body),\n ]\n .filter((m): m is string => m !== undefined)\n .join(\"\\n\\n\");\n\n// Full-review ancestry for the SEED-side readers (gather + seed-draft): the route marker wins;\n// a route-less body counts only through the carried completed-ancestor marker and never through\n// mechanic ancestry. A mechanic-route body (a mechanic sticky or a placeholder over one) fails\n// both clauses — its carried ancestor marker must not read as a full review's.\nexport const isFullReviewAncestry = (body: string): boolean =>\n parseReviewedRoute(body) === \"full review\" ||\n (parseReviewedRoute(body) === null &&\n parseCompletedAncestor(body) &&\n !parseMechanicAncestor(body));\n\n// The ancestry markers a NOTICE carries: the route marker itself is NEVER re-emitted onto an\n// incomplete body — a notice carrying `reviewed-route: full review` would read as a completed full\n// review to every downstream route check — so a mechanic prior's provenance rides the dedicated\n// mechanic-ancestor marker, and the completed-ancestor marker keeps the empty-mechanic guard's\n// pre-route protection alive.\nexport const carriedAncestryMarkers = (body: string): string =>\n [\n // A notice body carries no route marker, so the second hop reads the ancestor marker itself:\n // mechanic ancestry survives notice-over-notice, not just notice-over-sticky.\n parseReviewedRoute(body) === \"mechanic\" || parseMechanicAncestor(body)\n ? MECHANIC_ANCESTOR_MARKER\n : undefined,\n completedAncestryMarker(body),\n ]\n .filter((m): m is string => m !== undefined)\n .join(\"\\n\\n\");\n\nexport const carryForwardMarkers = (body: string): string => {\n const findings = carriedFindingsMarker(body);\n const reviewedSha = /<!-- reviewed-sha: [0-9a-fA-F]{40} -->/.exec(body)?.[0];\n // The compact convergence marker (issue #185 review) rides beside the findings link, so the\n // in-progress placeholder must carry it forward too or the trajectory is lost across the swap.\n const convergence = CONVERGENCE_RE.exec(body)?.[0];\n const rounds = ROUNDS_RE.exec(body)?.[0];\n const signal = SIGNAL_RE.exec(body)?.[0];\n const findingsBlock = findings ? `${AGENTS_STOP_DIRECTIVE}\\n${findings}` : undefined;\n return [findingsBlock, reviewedSha, carriedProvenanceMarkers(body), convergence, rounds, signal]\n .filter((m): m is string => m !== undefined && m !== \"\")\n .join(\"\\n\\n\");\n};\n\n// Escape triple-backticks so fenced content can't break out of its block.\nexport const escapeFence = (text: string): string => text.replace(/```/g, \"`` ` ``\");\n\n// A GitHub ```suggestion when the patch lowers to replacement text, a non-lossy ```patch fallback\n// when it can't, or nothing when the finding carries no patch.\nexport type PatchProjection =\n | { readonly kind: \"suggestion\"; readonly text: string }\n | { readonly kind: \"patch\"; readonly raw: string }\n | { readonly kind: \"none\" };\n\n// GitHub renders a ```suggestion as an Apply button ONLY in a review comment anchored to diff lines.\n// In an issue comment — which is what the sticky is — the same block is inert, and worse than inert:\n// it shows the replacement text stripped of the lines it replaces, so the reader sees the fix with no\n// indication of what it displaces. The raw patch is a hunk and reads as one, so a comment-body\n// surface keeps it rather than lowering it to a suggestion that surface cannot honour. Both forms\n// still go through escapeFence: a hunk that itself contains a triple backtick would otherwise close\n// the block it is rendered in, so the escape is what keeps the rest of the comment intact — the\n// displayed hunk is faithful except for that sequence.\nexport type PatchSurface = \"diff-anchored\" | \"comment-body\";\n\nexport const projectPatch = (patch: string | undefined, surface: PatchSurface): PatchProjection => {\n if (patch === undefined) return { kind: \"none\" };\n const lowered = surface === \"diff-anchored\" ? patchToSuggestion(patch) : undefined;\n return typeof lowered === \"string\"\n ? { kind: \"suggestion\", text: escapeFence(lowered) }\n : { kind: \"patch\", raw: escapeFence(patch) };\n};\n\nexport const formatConfidence = (n: number): string => n.toFixed(2);\n\n// The review-object body: a bare one-line pointer to the sticky, where the findings document lives —\n// the sole documented decode surface (issue #161) — and to the run that produced the review (issue\n// #204), so a reader who lands here has a path back to the evidence. It never embeds the document: the\n// review body is written only after upsertSticky returns — a genuinely failed sticky write throws and\n// aborts post() first, and a response it cannot parse leaves these words unlinked rather than\n// embedding the blob here. SSOT shared by the commenter (post.ts) and the `preview` command.\n// The two links degrade differently: no sticky URL leaves the words unlinked, no run URL omits the run\n// sentence entirely. The run sentence names what the link is FOR rather than what the run still holds —\n// retention prunes logs and artifacts while the review object persists. The run's SUMMARY is the\n// review rendered whole (issue #205) — the sticky shows the latest round, the summaries show each\n// round as it stood — so the sentence names it, but only when there is one: `post` run outside\n// Actions writes no summary, and a pointer promising a document that was never written is worse than\n// one that promises less.\nexport const reviewBodyPointer = (\n headSha: string,\n stickyUrl: string | undefined,\n runUrl: string | undefined,\n runHasSummary: boolean,\n): string => {\n const sha7 = headSha.slice(0, 7);\n const summary = stickyUrl ? `the [summary comment](${stickyUrl})` : \"the summary comment\";\n const run = runUrl\n ? ` See the [workflow run](${runUrl}) for ${runHasSummary ? \"this round's review in full, its job log,\" : \"the job log\"} and the findings artifact.`\n : \"\";\n return `🤖 Automated code review for \\`${sha7}\\` — see ${summary} for the verdict, walkthrough, and cost.${run}`;\n};\n","// The cycle-safe in_reply_to climb, shared by the answered-registry walk and the discussion-aside\n// walk so the cycle-guard semantics live in one place. The climb terminates at a gap: a dangling\n// parent id (a deleted comment whose replies keep pointing at it) ends the chain where the map\n// stopped — both consumers accept that a severed subtree stays out of their grouping.\nexport function* ancestors<T>(start: T, parentOf: (node: T) => T | null): Generator<T> {\n const seen = new Set<T>();\n let current: T | null = start;\n while (current !== null && !seen.has(current)) {\n yield current;\n seen.add(current);\n current = parentOf(current);\n }\n}\n","// The transcript is the only surviving spend record when a wall-clock kill leaves no clean result\n// envelope, and the live in-flight signal the budget hook steers on. Reading is total: a truncated\n// final line (a `timeout` kill mid-flush) or any malformed entry is skipped, never thrown.\n\nimport { readdirSync } from \"node:fs\";\nimport { basename, dirname, join } from \"node:path\";\nimport type { ModelUsageEntry } from \"./schema.js\";\nimport { asRecord, modelIdentity, readFileOrNull } from \"./util.js\";\n\nexport interface TranscriptUsage {\n readonly models: readonly ModelUsageEntry[];\n readonly turns: number;\n readonly durationMs: number;\n readonly firstTsMs: number | null;\n readonly lastTsMs: number | null;\n}\n\n// `missing` distinguishes an unreadable main transcript (no signal at all) from an empty-but-present one.\nexport interface TranscriptTree {\n readonly entries: readonly unknown[];\n readonly files: readonly string[];\n readonly missing: boolean;\n}\n\n// Non-negative finite, else 0 — a NaN/absent field must not poison the sum.\nconst numField = (rec: Record<string, unknown>, key: string): number => {\n const v = rec[key];\n return typeof v === \"number\" && Number.isFinite(v) && v >= 0 ? v : 0;\n};\n\ninterface MessageUsage {\n readonly id: string | null;\n readonly model: string;\n readonly input: number;\n readonly output: number;\n readonly cacheRead: number;\n readonly cacheWrite: number;\n}\n\n// Claude Code names cache fields cache_read_input_tokens/cache_creation_input_tokens; the abstract\n// envelope names them cache_read_tokens/cache_write_tokens — the rename happens here. `id` is carried\n// so a message logged across several lines (one per content block of a parallel tool-use turn, each\n// repeating the message-level usage) is summed once.\nconst messageUsage = (entry: unknown): MessageUsage | null => {\n const rec = asRecord(entry);\n if (rec === null || rec[\"type\"] !== \"assistant\") return null;\n const msg = asRecord(rec[\"message\"]);\n if (msg === null) return null;\n const model = msg[\"model\"];\n const usage = asRecord(msg[\"usage\"]);\n if (typeof model !== \"string\" || usage === null) return null;\n const id = msg[\"id\"];\n return {\n id: typeof id === \"string\" ? id : null,\n model: modelIdentity(model),\n input: numField(usage, \"input_tokens\"),\n output: numField(usage, \"output_tokens\"),\n cacheRead: numField(usage, \"cache_read_input_tokens\"),\n cacheWrite: numField(usage, \"cache_creation_input_tokens\"),\n };\n};\n\nconst tsMsOf = (entry: unknown): number | null => {\n const rec = asRecord(entry);\n const ts = rec?.[\"timestamp\"];\n if (typeof ts !== \"string\") return null;\n const ms = Date.parse(ts);\n return Number.isNaN(ms) ? null : ms;\n};\n\ninterface Totals {\n readonly input: number;\n readonly output: number;\n readonly cacheRead: number;\n readonly cacheWrite: number;\n}\nconst EMPTY_TOTALS: Totals = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };\n\n// One object per non-blank line, dropping any that fails to parse — this makes a timeout-truncated\n// final line a no-op rather than a crash.\nexport const parseJsonl = (text: string): readonly unknown[] =>\n text\n .split(\"\\n\")\n .filter((line) => line.trim() !== \"\")\n .flatMap((line) => {\n try {\n return [JSON.parse(line) as unknown];\n } catch {\n return [];\n }\n });\n\n// A message logged over multiple lines (repeated message.id) is counted once — otherwise a parallel\n// tool-use turn's usage, stamped on every content-block line, is summed several times and inflates\n// spend. Entries with no id are counted as-is. `models` order follows first-appearance.\nexport const sumTranscriptUsage = (entries: readonly unknown[]): TranscriptUsage => {\n const summed = entries.reduce<{ totals: Map<string, Totals>; turns: number; seen: Set<string> }>(\n (acc, entry) => {\n const u = messageUsage(entry);\n if (u === null) return acc;\n if (u.id !== null && acc.seen.has(u.id)) return acc;\n if (u.id !== null) acc.seen.add(u.id);\n const prev = acc.totals.get(u.model) ?? EMPTY_TOTALS;\n acc.totals.set(u.model, {\n input: prev.input + u.input,\n output: prev.output + u.output,\n cacheRead: prev.cacheRead + u.cacheRead,\n cacheWrite: prev.cacheWrite + u.cacheWrite,\n });\n return { totals: acc.totals, turns: acc.turns + 1, seen: acc.seen };\n },\n { totals: new Map(), turns: 0, seen: new Set() },\n );\n\n const models: readonly ModelUsageEntry[] = [...summed.totals].map(([model, t]) => ({\n model,\n input_tokens: t.input,\n output_tokens: t.output,\n cache_read_tokens: t.cacheRead,\n cache_write_tokens: t.cacheWrite,\n }));\n\n const bounds = entries.reduce<{ min: number | null; max: number | null }>(\n (acc, entry) => {\n const ms = tsMsOf(entry);\n if (ms === null) return acc;\n return {\n min: acc.min === null || ms < acc.min ? ms : acc.min,\n max: acc.max === null || ms > acc.max ? ms : acc.max,\n };\n },\n { min: null, max: null },\n );\n\n return {\n models,\n turns: summed.turns,\n durationMs: bounds.min !== null && bounds.max !== null ? bounds.max - bounds.min : 0,\n firstTsMs: bounds.min,\n lastTsMs: bounds.max,\n };\n};\n\n// Claude Code writes each subagent to <dir>/<session-id>/subagents/agent-*.jsonl, beside\n// <dir>/<session-id>.jsonl. An empty result covers a missing directory or an older/other layout.\nconst subagentFiles = (mainPath: string): readonly string[] => {\n const dir = join(dirname(mainPath), basename(mainPath, \".jsonl\"), \"subagents\");\n try {\n return readdirSync(dir)\n .filter((name) => name.endsWith(\".jsonl\"))\n .map((name) => join(dir, name));\n } catch {\n return [];\n }\n};\n\n// Two layouts: subagents in their own files, OR inlined into the main marked isSidechain:true. Read\n// the sibling files ONLY when the main carries no inline sidechain, so either layout is summed once.\nexport const readTranscriptTree = (mainPath: string): TranscriptTree => {\n const mainText = readFileOrNull(mainPath);\n const mainEntries = mainText === null ? [] : parseJsonl(mainText);\n const inlineSidechains = mainEntries.some((e) => asRecord(e)?.[\"isSidechain\"] === true);\n const siblings = inlineSidechains ? [] : subagentFiles(mainPath);\n const siblingReads = siblings.flatMap((path) => {\n const text = readFileOrNull(path);\n return text === null ? [] : [{ path, entries: parseJsonl(text) }];\n });\n return {\n entries: [...mainEntries, ...siblingReads.flatMap((r) => r.entries)],\n files: [...(mainText === null ? [] : [mainPath]), ...siblingReads.map((r) => r.path)],\n missing: mainText === null,\n };\n};\n","// The \"already answered\" state (issue #151): the deterministic registry of prior inline findings\n// whose threads a human reply answered, plus the two rules built on it — the re-review seed surfaces\n// the registry so the next-round agent does not re-raise, and post() treats a VERBATIM re-raise as\n// closed: identical match (id), identical claim TEXT (title + description + reasoning),\n// identical severity, and identical location/fix (path + patch — the line is deliberately excluded,\n// positional drift is not evidence), i.e. no new evidence by definition. The drop is removed from\n// the surfaced review and NAMED in the sticky; a re-raise with any changed component is kept and\n// annotated with the prior answer's link.\n\nimport * as t from \"io-ts\";\nimport { ancestors } from \"./comment-chain.js\";\nimport { escapeCodeBackticks, parseFindingsMarker } from \"./surface.js\";\nimport { parseJsonl } from \"./transcript.js\";\nimport type { GhApi } from \"./gh.js\";\nimport {\n isSynthesizedFindingId,\n resolveFindingId,\n resolveRuleId,\n synthesizedFindingId,\n} from \"./schema.js\";\nimport type { Finding, Severity } from \"./schema.js\";\nimport { clipText, errMsg } from \"./util.js\";\n\n// One flat review comment as REST `pulls/{n}/comments` returns it — enough to rebuild reply threads\n// from `in_reply_to_id` chains (a reply to a reply included) and to decode the bot comment's embedded\n// per-finding marker.\nexport interface ThreadComment {\n readonly id: number;\n readonly in_reply_to_id: number | null;\n readonly user_login: string;\n // \"User\" | \"Bot\" — lets the registry exclude replies from OTHER bots (a CI/dependabot comment\n // is not a human answer), not just this pipeline's own bot login.\n readonly user_type: string | null;\n readonly body: string | null;\n readonly html_url: string;\n readonly path: string | null;\n readonly line: number | null;\n readonly created_at: string | null;\n}\n\n// The jq projection gather and post share. It emits BOTH the flat `user_login`/`user_type` the\n// answered-registry codec reads AND the nested `user: {login}` (+ author_association) the\n// conversation codec reads — one fetch feeds two consumers, and neither may be silently starved by\n// a field rename (issue #151 review r1: the original single-shape projection emptied the\n// conversation's review_comments in production while the mocks, which bypass jq, kept the tests\n// green).\nexport const THREAD_COMMENT_JQ =\n \".[] | {id, in_reply_to_id, user: {login: .user.login}, user_login: .user.login, user_type: .user.type, body, html_url, path, line, created_at, author_association}\";\n\nexport const ThreadCommentCodec = t.type({\n id: t.number,\n in_reply_to_id: t.union([t.number, t.null]),\n user_login: t.string,\n user_type: t.union([t.string, t.null]),\n body: t.union([t.string, t.null]),\n html_url: t.string,\n path: t.union([t.string, t.null]),\n line: t.union([t.number, t.null]),\n created_at: t.union([t.string, t.null]),\n});\n\n// The registry entry for one answered finding: the finding's identifying fields (the verbatim-match\n// targets), the thread link, and the last human reply's link + a clipped excerpt for the seed.\nexport interface AnsweredEntry {\n // The answered finding's id; a pre-id marker resolves it the same way the registry's legacy\n // upcast does (code → id, else synthesized), so the entry keys to the identical claim next round.\n readonly code: string;\n readonly title: string;\n readonly description: string;\n readonly reasoning: string;\n // The answered finding's severity — a re-raise ESCALATED in severity is not verbatim (the claim\n // weight changed), so it is kept and annotated rather than dropped (issue #151 review r1).\n readonly severity: Severity;\n // The answered finding's path and proposed patch — a re-raise RELOCATED to another file, or one\n // whose proposed fix changed, carries something new and is kept, not dropped (issue #151 review\n // r3). patch is null when the answered finding carried none. The LINE is deliberately NOT part of\n // the predicate: positional drift (a rebase moving the same claim) is not evidence, while a\n // genuinely new instance changes the claim text.\n readonly path: string;\n readonly patch: string | null;\n // The LAST human reply's timestamp and id — both READ for the dedup: \"most recent answer wins\"\n // keys on the ANSWER time, never the root (review-posting) order, and an equal-timestamp tie\n // breaks by the reply id (monotonic with creation), not by thread order (issues #151 review r4 +\n // r7).\n readonly repliedAt: string | null;\n readonly replyId: number;\n readonly threadUrl: string;\n readonly replyUrl: string;\n readonly replyAuthor: string;\n readonly replyExcerpt: string;\n}\n\n// The staged-registry codec (what gather writes to answered.json and seed-draft reads back) — the\n// SNAKE_CASE wire shape, distinct from the camelCase in-process AnsweredEntry; rows that fail decode\n// are dropped like every other untrusted artifact, never fatal.\nexport const AnsweredEntryCodec = t.type({\n code: t.string,\n title: t.string,\n description: t.string,\n reasoning: t.string,\n severity: t.union([\n t.literal(\"critical\"),\n t.literal(\"major\"),\n t.literal(\"minor\"),\n t.literal(\"nit\"),\n ]),\n path: t.string,\n patch: t.union([t.string, t.null]),\n replied_at: t.union([t.string, t.null]),\n reply_id: t.number,\n thread_url: t.string,\n reply_url: t.string,\n reply_author: t.string,\n reply_excerpt: t.string,\n});\n\nexport type StagedAnsweredEntry = t.TypeOf<typeof AnsweredEntryCodec>;\n\nexport const encodeAnsweredEntry = (e: AnsweredEntry): StagedAnsweredEntry => ({\n code: e.code,\n title: e.title,\n description: e.description,\n reasoning: e.reasoning,\n severity: e.severity,\n path: e.path,\n patch: e.patch,\n replied_at: e.repliedAt,\n reply_id: e.replyId,\n thread_url: e.threadUrl,\n reply_url: e.replyUrl,\n reply_author: e.replyAuthor,\n reply_excerpt: e.replyExcerpt,\n});\n\nexport const decodeAnsweredEntry = (raw: unknown): StagedAnsweredEntry | null => {\n const decoded = AnsweredEntryCodec.decode(raw);\n return decoded._tag === \"Right\" ? decoded.right : null;\n};\n\n// A reply is \"answered\" when a HUMAN commented on the thread: neither this pipeline's bot (matched\n// by login) nor any other bot account (matched by the REST user.type, so a CI/dependabot comment\n// can't masquerade as an answer — issue #151 review r1). A MISSING type (null — an unexpected API\n// shape) fails closed to \"not human\": an uncertain answer must not cause a finding to be dropped\n// (issue #151 review r2).\nconst isHuman = (login: string, type: string | null, botLogin: string): boolean =>\n login !== botLogin && type === \"User\";\n\nconst EXCERPT_LIMIT = 400;\n\n// OUTDATED/minimized threads are deliberately NOT excluded: the pipeline minimizes superseded\n// bot comments at the end of every post, so excluding them would erase the very persistence the\n// feature exists for — an answer from round 1 must still close a verbatim re-raise in round 8\n// (issue #151 review r1 considered and rejected the stale-thread scope).\n\n// The pure thread→registry construction. A thread is anchored on the bot's comment (by login); the\n// root's embedded per-finding marker names the finding. Replies are every non-bot comment whose\n// in_reply_to chain reaches that root. The LAST human reply per thread is recorded (the operative\n// dismissal — issue #151 review r5); when the same\n// code was answered in several threads, the most recent thread wins. Tolerant: an undecodable bot\n// comment (no marker, or a marker that fell to the link form) contributes nothing.\nexport const answeredRegistryFrom = (\n comments: readonly ThreadComment[],\n botLogin: string,\n): readonly AnsweredEntry[] => {\n // Order-independent: the REST order (ascending creation) is not a contract, so the reply\n // selections sort explicitly by (created_at, id) before processing (issue #151 review r2). A\n // MISSING created_at sorts FIRST (\"\"), so an unknown-time reply is never picked as the\n // operative LAST answer (issue #151 review r7).\n const ordered = [...comments].sort(\n (a, b) =>\n (a.created_at ?? \"\").localeCompare(b.created_at ?? \"\") ||\n (a.id > b.id ? 1 : a.id < b.id ? -1 : 0),\n );\n const byId = new Map<number, ThreadComment>();\n for (const c of ordered) byId.set(c.id, c);\n\n // The root of a comment's chain (walk in_reply_to_id up, cycle-safe); null when the chain never\n // reaches a top-level comment within the fetched set.\n const rootOf = (c: ThreadComment): ThreadComment | null => {\n const chain = [\n ...ancestors(c, (n) =>\n n.in_reply_to_id === null ? null : (byId.get(n.in_reply_to_id) ?? null),\n ),\n ];\n const root = chain[chain.length - 1];\n return root !== undefined && root.in_reply_to_id === null ? root : null;\n };\n\n // The answered finding of a bot-rooted thread, from the root comment's embedded per-finding marker.\n const findingOf = (\n root: ThreadComment,\n ): {\n code: string;\n title: string;\n description: string;\n reasoning: string;\n severity: Severity;\n path: string;\n patch: string | null;\n } | null => {\n const decoded = parseFindingsMarker(root.body ?? \"\");\n const doc =\n typeof decoded === \"object\" && decoded !== null\n ? (decoded as { findings?: unknown }).findings\n : undefined;\n const first = Array.isArray(doc) ? (doc[0] as Record<string, unknown> | undefined) : undefined;\n if (first === undefined) return null;\n const title = first[\"title\"];\n const description = first[\"description\"];\n const reasoning = first[\"reasoning\"];\n const id = first[\"id\"];\n const legacyCode = first[\"code\"];\n const severity = first[\"severity\"];\n const path = first[\"path\"];\n const patch = first[\"patch\"];\n return typeof title === \"string\" &&\n typeof description === \"string\" &&\n typeof reasoning === \"string\" &&\n typeof path === \"string\" &&\n (severity === \"critical\" ||\n severity === \"major\" ||\n severity === \"minor\" ||\n severity === \"nit\")\n ? {\n // resolveRuleId: the ONE legacy-spelling precedence the upcast, this reader, and the\n // below-floor nit reader share — a pre-id marker (or one written before the migration)\n // carries `code`; a codeless one resolves to the same synthesized id the registry's\n // legacy upcast derives, so the entry keys to the identical claim on the next round.\n code:\n resolveRuleId({\n id: typeof id === \"string\" ? id : undefined,\n code: typeof legacyCode === \"string\" ? legacyCode : undefined,\n path,\n title,\n }) ?? synthesizedFindingId(path, title),\n title,\n description,\n reasoning,\n severity,\n path,\n patch: typeof patch === \"string\" ? patch : null,\n }\n : null;\n };\n\n // Group every comment under its root id; the root's own id keys the group. Iterating the SORTED\n // array feeds both selections below — the first-human-reply find() and the last-wins dedup both\n // read group/map insertion order, so the sort must drive that order (issue #151 review r3: the\n // original fix sorted into `byId` only, leaving the selection loops on the raw API order).\n const threads = new Map<number, ThreadComment[]>();\n for (const c of ordered) {\n const root = rootOf(c);\n if (root === null) continue;\n const group = threads.get(root.id);\n if (group === undefined) threads.set(root.id, [c]);\n else group.push(c);\n }\n\n // One entry per answered bot-rooted thread: the thread must be anchored on the BOT's comment;\n // the answer recorded is the LAST HUMAN reply in it — the operative dismissal is the most recent\n // answer, and a thread answered twice must not have its earlier reply win the dedup below (issue\n // #151 review r5).\n const entries: AnsweredEntry[] = [];\n for (const [rootId, group] of threads) {\n const root = byId.get(rootId);\n if (root === undefined || root.user_login !== botLogin) continue;\n const finding = findingOf(root);\n if (finding === null) continue;\n const humanReplies = group.filter(\n (c) => c.id !== root.id && isHuman(c.user_login, c.user_type, botLogin),\n );\n const reply = humanReplies[humanReplies.length - 1];\n if (reply === undefined) continue;\n entries.push({\n ...finding,\n repliedAt: reply.created_at,\n replyId: reply.id,\n threadUrl: root.html_url,\n replyUrl: reply.html_url,\n replyAuthor: reply.user_login,\n replyExcerpt: clipText(reply.body ?? \"\", EXCERPT_LIMIT),\n });\n }\n // Dedup by the shared note key, keeping the entry with the MOST RECENT ANSWER — keyed on the\n // REPLY time, never the root (review-posting) order: an older thread answered later must win over\n // a newer thread answered earlier (issue #151 review r4). Sort DESCENDING by (repliedAt, replyId)\n // and keep the first per key — an equal-timestamp tie breaks toward the LATER reply id\n // (monotonic with creation), not toward any thread order (issue #151 review r7).\n const byKey = new Map<string, AnsweredEntry>();\n for (const entry of [...entries].sort(\n (a, b) => (b.repliedAt ?? \"\").localeCompare(a.repliedAt ?? \"\") || b.replyId - a.replyId,\n )) {\n const key = answeredNoteKey({ id: entry.code, title: entry.title });\n if (!byKey.has(key)) byKey.set(key, entry);\n }\n return [...byKey.values()];\n};\n\n// The id match: 0.10 requires every finding to carry an id, and the legacy upcast gives every pre-id\n// finding one (code → id, or synthesized), so two rounds of the same claim always key to equal ids.\n// An EMPTY id resolves exactly the way the registry builder resolves a marker finding — the two sides\n// share resolveFindingId, so a verbatim re-raise of an empty-id finding still matches the entry its\n// marker synthesized. A TITLE match is the second chance the pre-0.10 \"code (or title)\" rule gave,\n// RESTRICTED to entries whose code was synthesized (isSynthesizedFindingId): a codeless claim whose\n// answer pre-dates ids can only recover its annotation when the re-raise is RELOCATED (the\n// synthesized key is path-derived) or carries a fresh agent id — while an unrelated same-title entry\n// with a real code can never mis-bind. The full-claim verbatim check still gates the drop.\nconst isSynthesizedTitleMatch = (f: Finding, e: Pick<AnsweredEntry, \"code\" | \"title\">): boolean =>\n isSynthesizedFindingId(e.code) && e.title === f.title;\n\nconst matches = (\n resolvedId: string,\n f: Finding,\n e: Pick<AnsweredEntry, \"code\" | \"title\">,\n): boolean => e.code === resolvedId || isSynthesizedTitleMatch(f, e);\n\n// The full-claim verbatim predicate, extracted from applyAnswered below so the seed's pre-filter\n// (issue #233 r2) can ask the SAME question of the staged registry — one definition, two consumers.\n// The ONE verbatim claim-field list: the six per-field comparisons consumed by both the full-claim\n// predicate and the title-second-chance scorer. The VerbatimPick type DERIVES from the array, so\n// adding a claim field is a single edit the compiler verifies — the type and the runtime list can\n// never diverge (the same one-definition discipline as answeredNoteKey below).\nconst VERBATIM_FIELDS = [\"title\", \"description\", \"reasoning\", \"severity\", \"path\", \"patch\"] as const;\ntype VerbatimPick = Pick<AnsweredEntry, (typeof VERBATIM_FIELDS)[number]>;\n\nconst verbatimFieldEqual = (\n f: Finding,\n e: VerbatimPick,\n field: (typeof VERBATIM_FIELDS)[number],\n): boolean => (field === \"patch\" ? (f.patch ?? null) === e.patch : f[field] === e[field]);\n\nexport const isVerbatimReRaise = (f: Finding, e: VerbatimPick): boolean =>\n VERBATIM_FIELDS.every((field) => verbatimFieldEqual(f, e, field));\n\n// Would post's answered-filter DROP this finding? applyAnswered below and the seed's pre-filter\n// both ask this (issue #233 r2), so \"answered\" can never mean two things across the pipeline. e is\n// the staged wire shape too: every field the predicate reads shares its name across both types.\n// The one known corner where the two consumers disagree: a finding that id-matches a NON-verbatim\n// entry while a verbatim (6/6) synthesized same-title entry sits beside it — post keeps it (only\n// the chosen entry feeds the drop), the seed's existential scan drops it (see applyAnswered).\nexport const isAnsweredDrop = (\n resolvedId: string,\n f: Finding,\n e: Pick<\n AnsweredEntry,\n \"code\" | \"title\" | \"description\" | \"reasoning\" | \"severity\" | \"path\" | \"patch\"\n >,\n): boolean => matches(resolvedId, f, e) && isVerbatimReRaise(f, e) && f.severity !== \"critical\";\n\n// How many of the verbatim claim fields a finding shares with an entry — the title-second-chance\n// scorer: among several synthesized same-title entries (same title, different paths — their\n// synthesized ids differ), the entry sharing the MOST fields is the thread the claim came from, so\n// a kept re-raise's annotation link binds it rather than the first same-title entry in registry\n// order.\nconst verbatimMatchCount = (f: Finding, e: VerbatimPick): number =>\n VERBATIM_FIELDS.reduce((count, field) => count + (verbatimFieldEqual(f, e, field) ? 1 : 0), 0);\n\n// The ONE note-key contract: a finding's annotation key is its id; an empty id (a pre-id staged row,\n// or a reviewer-supplied empty id) falls back to \"title:<title>\" so the note still keys to something\n// — written once here, consumed by the registry builder, applyAnswered, and both renderers, so the\n// key can never drift between the writer and the lookups (issue #151 review r2).\nexport const answeredNoteKey = (f: { id: string; title: string }): string =>\n f.id !== \"\" ? f.id : `title:${f.title}`;\n\n// The title second chance, run ONLY on an id miss (the common case pays nothing): the synthesized\n// same-title entry sharing the most verbatim claim fields, ties keeping registry order. Scored in\n// one pass — each candidate once, strict > preserves the first on ties.\nconst NO_TITLE_MATCH = { entry: undefined, score: -1 } as const;\n\nconst bestTitleMatch = (\n f: Finding,\n registry: readonly AnsweredEntry[],\n): { entry: AnsweredEntry | undefined; score: number } => {\n let best: AnsweredEntry | undefined;\n let bestScore = -1;\n for (const e of registry) {\n if (!isSynthesizedTitleMatch(f, e)) continue;\n const score = verbatimMatchCount(f, e);\n if (score > bestScore) {\n best = e;\n bestScore = score;\n if (score === VERBATIM_FIELDS.length) break;\n }\n }\n return { entry: best, score: bestScore };\n};\n\n// The per-finding \"re-raised; prior answer at <link>\" annotation for a kept (changed-evidence)\n// re-raise; the pipeline cannot judge whether the reply dismissed or acknowledged the finding, so the\n// annotation links it and demands the new evidence be named.\nexport const answeredNote = (e: AnsweredEntry): string =>\n `Re-raised; prior answer at ${e.replyUrl} by ${e.replyAuthor} — cite the new evidence that invalidates it.`;\n\nexport interface AnsweredFilter {\n readonly findings: readonly Finding[];\n // code → note for KEPT re-raises with changed evidence; rendered under each such finding.\n readonly reRaisedNotes: Readonly<Record<string, string>>;\n // The entries whose findings were dropped: verbatim re-raises of an answered finding, named in the\n // sticky rather than silently vanishing. DEDUPED by ENTRY — several findings dropped against one\n // answer (an id repeated within a round, or same-title fresh-id re-raises of a synthesized entry)\n // list the answer once, never double-counted (issue #151 review r2).\n readonly verbatimReRaised: readonly AnsweredEntry[];\n // The dropped FINDINGS' ids (resolved): post strips these from systemic finding_ids — a title-\n // matched drop keys the entry's synthesized code, but the systemic list names the finding's own id,\n // so stripping by entry code alone would dangle a dropped finding (the two sides must agree on what\n // a drop removes).\n readonly droppedFindingIds: readonly string[];\n // The TRUE count of dropped findings (pre-dedup): the sticky's count must not understate the\n // suppression just because several findings shared one code (issue #151 review r5).\n readonly droppedCount: number;\n}\n\n// The deterministic backstop beneath the seed guidance: an answered finding re-raised VERBATIM\n// (identical title, description, and reasoning — no new evidence by definition) is treated as closed\n// and dropped from this review, so the round's counts and stop signal reflect the dismissal. The\n// claim TEXT is the evidence: a change to any of title/description/reasoning, or to the severity,\n// means the re-raise carries something new and MUST be kept + annotated (issue #151 review r2 — the\n// SPEC's \"no new evidence\" criterion, not just a title+reasoning byte-match). A critical is never\n// dropped — the pipeline must not suppress a critical from the surfaced review.\nexport const applyAnswered = (\n findings: readonly Finding[],\n registry: readonly AnsweredEntry[],\n): AnsweredFilter => {\n const kept: Finding[] = [];\n // Built via Object.fromEntries (CreateDataProperty): a reviewer-supplied code like \"__proto__\"\n // must become an OWN data key, never a prototype write that silently no-ops the annotation (the\n // same invariant the codebase's other code-keyed maps hold — issue #151 review r1).\n const noteEntries: [string, string][] = [];\n const droppedByEntry = new Map<number, AnsweredEntry>();\n const droppedFindingIds: string[] = [];\n let droppedCount = 0;\n for (const f of findings) {\n // ID match first across the WHOLE registry, title second chance only against synthesized\n // entries: a finding title-matching an unrelated entry ahead of its true id-matched entry must\n // not mis-bind its annotation (the id match wins wherever it exists). The second chance picks\n // the synthesized same-title entry sharing the MOST verbatim claim fields (ties keep registry\n // order), so two codeless same-title answers under different paths cannot mis-bind a kept\n // re-raise. The chosen entry alone feeds the drop decision: a title-matched entry drops the\n // finding exactly when its score is a full verbatim match (6/6), while the seed pre-filter is\n // existential over the whole registry — so the two sides disagree in one corner (a non-verbatim\n // id match beside a verbatim same-title entry; documented on isAnsweredDrop). The scorer\n // changes suppression, not just annotation.\n const resolvedId = resolveFindingId(f);\n const idMatch = registry.find((e) => e.code === resolvedId);\n const { entry: titleMatch, score: titleScore } =\n idMatch === undefined ? bestTitleMatch(f, registry) : NO_TITLE_MATCH;\n const entry = idMatch ?? titleMatch;\n if (entry === undefined) {\n kept.push(f);\n continue;\n }\n // The full claim: text (title/description/reasoning), weight (severity), AND location/fix\n // (path, patch) — a re-raise relocated to another file or proposing a different fix carries\n // something new. The line is deliberately excluded: positional drift (a rebase moving the same\n // claim) is not evidence (issue #151 review r3). patch is normalized (undefined → null) so an\n // absent patch on both sides compares equal. isAnsweredDrop's conjunction holds by\n // construction here (the entry was selected BY a match), so the drop reuses the scorer's\n // already-computed verbatim count on the title path — score === VERBATIM_FIELDS.length is\n // exactly isVerbatimReRaise, and the id path re-runs the predicate the seed shares.\n const dropped =\n (idMatch !== undefined\n ? isVerbatimReRaise(f, entry)\n : titleScore === VERBATIM_FIELDS.length) && f.severity !== \"critical\";\n if (dropped) {\n droppedByEntry.set(entry.replyId, entry);\n droppedFindingIds.push(resolvedId);\n droppedCount += 1;\n } else {\n kept.push(f);\n noteEntries.push([answeredNoteKey(f), answeredNote(entry)]);\n }\n }\n return {\n findings: kept,\n reRaisedNotes: Object.fromEntries(noteEntries),\n verbatimReRaised: [...droppedByEntry.values()],\n droppedFindingIds,\n droppedCount,\n };\n};\n\n// The sticky note naming what was dropped — the suppression is never silent (SPEC §3.3 truthful).\n// The COUNT is the true pre-dedup finding count (several findings sharing one code count as several\n// suppressions); the LINES stay deduped by key (issue #151 review r5). count is REQUIRED — a\n// default would silently reintroduce the understated count for a caller that forgets it (issue\n// #151 review r7).\nexport const answeredReRaiseNote = (entries: readonly AnsweredEntry[], count: number): string => {\n if (entries.length === 0) return \"\";\n const label = (e: AnsweredEntry): string =>\n e.code !== \"\" ? `\\`${escapeCodeBackticks(e.code)}\\`` : `“${escapeCodeBackticks(e.title)}”`;\n const lines = entries.map(\n (e) => `> - ${label(e)} — [prior answer](${e.replyUrl}) by ${e.replyAuthor}`,\n );\n return [\n `> ↩️ **${String(count)} finding(s) re-raised without new evidence — treated as answered** (each has a human reply on its prior inline thread):`,\n ...lines,\n ].join(\"\\n\");\n};\n\n// Best-effort fetch of the full review-comment set (bot + human, paginated at the API's max page\n// size so a long-lived PR's history costs the fewest requests — the FULL history is intentional,\n// persistence is the feature: an answer from round 1 must still close a round-8 verbatim re-raise);\n// null on any transport error so a degraded channel degrades to an empty registry — never a failed\n// post.\nexport const fetchThreadComments = async (\n ghApi: GhApi,\n repo: string,\n prNumber: number,\n): Promise<readonly ThreadComment[] | null> => {\n try {\n const rows = parseJsonl(\n await ghApi([\n // per_page rides the QUERY string — a `-f` field would flip `gh api` from GET to POST\n // and 422 every answered-thread fetch.\n `repos/${repo}/pulls/${String(prNumber)}/comments?per_page=100`,\n \"--paginate\",\n \"--jq\",\n THREAD_COMMENT_JQ,\n ]),\n );\n return rows.flatMap((row) => {\n const decoded = ThreadCommentCodec.decode(row);\n return decoded._tag === \"Right\" ? [decoded.right] : [];\n });\n } catch (err) {\n process.stderr.write(\n `Warning: could not fetch review threads to detect answered findings (${errMsg(err)}) — no answered-finding state for this post\\n`,\n );\n return null;\n }\n};\n","// Pure data-in, string-out Eta rendering — no side effects, no model invocation.\n\nimport { Eta } from \"eta\";\nimport { BODY_CLIP_CHARS, clipText } from \"./util.js\";\nimport type { Finding, Severity, SystemicProblem, Verdict } from \"./schema.js\";\nimport { isIncompleteFindings, resolveFindingId } from \"./schema.js\";\nimport type { DiscussionLink, RenderInput, SeverityCounts } from \"./types.js\";\nimport { computeCost, parseInstant } from \"./cost.js\";\nimport {\n severityEmoji,\n projectPatch,\n formatConfidence,\n roundsSummary,\n convergenceSummary,\n convergenceBadge,\n changeSizeSummary,\n computeSameRootNotes,\n metastasisNote,\n findingsMarkerPair,\n escapeCodeBackticks,\n escapeFence,\n lineRange,\n DEFAULT_NIT_VISIBILITY_FLOOR,\n} from \"./surface.js\";\nimport { answeredNoteKey } from \"./answered.js\";\nimport type { PatchProjection } from \"./surface.js\";\n\n// pipes break markdown table columns.\nconst escapePipes = (text: string): string => text.replace(/\\|/g, \"\\\\|\");\n\n// A code renders inside backticks and a code_url inside a markdown link: a backtick in the code\n// breaks the span, and a paren/newline in the URL breaks the link (or the blockquote the nit's\n// aside sits in) — issue #233 r2. The newline/backtick handling is escapeCodeBackticks' own.\n// The paren policy has ONE owner: an unbalanced paren truncates GitHub's autolink, so every\n// URL-building surface on the sticky shares this encoding (issue #231 r2).\nconst encodeAutolinkParens = (url: string): string =>\n url.replace(/\\(/g, \"%28\").replace(/\\)/g, \"%29\");\n\nconst linkSafeUrl = (url: string): string => encodeAutolinkParens(escapeCodeBackticks(url));\n\n// A stray finding the sticky lists links back to its code at the reviewed SHA: a BARE URL — GitHub\n// autolinks it and sizes the rendering sensibly, where the nested-aside `<details>` permalink JP\n// prototyped renders dead in issue comments (issue #231). Each segment is percent-encoded: lone\n// surrogates are replaced with U+FFFD first (encodeURIComponent THROWS on them — a junk path must\n// degrade, never crash the post), then parens after it (an unbalanced paren truncates GitHub's\n// autolink; linkSafeUrl's policy — issue #231 r1). Returns null for the findings a link would lie\n// about: a LEFT-side finding (its line numbers index the BASE tree, so a head-blob anchor names\n// the wrong code) and an empty path. `anchor` false links the path only — a stray GitHub rejected\n// inline must not re-assert its known-bad coordinates as an exact anchor.\nconst permalinkFor = (base: string, f: Finding, anchor: boolean): string | undefined => {\n if (f.path === \"\" || f.side === \"LEFT\") return undefined;\n const path = f.path\n .split(\"/\")\n .map((segment) =>\n encodeAutolinkParens(\n encodeURIComponent(\n segment.replace(\n /[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?<![\\uD800-\\uDBFF])[\\uDC00-\\uDFFF]/g,\n \"�\",\n ),\n ),\n // Markdown emphasis/syntax characters: `__` runs split the bare URL across CommonMark\n // nodes and truncate the autolink, and a path-only link ending in one of these loses its\n // tail to the autolinker's trailing-punctuation trim (issue #231 r4).\n )\n .replace(/_/g, \"%5F\")\n .replace(/\\*/g, \"%2A\")\n .replace(/'/g, \"%27\")\n .replace(/!/g, \"%21\"),\n )\n .join(\"/\");\n return anchor ? `${base}${path}#L${lineRange(f.start_line, f.end_line, \"-L\")}` : `${base}${path}`;\n};\n\n// The machine-channel budget for suppressed-nit blocks: each field is clipped individually\n// (BODY_CLIP_CHARS), but the SUM across a nit-heavy round is unbounded, and the sticky is the one\n// comment post deliberately does not shed — an unbounded machine block can still 422 it, which the\n// old embed-limit valve structurally prevented (issue #233 r1). The budget counts each nit's\n// WHOLE block — the carried lines plus the fixed summary/severity/location/`-->` lines and their\n// blockquote prefixes — and drops a nit's entire block once exhausted. The cut is marked in the\n// machine channel, never silent (issue #233 r5).\nconst CARRIED_TOTAL_CHARS = 40_000;\nconst SUPPRESSED_NIT_BLOCK_OVERHEAD = 280;\n\n// The discussion surface's budget: the per-finding asides AND the orphaned \"earlier rounds\"\n// section are additive to the one body post never sheds, so a discussion-heavy round drops whole\n// asides past this total — the cut is named in the template, never silent (the same discipline\n// the suppressed-nit budget applies). The orphaned section draws FIRST: its cut is permanent (a\n// departed id never re-enters a prior round's findings, so a dropped orphan is never re-listed),\n// while an aside cut recovers next round when the finding is still current.\nconst DISCUSSION_TOTAL_CHARS = 8_000;\nconst DISCUSSION_BLOCK_OVERHEAD = 120;\n// The orphaned entry renders as ONE composed line — the template interpolates this exact string,\n// so the budget charges the rendered length and no markup model can drift from it.\nconst orphanedEntryHtml = (\n token: string,\n links: readonly DiscussionLink[],\n truncated?: number,\n): string =>\n `- **\\`${token}\\`**: ${links\n .map((d) => `[${escapeHtml(d.author)} · ${d.when}](${linkSafeUrl(d.url)})`)\n .join(\" \")}${\n truncated !== undefined\n ? ` _(showing the ${String(PER_FINDING_LINKS)} newest of ${String(truncated)})_`\n : \"\"\n }`;\n// The newest-first cap every discussion list keeps (per-finding, per-orphan-token, and the\n// suppressed aside's slots). LIVES HERE so the template's \"showing the N newest of M\" notes\n// interpolate it — a cap change cannot leave a rendered note lying.\nexport const PER_FINDING_LINKS = 6;\n// How many dropped-thread ids the disclosure names per class; the rest ride the \"+N more\" suffix.\nconst DROPPED_IDS_SHOWN = 6;\n\n// The shared \"budget by rendered size\" walk both collateral asides use: items are added in order\n// while the ACCUMULATED size fits the cap; past it, onDrop decides each dropped item's fate\n// (null drops it entirely, a transformed item stays rendered emptied). The two budgets were\n// near-twins that drifted into a dead-budget bug — one walk, one cap comparison.\nconst budgetBySize = <T>(\n items: readonly T[],\n cap: number,\n sizeOf: (item: T) => number,\n onDrop: (item: T) => T | null,\n): { readonly kept: readonly T[]; readonly droppedItems: readonly T[]; readonly used: number } => {\n const kept: T[] = [];\n const droppedItems: T[] = [];\n let used = 0;\n for (const item of items) {\n const size = sizeOf(item);\n if (used + size > cap) {\n droppedItems.push(item);\n const replaced = onDrop(item);\n if (replaced !== null) kept.push(replaced);\n continue;\n }\n kept.push(item);\n used += size;\n }\n return { kept, droppedItems, used };\n};\n\nconst escapeHtml = (text: string): string =>\n text.replace(\n /[&<>\"']/g,\n (c) => ({ \"&\": \"&amp;\", \"<\": \"&lt;\", \">\": \"&gt;\", '\"': \"&quot;\", \"'\": \"&#39;\" })[c] ?? c,\n );\n\n// The aside's list + truncation note, composed ONCE here — the stray, systemic, and suppressed\n// surfaces all render this exact snippet (with the suppressed variant's blockquote prefix), so the\n// list markup and the \"showing the N newest of M\" wording have one owner. The template wraps it in\n// the <details> shell.\nconst discussionAsideHtml = (\n links: readonly DiscussionLink[],\n truncated: number | undefined,\n prefix: string,\n): string =>\n [\n ...links.map((d) => `${prefix}- [${escapeHtml(d.author)} · ${d.when}](${linkSafeUrl(d.url)})`),\n ...(truncated !== undefined\n ? [\n // A blank line closes the list: the note stands apart as its own paragraph instead of\n // reading as a continuation of the newest bullet.\n prefix,\n `${prefix}_(showing the ${String(PER_FINDING_LINKS)} newest of ${String(\n truncated,\n )} replies — the rest live on the comment thread.)_`,\n ]\n : []),\n ].join(\"\\n\");\n\ntype StrayView = Finding & {\n readonly patchProjection: PatchProjection;\n readonly answeredNote: string;\n // The RAW id, carried beside the escaped display form: the same-root note lookup in the\n // template is keyed on raw ids, so a backtick/newline id must not lose its note through\n // the escaping (issue #233 r3).\n readonly idKey: string;\n // The heading's collapsed line range (`start–end` via the shared lineRange collapse, so the\n // heading and the permalink anchor can never disagree — issue #231 r1).\n readonly rangeLabel: string;\n // Pre-encoded bare permalink to the finding's code at the reviewed SHA (issue #231); absent when\n // the caller supplies no repo (the standalone render command), for a LEFT-side finding (its\n // coordinates index the base tree), or for an empty path.\n readonly permalink?: string;\n // False for a stray GitHub rejected inline: its permalink links the path only, so the template\n // can tell an anchored link (which carries the agent-reported qualifier) from a bare one.\n readonly permalinkAnchored?: boolean;\n // Replies to the sticky comment that mention this finding's id (issue #246): the discussion\n // aside's linked list — pointers only, never reply prose.\n readonly discussion: readonly DiscussionLink[];\n // The pre-cap reply count when the 6-newest cap trimmed this finding's list — the aside names\n // its cut instead of rendering indistinguishably from a short thread.\n readonly discussionTruncated?: number;\n // The aside's composed list + truncation note (discussionAsideHtml) — empty when there is no\n // aside to render.\n readonly discussionHtml?: string;\n};\n\n// The per-stray \"re-raised; prior answer\" note, resolved HERE from the RAW finding's key — the\n// title is sanitized for rendering (escapePipes) but the note key was built from the raw title, so\n// a template-side lookup against the sanitized title would miss on a pipe/backtick title (issue\n// #151 review r2). The template renders the precomputed note.\nconst sanitizeFinding = (\n f: Finding,\n answeredNotes: Readonly<Record<string, string>> | undefined,\n discussionByFinding: Readonly<Record<string, readonly DiscussionLink[]>> | undefined,\n permalinkBase?: string,\n unanchored?: ReadonlySet<Finding>,\n discussionTruncated?: Readonly<Record<string, number>>,\n): StrayView => {\n const key = answeredNoteKey(f);\n // Reference identity, not a location key: post spreads the SAME finding objects into both\n // arrays, so the rejected set un-anchors exactly the findings GitHub rejected — a string key\n // would also demote a distinct twin finding at the same coordinates (issue #231 r2).\n const anchored = permalinkBase !== undefined && !(unanchored?.has(f) ?? false);\n const permalink =\n permalinkBase === undefined ? undefined : permalinkFor(permalinkBase, f, anchored);\n // permalinkBase undefined AND a LEFT/empty-path omission both land on `undefined`, so the spread\n // below is truly absent for every no-permalink case — the StrayView contract (issue #231 r4).\n return {\n ...f,\n title: escapePipes(f.title),\n path: escapeCodeBackticks(f.path),\n id: escapeCodeBackticks(f.id),\n // The RESOLVED id: the same-root notes are keyed on resolveFindingId (an empty id resolves to\n // its synthesized key), so the lookup must not miss the note on the raw id.\n idKey: resolveFindingId(f),\n ...(f.code_url !== undefined ? { code_url: linkSafeUrl(f.code_url) } : {}),\n rangeLabel: lineRange(f.start_line, f.end_line, \"–\"),\n ...(permalink !== undefined ? { permalink, permalinkAnchored: anchored } : {}),\n patchProjection: projectPatch(f.patch, \"comment-body\"),\n answeredNote:\n answeredNotes !== undefined && Object.prototype.hasOwnProperty.call(answeredNotes, key)\n ? (answeredNotes[key] ?? \"\")\n : \"\",\n discussion:\n discussionByFinding !== undefined &&\n Object.prototype.hasOwnProperty.call(discussionByFinding, f.id)\n ? (discussionByFinding[f.id] ?? [])\n : [],\n ...(discussionTruncated !== undefined &&\n Object.prototype.hasOwnProperty.call(discussionTruncated, f.id)\n ? { discussionTruncated: discussionTruncated[f.id] }\n : {}),\n };\n};\n\n// The suppressed-nit aside sits inside a `> [!NOTE]` blockquote, so a reviewer-supplied newline in a\n// title or path would break out of it (the hazard escapeCodeBackticks documents — it collapses\n// newlines AND neutralizes backticks). `m` is the confidence × likelihood the floor compared against,\n// shown so a maintainer who expands the aside sees WHY each nit was shelved (issue #164).\n// A below-floor nit is HIDDEN from the human list by policy (issue #164) — that is a visibility\n// decision, and it must not become a content filter. The projection used to keep 5 of a finding's 14\n// fields, which meant description, recommendation, reasoning and patch existed nowhere in the comment;\n// harmless while the document rode along as base64, a real hole once the document moved to the\n// artifact (issue #217). Everything now travels: the summary line stays exactly as it was, and the\n// rest rides the machine channel beside it, where a hidden nit's detail belongs.\ntype SuppressedNitView = {\n readonly title: string;\n readonly id: string;\n readonly codeUrl?: string;\n readonly path: string;\n // The machine location line renders start-end ALWAYS FULL (plain hyphen, no collapse) — a\n // machine-parseable form, deliberately distinct from the heading's collapsed rangeLabel; do not\n // migrate it onto lineRange (issue #231 r4).\n readonly startLine: number;\n readonly endLine: number;\n readonly side?: string;\n readonly severity: string;\n readonly confidence: string;\n readonly likelihood: string;\n readonly m: string;\n // Pre-split into blockquote-safe lines: the aside is a `>` blockquote, so an unprefixed line would\n // break out of it and spill a hidden nit's detail into the visible prose.\n readonly carried: readonly string[];\n // Replies naming this hidden nit's id (the aside's discussion slot — the suppressed aside is a\n // discussion surface like the strays').\n readonly discussion: readonly DiscussionLink[];\n readonly discussionTruncated?: number;\n // The aside's composed list + truncation note, blockquote-prefixed (discussionAsideHtml).\n readonly discussionHtml: string;\n};\n\n// HTML comments cannot nest, so a `-->` inside a carried field would close the block early and spill\n// the rest into the visible prose. A zero-width space between the dashes and the `>` breaks the\n// sequence while rendering invisibly, so a human reading the carried text sees it VERBATIM — the\n// previous replacement mutated the author's own text to a visible hyphen (issue #217 review r7).\nconst commentSafe = (text: string): string =>\n text.replace(/--+(?=>)/g, (dashes) => `${dashes}\\u200b`);\n\nconst sanitizeSuppressedNit = (\n f: Finding,\n discussion: readonly DiscussionLink[],\n discussionTruncated?: number,\n): SuppressedNitView => ({\n title: escapeCodeBackticks(f.title),\n id: escapeCodeBackticks(f.id),\n ...(f.code_url !== undefined ? { codeUrl: linkSafeUrl(f.code_url) } : {}),\n path: commentSafe(escapeCodeBackticks(f.path)),\n startLine: f.start_line,\n endLine: f.end_line,\n ...(f.side !== undefined ? { side: f.side } : {}),\n severity: f.severity,\n confidence: formatConfidence(f.confidence),\n likelihood: formatConfidence(f.likelihood),\n m: formatConfidence(f.confidence * f.likelihood),\n carried: carriedLines(f),\n discussion,\n ...(discussionTruncated !== undefined ? { discussionTruncated } : {}),\n discussionHtml:\n discussion.length > 0 ? discussionAsideHtml(discussion, discussionTruncated, \"> \") : \"\",\n});\n\n// Each carried field is clipped. Every below-floor nit's full finding rides in the sticky body, and\n// that body is the one GitHub rejects over 65536 chars — which post deliberately does not shed, so an\n// oversized body 422s the round with the announce placeholder still up. Removing the ~32KB document\n// bought far more room than this spends, but \"far more room\" is not a bound. The cap IS the\n// conversation clip's (BODY_CLIP_CHARS, util.ts) — one constant so the two can't drift — and clipText\n// marks what it cut so a reader is never silently shown a fragment.\n\nconst carriedLines = (f: Finding): readonly string[] =>\n [\n `description: ${clipText(f.description, BODY_CLIP_CHARS)}`,\n ...(f.recommendation !== undefined\n ? [`recommendation: ${clipText(f.recommendation, BODY_CLIP_CHARS)}`]\n : []),\n `reasoning: ${clipText(f.reasoning, BODY_CLIP_CHARS)}`,\n ...(f.patch !== undefined ? [\"patch:\", clipText(f.patch, BODY_CLIP_CHARS)] : []),\n ]\n .flatMap((block) => commentSafe(block).split(\"\\n\"))\n .map((line) => line.trimEnd());\n\n// The same render-safety escaping as strays: pipes break tables, backticks break inline code spans.\n// finding_ids render inside backticks too, so they get the same backtick escaping as paths.\nconst sanitizeSystemic = (\n s: SystemicProblem,\n discussion: readonly DiscussionLink[],\n discussionTruncated?: number,\n): SystemicProblem & {\n readonly discussion: readonly DiscussionLink[];\n readonly discussionTruncated?: number;\n readonly discussionHtml: string;\n} => ({\n ...s,\n title: escapePipes(s.title),\n discussion,\n ...(discussionTruncated !== undefined ? { discussionTruncated } : {}),\n discussionHtml:\n discussion.length > 0 ? discussionAsideHtml(discussion, discussionTruncated, \"\") : \"\",\n ...(s.id !== undefined ? { id: escapeCodeBackticks(s.id) } : {}),\n ...(s.code_url !== undefined ? { code_url: linkSafeUrl(s.code_url) } : {}),\n ...(s.paths !== undefined ? { paths: s.paths.map(escapeCodeBackticks) } : {}),\n ...(s.finding_ids !== undefined ? { finding_ids: s.finding_ids.map(escapeCodeBackticks) } : {}),\n});\n\nconst emptySeverityCounts = (): Record<Severity, number> => ({\n critical: 0,\n major: 0,\n minor: 0,\n nit: 0,\n});\n\nexport const computeSeverityCounts = (findings: readonly Finding[]): SeverityCounts =>\n findings.reduce<Record<Severity, number>>(\n (acc, f) => (f.severity in acc ? { ...acc, [f.severity]: acc[f.severity] + 1 } : acc),\n emptySeverityCounts(),\n );\n\n// The other half of the round decision, shared by post (round append) and render (badge): \"error\"\n// is the pipeline-reserved no-verdict value, so a doc that carries it — even one that somehow also\n// carries findings — never counts as a completed review and must never read as converged (#141).\nexport const isReviewVerdict = (verdict: Verdict): boolean => verdict !== \"error\";\n\n// The single decision \"is THIS run a convergence-defining full-review round?\" — a completed full\n// review (not a CI-fix mechanic pass, not an incomplete notice). post() calls it to decide the round\n// append AND passes the result to render() for the badge gate, so the two can never disagree; render()\n// falls back to it only for the standalone `render` command, which has no post to compute it.\nexport const isConvergenceRound = (\n route: string | null | undefined,\n incomplete: boolean,\n): boolean => route === \"full review\" && !incomplete;\n\nexport const render = (input: RenderInput): string => {\n const eta = new Eta({ autoTrim: false });\n const usageAvailable = input.envelope !== null;\n // The meta line prints turns/cost only when there is real usage to print — a present-but-zeroed\n // envelope (the synthesized notice wrap: no models) would otherwise show a false \"$0.00 · turns 0\".\n const hasUsage = input.envelope !== null && input.envelope.models.length > 0;\n // Enforce the invariant here, not just at the producers: a no-verdict notice (isIncompleteFindings)\n // is ALWAYS incomplete however it reached render (an envelope-less notice, a recovered draft), so it\n // never renders \"clean review\" or the review-complete marker.\n const incomplete =\n (input.incomplete ?? input.envelope?.incomplete ?? false) ||\n isIncompleteFindings(input.findings);\n // Price a time-slotted model at the RUN's completion instant (issue #170) — stamped in the envelope\n // by adapt, so re-rendering the same envelope always picks the same slot; input.pricedAt is only the\n // fallback for a pre-#170 envelope that carries no generated_at.\n const pricedAt = parseInstant(input.envelope?.generated_at) ?? input.pricedAt;\n const costReport = input.envelope\n ? computeCost(input.envelope.models, input.prices, pricedAt)\n : null;\n const pricesProvided = input.pricesProvided ?? true;\n const route = input.route ?? input.envelope?.route ?? null;\n const effort = input.effort ?? input.envelope?.effort ?? null;\n const modelNames = input.envelope ? input.envelope.models.map((m) => m.model).join(\", \") : \"\";\n const severityCounts = input.severityCounts ?? computeSeverityCounts(input.findings.findings);\n // The pipeline-stamped convergence field (issue #174) is the source for the trajectory and the badge.\n // `input.rounds` is a fallback only for callers that supply a legacy trajectory directly (tests, or a\n // standalone render of a doc without convergence); its entries carry no score and render \"—\". Every\n // production sticky carries convergence — in the compact marker beside the link (issue #217) — so\n // the fallback never fires there.\n const convergence = input.findings.convergence;\n const trajectory = convergence?.rounds ?? input.rounds ?? [];\n // The same-root annotation: post passes the explicit map computed from the PRIOR-round history it\n // parsed before appending this run's record; the standalone render command derives it from the\n // supplied history minus its last (current) round. Keyed by code, rendered under each finding that\n // carries it; empty when nothing recurs — no annotation.\n const sameRootNotes =\n input.sameRootNotes ?? computeSameRootNotes(trajectory.slice(0, -1), input.findings.findings);\n // The convergence badge is a property of a completed FULL-REVIEW round: render it only then, from\n // the completed round's counts. A CI-fix mechanic pass, a lost-envelope pass, and a notice each\n // append no round and declare no convergence verdict — a badge from the current findings would sit\n // \"converged\" above a mechanic's fresh critical, and one from a carried-forward prior round would\n // contradict the findings beside it. Neither is a truthful stop signal, so no badge shows; the\n // carried-forward trajectory alone gives context. Prefer post's explicit signal (which also gates\n // the round append, so badge ⇔ append); fall back to the shared predicate for the standalone\n // `render` command — which additionally requires a rounds history, since without one no round has\n // completed and neither the badge nor the stop signal may appear (the README's omission\n // semantics, issue #141 review r4). The verdict guard (isReviewVerdict, shared with post's round\n // append) closes an edge isIncompleteFindings misses (it flags an \"error\" verdict only when\n // findings are also empty): an error doc that carries findings must still show no badge, never\n // \"converged\" beside the \"no review verdict\" badge.\n const isFullReviewRound =\n (input.convergenceRound ?? (isConvergenceRound(route, incomplete) && trajectory.length > 0)) &&\n isReviewVerdict(input.findings.verdict);\n\n // The badge and the trajectory both read the ONE pipeline-stamped `convergence` field (issue #174),\n // whose score is per-finding — reading confidence × likelihood off the findings themselves, not a\n // round's aggregate counts (issue #162) — so by construction they can never disagree (issue #141\n // review r2). In the post path this run is the last stored round, so the stamped score matches the\n // trajectory's last chip; the score already weighs a systemic critical like a finding critical (issue #134 scope).\n // The advisory notes (same-root + scope-metastasis) are a property of a real review, gated by the\n // same decision as the badge (a completed FULL-REVIEW round): a mechanic pass or a lost-envelope\n // completed review must not render a \"still recurring\" claim from carried-forward rounds beside a\n // suppressed convergence badge.\n const advisoryAllowed = isFullReviewRound;\n\n // The discussion links a below-floor nit's aside slot renders — keyed by the RAW id like every\n // other discussion lookup.\n const discussionLinksFor = (id: string): readonly DiscussionLink[] =>\n input.discussionByFinding !== undefined &&\n Object.prototype.hasOwnProperty.call(input.discussionByFinding, id)\n ? (input.discussionByFinding[id] ?? [])\n : [];\n const discussionTruncatedFor = (id: string): number | undefined =>\n input.discussionTruncated !== undefined &&\n Object.prototype.hasOwnProperty.call(input.discussionTruncated, id)\n ? input.discussionTruncated[id]\n : undefined;\n\n const suppressedBudget = budgetBySize(\n (input.suppressedNits ?? []).map((f) =>\n sanitizeSuppressedNit(f, discussionLinksFor(f.id), discussionTruncatedFor(f.id)),\n ),\n CARRIED_TOTAL_CHARS,\n (n) =>\n // The fixed overhead covers the summary line's structure; the reviewer-controlled variable\n // parts are budgeted at their true RENDERED size — the title, the path TWICE (summary +\n // location line), the code/code_url the summary line renders, each carried line's `> `\n // blockquote prefix (length + 3: prefix + newline), the location line's line numbers and\n // side label, and the discussion slot's link list.\n n.carried.reduce((sum, line) => sum + line.length + 3, 0) +\n SUPPRESSED_NIT_BLOCK_OVERHEAD +\n n.title.length +\n n.path.length * 2 +\n // The id renders with its two wrapper backticks; the code_url adds the [](...) link form.\n // The id renders ONCE: a backtick span inside parens, or the []() link form.\n n.id.length +\n (n.codeUrl !== undefined ? n.codeUrl.length + 8 : 4) +\n String(n.startLine).length * 2 +\n String(n.endLine).length +\n (n.side !== undefined ? n.side.length + 2 : 0) +\n // The composed slot's EXACT rendered size — its `> ` blockquote prefixes included.\n n.discussionHtml.length,\n () => null,\n );\n\n // The permalink identity is ONE optional: repo + reviewedSha only mean something together, and a\n // half-supplied OR EMPTY pair must not render malformed `//blob/` links — precomputed once per\n // render rather than rebuilt per stray (issue #231 r1 + r3).\n const permalinkBase =\n input.repo !== undefined &&\n input.repo !== \"\" &&\n input.reviewedSha !== undefined &&\n input.reviewedSha !== \"\"\n ? `https://github.com/${input.repo}/blob/${input.reviewedSha}/`\n : undefined;\n const unanchored = new Set(input.unanchoredStrays ?? []);\n\n const strayViews = (input.strays ?? []).map((f) => {\n const view = sanitizeFinding(\n f,\n input.answeredNotes,\n input.discussionByFinding,\n permalinkBase,\n unanchored,\n input.discussionTruncated,\n );\n return {\n ...view,\n discussionHtml:\n view.discussion.length > 0\n ? discussionAsideHtml(view.discussion, view.discussionTruncated, \"\")\n : \"\",\n };\n });\n // The discussion aside is additive to the one body post deliberately never sheds: the orphaned\n // section and the per-finding asides draw from ONE budget, whole asides dropped past it, the cut\n // named in the template, never silent. An aside whose finding has no replies costs nothing and\n // is never counted as dropped — only a thread that existed can be \"not listed\".\n // Escape-twin raw entries fold into ONE display-keyed item BEFORE the budget walk, so the\n // budget decides whole display entries: a dropped name is a spelling the render truly lacks,\n // never a twin whose sibling is still listed under the same spelling.\n const orphanedPreBudget = new Map<\n string,\n {\n readonly links: readonly DiscussionLink[];\n readonly truncated?: number;\n readonly html: string;\n }\n >();\n for (const [token, links] of Object.entries(input.orphanedDiscussion ?? {})) {\n const key = escapeCodeBackticks(token);\n const truncatedFor =\n input.orphanedTruncated !== undefined &&\n Object.prototype.hasOwnProperty.call(input.orphanedTruncated, token)\n ? input.orphanedTruncated[token]\n : undefined;\n const existing = orphanedPreBudget.get(key);\n const htmlFor = (entryLinks: readonly DiscussionLink[], entryTruncated?: number): string =>\n orphanedEntryHtml(key, entryLinks, entryTruncated);\n if (existing === undefined) {\n orphanedPreBudget.set(key, {\n links,\n ...(truncatedFor !== undefined ? { truncated: truncatedFor } : {}),\n html: htmlFor(links, truncatedFor),\n });\n } else {\n const mergedTotal =\n (existing.truncated ?? existing.links.length) + (truncatedFor ?? links.length);\n const merged = [...existing.links, ...links].sort((a, b) =>\n (b.at ?? b.when).localeCompare(a.at ?? a.when),\n );\n const mergedLinks = merged.slice(0, PER_FINDING_LINKS);\n const mergedTruncated = mergedTotal > PER_FINDING_LINKS ? mergedTotal : undefined;\n orphanedPreBudget.set(key, {\n links: mergedLinks,\n ...(mergedTruncated !== undefined ? { truncated: mergedTruncated } : {}),\n html: htmlFor(mergedLinks, mergedTruncated),\n });\n }\n }\n const orphanedBudget = budgetBySize(\n [...orphanedPreBudget.entries()],\n DISCUSSION_TOTAL_CHARS,\n ([, entry]) => entry.html.length,\n () => null,\n );\n const discussionBudget = budgetBySize(\n strayViews,\n DISCUSSION_TOTAL_CHARS - orphanedBudget.used,\n (view) =>\n view.discussion.length > 0 ? DISCUSSION_BLOCK_OVERHEAD + view.discussionHtml.length : 0,\n (view) => ({ ...view, discussion: [], discussionHtml: \"\" }),\n );\n // The systemic asides draw from the SAME pool, third in line: orphaned (permanent cut) first,\n // then the strays' asides, then the systemics'.\n const systemicBudget = budgetBySize(\n (input.findings.systemic_problems ?? []).map((s) =>\n sanitizeSystemic(\n s,\n s.id !== undefined ? discussionLinksFor(s.id) : [],\n s.id !== undefined ? discussionTruncatedFor(s.id) : undefined,\n ),\n ),\n DISCUSSION_TOTAL_CHARS - orphanedBudget.used - discussionBudget.used,\n (s) => (s.discussion.length > 0 ? DISCUSSION_BLOCK_OVERHEAD + s.discussionHtml.length : 0),\n (s) => ({ ...s, discussion: [], discussionHtml: \"\" }),\n );\n // The \"(showing N of M)\" total counts DISTINCT DISPLAYED entries — the pre-budget fold above\n // already merged twins, and the budget's own drops are named in the dropped-threads marker.\n const orphanedRender = {\n lines: orphanedBudget.kept.map(([, entry]) => entry.html),\n // The \"(showing N of M)\" total counts DISTINCT DISPLAYED entries — the pre-budget fold above\n // already merged twins, and the budget's own drops are named in the dropped-threads marker.\n total:\n input.orphanedTotal !== undefined\n ? input.orphanedTotal -\n (Object.keys(input.orphanedDiscussion ?? {}).length - orphanedPreBudget.size)\n : orphanedPreBudget.size - orphanedBudget.droppedItems.length,\n };\n\n return eta.renderString(input.template, {\n findings: input.findings,\n envelope: input.envelope,\n usageAvailable,\n hasUsage,\n incomplete,\n costReport,\n pricesProvided,\n route,\n effort,\n modelNames,\n testReport: input.testReport ?? null,\n // The agent's best-effort role split (issue #182) and the pipeline's deterministic cloc table; both\n // chrome, gated to a completed review by the template's !incomplete block.\n changeSummary: changeSizeSummary(input.findings.change_size),\n clocDiff: input.clocDiff !== undefined ? escapeFence(input.clocDiff) : null,\n reviewedSha: input.reviewedSha ?? \"0000000000000000000000000000000000000000\",\n postedAt: input.postedAt ?? \"\",\n severityCounts,\n convergenceSummary: !isFullReviewRound\n ? \"\"\n : convergence\n ? convergenceBadge(convergence)\n : convergenceSummary(input.findings, input.convergenceThreshold),\n strays: discussionBudget.kept,\n orphanedLines: orphanedRender.lines,\n orphanedUnresolvable: input.orphanedUnresolvable === true,\n discussionDropped:\n discussionBudget.droppedItems.length +\n systemicBudget.droppedItems.length +\n orphanedBudget.droppedItems.length,\n discussionDroppedIds: discussionBudget.droppedItems\n .map((v) => clipText(escapeCodeBackticks(v.idKey), 64))\n .slice(0, DROPPED_IDS_SHOWN),\n discussionDroppedSystemicIds: systemicBudget.droppedItems\n .flatMap((s) => (s.id !== undefined ? [clipText(s.id, 64)] : []))\n .slice(0, DROPPED_IDS_SHOWN),\n discussionDroppedOrphanedIds: orphanedBudget.droppedItems\n .map(([token]) => clipText(token, 64))\n .slice(0, DROPPED_IDS_SHOWN),\n discussionDroppedExtra:\n Math.max(0, discussionBudget.droppedItems.length - DROPPED_IDS_SHOWN) +\n Math.max(0, systemicBudget.droppedItems.length - DROPPED_IDS_SHOWN) +\n Math.max(0, orphanedBudget.droppedItems.length - DROPPED_IDS_SHOWN),\n discussionCap: PER_FINDING_LINKS,\n orphanedTotal: orphanedRender.total,\n suppressedNits: suppressedBudget.kept,\n carriedDroppedNits: suppressedBudget.droppedItems.length,\n nitVisibilityFloor: input.nitVisibilityFloor ?? DEFAULT_NIT_VISIBILITY_FLOOR,\n systemic: systemicBudget.kept,\n unanchoredCount: input.unanchoredCount ?? 0,\n inlineDisposition: input.inlineDisposition ?? null,\n unverifiedNoLogs: input.unverifiedNoLogs === true,\n runUrl: input.runUrl ?? null,\n jsonUrl: input.jsonUrl ?? null,\n // The marker names the findings artifact, so the convergence no longer rides inside the comment —\n // it needs its own compact marker beside the link or a trajectory would require a fetch to read\n // (issue #217). post precomputes both together in findingsBlob; the standalone `render` command\n // builds the same pair here, so neither path can emit a link with the convergence missing.\n findingsPointer:\n input.findingsPointer ?? findingsMarkerPair(input.jsonUrl, input.findings.convergence),\n roundsSummary: roundsSummary(trajectory, input.roundCount),\n metastasisNote: advisoryAllowed ? metastasisNote(trajectory) : \"\",\n sameRootNotes: advisoryAllowed ? sameRootNotes : {},\n answeredNotes: input.answeredNotes ?? {},\n answeredReRaiseNote: input.answeredReRaiseNote ?? \"\",\n reviewUrl: input.reviewUrl ?? null,\n formatTokens: (n: number): string =>\n Number.isFinite(n) && n >= 0 ? n.toLocaleString(\"en-US\") : \"—\",\n // N/A (never a false $0.00) when no real price map was provided — real tokens, no rates to price them.\n formatCost: (n: number): string =>\n !pricesProvided\n ? \"N/A\"\n : Number.isFinite(n)\n ? n > 0 && n.toFixed(2) === \"0.00\"\n ? \"<$0.01\"\n : `$${n.toFixed(2)}`\n : \"—\",\n formatDuration: (ms: number): string => {\n if (!Number.isFinite(ms) || ms < 0) return \"—\";\n const s = Math.round(ms / 1000);\n return s >= 60 ? `${String(Math.floor(s / 60))}m ${String(s % 60)}s` : `${String(s)}s`;\n },\n verdictBadge: (v: string): string => {\n switch (v) {\n case \"approve\":\n return \"✅ approved\";\n case \"comment\":\n return \"💬 comment\";\n case \"changes\":\n return \"🔧 changes requested\";\n case \"error\":\n return \"🛠️ no review verdict\";\n default:\n return `❓ ${v}`;\n }\n },\n severityEmoji,\n formatConfidence,\n });\n};\n","import parseDiff from \"parse-diff\";\nimport type { Finding, Side } from \"./schema.js\";\n\nexport type DiffLineIndex = ReadonlySet<string>;\n\nconst key = (path: string, line: number): string => `${path}:${String(line)}`;\n\nconst indexChanges = (\n keys: Set<string>,\n fpath: string,\n changes: ReadonlyArray<{\n readonly type: \"normal\" | \"add\" | \"del\";\n readonly ln1?: number;\n readonly ln2?: number;\n readonly ln?: number;\n }>,\n): void => {\n for (const change of changes) {\n if (change.type === \"normal\") {\n if (change.ln1 !== undefined) keys.add(key(fpath, change.ln1));\n if (change.ln2 !== undefined) keys.add(key(fpath, change.ln2));\n } else if (change.ln !== undefined) {\n keys.add(key(fpath, change.ln));\n }\n }\n};\n\n// For renamed files, both old and new paths are indexed so a finding on either matches.\nexport const indexDiff = (diff: string): DiffLineIndex => {\n const files = parseDiff(diff);\n if (!Array.isArray(files)) return new Set();\n\n const keys = new Set<string>();\n for (const file of files) {\n // from ?? to covers deleted (to=/dev/null), new (from undefined), and modified; a rename differs\n // and is indexed under both paths.\n const primary = file.from ?? file.to;\n if (!primary) continue;\n\n indexChanges(\n keys,\n primary,\n file.chunks.flatMap((c) => c.changes),\n );\n\n if (file.to && file.to !== \"/dev/null\" && file.to !== primary) {\n indexChanges(\n keys,\n file.to,\n file.chunks.flatMap((c) => c.changes),\n );\n }\n }\n return keys;\n};\n\nexport const isInDiff = (index: DiffLineIndex, path: string, line: number): boolean =>\n index.has(key(path, line));\n\nexport const isEmptyDiff = (diff: string): boolean => {\n if (diff.trim().length === 0) return true;\n const files = parseDiff(diff);\n return !Array.isArray(files) || files.length === 0 || files.every((f) => f.chunks.length === 0);\n};\n\nexport const defaultSide = (side: string | undefined): Side => (side === \"LEFT\" ? \"LEFT\" : \"RIGHT\");\n\nexport const partitionFindings = (\n findings: readonly Finding[],\n index: DiffLineIndex,\n): {\n readonly inDiff: readonly Finding[];\n readonly strays: readonly Finding[];\n} => {\n const inDiff: Finding[] = [];\n const strays: Finding[] = [];\n for (const f of findings) {\n if (isInDiff(index, f.path, f.start_line) && isInDiff(index, f.path, f.end_line)) {\n inDiff.push(f);\n } else {\n strays.push(f);\n }\n }\n return { inDiff, strays };\n};\n","import { Eta } from \"eta\";\nimport { partitionFindings, indexDiff, defaultSide } from \"./diff.js\";\nimport {\n severityEmoji,\n findingPointer,\n findingPayload,\n INLINE_PROSE_CLIP_THRESHOLD_CHARS,\n projectPatch,\n formatConfidence,\n} from \"./surface.js\";\nimport { BODY_CLIP_CHARS, clipText } from \"./util.js\";\nimport { answeredNoteKey } from \"./answered.js\";\nimport { resolveFindingId } from \"./schema.js\";\nimport type { Finding, Findings } from \"./schema.js\";\nimport type { InlineComment, InlineResult } from \"./types.js\";\n\nconst formatModels = (models: readonly string[]): string =>\n models.length > 0 ? models.map((m) => `\\`${m}\\``).join(\"/\") : \"an AI model\";\n\n// The template is the SSOT for all body text; TS supplies only data. The patch is projected here\n// (never a `suggestion` field — that field is gone as of schema 0.4).\nconst renderCommentBody = (\n f: Finding,\n eta: Eta,\n template: string,\n modelsText: string,\n jsonUrl: string | undefined,\n pointer: string,\n sameRootNote: string,\n answeredNote: string,\n): string =>\n // Eta.renderString returns string | Promise<string>; with autoTrim:false it's always sync.\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n eta.renderString(template, {\n ...f,\n patchProjection: projectPatch(f.patch, \"diff-anchored\"),\n severityEmoji,\n formatConfidence,\n modelsText,\n jsonUrl: jsonUrl ?? null,\n findingsPointer: pointer,\n sameRootNote,\n answeredNote,\n }) as string;\n\nexport interface InlineContext {\n readonly inlineTemplate: string;\n readonly models?: readonly string[];\n readonly jsonUrl?: string;\n // Each in-diff comment embeds only its OWN finding, but needs the document's schema_version to do\n // so; omitted when the caller has no document (each comment's marker is then omitted too).\n readonly findings?: Findings;\n // Code → \"same mechanism as round N\" note, rendered under a finding whose code recurred in a prior\n // round; omitted/empty ⇒ no per-comment annotation.\n readonly sameRootNotes?: Readonly<Record<string, string>>;\n // Code → \"Re-raised; prior answer at <link>\" note for a kept finding whose code an answered prior\n // thread named (issue #151); omitted/empty ⇒ no per-comment annotation.\n readonly answeredNotes?: Readonly<Record<string, string>>;\n // A precomputed in-diff partition — the caller that needs the split for other reasons (the\n // discussion known set) computes it once and shares it; omitted ⇒ built here.\n readonly partition?: {\n readonly inDiff: readonly Finding[];\n readonly strays: readonly Finding[];\n };\n}\n\nexport const buildInlineComments = (\n findings: readonly Finding[],\n diff: string,\n context: InlineContext,\n): InlineResult => {\n const { inlineTemplate, models = [], jsonUrl, findings: fullFindings } = context;\n const { inDiff, strays } = context.partition ?? partitionFindings(findings, indexDiff(diff));\n const eta = new Eta({ autoTrim: false });\n const modelsText = formatModels(models);\n\n const noteFor = (notes: Readonly<Record<string, string>> | undefined, key: string): string =>\n notes !== undefined && Object.prototype.hasOwnProperty.call(notes, key)\n ? (notes[key] ?? \"\")\n : \"\";\n\n const comments: InlineComment[] = inDiff.map((f) => {\n const pointer = fullFindings ? findingPointer(f, fullFindings.schema_version, jsonUrl) : \"\";\n // In the clip band the prose sheds so the comment fits — the marker still embeds the WHOLE\n // finding, which is what keeps the answered registry decoding the thread (issue #233 r2). The\n // clip is clipText's marked truncation, never silent.\n const clipProse =\n fullFindings !== undefined &&\n findingPayload(f, fullFindings.schema_version).length > INLINE_PROSE_CLIP_THRESHOLD_CHARS;\n const view = clipProse\n ? {\n ...f,\n title: clipText(f.title, BODY_CLIP_CHARS),\n description: clipText(f.description, BODY_CLIP_CHARS),\n ...(f.recommendation != null\n ? { recommendation: clipText(f.recommendation, BODY_CLIP_CHARS) }\n : {}),\n reasoning: clipText(f.reasoning, BODY_CLIP_CHARS),\n ...(f.patch != null ? { patch: clipText(f.patch, BODY_CLIP_CHARS) } : {}),\n }\n : f;\n // Each map keys differently, per its writer: the same-root notes key on the RESOLVED id\n // (computeSameRootNotes), the answered notes on answeredNoteKey (applyAnswered) — the lookup\n // must match the writer, not one shared key.\n const sameRootNote = noteFor(context.sameRootNotes, resolveFindingId(f));\n const answeredNote = noteFor(context.answeredNotes, answeredNoteKey(f));\n const comment: InlineComment = {\n path: f.path,\n line: f.end_line,\n side: defaultSide(f.side),\n body: renderCommentBody(\n view,\n eta,\n inlineTemplate,\n modelsText,\n jsonUrl,\n pointer,\n sameRootNote,\n answeredNote,\n ),\n };\n if (f.start_line < f.end_line) {\n return {\n ...comment,\n start_line: f.start_line,\n start_side: defaultSide(f.side),\n };\n }\n return comment;\n });\n\n return { comments, strays, inDiff };\n};\n\nexport const renderStraysSection = (strays: readonly Finding[]): string => {\n if (strays.length === 0) return \"\";\n\n const items = strays.map(\n (f) => `- **${f.severity}** · \\`${f.path}:${String(f.start_line)}\\` — ${f.title}`,\n );\n\n return [\n \"\",\n \"---\",\n \"\",\n \"#### ⚠️ Findings on lines not in the diff (demoted to summary)\",\n \"\",\n ...items,\n ].join(\"\\n\");\n};\n","// Defense-in-depth: the CLI already enforces the schema on the agent side.\n\nimport { Ajv2020 } from \"ajv/dist/2020.js\";\nimport type { ValidateFunction as AjvValidateFunction } from \"ajv/dist/2020.js\";\nimport _addFormats from \"ajv-formats\";\nimport { readFileSync } from \"node:fs\";\nimport type { Either } from \"fp-ts/Either\";\nimport { FindingsCodec } from \"./schema.js\";\nimport type { Findings } from \"./schema.js\";\n\nconst addFormats = _addFormats as unknown as (ajv: Ajv2020) => void;\n\nconst validatorCache = new Map<string, AjvValidateFunction>();\n\nconst compileSchema = (schemaPath: string): AjvValidateFunction => {\n const cached = validatorCache.get(schemaPath);\n if (cached) return cached;\n\n let schemaJson: string;\n try {\n schemaJson = readFileSync(schemaPath, \"utf-8\");\n } catch {\n throw new Error(`Cannot read schema file: ${schemaPath}`);\n }\n let schema: unknown;\n try {\n schema = JSON.parse(schemaJson);\n } catch {\n throw new Error(`Invalid JSON in schema file: ${schemaPath}`);\n }\n const ajv = new Ajv2020({ allErrors: true, strict: true });\n addFormats(ajv);\n const validator = ajv.compile(schema as Record<string, unknown>);\n validatorCache.set(schemaPath, validator);\n return validator;\n};\n\nexport interface ValidateResult {\n readonly valid: boolean;\n readonly errors: readonly string[];\n}\n\nexport const validateAgainstSchema = (findings: unknown, schemaPath: string): ValidateResult => {\n const validator = compileSchema(schemaPath);\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion -- ajv returns boolean | Promise<unknown>\n const valid = validator(findings) as boolean;\n const errors: readonly string[] =\n valid || !validator.errors\n ? []\n : validator.errors.map((e) => `${e.instancePath} ${e.message ?? \"unknown error\"}`);\n return { valid, errors };\n};\n\nexport const unsafeUnwrap = <A>(decoded: Either<unknown, A>): A => {\n if (decoded._tag === \"Right\") return decoded.right;\n throw new Error(\"io-ts decode failed — data does not match expected shape\");\n};\n\nexport const decodeFindings = (data: unknown): Findings => unsafeUnwrap(FindingsCodec.decode(data));\n","// A Claude Code Stop hook that refuses to let the review agent end its turn until it has written a\n// findings document that validates against the schema — turning \"validate before stopping\" from a\n// hope into an invariant. Same validation as `code-review validate`.\n\nimport { readFileSync, writeFileSync } from \"node:fs\";\nimport { validateAgainstSchema } from \"./validate.js\";\nimport { errMsg } from \"./util.js\";\n\n// Distinguishes an UNREADABLE file (EACCES/EISDIR) from an INVALID one — \"does not validate\" is a\n// lie when the file could not even be read.\nexport type DraftState =\n | { readonly kind: \"missing\" }\n | { readonly kind: \"unreadable\"; readonly error: string }\n | { readonly kind: \"invalid\"; readonly errors: readonly string[] }\n | { readonly kind: \"valid\" };\n\nexport type GateDecision =\n { readonly kind: \"allow\" } | { readonly kind: \"block\"; readonly reason: string };\n\nconst whatsWrong = (\n state: Exclude<DraftState, { kind: \"valid\" }>,\n draftPath: string,\n kind: string,\n): string => {\n switch (state.kind) {\n case \"missing\":\n return `${draftPath} does not exist yet`;\n case \"unreadable\":\n return `${draftPath} could not be read: ${state.error}`;\n case \"invalid\":\n return `${draftPath} does not validate against the ${kind} schema:\\n${state.errors\n .map((e) => ` - ${e}`)\n .join(\"\\n\")}`;\n }\n};\n\nexport interface StopHookSettings {\n readonly hooks: {\n readonly Stop: readonly {\n readonly hooks: readonly { readonly type: \"command\"; readonly command: string }[];\n }[];\n };\n}\n\nexport const decideGate = (\n state: DraftState,\n nudges: number,\n maxNudges: number,\n draftPath: string,\n kind: string,\n): GateDecision => {\n if (state.kind === \"valid\") return { kind: \"allow\" };\n if (nudges >= maxNudges) return { kind: \"allow\" };\n return {\n kind: \"block\",\n reason: [\n `This review is not complete — ${whatsWrong(state, draftPath, kind)}`,\n `The only deliverable is a ${kind} document that validates against the ${kind} schema — run \"code-review print-schema ${kind}\" to see the exact shape.`,\n `Write it to ${draftPath}, then run \"code-review validate ${draftPath} --kind ${kind} --explain\" until it exits 0 before ending your turn (--explain prints the schema when the shape is wrong).`,\n ].join(\"\\n\"),\n };\n};\n\n// Never throws — every failure mode degrades to a DraftState the gate can act on, rather than\n// crashing the hook and letting the agent stop by default.\nexport const draftState = (\n draftPath: string,\n resolveSchema: (parsed: unknown) => string,\n): DraftState => {\n let raw: string;\n try {\n raw = readFileSync(draftPath, \"utf-8\");\n } catch (err) {\n if (err instanceof Error && (err as NodeJS.ErrnoException).code === \"ENOENT\") {\n return { kind: \"missing\" };\n }\n return { kind: \"unreadable\", error: errMsg(err) };\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (err) {\n return {\n kind: \"invalid\",\n errors: [`not valid JSON: ${errMsg(err)}`],\n };\n }\n let schemaPath: string;\n try {\n schemaPath = resolveSchema(parsed);\n } catch (err) {\n return { kind: \"invalid\", errors: [errMsg(err)] };\n }\n try {\n const { valid, errors } = validateAgainstSchema(parsed, schemaPath);\n return valid ? { kind: \"valid\" } : { kind: \"invalid\", errors };\n } catch (err) {\n return { kind: \"invalid\", errors: [errMsg(err)] };\n }\n};\n\n// Absent or unparseable reads as 0, so a fresh review starts with a full nudge budget.\nexport const readNudges = (counterPath: string): number => {\n try {\n const n = Number.parseInt(readFileSync(counterPath, \"utf-8\").trim(), 10);\n return Number.isInteger(n) && n >= 0 ? n : 0;\n } catch {\n return 0;\n }\n};\n\n// The caller passes the `current` it just read (no stale second read). May throw on a write failure —\n// the caller decides how to handle that.\nexport const bumpNudges = (counterPath: string, current: number): void => {\n writeFileSync(counterPath, `${String(current + 1)}\\n`);\n};\n\nexport const shellQuote = (s: string): string => `'${s.replace(/'/g, `'\\\\''`)}'`;\n\nexport const defaultHookCommand = (\n draftPath: string,\n opts: {\n readonly kind?: string;\n readonly schema?: string;\n readonly schemaVersion?: string;\n readonly maxNudges?: string;\n readonly counter?: string;\n },\n): string =>\n [\n \"code-review stop-gate --draft\",\n shellQuote(draftPath),\n ...(opts.kind ? [\"--kind\", shellQuote(opts.kind)] : []),\n ...(opts.schema ? [\"--schema\", shellQuote(opts.schema)] : []),\n ...(opts.schemaVersion ? [\"--schema-version\", shellQuote(opts.schemaVersion)] : []),\n ...(opts.maxNudges ? [\"--max-nudges\", shellQuote(opts.maxNudges)] : []),\n ...(opts.counter ? [\"--counter\", shellQuote(opts.counter)] : []),\n ].join(\" \");\n\nexport const stopHookSettings = (command: string): StopHookSettings => ({\n hooks: { Stop: [{ hooks: [{ type: \"command\", command }] }] },\n});\n","// Pure — the CLI (index.ts) owns IO and degrades any error to an allow-everything no-op.\n\nimport { basename, dirname, extname, join } from \"node:path\";\n\nimport { shellQuote } from \"./stop-gate.js\";\nimport { asRecord } from \"./util.js\";\n\nexport const DEADLINE_ENV = \"CODE_REVIEW_DEADLINE_EPOCH\";\n\nexport interface BudgetInputs {\n // Unmeasurable spend is null, never 0 — never tell the agent \"$0.00 spent\".\n readonly spentUsd: number | null;\n readonly budgetUsd: number | null;\n readonly elapsedMs: number | null;\n readonly wallMs: number | null;\n readonly reserve: ReserveParams;\n}\n\nexport interface ReserveParams {\n readonly frac: number;\n readonly growth: number;\n readonly flatUsd: number;\n readonly flatMs: number;\n}\n\nexport const DEFAULT_RESERVE: ReserveParams = {\n frac: 0.15,\n growth: 0.25,\n flatUsd: 0.02,\n flatMs: 120_000,\n};\n\nconst SOFT_MULTIPLE = 2;\n\nexport type BudgetPhase =\n { readonly kind: \"ok\" } | { readonly kind: \"soft\" } | { readonly kind: \"hard\" };\n\n// Each axis carries its own absolute hardReserve, grown with usage so convergence lands earlier the\n// longer the run has gone. axisSeverity then only compares remaining headroom to that reserve.\ninterface Axis {\n readonly used: number;\n readonly limit: number;\n readonly hardReserve: number;\n}\n\nconst growingReserve = (used: number, limit: number, flat: number, r: ReserveParams): number => {\n const usedFrac = Math.min(1, Math.max(0, used / limit));\n return Math.max(flat, (r.frac + r.growth * usedFrac) * limit);\n};\n\nconst costAxis = (i: BudgetInputs): Axis | null =>\n i.spentUsd !== null && i.budgetUsd !== null && i.budgetUsd > 0\n ? {\n used: i.spentUsd,\n limit: i.budgetUsd,\n hardReserve: growingReserve(i.spentUsd, i.budgetUsd, i.reserve.flatUsd, i.reserve),\n }\n : null;\n\nconst timeAxis = (i: BudgetInputs): Axis | null =>\n i.elapsedMs !== null && i.wallMs !== null && i.wallMs > 0\n ? {\n used: i.elapsedMs,\n limit: i.wallMs,\n hardReserve: growingReserve(i.elapsedMs, i.wallMs, i.reserve.flatMs, i.reserve),\n }\n : null;\n\nconst axisSeverity = (a: Axis): 0 | 1 | 2 => {\n const remaining = a.limit - a.used;\n if (remaining <= a.hardReserve) return 2;\n if (remaining <= SOFT_MULTIPLE * a.hardReserve) return 1;\n return 0;\n};\n\nexport const decideBudget = (i: BudgetInputs): BudgetPhase => {\n const worst = [costAxis(i), timeAxis(i)]\n .filter((a): a is Axis => a !== null)\n .reduce<0 | 1 | 2>((max, a) => Math.max(max, axisSeverity(a)) as 0 | 1 | 2, 0);\n return worst === 2 ? { kind: \"hard\" } : worst === 1 ? { kind: \"soft\" } : { kind: \"ok\" };\n};\n\nconst pct = (n: number): string => `${String(Math.round(n * 100))}%`;\nconst money = (n: number): string => `$${n.toFixed(2)}`;\nconst mins = (ms: number): string => `${(ms / 60_000).toFixed(1)}m`;\n\nconst spendClause = (i: BudgetInputs): string | null =>\n i.spentUsd === null\n ? null\n : i.budgetUsd !== null && i.budgetUsd > 0\n ? `spent ${money(i.spentUsd)}/${money(i.budgetUsd)} (${pct(i.spentUsd / i.budgetUsd)})`\n : `spent ${money(i.spentUsd)}`;\n\nconst timeClause = (i: BudgetInputs): string | null =>\n i.elapsedMs === null\n ? null\n : i.wallMs !== null && i.wallMs > 0\n ? `${mins(i.elapsedMs)}/${mins(i.wallMs)} elapsed (${pct(i.elapsedMs / i.wallMs)})`\n : `${mins(i.elapsedMs)} elapsed`;\n\n// A subagent can't write the draft (single-writer deny below), so it is told to report back, not write.\nconst directive = (\n phase: Exclude<BudgetPhase, { kind: \"ok\" }>,\n draftPath: string,\n isSubagent: boolean,\n): string => {\n if (isSubagent)\n return phase.kind === \"hard\"\n ? `Budget nearly exhausted — STOP all new investigation now and report the findings you have back to the main agent in your reply. Do not write ${draftPath} yourself; only the main agent writes it.`\n : `Wind down investigation and report the findings you have back to the main agent in your reply — do not write ${draftPath} yourself; the main agent writes it, and you may run out of budget otherwise.`;\n return phase.kind === \"hard\"\n ? `Budget nearly exhausted — STOP all new investigation now. Do not wait for subagents still running in the background. Write your COMPLETE findings from what you already have to ${draftPath} and run \\`code-review validate ${draftPath} --explain\\` until it passes (--explain prints the exact schema when the shape is wrong). Other tools are blocked until that draft is written.`\n : `Wind down investigation and write your COMPLETE findings to ${draftPath} now, then run \\`code-review validate ${draftPath} --explain\\` (it prints the exact schema if the shape is wrong) — fold in the subagent reports you already have rather than waiting on stragglers; you may run out of budget before you finish otherwise.`;\n};\n\nexport const budgetMessage = (\n i: BudgetInputs,\n phase: Exclude<BudgetPhase, { kind: \"ok\" }>,\n draftPath: string,\n isSubagent: boolean,\n): string => {\n const status = [spendClause(i), timeClause(i)].filter((c): c is string => c !== null).join(\" · \");\n return `Budget check — ${status}. ${directive(phase, draftPath, isSubagent)}`;\n};\n\nconst invokesCodeReviewValidate = (toolInput: unknown): boolean => {\n const cmd = asRecord(toolInput)?.[\"command\"];\n // (?![\\w-]) excludes validate-patches — a findings-mutating command that must not pass this gate.\n return typeof cmd === \"string\" && /\\bcode-review\\s+validate(?![\\w-])/.test(cmd);\n};\n\nconst SPAWN_TOOLS: ReadonlySet<string> = new Set([\"Agent\", \"Task\"]);\nconst WEB_TOOLS: ReadonlySet<string> = new Set([\"WebFetch\", \"WebSearch\"]);\n\nexport const blockedDuringConvergence = (toolName: string, toolInput: unknown): boolean => {\n if (SPAWN_TOOLS.has(toolName) || WEB_TOOLS.has(toolName)) return true;\n if (toolName === \"Bash\") return !invokesCodeReviewValidate(toolInput);\n return false;\n};\n\nconst escapeRegExp = (s: string): string => s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\nconst WRITE_TOOLS: ReadonlySet<string> = new Set([\"Write\", \"Edit\", \"MultiEdit\", \"NotebookEdit\"]);\n\n// Scoped to the accidental fan-out race, not adversarial evasion (cp/mv/dd are out of scope).\nexport const writesToDraft = (toolName: string, toolInput: unknown, draftPath: string): boolean => {\n const rec = asRecord(toolInput);\n const targets = [draftPath, basename(draftPath), \"$DRAFT\", \"${DRAFT}\"];\n if (WRITE_TOOLS.has(toolName)) {\n const fp = rec?.[\"file_path\"] ?? rec?.[\"notebook_path\"];\n if (typeof fp === \"string\" && targets.some((t) => fp === t || basename(fp) === basename(t)))\n return true;\n }\n if (toolName === \"Bash\") {\n const cmd = rec?.[\"command\"];\n if (typeof cmd !== \"string\") return false;\n const alt = targets.map(escapeRegExp).join(\"|\");\n const end = \"(?=$|[\\\\s|&;)])\";\n const redirect = new RegExp(`>>?\\\\|?\\\\s*(['\"]?)(?:${alt})\\\\1${end}`);\n const teeArg = new RegExp(`\\\\btee\\\\b(?:\\\\s+-{1,2}\\\\S+)*\\\\s+(['\"]?)(?:${alt})\\\\1${end}`);\n return redirect.test(cmd) || teeArg.test(cmd);\n }\n return false;\n};\n\n// Agent-facing (ships to every user's review): no internal refs.\nexport const singleWriterMessage = (draftPath: string): string =>\n `Only the main agent may write ${draftPath}. When a subagent writes it too, the concurrent writers clobber each other and the review comes out empty. Do NOT write, edit, or redirect into ${draftPath} — instead, return the findings you discovered in your reply (the field names are in the schema); the main agent collects every subagent's reported findings and writes the draft itself.`;\n\n// The pre-seed is a SENTINEL, never a valid findings document (issue #127): no recovery path — the\n// extraction ladder's agent-file/last-valid rungs, the budget hook's fan-out floor — can mistake it\n// for a review, so \"agent produced nothing\" is always an honest incomplete notice. Content, not\n// mtime: a coarse-timestamp filesystem can't misclassify a fresh draft written in the same clock\n// tick, and a missing draft is simply inert (there is no seed to recover).\nexport const SEED_SENTINEL =\n \"code-review seed sentinel — not a review; replace this file with your findings review.\";\n\n// A normalized compare: a trailing newline, CRLF, or leading BOM added by any tool that touches the\n// file must not silently flip the \"untouched seed\" signal. Anything beyond that is a different\n// content — the agent's own writing. One normalization, shared by both predicates.\nconst normalizedDraft = (draftText: string | null): string =>\n typeof draftText === \"string\" ? draftText.replace(/^\\uFEFF/, \"\").trim() : \"\";\n\nexport const isSeedSentinel = (draftText: string | null): boolean =>\n normalizedDraft(draftText) === SEED_SENTINEL;\n\n// The fan-out floor: the main agent has replaced the sentinel with real first-pass content — an\n// empty or missing draft is not a first pass.\nexport const mainHasWrittenDraft = (draftText: string | null): boolean => {\n const normalized = normalizedDraft(draftText);\n return normalized !== \"\" && normalized !== SEED_SENTINEL;\n};\n\n// One sidecar-name derivation for every postfix-before-extension convention, so last-valid and\n// prior-context can never drift apart.\nconst sidecarPath = (draftPath: string, postfix: string): string => {\n const ext = extname(draftPath);\n return join(dirname(draftPath), `${basename(draftPath, ext)}${postfix}${ext}`);\n};\n\n// The prior review's decoded findings, delivered OUT-OF-BAND beside the sentinel draft: the agent\n// may read this as re-review context, but no recovery path ever validates it as the run's\n// deliverable (only $DRAFT, its last-valid snapshot, and the native envelope are read back).\nexport const priorContextPath = (draftPath: string): string => sidecarPath(draftPath, \".prior\");\n\n// The prior review's \"already answered\" registry (issue #151) — the prior inline findings whose\n// threads a human reply answered — delivered beside the prior context so the next-round agent sees\n// what it must not re-raise verbatim. Like $PRIOR_CONTEXT, it is read-only context, never a\n// deliverable.\nexport const priorAnswersPath = (draftPath: string): string =>\n sidecarPath(draftPath, \".prior-answers\");\n\n// The prior review's below-visibility-floor nits (issue #164) — the nits the last round shelved\n// below the noise floor — delivered beside the prior context so the next-round agent knows not to\n// re-raise them as fresh nits. Like $PRIOR_CONTEXT/$PRIOR_ANSWERS, read-only context, never a\n// deliverable.\nexport const priorSuppressedPath = (draftPath: string): string =>\n sidecarPath(draftPath, \".prior-suppressed\");\n\n// Holds only ever a document that passed the extraction ladder: the budget hook snapshots the draft\n// here whenever it validates, so a wall-kill that leaves the live draft truncated still recovers the\n// last valid state instead of posting \"did not complete\". The postfix goes before the extension so\n// the snapshot keeps the draft's real type (findings-draft.last-valid.json). The sentinel never\n// validates, so it can never be checkpointed here.\nexport const lastValidPath = (draftPath: string): string => sidecarPath(draftPath, \".last-valid\");\n\n// Agent-facing: no internal refs.\nexport const spawnFloorMessage = (draftPath: string): string =>\n `Write your own first-pass findings to ${draftPath} before spawning subagents — a review must never depend on subagents alone, and the pre-seeded $DRAFT is a non-review sentinel: it does not count until you have replaced it with your own review. Write ${draftPath} from what you have read so far (preliminary findings are fine), run \\`code-review validate ${draftPath} --explain\\` until it passes, then fan out; your subagents run in the background, so keep refining the draft as their reports arrive.`;\n\n// Background so the spawner never blocks on a batch join, where no hook can reach it to steer.\nexport const forceBackgroundSpawn = (toolInput: unknown): Record<string, unknown> => ({\n hookSpecificOutput: {\n hookEventName: \"PreToolUse\",\n permissionDecision: \"allow\",\n updatedInput: { ...(asRecord(toolInput) ?? {}), run_in_background: true },\n },\n});\n\nexport interface BudgetParams {\n readonly spentUsd: number | null;\n readonly budgetUsd: number | null;\n readonly elapsedMs: number | null;\n readonly wallMs: number | null;\n readonly reserve: ReserveParams;\n readonly draftPath: string;\n // A THUNK: the draft read is only needed on the main agent's PreToolUse spawn gate, the single\n // consumer of this check — evaluating it on every hook event would read the whole draft file on\n // every tool call (the hook fires with no matcher).\n readonly mainDraftWritten: () => boolean;\n}\n\nconst denyPreTool = (reason: string): Record<string, unknown> => ({\n hookSpecificOutput: {\n hookEventName: \"PreToolUse\",\n permissionDecision: \"deny\",\n permissionDecisionReason: reason,\n },\n});\n\n// A non-empty agent_id marks a fan-out subagent; the main agent has none (or \"\"). The one predicate\n// every consumer shares, so the snapshot gate and the single-writer deny never disagree on \"\".\nexport const isSubagentHookInput = (input: unknown): boolean => {\n const agentId = asRecord(input)?.[\"agent_id\"];\n return typeof agentId === \"string\" && agentId.length > 0;\n};\n\nexport const evaluateBudgetHook = (\n input: unknown,\n params: BudgetParams,\n): Record<string, unknown> => {\n const rec = asRecord(input);\n const inputs: BudgetInputs = {\n spentUsd: params.spentUsd,\n budgetUsd: params.budgetUsd,\n elapsedMs: params.elapsedMs,\n wallMs: params.wallMs,\n reserve: params.reserve,\n };\n const phase = decideBudget(inputs);\n const isSubagent = isSubagentHookInput(input);\n\n switch (rec?.[\"hook_event_name\"]) {\n case \"PostToolBatch\":\n return phase.kind === \"ok\"\n ? {}\n : {\n hookSpecificOutput: {\n hookEventName: \"PostToolBatch\",\n additionalContext: budgetMessage(inputs, phase, params.draftPath, isSubagent),\n },\n };\n case \"PreToolUse\": {\n const toolName = rec[\"tool_name\"];\n if (typeof toolName !== \"string\") return {};\n // Single-writer enforcement is independent of budget phase.\n if (isSubagent && writesToDraft(toolName, rec[\"tool_input\"], params.draftPath))\n return denyPreTool(singleWriterMessage(params.draftPath));\n if (phase.kind === \"hard\" && blockedDuringConvergence(toolName, rec[\"tool_input\"]))\n return denyPreTool(budgetMessage(inputs, phase, params.draftPath, isSubagent));\n // Gate the main agent's first fan-out on its own draft existing; then background every spawn.\n if (SPAWN_TOOLS.has(toolName)) {\n if (!isSubagent && !params.mainDraftWritten())\n return denyPreTool(spawnFloorMessage(params.draftPath));\n return forceBackgroundSpawn(rec[\"tool_input\"]);\n }\n return {};\n }\n default:\n return {};\n }\n};\n\nexport const parseWallMs = (raw: string): number | null => {\n const m = /^(\\d+(?:\\.\\d+)?)(ms|s|m|h)?$/.exec(raw.trim());\n if (m === null) return null;\n const [, num = \"\", unit = \"s\"] = m;\n const n = Number.parseFloat(num);\n if (!Number.isFinite(n)) return null;\n switch (unit) {\n case \"ms\":\n return n;\n case \"s\":\n return n * 1000;\n case \"m\":\n return n * 60_000;\n default:\n return n * 3_600_000;\n }\n};\n\nexport const parseEpochSecMs = (raw: string | undefined): number | null => {\n if (raw === undefined) return null;\n const t = raw.trim();\n if (!/^\\d+$/.test(t)) return null;\n const n = Number.parseInt(t, 10);\n return Number.isFinite(n) && n > 0 ? n * 1000 : null;\n};\n\n// Prefer the shared deadline anchor: a fresh subagent's transcript-start reads ≈0, so per-transcript\n// elapsed would leave the fan-out unsteered. Falls back to transcript start, then null (axis off).\nexport const anchoredElapsedMs = (src: {\n readonly deadlineMs: number | null;\n readonly wallMs: number | null;\n readonly firstTsMs: number | null;\n readonly nowMs: number;\n}): number | null => {\n if (src.deadlineMs !== null && src.wallMs !== null)\n return Math.max(0, src.wallMs - (src.deadlineMs - src.nowMs));\n if (src.firstTsMs !== null) return Math.max(0, src.nowMs - src.firstTsMs);\n return null;\n};\n\n// Round the wall UP to whole seconds so the anchor never expires before the matching timeout kill.\nexport const deadlineEpochSec = (wallMs: number, nowMs: number): number =>\n Math.floor(nowMs / 1000) + Math.ceil(wallMs / 1000);\n\n// 0 is valid: it disables the fraction term, leaving only the flat floor.\nexport const parseFraction = (raw: string | undefined, fallback: number): number => {\n if (raw === undefined) return fallback;\n const n = Number.parseFloat(raw);\n return Number.isFinite(n) && n >= 0 && n <= 1 ? n : fallback;\n};\n\n// One string wired to both hooks; it self-dispatches on the event it reads from stdin.\nexport const budgetHookCommand = (\n draftPath: string,\n opts: {\n readonly budgetUsd?: string;\n readonly wall?: string;\n readonly prices?: string;\n readonly reserveFrac?: string;\n readonly reserveGrowth?: string;\n readonly reserveUsd?: string;\n readonly reserveWall?: string;\n },\n): string =>\n [\n \"code-review budget-hook --draft\",\n shellQuote(draftPath),\n ...(opts.budgetUsd ? [\"--budget-usd\", shellQuote(opts.budgetUsd)] : []),\n ...(opts.wall ? [\"--wall\", shellQuote(opts.wall)] : []),\n ...(opts.prices ? [\"--prices\", shellQuote(opts.prices)] : []),\n ...(opts.reserveFrac ? [\"--reserve-frac\", shellQuote(opts.reserveFrac)] : []),\n ...(opts.reserveGrowth ? [\"--reserve-growth\", shellQuote(opts.reserveGrowth)] : []),\n ...(opts.reserveUsd ? [\"--reserve-usd\", shellQuote(opts.reserveUsd)] : []),\n ...(opts.reserveWall ? [\"--reserve-wall\", shellQuote(opts.reserveWall)] : []),\n ].join(\" \");\n","// Fenced code blocks pass through verbatim — a `suggestion` block's blank lines and trailing\n// whitespace are significant.\n\ninterface ScanState {\n readonly lines: readonly string[];\n readonly inFence: boolean;\n readonly blankRun: number;\n}\n\nconst FENCE_RE = /^\\s*```/;\n\nconst scanLine = (state: ScanState, line: string): ScanState => {\n if (FENCE_RE.test(line)) {\n return { lines: [...state.lines, line], inFence: !state.inFence, blankRun: 0 };\n }\n if (state.inFence) {\n return { lines: [...state.lines, line], inFence: true, blankRun: 0 };\n }\n const trimmed = line.replace(/[ \\t]+$/, \"\");\n if (trimmed !== \"\") {\n return { lines: [...state.lines, trimmed], inFence: false, blankRun: 0 };\n }\n const blankRun = state.blankRun + 1;\n return blankRun === 1\n ? { lines: [...state.lines, \"\"], inFence: false, blankRun }\n : { ...state, blankRun };\n};\n\nexport const formatMarkdown = (md: string): string => {\n const { lines } = md\n .split(\"\\n\")\n .reduce<ScanState>(scanLine, { lines: [], inFence: false, blankRun: 0 });\n return `${lines.join(\"\\n\").replace(/\\n+$/, \"\")}\\n`;\n};\n\nconst pad2 = (n: number): string => String(n).padStart(2, \"0\");\n\n// Computed at the IO boundary so render() stays pure/clockless.\nexport const formatUtc = (d: Date): string =>\n `${String(d.getUTCFullYear())}-${pad2(d.getUTCMonth() + 1)}-${pad2(d.getUTCDate())} ${pad2(d.getUTCHours())}:${pad2(d.getUTCMinutes())} UTC`;\n","// The notices the review workflow synthesizes when there is no completed review to post: a security\n// block (triage returned a genuine unsafe verdict), a triage that could not evaluate (an operational\n// failure, not a verdict about the diff), a setup failure before triage could run, a PR head that\n// would not check out, or a run that passed triage but emitted nothing. Their messages and the\n// \"incomplete\" envelope shape live here — one typed SSOT — rather than as jq object literals spread\n// across the workflow YAML, so the commenter renders every one honestly (no false \"clean\n// review\"/\"$0.00\", and an operational failure never reads as a security verdict about the diff) and\n// the sticky precedence guard treats them as non-completing.\n\nimport { DEFAULT_SCHEMA_VERSION, incompleteFindings } from \"./schema.js\";\nimport type { ResultEnvelope } from \"./schema.js\";\n\n// One list is the source of truth for the kind union, its runtime guard, and the CLI's kind listing,\n// so adding a kind is a single edit rather than five that can drift out of sync.\nexport const NOTICE_KINDS = [\n \"security-blocked\",\n \"triage-error\",\n \"setup-failed\",\n \"checkout-failed\",\n \"no-output\",\n] as const;\n\nexport type NoticeKind = (typeof NOTICE_KINDS)[number];\n\nexport const isNoticeKind = (s: string): s is NoticeKind => NOTICE_KINDS.some((k) => k === s);\n\n// A host is safe to name in the raw-rendered, grep-scanned summary only if it can neither break out of\n// its backtick code span (`) nor forge a comment marker (<, >) nor start a new line (\\n, \\r) or table\n// cell (|). This is a render-safety denylist, NOT a hostname grammar: it keeps legitimate but unusual\n// hosts (bracketed IPv6, IDN) a strict pattern would wrongly drop, while still neutralizing a tampered\n// sandbox.json (the agent can rewrite it — the jail confines egress, not the filesystem). Shared with\n// scope.ts, whose scope values are spliced into the review prompt and must reject exactly these\n// prompt-structure breakers (issue #139).\nexport const UNSAFE_IN_SUMMARY = /[\\n\\r`<>|]/;\n\n// Cap how many hosts are named: a tampered config could pad allowedDomains until the rendered summary\n// blows past GitHub's 65536-char comment limit and the comment fails to post at all. A real allowlist\n// is a handful; the count is the diagnostic signal, not every entry.\nconst MAX_NAMED_HOSTS = 20;\n\n// The review agent's egress jail (sandbox-runtime) confines ONLY the agent — setup, install, and\n// gather run unfiltered. So when a jailed run produced no review, naming the jail's allowlist turns\n// \"the agent could not reach a host it needed\" into a one-line diagnosis. Pure: pulls\n// network.allowedDomains out of a parsed sandbox config, keeping only render-safe, sanely-sized host\n// strings (capped) and yielding none for any other shape (a missing config, or one before jail setup).\nexport const parseAgentAllowlist = (sandboxConfig: unknown): readonly string[] => {\n const domains = (sandboxConfig as { network?: { allowedDomains?: unknown } } | null | undefined)\n ?.network?.allowedDomains;\n return Array.isArray(domains)\n ? domains\n .filter(\n (d): d is string =>\n typeof d === \"string\" && d.length <= 256 && !UNSAFE_IN_SUMMARY.test(d),\n )\n .slice(0, MAX_NAMED_HOSTS)\n : [];\n};\n\n// Appended only to the notices where a jailed `claude -p` actually ran (no-output, triage-error), so\n// an egress-blocked host it needed is nameable against the allowlist. Framed conditionally — these\n// notices also fire for non-egress causes (a missing key, a wall-clock kill) — so it informs without\n// asserting egress was the cause. Empty allowlist ⇒ empty note.\nconst egressNote = (agentAllowlist: readonly string[]): string =>\n agentAllowlist.length === 0\n ? \"\"\n : `\\n\\nIf the review failed because the agent could not reach a host it needed, note that its network egress is jailed to only ${agentAllowlist\n .map((host) => `\\`${host}\\``)\n .join(\n \", \",\n )}. Add any missing host to the agent's egress allowlist — the reusable workflow's \\`extra_endpoints\\` input, or a single-file workflow's \\`--extra\\` flag on \\`sandbox-config\\`.`;\n\n// Blockquote every line so a multi-line reason stays quoted, not just its first line.\nconst blockquote = (text: string): string => text.replaceAll(\"\\n\", \"\\n> \");\n\n// A reason-bearing notice: when the triage supplied a detail string — a genuine unsafe verdict, or\n// the operational failure it hit — quote it under the lead; otherwise fall back to the no-reason\n// wording. The `typeof` guard fails closed on a null reason too (a JSON round-trip can yield null\n// where the type says undefined), never crashing this render path on `.trim()`.\nconst reasoned = (lead: string, noReason: string, reasons: string | undefined): string =>\n typeof reasons === \"string\" && reasons.trim() !== \"\"\n ? `${lead}\\n\\n> ${blockquote(reasons)}`\n : noReason;\n\nconst noticeSummary = (\n kind: NoticeKind,\n reasons: string | undefined,\n agentAllowlist: readonly string[],\n): string => {\n switch (kind) {\n case \"security-blocked\":\n return reasoned(\n \"### 🛑 Code review skipped by the security gate\\n\\nThe diff was flagged as unsafe to apply and execute:\",\n \"### 🛑 Code review skipped by the security gate\\n\\nThe security triage returned an unsafe verdict without a reason. See workflow logs.\",\n reasons,\n );\n case \"triage-error\":\n return (\n reasoned(\n \"### 🛠️ Security gate could not evaluate\\n\\nThe security triage could not produce a verdict (operational error), so the review failed closed — this is an infrastructure failure, not a finding about this diff. Re-run to retry a transient fault; a persistent one is a configuration issue (see the workflow logs). The triage step reported:\",\n \"### 🛠️ Security gate could not evaluate\\n\\nThe security triage could not produce a verdict (operational error), so the review failed closed — this is an infrastructure failure, not a finding about this diff. Re-run to retry a transient fault; a persistent one is a configuration issue (see the workflow logs).\",\n reasons,\n ) + egressNote(agentAllowlist)\n );\n case \"setup-failed\":\n return \"### 🛠️ Review did not run\\n\\nThe review job failed before the security triage could run (e.g. dependency install or environment setup). See the workflow logs — this is an infrastructure failure, not a security verdict.\";\n case \"checkout-failed\":\n return \"### ⚠️ Could not check out the PR head\\n\\nThe PR head commit could not be fetched or checked out (it may have been force-pushed away, or is otherwise unavailable), so the review was skipped rather than run against the wrong tree. See workflow logs.\";\n case \"no-output\":\n return (\n \"### ⚠️ Review did not complete\\n\\nThe diff passed triage but the review produced no output. See workflow logs.\" +\n egressNote(agentAllowlist)\n );\n }\n};\n\nconst noticeEnvelope = (summary: string): ResultEnvelope => ({\n schema_version: DEFAULT_SCHEMA_VERSION,\n findings: incompleteFindings(summary),\n models: [],\n turns: 0,\n duration_ms: 0,\n vendor_cost_usd: null,\n incomplete: true,\n});\n\nexport const buildNoticeEnvelope = (\n kind: NoticeKind,\n reasons?: string,\n agentAllowlist: readonly string[] = [],\n): ResultEnvelope => noticeEnvelope(noticeSummary(kind, reasons, agentAllowlist));\n\n// A workflow that asks for a kind this CLI does not know is almost always version skew — the pinned\n// CLI is older than the workflow calling it. Degrade to an honest incomplete envelope that names the\n// cause rather than exiting non-zero and crashing the assemble step into posting nothing at all.\nexport const buildUnknownNoticeEnvelope = (kind: string): ResultEnvelope =>\n noticeEnvelope(\n `### ⚠️ Review could not be rendered\\n\\nThe workflow asked for an unrecognized notice kind (\\`${kind}\\`) — the pinned code-review CLI is older than the workflow calling it (check that its version matches). Failing closed. See the workflow logs.`,\n );\n","// Findings 0.4 REQUIRES reasoning/confidence, which can't be honestly upcast from a 0.2/0.3 document\n// (confidence can't be fabricated) — so older minors are dropped from the table and degrade to the\n// unsupported-version notice. Imports schema.ts one-way (schema.ts stays a leaf; no import cycle).\n// Bundled schema paths resolve via tsup into the same dist as index.ts, so import.meta.dirname\n// matches at runtime, in dev, and from the published package.\n\nimport { resolve as resolvePath } from \"node:path\";\nimport type * as t from \"io-ts\";\nimport type { Decoder, Encoder, Errors, ValidationError } from \"io-ts\";\nimport {\n FindingsCodec,\n FindingsCodecV09,\n normalizeV09,\n TriageCodec,\n PriceMapCodec,\n DEFAULT_SCHEMA_VERSION,\n} from \"./schema.js\";\nimport type { Findings, Triage, PriceMap } from \"./schema.js\";\n\nexport type SchemaKind = \"findings\" | \"triage\" | \"prices\";\n\nexport interface DecodedFor {\n readonly findings: Findings;\n readonly triage: Triage;\n readonly prices: PriceMap;\n}\n\ninterface VersionEntry<K extends SchemaKind, A, D = A> {\n /** major.minor of `schema_version` this entry dispatches on; patch is ignored. */\n readonly minor: string;\n /** full semver stamped when a document omits `schema_version` (findings) or reported as the\n * resolved version for kinds with no in-data signal (triage, prices). */\n readonly defaultVersion: string;\n readonly schemaFile: string;\n readonly codec: Decoder<unknown, D> & Encoder<D, unknown>;\n /** upcast to the latest shape for this kind; identity when the codec already accepts both\n * shapes (e.g. an additive minor whose new field is optional). */\n readonly normalize: (decoded: D) => DecodedFor[K];\n readonly latest: boolean;\n}\n\nexport type Resolution<K extends SchemaKind> =\n | { readonly kind: \"ok\"; readonly version: string; readonly value: DecodedFor[K] }\n | {\n readonly kind: \"unsupported-version\";\n readonly version: string;\n readonly supported: readonly string[];\n }\n | { readonly kind: \"invalid-shape\"; readonly errors: readonly string[] }\n | { readonly kind: \"missing-version\" }; // findings only; triage/prices never return this\n\nconst identity = <A>(decoded: A): A => decoded;\n\n// 0.5 widened the verdict enum with the pipeline-only \"error\" value, 0.6 added the optional\n// systemic_problems array, and 0.9 added REQUIRED `likelihood` (the draft axis skips 0.7/0.8, which\n// belong to the surface-signal axis — issue #156 — so the two version spaces stay distinct). 0.10\n// made `id` REQUIRED (code → id), so every pre-0.10 minor now decodes through the one tolerant legacy\n// codec and upcasts to the 0.10 shape (code → id, or the synthesized content-derived id when a\n// finding carried none) — a pre-0.10 doc without an id still resolves, and the dropped 0.2/0.3 minors\n// still can't (they lack the required reasoning/confidence). Keeping the older minors live matches\n// their declared version to a supported entry rather than reporting an unknown version.\nconst legacyFindingsCodec = FindingsCodecV09 as unknown as Decoder<unknown, Findings> &\n Encoder<Findings, unknown>;\nconst legacyFindingsNormalize = (doc: t.TypeOf<typeof FindingsCodecV09>): Findings =>\n normalizeV09(doc);\n\nconst findingsTable: readonly VersionEntry<\"findings\", Findings>[] = [\n {\n minor: \"0.4\",\n defaultVersion: \"0.4.0\",\n // The frozen tolerant-in legacy schema, NOT the live 0.10 file: every ajv-gated channel\n // (validate --schema-version, the extraction ladder) dispatches the RAW doc's declared minor\n // through schemaPathFor, so the ajv gate must accept exactly what the tolerant legacy codec\n // accepts — the live file (id required) would reject the legacy docs the upcast promises to read.\n schemaFile: \"v0.9/findings.schema.json\",\n codec: legacyFindingsCodec,\n normalize: legacyFindingsNormalize,\n latest: false,\n },\n {\n minor: \"0.5\",\n defaultVersion: \"0.5.0\",\n schemaFile: \"v0.9/findings.schema.json\",\n codec: legacyFindingsCodec,\n normalize: legacyFindingsNormalize,\n latest: false,\n },\n {\n minor: \"0.6\",\n defaultVersion: \"0.6.0\",\n schemaFile: \"v0.9/findings.schema.json\",\n codec: legacyFindingsCodec,\n normalize: legacyFindingsNormalize,\n latest: false,\n },\n {\n minor: \"0.9\",\n defaultVersion: \"0.9.0\",\n schemaFile: \"v0.9/findings.schema.json\",\n codec: legacyFindingsCodec,\n normalize: legacyFindingsNormalize,\n latest: false,\n },\n {\n minor: \"0.10\",\n defaultVersion: DEFAULT_SCHEMA_VERSION,\n schemaFile: \"findings.schema.json\",\n codec: FindingsCodec,\n normalize: identity,\n latest: true,\n },\n];\n\nconst triageTable: readonly VersionEntry<\"triage\", Triage>[] = [\n {\n minor: \"0.1\",\n defaultVersion: \"0.1.0\",\n schemaFile: \"triage.schema.json\",\n codec: TriageCodec,\n normalize: identity,\n latest: true,\n },\n];\n\nconst pricesTable: readonly VersionEntry<\"prices\", PriceMap>[] = [\n {\n // Retained non-latest so `validate`/`print-schema --schema-version 0.1` still resolves (the\n // keep-old-minors convention the findings table follows). The price map carries no version signal,\n // and the schema is a single unversioned file, so both entries point at it; the codec's oneOf\n // accepts a flat 0.1-era map unchanged.\n minor: \"0.1\",\n defaultVersion: \"0.1.0\",\n schemaFile: \"prices.schema.json\",\n codec: PriceMapCodec,\n normalize: identity,\n latest: false,\n },\n {\n // v0.2.0 (issue #170): a model's value gained the time-slotted alternative (flat | { slots }).\n minor: \"0.2\",\n defaultVersion: \"0.2.0\",\n schemaFile: \"prices.schema.json\",\n codec: PriceMapCodec,\n normalize: identity,\n latest: true,\n },\n];\n\ntype Table<K extends SchemaKind> = readonly VersionEntry<K, DecodedFor[K]>[];\n\nconst tables: { readonly [K in SchemaKind]: Table<K> } = {\n findings: findingsTable,\n triage: triageTable,\n prices: pricesTable,\n};\n\nconst tableFor = <K extends SchemaKind>(kind: K): Table<K> => tables[kind];\n\n/** major.minor of a semver-ish string; dispatch ignores patch and any prerelease/build suffix. */\nconst majorMinor = (version: string): string => version.split(\".\").slice(0, 2).join(\".\");\n\nconst describeValidationError = (e: ValidationError): string => {\n const path = e.context\n .map((entry) => entry.key)\n .filter((key) => key.length > 0)\n .join(\".\");\n return e.message ?? `${path || \"(root)\"}: invalid value ${JSON.stringify(e.value)}`;\n};\n\nconst formatErrors = (errors: Errors): readonly string[] => errors.map(describeValidationError);\n\nexport const declaredVersion = (raw: unknown): string | undefined =>\n typeof raw === \"object\" && raw !== null && \"schema_version\" in raw\n ? typeof raw.schema_version === \"string\"\n ? raw.schema_version\n : undefined\n : undefined;\n\nexport const supportedVersions = (kind: SchemaKind): readonly string[] =>\n tableFor(kind).map((entry) => entry.minor);\n\nexport const defaultVersion = (kind: SchemaKind): string => {\n const latest = tableFor(kind).find((entry) => entry.latest);\n if (!latest) throw new Error(`Registry invariant violated — no latest entry for \"${kind}\"`);\n return latest.defaultVersion;\n};\n\nconst bundledSchemaPath = (relativePath: string): string =>\n resolvePath(import.meta.dirname, \"..\", \"schema\", relativePath);\n\nexport const schemaPathFor = (kind: SchemaKind, version?: string): string => {\n const table = tableFor(kind);\n const entry =\n version === undefined\n ? table.find((v) => v.latest)\n : table.find((v) => v.minor === majorMinor(version));\n if (!entry) {\n throw new Error(\n `Unsupported ${kind} schema version \"${version ?? \"\"}\" — supported: ${supportedVersions(kind).join(\", \")}`,\n );\n }\n return bundledSchemaPath(entry.schemaFile);\n};\n\nconst resolveFindings = (raw: unknown): Resolution<\"findings\"> => {\n const version = declaredVersion(raw);\n if (version === undefined) return { kind: \"missing-version\" };\n const entry = findingsTable.find((v) => v.minor === majorMinor(version));\n if (!entry) {\n return { kind: \"unsupported-version\", version, supported: supportedVersions(\"findings\") };\n }\n const decoded = entry.codec.decode(raw);\n return decoded._tag === \"Left\"\n ? { kind: \"invalid-shape\", errors: formatErrors(decoded.left) }\n : { kind: \"ok\", version, value: entry.normalize(decoded.right) };\n};\n\n/** Resolve a kind with no in-data version signal, never \"missing-version\". A versionless document is\n * the CURRENT contract, so it resolves against the latest entry (matching defaultVersion/schemaPathFor);\n * older entries exist only so an explicit `--schema-version` still resolves. */\nconst resolveSingleVersion = <K extends \"triage\" | \"prices\">(\n kind: K,\n raw: unknown,\n): Resolution<K> => {\n const table = tableFor(kind);\n const entry = table.find((e) => e.latest) ?? table[0];\n if (!entry) throw new Error(`Registry invariant violated — no entry for \"${kind}\"`);\n const decoded = entry.codec.decode(raw);\n return decoded._tag === \"Left\"\n ? { kind: \"invalid-shape\", errors: formatErrors(decoded.left) }\n : { kind: \"ok\", version: entry.defaultVersion, value: entry.normalize(decoded.right) };\n};\n\nconst resolvers: { readonly [K in SchemaKind]: (raw: unknown) => Resolution<K> } = {\n findings: resolveFindings,\n triage: (raw) => resolveSingleVersion(\"triage\", raw),\n prices: (raw) => resolveSingleVersion(\"prices\", raw),\n};\n\n/** Decode + version-dispatch a raw document for a schema kind. Pure — no IO. */\nexport const resolve = <K extends SchemaKind>(kind: K, raw: unknown): Resolution<K> =>\n resolvers[kind](raw);\n\n// The seed chain's tolerant findings resolution: the value when the document resolves, and — when the\n// STRICT entry rejects a body the migration's tolerant-in contract admits (a peeled legacy surfaced\n// blob re-stamped with the CURRENT draft version, or a hybrid doc whose findings carry the pre-0.10\n// `code` spelling) — the legacy codec's upcast value. null for an unsupported-version stamp: the\n// fallback must never revive a version the allowlist refuses (a dropped 0.2/0.3 minor, a future\n// 0.11+/1.x) and re-stamp it 0.10.0. The ONE place this upcast policy lives, shared by every raw-\n// document channel (the seed gate; the marker readers apply the same precedence on their fragments).\nexport const resolveTolerantFindings = (doc: unknown): Findings | null => {\n const r = resolveFindings(doc);\n if (r.kind === \"ok\") return r.value;\n if (r.kind === \"unsupported-version\") return null;\n const legacy = FindingsCodecV09.decode(doc);\n return legacy._tag === \"Right\" ? normalizeV09(legacy.right) : null;\n};\n","// The single child-process boundary for the external CLIs (`gh`, `git`); pure callers inject fakes.\n\nimport { execFile } from \"node:child_process\";\nimport { errMsg } from \"./util.js\";\n\nconst MAX_BUFFER = 100 * 1024 * 1024;\n\n// Node's child_process `timeout` is a `setTimeout` under the hood, which clamps any delay above the\n// signed-32-bit maximum to 1ms — an over-large override would paradoxically kill every call almost\n// instantly. Honor a large-but-valid ceiling; treat an out-of-range value as invalid (fall back).\nconst MAX_TIMEOUT_MS = 2_147_483_647;\n\n// `/^\\d+$/` matches the codebase's other numeric-env parsers (requireMaxNudges, requirePositiveInt):\n// it rejects the surprising forms `Number` would coerce (`\"0.5\"` → 0.5ms, `\"0x10\"`, `\"3e5\"`).\nexport const parseTimeoutMs = (raw: string | undefined, fallback: number): number => {\n if (raw === undefined || !/^\\d+$/.test(raw)) return fallback;\n const parsed = Number(raw);\n return parsed > 0 && parsed <= MAX_TIMEOUT_MS ? parsed : fallback;\n};\n\nconst SUBPROCESS_TIMEOUT_ENV = \"CODE_REVIEW_SUBPROCESS_TIMEOUT_MS\";\nconst DEFAULT_SUBPROCESS_TIMEOUT_MS = 120_000;\n\nexport const subprocessTimeoutMs = (): number =>\n parseTimeoutMs(process.env[SUBPROCESS_TIMEOUT_ENV], DEFAULT_SUBPROCESS_TIMEOUT_MS);\n\n// A child that outlives the timeout is killed via SIGKILL, and `maxBuffer` overflow kills it too;\n// both surface as `killed`, so name which one fired (and fall back to the child's own stderr/error)\n// rather than blame a timeout for an overflow.\nexport const classifyExecError = (err: unknown, stderr: string, timeoutMs: number): string => {\n const e = err as { killed?: boolean; code?: unknown };\n const stderrStr = stderr.trim();\n if (e.code === \"ERR_CHILD_PROCESS_STDIO_MAXBUFFER\")\n return `output exceeded ${String(MAX_BUFFER)} bytes (killed)`;\n // `killed` is set for any signal (the timeout SIGKILL, or an external one), so keep the child's own\n // stderr when it left some — an externally-killed child is still diagnosable from its output.\n if (e.killed === true)\n return `no response within ${String(timeoutMs)}ms (killed a hung child)${stderrStr ? `: ${stderrStr}` : \"\"}`;\n return stderrStr || errMsg(err);\n};\n\nexport type ExecSpec = {\n readonly command: string;\n readonly args: readonly string[];\n readonly label: string;\n readonly timeoutMs: number;\n readonly env?: Readonly<Record<string, string>>;\n readonly stdin?: string;\n};\n\n// A wedged external CLI (a stalled network read, an interactive auth/pager prompt that never\n// returns) would otherwise hang the whole job until the workflow's own wall clock fires. `env` is\n// spread over the inherited environment only when overrides are supplied; untrusted values reach the\n// child via `env.NAME`, never interpolated into a command.\nexport const execFileWithTimeout = (spec: ExecSpec): Promise<string> =>\n new Promise<string>((resolve, reject) => {\n const child = execFile(\n spec.command,\n [...spec.args],\n {\n ...(spec.env ? { env: { ...process.env, ...spec.env } } : {}),\n encoding: \"utf-8\",\n maxBuffer: MAX_BUFFER,\n timeout: spec.timeoutMs,\n killSignal: \"SIGKILL\",\n },\n (err, stdout, stderr) => {\n if (err)\n reject(\n new Error(`${spec.label} failed: ${classifyExecError(err, stderr, spec.timeoutMs)}`),\n );\n else resolve(stdout);\n },\n );\n if (spec.stdin !== undefined) {\n // A SIGKILLed child (timeout/maxBuffer) can tear down its stdin mid-write; without this handler\n // the resulting EPIPE would crash the process instead of letting the promise reject.\n child.stdin?.on(\"error\", () => undefined);\n child.stdin?.end(spec.stdin);\n }\n });\n","// The single GitHub-API shell boundary; pure callers inject a fake GhApi.\n\nimport { execFileWithTimeout, subprocessTimeoutMs } from \"./exec.js\";\nimport { errMsg } from \"./util.js\";\n\nexport type GhApi = (\n args: readonly string[],\n stdin?: string,\n env?: Readonly<Record<string, string>>,\n) => Promise<string>;\n\n// The endpoint for the error message: `graphql`, or the first path-shaped arg (a REST endpoint always\n// contains a `/`), so a swallowed 403 names WHICH call failed even for `--method POST <path>` forms\n// where the path is not args[0]. Falls back to args[0] for the pathological no-path case.\nexport const describeEndpoint = (args: readonly string[]): string =>\n args.find((a) => a === \"graphql\" || (a.includes(\"/\") && !a.startsWith(\"-\"))) ??\n args[0] ??\n \"(no endpoint)\";\n\n// Newer gh REFUSES raw responses containing terminal escapes unless told to allow them, and GitHub's\n// endpoints now embed ANSI color in responses built from untrusted PR content (job logs, and any\n// diff/conversation an author happens to carry raw escapes in). Every response here is CAPTURED —\n// written to a file or parsed, never echoed to a terminal — so the escapes are always safe to allow.\n// The refusal names its own remedy, so each call retries against the error it actually got: plain\n// first (an old gh accepts it, a new gh accepts it for escape-free content), and a refusal retries\n// with --allow-escape-sequences. A successful retry memoizes flag-first for the process — an old gh\n// never sees the flag, so no capability probe is needed and no probe failure can silently degrade\n// the boundary. The retry re-executes the command, so only IDEMPOTENT calls may retry — a write\n// that already landed server-side before the refusal must surface loudly, never replay. The retry's\n// cost is bounded by design: it re-fetches ONE already-buffered response (for a --paginate call,\n// gh has buffered every page before it refuses, so the retry re-downloads the whole sequence once),\n// and concurrent first calls can each refuse-and-retry once before the memoization lands — a\n// one-time per-process per-endpoint doubling, paid again in each fresh workflow step.\nlet flagFirst: boolean | undefined;\n\nexport const withEscapeRetry = async <T>(\n run: (withFlag: boolean) => Promise<T>,\n idempotent: boolean,\n): Promise<T> => {\n if (flagFirst) return run(true);\n try {\n return await run(false);\n } catch (err) {\n if (errMsg(err).includes(\"--allow-escape-sequences\")) {\n if (!idempotent) throw err;\n flagFirst = true;\n return run(true);\n }\n throw err;\n }\n};\n\n// A write call is one carrying --input, an explicit --method, or a graphql invocation — a\n// conservative reading: a `--method GET` is idempotent too, but nothing here issues one, and the one\n// graphql read query loses nothing by opting out (JSON responses bypass gh's guard anyway), while\n// the graphql minimize MUTATION carries neither REST write flag and must never replay.\nconst isIdempotentCall = (args: readonly string[]): boolean =>\n !args.includes(\"--input\") && !args.includes(\"--method\") && !args.includes(\"graphql\");\n\nexport const runGhApi: GhApi = (args, stdin, env) =>\n withEscapeRetry(\n (withFlag) =>\n execFileWithTimeout({\n command: \"gh\",\n args: [\"api\", ...(withFlag ? [\"--allow-escape-sequences\"] : []), ...args],\n label: `gh api ${describeEndpoint(args)}`,\n timeoutMs: subprocessTimeoutMs(),\n env,\n stdin,\n }),\n isIdempotentCall(args),\n );\n","import { execFile } from \"node:child_process\";\nimport { mkdtemp, readFile, rm, writeFile } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { join, resolve, sep } from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { parseConvergenceMarker, parseFindingsMarker } from \"./surface.js\";\nimport { annotationSafe, errMsg } from \"./util.js\";\nimport { withEscapeRetry } from \"./gh.js\";\n\nconst run = promisify(execFile);\n\n// A hung `gh api` or a stalled `unzip` would wait forever, in a gather step the workflow deliberately\n// leaves without a job-level cap. The seed degrades to \"no prior findings\" on timeout, which is the\n// same state as a first round — strictly better than a stuck job.\nconst STEP_TIMEOUT_MS = 60_000;\n\n// The sticky's marker names the findings artifact rather than carrying it (issue #217). Anything that\n// needs a PRIOR round's findings — the re-review seed, the nit-visibility-floor stickiness — resolves\n// it through here.\n//\n// This runs OUTSIDE the reviewing agent's jail, in gather/seed-draft/post, which hold the token. The\n// jailed agent is netns-confined to the model host and cannot reach GitHub at all; it receives prior\n// findings the same way it always has, through the out-of-band context file seed-draft writes.\nconst MARKER_URL = /<!-- code-review:findings-json (https?:\\/\\/[^\\s>]+) -->/;\n\nexport const findingsArtifactUrl = (body: string): string | null =>\n MARKER_URL.exec(body)?.[1] ?? null;\n\n// The located member name comes from the archive's own listing; before reading it, verify the\n// resolved path stays inside the extraction directory — a stored name like `../../findings.json`\n// must resolve to null, never to a file outside the temp dir (issue #233 r4).\nexport const containedPath = (dir: string, member: string): string | null => {\n const target = resolve(dir, member);\n return target.startsWith(`${dir}${sep}`) || target === dir ? target : null;\n};\n\n// Does the sticky carry a findings marker the next round could seed from — the embedded blob or the\n// artifact link? The single probe post's no-json-url guard and the resolver's callers share, so the\n// two can never disagree on what \"has a prior document\" means (issue #233 r5).\nexport const hasFindingsMarker = (body: string): boolean =>\n parseFindingsMarker(body) !== null || findingsArtifactUrl(body) !== null;\n\n// The exact stored name of the findings member in `unzip -Z1` output, matched CASE-INSENSITIVELY — a\n// case-sensitive filter misses a `Findings.json` member and the seed goes cold with nothing logged\n// (issue #217 review r7). Shortest match wins, so a root-level member is preferred over a nested one\n// if an archive ever holds both — the pipeline uploads a single directory, so today there is exactly\n// one.\nexport const locateFindingsMember = (listing: string): string | null =>\n listing\n .split(\"\\n\")\n .map((l) => l.trim())\n .filter(\n (l) => l.toLowerCase() === \"findings.json\" || l.toLowerCase().endsWith(\"/findings.json\"),\n )\n .sort((a, b) => a.length - b.length)[0] ?? null;\n\n// Reads `findings.json` out of the zip an artifact URL serves. Injected at the call sites so the\n// resolver is testable without a network or an unzip binary.\nexport type ArtifactReader = (zipUrl: string) => Promise<string | null>;\n\nexport const readArtifactFindings = (\n ghApiPath: (url: string, outPath: string) => Promise<void>,\n): ArtifactReader => {\n return async (zipUrl: string): Promise<string | null> => {\n try {\n const dir = await mkdtemp(join(tmpdir(), \"code-review-artifact-\"));\n const zip = join(dir, \"findings.zip\");\n try {\n await ghApiPath(zipUrl, zip);\n // The member is located by NAME, not assumed at the root (locateFindingsMember below) — a\n // findings document can nest as `findings/findings.json`, and today's upload-artifact strips the\n // directory prefix (verified against a real archive), but that is its behaviour, not ours.\n const { stdout: listing } = await run(\"unzip\", [\"-Z1\", zip], {\n encoding: \"utf-8\",\n maxBuffer: 4 * 1024 * 1024,\n timeout: STEP_TIMEOUT_MS,\n });\n const member = locateFindingsMember(listing);\n if (member === null) return null;\n // Extract ALL members and read the located one by exact filesystem path. `unzip -p <zip>\n // <member>` treats the name as a WILDCARD pattern, so a stored path containing `[`/`]`/`*`/`?`\n // matches nothing, exits 11, and the catch returns null — the exact silent cold-seed the\n // located-name fix exists to prevent (issue #217 review r7, verified empirically on Info-ZIP\n // 6.00). A path read has no pattern semantics at all.\n await run(\"unzip\", [zip, \"-d\", dir], {\n maxBuffer: 64 * 1024 * 1024,\n timeout: STEP_TIMEOUT_MS,\n });\n const target = containedPath(dir, member);\n if (target === null) {\n process.stderr.write(\n `::warning::the findings artifact names a member outside the archive directory (${member}) — the re-review seeds without the prior document`,\n );\n return null;\n }\n return await readFile(target, \"utf-8\");\n } finally {\n // Best-effort: a failed cleanup must not override the document/null this promise resolved\n // to — both callers await with no try/catch, so a rejection here would fail the gather\n // step or abort the post (issue #233 r1).\n await rm(dir, { recursive: true, force: true }).catch(() => undefined);\n }\n } catch (err) {\n // Every other best-effort channel in gather/post logs its failures; a mute one made an\n // expired-artifact cold seed undiagnosable. ::warning:: so the Actions UI surfaces it as an\n // annotation, not just a log line (issue #233 r1 + r2).\n process.stderr.write(\n annotationSafe(\n `::warning::could not resolve the prior findings artifact ${zipUrl} (${errMsg(err)}) — the re-review seeds without the prior document`,\n ),\n );\n return null;\n }\n };\n};\n\n// The default reader: `gh api <url> > <path>` — gh follows the artifact redirect and writes the zip.\n// gh's guard classifies binary responses by their first bytes and refuses them only when writing to\n// a TTY, which this piped child stdout never is — so the zip streams verbatim today. The shared\n// escape-retry still wraps the call as defense against a future gh that inspects binary bodies, and\n// to keep every gh api site on one boundary (this one reads its own run call because it needs buffer\n// output rather than runGhApi's string).\nexport const ghArtifactReader = readArtifactFindings(async (url, outPath) => {\n const { stdout } = await withEscapeRetry(\n (withFlag) =>\n run(\"gh\", [\"api\", ...(withFlag ? [\"--allow-escape-sequences\"] : []), url], {\n encoding: \"buffer\",\n maxBuffer: 256 * 1024 * 1024,\n timeout: STEP_TIMEOUT_MS,\n }),\n true,\n );\n await writeFile(outPath, stdout);\n});\n\n// convergence is pipeline-owned, and the artifact holds the agent's draft — uploaded before post stamps\n// it — so a fetched document's convergence is the agent ECHOING what the prior seed showed it. The\n// sticky's compact marker beside the link is the stamped copy, and replaces the echo here so every\n// consumer downstream reads one corrected document. A link with no marker predates the marker and drops\n// the echo; priorTrajectory's legacy rounds-marker fallback covers it.\nconst withoutKey = (doc: Record<string, unknown>, key: string): Record<string, unknown> =>\n Object.fromEntries(Object.entries(doc).filter(([k]) => k !== key));\n\nconst withStampedConvergence = (doc: unknown, body: string): unknown => {\n if (typeof doc !== \"object\" || doc === null || Array.isArray(doc)) return doc;\n const stripped = withoutKey(doc as Record<string, unknown>, \"convergence\");\n const stamped = parseConvergenceMarker(body);\n return stamped === null ? stripped : { ...stripped, convergence: stamped };\n};\n\n// A prior sticky's findings document, or null when the body names none and carries none.\n//\n// The embedded branch is read-only legacy: nothing writes a base64 marker any more, but every sticky\n// posted before #217 holds one, and each PR only rewrites its own on its next round — so this branch\n// is what keeps those PRs' seeds alive rather than a form we still produce.\nexport const resolvePriorFindings = async (\n body: string,\n read: ArtifactReader,\n): Promise<unknown> => {\n const embedded = parseFindingsMarker(body);\n if (embedded !== null) return embedded;\n\n const url = findingsArtifactUrl(body);\n if (url === null) return null;\n\n const text = await read(url);\n if (text === null) return null;\n try {\n return withStampedConvergence(JSON.parse(text), body);\n } catch (err) {\n process.stderr.write(\n annotationSafe(\n `::warning::could not parse the findings document fetched from ${url} (${errMsg(err)}) — the re-review seeds without the prior document`,\n ),\n );\n return null;\n }\n};\n","// post (comment job) and gather (review job) resolve the PR on separate runners but from this SAME\n// pure logic, so they never disagree on which PR (no split-brain).\n\nimport type { GhApi } from \"./gh.js\";\nimport { parseJsonl } from \"./transcript.js\";\n\ninterface PrCandidate {\n readonly number: number;\n readonly state: string;\n readonly headRef: string;\n readonly headSha: string;\n}\n\nconst CANDIDATE_JQ =\n \".[] | {number: .number, state: .state, headRef: .head.ref, headSha: .head.sha}\";\n\nconst parseCandidates = (stdout: string): readonly PrCandidate[] =>\n parseJsonl(stdout) as readonly PrCandidate[];\n\n// A fork PR's head commit lives on the fork, unreachable from the base repo, so\n// `commits/{sha}/pulls` returns nothing for it. Fall back to matching head.sha across open PRs,\n// which does reach forks. The commit endpoint stays the primary path: it is a targeted O(1)\n// lookup and resolves same-repo PRs even when head.sha has since advanced past the CI commit.\n//\n// The primary is treated as advisory: a fork head SHA absent from the base repo can 403 (not just\n// return empty) on a read-scoped token, which is exactly when the fork listing is needed — so a\n// throwing primary falls through the same way an empty one does. A genuine permission gap then\n// surfaces on the listing call (named by ghApi), never swallowed silently here.\nconst fetchDirectCandidates = async (\n repo: string,\n headSha: string,\n ghApi: GhApi,\n): Promise<readonly PrCandidate[]> => {\n try {\n return parseCandidates(\n await ghApi([`repos/${repo}/commits/${headSha}/pulls`, \"--jq\", CANDIDATE_JQ]),\n );\n } catch {\n return [];\n }\n};\n\nexport const fetchPrCandidates = async (\n repo: string,\n headSha: string,\n ghApi: GhApi,\n): Promise<readonly PrCandidate[]> => {\n const direct = await fetchDirectCandidates(repo, headSha, ghApi);\n if (direct.length > 0) return direct;\n const open = parseCandidates(\n await ghApi([\n `repos/${repo}/pulls?state=open&per_page=100`,\n \"--paginate\",\n \"--jq\",\n CANDIDATE_JQ,\n ]),\n );\n return open.filter((c) => c.headSha === headSha);\n};\n\nexport type PrResolution =\n | { readonly kind: \"none\" }\n | { readonly kind: \"not-open\"; readonly prNumber: number; readonly state: string }\n | { readonly kind: \"open\"; readonly prNumber: number };\n\nexport const resolvePr = (\n candidates: readonly PrCandidate[],\n headBranch: string | undefined,\n): PrResolution => {\n if (candidates.length === 0) return { kind: \"none\" };\n const scoped =\n candidates.length > 1 && headBranch\n ? candidates.filter((c) => c.headRef === headBranch)\n : candidates;\n const chosen = scoped.find((c) => c.state === \"open\") ?? scoped[0] ?? candidates[0];\n if (chosen === undefined) return { kind: \"none\" };\n return chosen.state === \"open\"\n ? { kind: \"open\", prNumber: chosen.number }\n : { kind: \"not-open\", prNumber: chosen.number, state: chosen.state };\n};\n\nexport const fetchDiff = async (repo: string, prNumber: number, ghApi: GhApi): Promise<string> =>\n ghApi([\n `repos/${repo}/pulls/${String(prNumber)}`,\n \"-H\",\n \"Accept: application/vnd.github.v3.diff\",\n ]);\n","// A native check-run on the PR head SHA is the attribution surface #115 asks for: it shows in the\n// PR's own checks list, correlates by construction (it IS on the SHA), and — because the review runs\n// from the base repo's default branch with a write token — works for fork PRs too, whose head commit\n// is reachable in the base repo via the PR ref. The in-progress check is created at review start (the\n// announce job, in its own concurrency group) so it survives a superseding run's cancellation. A\n// completed review finalizes it `neutral` (non-gating); a hard-failed review finalizes it `failure`;\n// a cancelled review finalizes its OWN check `cancelled` (issue #139). Every settlement is\n// OWNERSHIP-AWARE: it targets the check whose details_url carries this run's id (the announce stamps\n// `${server_url}/${repo}/actions/runs/<run_id>`), so a same-SHA supersede — where a newer run's\n// announce has already opened its own in-progress check — never settles the wrong run's check.\n\nimport type { GhApi } from \"./gh.js\";\nimport { runGhApi } from \"./gh.js\";\nimport { parseJsonl } from \"./transcript.js\";\n\nexport const CHECK_RUN_NAME = \"Code review\";\n\nexport type CheckIntent = \"in_progress\" | \"neutral\" | \"failure\" | \"cancelled\";\n\nexport interface ExistingCheck {\n readonly id: number;\n readonly status: string;\n readonly conclusion: string | null;\n readonly detailsUrl: string | null;\n}\n\n// Forward-only across the writers (comment finalizes `neutral`, attribute_failure finalizes\n// `failure`, the cancelled run settles `cancelled`) that can race on a same-SHA re-run: a completed\n// review is the truth, so `failure`/`cancelled` never overwrite a completed `neutral`/`success`, and\n// `in_progress` never re-opens a finished check.\nexport type CheckAction =\n | { readonly kind: \"noop\"; readonly reason: string }\n | {\n readonly kind: \"create\";\n readonly status: \"in_progress\" | \"completed\";\n readonly conclusion?: string;\n }\n | {\n readonly kind: \"patch\";\n readonly id: number;\n readonly status: \"completed\";\n readonly conclusion: string;\n };\n\nconst settled = new Set([\"success\", \"neutral\", \"skipped\"]);\n\n// The run id the announce job stamps into the check's details_url (`.../actions/runs/<run_id>`), used\n// to attribute a check to the run that created it. null when the URL doesn't carry one.\nexport const runIdFromUrl = (runUrl: string): string | null => {\n const m = /\\/actions\\/runs\\/(\\d+)\\/?$/.exec(runUrl);\n return m?.[1] ?? null;\n};\n\n// The check THIS run's announce created — the one whose details_url ends with `/runs/<this run id>`.\n// Matching the numeric run id (not a substring of the whole URL) keeps a successor whose run id has\n// this one as a numeric prefix from being matched.\nconst ownedCheck = (checks: readonly ExistingCheck[], runUrl: string): ExistingCheck | null => {\n const runId = runIdFromUrl(runUrl);\n if (runId === null) return null;\n return (\n checks.find((c) => c.detailsUrl !== null && c.detailsUrl.endsWith(`/runs/${runId}`)) ?? null\n );\n};\n\nexport const decideCheckAction = (\n checks: readonly ExistingCheck[],\n intent: CheckIntent,\n runUrl: string,\n): CheckAction => {\n const owned = ownedCheck(checks, runUrl);\n switch (intent) {\n case \"in_progress\":\n // Per-run idempotent: each run opens exactly ONE check (announce retries no-op once its own\n // exists), so a same-SHA supersede never shares a check with the superseded run.\n return owned !== null\n ? { kind: \"noop\", reason: \"this run's check is already in progress\" }\n : { kind: \"create\", status: \"in_progress\" };\n case \"neutral\":\n if (owned === null) return { kind: \"create\", status: \"completed\", conclusion: \"neutral\" };\n return owned.status === \"completed\" && owned.conclusion === \"neutral\"\n ? { kind: \"noop\", reason: \"the check already records this completed review\" }\n : { kind: \"patch\", id: owned.id, status: \"completed\", conclusion: \"neutral\" };\n case \"failure\":\n if (owned === null) return { kind: \"create\", status: \"completed\", conclusion: \"failure\" };\n if (\n owned.status === \"completed\" &&\n owned.conclusion !== null &&\n settled.has(owned.conclusion)\n )\n return { kind: \"noop\", reason: \"a completed review already recorded this head\" };\n return owned.status === \"completed\" && owned.conclusion === \"failure\"\n ? { kind: \"noop\", reason: \"the check already records this failure\" }\n : { kind: \"patch\", id: owned.id, status: \"completed\", conclusion: \"failure\" };\n case \"cancelled\":\n // Never reached via decideCheckAction — `cancelled` needs the runUrl and is dispatched to\n // decideCancelledAction by checkRun.\n return { kind: \"noop\", reason: \"cancelled is handled via decideCancelledAction\" };\n }\n};\n\n// Settle ONLY the check this run's announce created — matched by its details_url carrying this run's\n// id. Ownership-aware: on a concurrency-cancelled review the superseding run's announce has already\n// opened a NEWER in-progress check on the same head, and settling that one would falsely mark a live\n// review cancelled. Matching the numeric run id (not a substring of the whole URL) also keeps a\n// successor whose run id has this one as a numeric prefix from being matched.\nexport const decideCancelledAction = (\n checks: readonly ExistingCheck[],\n runUrl: string,\n): CheckAction => {\n const owned = ownedCheck(checks, runUrl);\n if (owned === null) return { kind: \"noop\", reason: \"no check was created by this run to settle\" };\n if (owned.status === \"completed\" && owned.conclusion === \"cancelled\")\n return { kind: \"noop\", reason: \"the check already records this cancelled run\" };\n // Forward-only like `failure`: never overwrite a completed review's settled check with cancelled.\n if (owned.status === \"completed\" && owned.conclusion !== null && settled.has(owned.conclusion))\n return { kind: \"noop\", reason: \"a completed review already recorded this head\" };\n return { kind: \"patch\", id: owned.id, status: \"completed\", conclusion: \"cancelled\" };\n};\n\nconst CHECK_JQ =\n \".check_runs[] | {id: .id, status: .status, conclusion: .conclusion, detailsUrl: .details_url}\";\n\nconst fetchChecks = async (\n repo: string,\n headSha: string,\n ghApi: GhApi,\n): Promise<readonly ExistingCheck[]> =>\n parseJsonl(\n await ghApi([\n `repos/${repo}/commits/${headSha}/check-runs?check_name=${encodeURIComponent(CHECK_RUN_NAME)}&per_page=100`,\n \"--paginate\",\n \"--jq\",\n CHECK_JQ,\n ]),\n ) as readonly ExistingCheck[];\n\nconst output = (intent: CheckIntent, runUrl: string): { title: string; summary: string } => {\n switch (intent) {\n case \"in_progress\":\n return {\n title: \"Code review in progress\",\n summary: `The review is running — [see the run](${runUrl}).`,\n };\n case \"neutral\":\n return {\n title: \"Code review complete\",\n summary: `The review was posted — [see the run](${runUrl}).`,\n };\n case \"failure\":\n return {\n title: \"Code review did not complete\",\n summary: `The review job failed — [see the run](${runUrl}). Re-request the review; do not treat this round as spent.`,\n };\n case \"cancelled\":\n return {\n title: \"Code review superseded\",\n summary: `This review run was cancelled — [see the run](${runUrl}). No action needed.`,\n };\n }\n};\n\nexport interface CheckRunInput {\n readonly repo: string;\n readonly headSha: string;\n readonly intent: CheckIntent;\n readonly runUrl: string;\n}\n\n// Resolve the current check, decide the forward-only ownership-aware action, then apply it. Head SHA\n// (not the PR) is the whole key — no PR resolution needed, which is why this also works for fork PRs.\nexport const checkRun = async (input: CheckRunInput, ghApi: GhApi = runGhApi): Promise<void> => {\n const checks = await fetchChecks(input.repo, input.headSha, ghApi);\n const action =\n input.intent === \"cancelled\"\n ? decideCancelledAction(checks, input.runUrl)\n : decideCheckAction(checks, input.intent, input.runUrl);\n if (action.kind === \"noop\") {\n process.stderr.write(`code-review check-run: ${action.reason} — leaving it\\n`);\n return;\n }\n const body =\n action.kind === \"create\"\n ? {\n name: CHECK_RUN_NAME,\n head_sha: input.headSha,\n status: action.status,\n details_url: input.runUrl,\n ...(action.conclusion ? { conclusion: action.conclusion } : {}),\n output: output(input.intent, input.runUrl),\n }\n : {\n status: action.status,\n conclusion: action.conclusion,\n details_url: input.runUrl,\n output: output(input.intent, input.runUrl),\n };\n const endpoint =\n action.kind === \"create\"\n ? [`--method`, `POST`, `repos/${input.repo}/check-runs`, `--input`, `-`]\n : [\n `--method`,\n `PATCH`,\n `repos/${input.repo}/check-runs/${String(action.id)}`,\n `--input`,\n `-`,\n ];\n await ghApi(endpoint, JSON.stringify(body));\n};\n","// Ordering invariant: all reads, decodes, and rendering complete before the first API write; then\n// the sticky, then the inline review. A posting failure propagates and exits non-zero (never partial).\n\nimport { readFileSync, appendFileSync } from \"node:fs\";\nimport type { DiscussionLink, InlineComment, InlineDisposition, RenderInput } from \"./types.js\";\nimport { buildInlineComments } from \"./inline.js\";\nimport { isEmptyDiff, indexDiff, partitionFindings } from \"./diff.js\";\nimport {\n render,\n computeSeverityCounts,\n isConvergenceRound,\n isReviewVerdict,\n PER_FINDING_LINKS,\n} from \"./render.js\";\nimport { formatMarkdown } from \"./format.js\";\nimport {\n buildConvergence,\n carriedAncestryMarkers,\n carriedConvergence,\n carriedFindingsMarker,\n carriedMarkerPointer,\n carryForwardMarkers,\n isFullReviewAncestry,\n computeIdCounts,\n computeSameRootNotes,\n findingsMarkerPair,\n inProgressConvergence,\n nextRoundNumber,\n isBelowVisibilityFloor,\n isFullReviewSticky,\n priorBelowFloorNits,\n parseCompletedAncestor,\n parseFindingsMarker,\n parseReviewComplete,\n parseMechanicAncestor,\n parseReviewedRoute,\n parseReviewedSha,\n priorTrajectory,\n reviewBodyPointer,\n mechanicConvergence,\n escapeCodeBackticks,\n DEFAULT_CONVERGENCE_THRESHOLD,\n} from \"./surface.js\";\nimport {\n ResultEnvelopeCodec,\n PriceMapCodec,\n TestSummaryCodec,\n incompleteFindings,\n isIncompleteFindings,\n RECOVERABLE_OPTIONAL_FIELDS,\n} from \"./schema.js\";\nimport { resolveFindingId, resolveRuleId, synthesizedSystemicId } from \"./schema.js\";\nimport type { Convergence, Finding, Findings, ResultEnvelope, TestSummary } from \"./schema.js\";\nimport { resolve, supportedVersions } from \"./registry.js\";\nimport type { GhApi } from \"./gh.js\";\nimport { runGhApi } from \"./gh.js\";\nimport {\n findingsArtifactUrl,\n ghArtifactReader,\n hasFindingsMarker,\n resolvePriorFindings,\n type ArtifactReader,\n} from \"./artifact.js\";\nexport type { GhApi } from \"./gh.js\";\nimport { fetchDiff, fetchPrCandidates, resolvePr } from \"./pr.js\";\nimport { runIdFromUrl } from \"./checkrun.js\";\nimport {\n applyAnswered,\n answeredNoteKey,\n answeredReRaiseNote,\n answeredRegistryFrom,\n fetchThreadComments,\n} from \"./answered.js\";\nimport { asRecord, errMsg, tryParseJson } from \"./util.js\";\n\nexport interface PostInput {\n readonly repo: string;\n // The head repo (owner/name of the fork) threaded by the workflow via HEAD_REPO — a finding\n // permalink targets the reviewed SHA, which the base repo stops resolving for a fork once the\n // pull ref is force-pushed away. The workflow derives it from the caller's event\n // (workflow_run.head_repository.full_name / pull_request.head.repo.full_name); this base-repo\n // fallback serves the event types it cannot derive from.\n readonly headRepo?: string;\n readonly headSha: string;\n readonly botLogin: string;\n readonly findingsPath: string;\n readonly envelopePath: string;\n readonly pricesPath: string;\n // false ⇒ the bundled all-zero example; the render layer shows cost as N/A, never a false $0.00.\n readonly pricesProvided: boolean;\n readonly templatePath: string;\n readonly inlineTemplatePath: string;\n readonly route?: string;\n readonly headBranch?: string;\n readonly testReportPath?: string;\n // Raw `cloc --git --diff` table (issue #182), rendered verbatim in the sticky's cloc collapsible.\n readonly clocDiffPath?: string;\n readonly effort?: string;\n readonly runUrl?: string;\n // Render findings as inline review comments on the diff. Omitted/false ⇒ the review object is\n // posted body-only and the findings are listed in the sticky instead, which is the default because\n // an inline thread is a human-only surface that cannot be revised: a later round can neither update\n // nor resolve it, so stale threads accumulate on the diff (issue #179).\n readonly inline?: boolean;\n // The fast-fix route ran with no failing-job logs staged (issue #154). Passed as a flag because\n // this runs in the comment job, where the staged logs are not: the review job counted them. It\n // could equally ride the envelope, which `adapt` stamps with route and effort after the agent —\n // the flag is the same channel `--route` already uses, and works when the envelope is lost.\n readonly unverifiedNoLogs?: boolean;\n // Findings-json marker's fallback across surfaces when the embedded form is too large.\n readonly jsonUrl?: string;\n // Advisory convergence tolerance passed through to render(); omitted ⇒ the render default.\n readonly convergenceThreshold?: number;\n // The nit visibility floor (issue #164): nits below confidence × likelihood are hidden from humans.\n // Omitted ⇒ the surface default.\n readonly nitVisibilityFloor?: number;\n // Computed by the caller via formatUtc so post() stays a clockless pass-through into render().\n readonly postedAt?: string;\n // The run's UTC instant (same instant as postedAt), threaded to render for time-slotted pricing\n // (issue #170); post() stays clockless. Ignored for a flat price map.\n readonly pricedAt?: Date;\n}\n\nconst DEFAULT_MARKER = \"<!-- code-review -->\";\n\nconst EMPTY_MECHANIC_LEAVE_MESSAGE =\n \"The CI-fix pass found no issues and the sticky already reflects a completed full review — leaving it in place\\n\";\nconst MAX_SUGGESTION_LINES = 10;\n\nconst countSuggestionLines = (text: string): number => text.split(\"\\n\").length;\n\nconst checkLongSuggestions = (\n comments: readonly InlineComment[],\n): { readonly comments: readonly InlineComment[]; readonly longFiles: readonly string[] } => {\n const longFiles: string[] = [];\n const adjusted = comments.map((c) => {\n const match = /```suggestion\\n([\\s\\S]*?)\\n```/.exec(c.body);\n if (match?.[1] && countSuggestionLines(match[1]) > MAX_SUGGESTION_LINES) {\n longFiles.push(`${c.path}:${String(c.line)}`);\n return {\n ...c,\n body: c.body.replace(\n /```suggestion\\n[\\s\\S]*?\\n```/,\n \"*(suggestion omitted — exceeds GitHub's ~10-line suggestion limit; see summary)*\",\n ),\n };\n }\n return c;\n });\n return { comments: adjusted, longFiles };\n};\n\n// Loaders never throw on untrusted artifacts — malformed input degrades to a tagged result the\n// caller renders as a notice, never crashing the post.\ntype FindingsLoadResult =\n | { readonly kind: \"ok\"; readonly findings: Findings }\n | { readonly kind: \"corrupt\" }\n | { readonly kind: \"invalid-shape\" }\n | { readonly kind: \"unsupported-schema-version\"; readonly version: string };\n\nconst decodeFindings = (doc: unknown): FindingsLoadResult => {\n const resolution = resolve(\"findings\", doc);\n switch (resolution.kind) {\n case \"ok\":\n return { kind: \"ok\", findings: resolution.value };\n case \"unsupported-version\":\n return { kind: \"unsupported-schema-version\", version: resolution.version };\n case \"invalid-shape\":\n case \"missing-version\":\n return { kind: \"invalid-shape\" };\n }\n};\n\nconst loadFindings = (path: string): FindingsLoadResult => {\n let raw: unknown;\n try {\n raw = JSON.parse(readFileSync(path, \"utf-8\")) as unknown;\n } catch {\n return { kind: \"corrupt\" };\n }\n const first = decodeFindings(raw);\n // The seed hands the agent a prior doc that carries `convergence`, and the agent is told not to write\n // it — but an echoed or mangled stamp must not fail the WHOLE review into a \"did not complete\" notice,\n // since the pipeline overwrites both stamped fields after load. Strip them and retry before degrading\n // (mirrors seed-draft's strip-and-retry, issue #185 review).\n if (\n first.kind === \"invalid-shape\" &&\n typeof raw === \"object\" &&\n raw !== null &&\n !Array.isArray(raw) &&\n Object.keys(raw).some((k) => RECOVERABLE_OPTIONAL_FIELDS.has(k))\n ) {\n const stripped = Object.fromEntries(\n Object.entries(raw).filter(([key]) => !RECOVERABLE_OPTIONAL_FIELDS.has(key)),\n );\n const retry = decodeFindings(stripped);\n if (retry.kind === \"ok\") {\n process.stderr.write(\n \"Warning: the review draft carried an invalid best-effort field (convergence/scope_metastasis/change_size) — stripped it and used the rest; the pipeline re-stamps convergence\\n\",\n );\n return retry;\n }\n }\n return first;\n};\n\nconst noticeMessageFor = (result: Exclude<FindingsLoadResult, { kind: \"ok\" }>): string => {\n switch (result.kind) {\n case \"corrupt\":\n return \"Review output was missing or malformed — the review did not complete. See the workflow run for logs.\";\n case \"invalid-shape\":\n return \"Review output was malformed — it did not conform to the findings schema. See the workflow run for logs.\";\n case \"unsupported-schema-version\": {\n const supported = supportedVersions(\"findings\")\n .map((minor) => `${minor}.x`)\n .join(\", \");\n return `Review output declares schema_version \"${result.version}\", which this commenter does not support (supported: ${supported}). See the workflow run for logs.`;\n }\n }\n};\n\nconst loadEnvelope = (path: string): ResultEnvelope | null => {\n let raw: unknown;\n try {\n raw = JSON.parse(readFileSync(path, \"utf-8\")) as unknown;\n } catch {\n return null;\n }\n const decoded = ResultEnvelopeCodec.decode(raw);\n return decoded._tag === \"Right\" ? decoded.right : null;\n};\n\n// Optional enrichment: any failure warns and returns undefined, never aborts the post.\nconst loadTestReport = (path: string): TestSummary | undefined => {\n let raw: unknown;\n try {\n raw = JSON.parse(readFileSync(path, \"utf-8\")) as unknown;\n } catch (err) {\n process.stderr.write(\n `Warning: could not read test report at ${path}: ${errMsg(err)} — omitting test panel\\n`,\n );\n return undefined;\n }\n const decoded = TestSummaryCodec.decode(raw);\n if (decoded._tag === \"Left\") {\n process.stderr.write(\n `Warning: test report at ${path} does not match the expected shape — omitting test panel\\n`,\n );\n return undefined;\n }\n return decoded.right;\n};\n\n// The raw cloc --diff table (issue #182), best-effort like loadTestReport: an unreadable path warns\n// and omits the collapsible, and an empty/whitespace-only file (cloc ran but produced nothing, or a\n// placeholder left by a failed run) is treated as absent so no empty collapsible renders.\nexport const loadClocDiff = (path: string): string | undefined => {\n let raw: string;\n try {\n raw = readFileSync(path, \"utf-8\");\n } catch (err) {\n process.stderr.write(\n `Warning: could not read cloc diff at ${path}: ${errMsg(err)} — omitting the cloc collapsible\\n`,\n );\n return undefined;\n }\n return raw.trim() === \"\" ? undefined : raw;\n};\n\nconst parseHtmlUrl = (raw: string): string | undefined => {\n const parsed = tryParseJson(raw);\n const htmlUrl = parsed.ok ? asRecord(parsed.value)?.[\"html_url\"] : undefined;\n return typeof htmlUrl === \"string\" ? htmlUrl : undefined;\n};\n\nconst commentPayload = (c: InlineComment): Record<string, unknown> => ({\n path: c.path,\n line: c.line,\n side: c.side,\n ...(c.start_line !== undefined && c.start_side !== undefined\n ? { start_line: c.start_line, start_side: c.start_side }\n : {}),\n body: formatMarkdown(c.body),\n});\n\n// comments[i] is the rendered comment for inDiff[i] (1:1, same order). Returns the review url\n// (undefined when no breadcrumb review object posted — the caller gates the dismiss/minimize on\n// `posted`, the POST's success, not the parsed url), the count that actually posted, and the\n// findings GitHub rejected (for the caller to surface in the sticky).\nconst postInlineReview = async (\n pr: {\n readonly repo: string;\n readonly prNumber: number;\n readonly headSha: string;\n readonly stickyUrl: string | undefined;\n readonly runUrl: string | undefined;\n },\n comments: readonly InlineComment[],\n inDiff: readonly Finding[],\n ghApi: GhApi,\n): Promise<{\n readonly url: string | undefined;\n readonly posted: boolean;\n readonly inlinePosted: number;\n readonly unposted: readonly Finding[];\n}> => {\n const pointer = reviewBodyPointer(\n pr.headSha,\n pr.stickyUrl,\n pr.runUrl,\n (process.env[\"GITHUB_STEP_SUMMARY\"] ?? \"\") !== \"\",\n );\n const reviewBody = (withComments: boolean): string =>\n JSON.stringify({\n body: pointer,\n commit_id: pr.headSha,\n event: \"COMMENT\",\n comments: withComments ? comments.map(commentPayload) : [],\n });\n const reviewsEndpoint = [`repos/${pr.repo}/pulls/${String(pr.prNumber)}/reviews`, \"--input\", \"-\"];\n try {\n const stdout = await ghApi(reviewsEndpoint, reviewBody(true));\n return { url: parseHtmlUrl(stdout), posted: true, inlinePosted: comments.length, unposted: [] };\n } catch (err) {\n // The reviews endpoint is atomic — one rejected position fails the whole batch — so on rejection\n // post the body only, then re-post each comment individually, collecting the ones GitHub rejects.\n if (comments.length === 0) {\n // No inline comments to salvage: the breadcrumb review-object POST itself failed. The sticky\n // already carries the full review, so this is a DEGRADED-but-complete round — report it and\n // return posted false; the caller gates the dismiss/minimize on `posted` (the POST's success —\n // an unparseable response still means the object exists), so a permanent failure never leaves\n // the PR review-less (issue #223).\n // An Actions annotation (::warning:: in the step output), not a GITHUB_OUTPUT key: the CLI\n // owns the loudness so every workflow copy and every pinned CLI version sees the degradation.\n process.stderr.write(\n `::warning:: the review-object POST on PR #${String(pr.prNumber)} failed (${errMsg(err)}) — the sticky carries the review, but no diff-anchored review object exists this round\\n`,\n );\n return { url: undefined, posted: false, inlinePosted: 0, unposted: [] };\n }\n process.stderr.write(\n `Warning: the batched inline review on PR #${String(pr.prNumber)} was rejected (${errMsg(err)}) — posting the review body-only, then each comment individually to keep the ones GitHub accepts (issue #57)\\n`,\n );\n let url: string | undefined;\n let posted = false;\n try {\n url = parseHtmlUrl(await ghApi(reviewsEndpoint, reviewBody(false)));\n posted = true;\n } catch (bodyErr) {\n // The body-only retry failed too — the individual comments still re-post, but no breadcrumb\n // review object exists this round; the caller gates the dismiss/minimize on `posted` (the\n // POST's success — an unparseable response still means the object exists) (issue #223).\n process.stderr.write(\n `::warning:: the body-only review retry on PR #${String(pr.prNumber)} failed (${errMsg(bodyErr)}) — individual comments still re-post, but no breadcrumb review object exists this round\\n`,\n );\n }\n const commentsEndpoint = [\n `repos/${pr.repo}/pulls/${String(pr.prNumber)}/comments`,\n \"--input\",\n \"-\",\n ];\n const unposted: Finding[] = [];\n let inlinePosted = 0;\n for (const [i, c] of comments.entries()) {\n try {\n await ghApi(\n commentsEndpoint,\n JSON.stringify({ commit_id: pr.headSha, ...commentPayload(c) }),\n );\n inlinePosted += 1;\n } catch (e) {\n const finding = inDiff[i];\n if (finding) unposted.push(finding);\n process.stderr.write(\n `Warning: inline comment on ${c.path}:${String(c.line)} rejected (${errMsg(e)}) — surfacing that finding in the sticky instead (issue #57)\\n`,\n );\n }\n }\n return { url, posted, inlinePosted, unposted };\n }\n};\n\n// ONE projection + ONE fetch for every issue-comment consumer: the sticky lookup (findBotComment)\n// and the discussion aside read the same rows. post() fetches the history once per round and passes\n// the rows to both; announce routes through findBotComment, which fetches on its own. Transport\n// errors PROPAGATE — the callers that must not mistake a failed fetch for an absent sticky let the\n// rejection through.\n// The issue-comments endpoint returns NO in_reply_to_id — the field exists only on pull-request\n// REVIEW comments (the answered registry's endpoint), and GitHub's API exposes no issue-comment\n// reply chain at all. The projection therefore carries only the fields the endpoint actually has.\nconst ISSUE_COMMENTS_JQ =\n '.[] | {id, user: (.user.login // \"(deleted)\"), created_at, html_url, body: (.body // \"\")}';\n\ninterface IssueCommentRow {\n readonly id: number;\n readonly author: string;\n readonly created: string;\n readonly url: string;\n readonly body: string;\n}\n\nconst parseIssueCommentRows = (\n raw: string,\n): { readonly rows: readonly IssueCommentRow[]; readonly malformed: number } => {\n let malformed = 0;\n const rows: IssueCommentRow[] = [];\n for (const line of raw.split(\"\\n\")) {\n const trimmed = line.trim();\n if (trimmed === \"\") continue;\n const parsed = tryParseJson(trimmed);\n if (!parsed.ok) {\n malformed += 1;\n continue;\n }\n const rec = asRecord(parsed.value);\n const id = rec?.[\"id\"];\n const author = rec?.[\"user\"];\n const created = rec?.[\"created_at\"];\n const url = rec?.[\"html_url\"];\n const body = rec?.[\"body\"];\n if (\n typeof id === \"number\" &&\n typeof author === \"string\" &&\n typeof created === \"string\" &&\n typeof url === \"string\" &&\n typeof body === \"string\"\n ) {\n rows.push({ id, author, created, url, body });\n } else {\n // A shape failure IS corruption: the ghost-account case this branch once served is now\n // coalesced to \"(deleted)\" in the projection, so every remaining drop is a field the\n // endpoint guarantees — and a dropped sticky row would read as \"no sticky\" and mint a\n // duplicate, the exact failure the fail-loud invariant exists to prevent.\n malformed += 1;\n }\n }\n // The REST order is not a contract — the caps and the walk derive recency from it, so the rows\n // sort explicitly by (created, id), the sibling registry's discipline.\n rows.sort(\n (a, b) => a.created.localeCompare(b.created) || (a.id > b.id ? 1 : a.id < b.id ? -1 : 0),\n );\n return { rows, malformed };\n};\n\nconst fetchIssueCommentRows = async (\n repo: string,\n prNumber: number,\n ghApi: GhApi,\n): Promise<readonly IssueCommentRow[]> => {\n const raw = await ghApi([\n // per_page rides the QUERY string — a `-f` field would flip `gh api` from GET to POST\n // (create-comment) and 422 every sticky lookup.\n `repos/${repo}/issues/${String(prNumber)}/comments?per_page=100`,\n \"--paginate\",\n \"--jq\",\n ISSUE_COMMENTS_JQ,\n ]);\n const { rows, malformed } = parseIssueCommentRows(raw);\n // A sticky lookup is a WRITE-GATING decision: a corrupted fetch that silently read as \"no sticky\"\n // would mint a duplicate sticky while the real one is still live. Fail loudly instead (the\n // pre-parseJsonl code threw on garbage for exactly this reason).\n if (malformed > 0) {\n throw new Error(\n `${String(malformed)} issue-comment row(s) failed to decode — refusing to treat a corrupted history as an absent sticky`,\n );\n }\n return rows;\n};\n\nconst selectBotComment = (\n rows: readonly IssueCommentRow[],\n botLogin: string,\n marker: string,\n): { readonly id: number; readonly body: string } | null => {\n const bot = rows.filter((r) => r.author === botLogin && r.body.startsWith(marker));\n const last = bot[bot.length - 1];\n return last === undefined ? null : { id: last.id, body: last.body };\n};\n\nexport const findBotComment = async (\n repo: string,\n prNumber: number,\n botLogin: string,\n marker: string,\n ghApi: GhApi,\n): Promise<{ readonly id: number; readonly body: string } | null> =>\n selectBotComment(await fetchIssueCommentRows(repo, prNumber, ghApi), botLogin, marker);\n\nconst parseCommentRef = (\n raw: string,\n): { readonly id: number; readonly html_url: string } | null => {\n const parsed = tryParseJson(raw);\n const rec = parsed.ok ? asRecord(parsed.value) : null;\n const id = rec?.[\"id\"];\n const html_url = rec?.[\"html_url\"];\n return typeof id === \"number\" && typeof html_url === \"string\" ? { id, html_url } : null;\n};\n\nconst patchComment = async (\n repo: string,\n commentId: number,\n body: string,\n ghApi: GhApi,\n): Promise<{ readonly html_url: string } | null> => {\n const stdout = await ghApi(\n [`repos/${repo}/issues/comments/${String(commentId)}`, \"--input\", \"-\"],\n JSON.stringify({ body }),\n );\n // Only html_url is needed — the id is already known — unlike parseCommentRef for a new comment.\n const htmlUrl = parseHtmlUrl(stdout);\n return htmlUrl !== undefined ? { html_url: htmlUrl } : null;\n};\n\nconst postComment = async (\n repo: string,\n prNumber: number,\n body: string,\n ghApi: GhApi,\n): Promise<{ readonly id: number; readonly html_url: string } | null> => {\n const stdout = await ghApi(\n [`repos/${repo}/issues/${String(prNumber)}/comments`, \"--input\", \"-\"],\n JSON.stringify({ body }),\n );\n return parseCommentRef(stdout);\n};\n\n// The discussion aside's reply chain (issue #246): every issue comment whose reply chain reaches the\n// sticky comment, grouped by the backtick-quoted finding ids its body mentions (the same form the\n// sticky renders). Pointers only — the implementer reads the replies at the links.\nexport interface StickyDiscussion {\n readonly byFinding: Readonly<Record<string, readonly DiscussionLink[]>>;\n // Replies naming an id THIS round's report no longer carries but the PRIOR sticky's findings did:\n // a finding that was fixed or re-id'd between rounds. The sticky is overwritten every round\n // (issue #205), so without this bucket the conversation's pointers vanish from the review surface\n // exactly when the finding left the report.\n readonly orphaned: Readonly<Record<string, readonly DiscussionLink[]>>;\n // How many distinct departed ids were mentioned in total — the rendered section shows\n // \"(showing N of M)\" when the cap trimmed some, so the cut is named, never silent.\n readonly orphanedTotal: number;\n // Finding id → the pre-cap link total, present only when the 6-newest cap trimmed that finding's\n // list — the aside names its cut instead of rendering indistinguishably from a short thread.\n readonly truncated: Readonly<Record<string, number>>;\n // The same per-token pre-cap totals for the orphaned bucket's entries.\n readonly orphanedTruncated: Readonly<Record<string, number>>;\n}\n\nconst ID_TOKEN_RE = /`([^`\\n]+)`/g;\nconst ORPHAN_TOKEN_CAP = 8;\n\n// The raw id → escaped DISPLAY spelling index: the sticky renders ids through escapeCodeBackticks\n// (backticks → '-', newlines → ' '), so a reply quoting the DISPLAYED spelling of an id must land\n// in the same bucket as a reply quoting the raw one. The escaping is not injective (escape-twin ids\n// display identically), and an ambiguous spelling must NOT be silently assigned a winner — the\n// token stays unmatched and the raw spellings remain the only keys.\nconst escapedIdIndex = (ids: readonly string[]): ReadonlyMap<string, string> => {\n const owners = new Map<string, string[]>();\n for (const id of ids) {\n const escaped = escapeCodeBackticks(id);\n if (escaped === id) continue;\n const list = owners.get(escaped);\n if (list === undefined) owners.set(escaped, [id]);\n // Deduped: ONE distinct raw id owns its spelling regardless of how many times it appears in\n // the input (a current id also carried by the prior doc); only DISTINCT escape-twins drop it.\n else if (!list.includes(id)) list.push(id);\n }\n return new Map(\n [...owners.entries()].flatMap(([escaped, raws]) =>\n raws.length === 1 && raws[0] !== undefined ? ([[escaped, raws[0]]] as const) : [],\n ),\n );\n};\n\n// The discussion rows: EVERY comment on the PR, the sticky's own excluded. GitHub's API exposes\n// no reply-chain for issue comments (in_reply_to_id exists only on pull-request REVIEW comments —\n// the answered registry's endpoint), so \"replies to the sticky\" cannot be derived from any\n// channel; the aside groups the whole comment conversation instead, which serves the same\n// discoverability. Rows are deduped by id, first occurrence wins — gh --paginate fetches pages\n// sequentially, and a comment edited mid-pagination can legitimately appear on two pages; two\n// rows for one comment must not push two links into one aside. Computed ONCE per round and shared\n// by the gate and the grouping.\nexport const discussionRows = (\n rows: readonly IssueCommentRow[],\n stickyId: number,\n botLogin: string,\n): readonly IssueCommentRow[] => {\n const seen = new Set<number>();\n return rows.filter((c) => {\n if (seen.has(c.id)) return false;\n seen.add(c.id);\n // Bot-authored comments are the pipeline's own surfaces — a stale or duplicate sticky\n // quotes every finding id and must never scrape into the asides as human discussion.\n return c.id !== stickyId && c.author !== botLogin;\n });\n};\n\n// Whether any non-sticky comment names a backtick token this round does NOT report —\n// the only case the orphan bucket can be non-empty, and therefore the only case the prior sticky's\n// findings document is worth resolving for it. A necessary-not-sufficient condition: a reply\n// quoting a code snippet or path in backticks fires it too, and the round pays the artifact\n// download for a token that was never a finding id — the local alternative (the sticky's carried\n// rounds marker) records ids top-N-capped, so pre-filtering on it would skip real departed ids.\n// On the notice path (an empty known set) the same false positive can escalate into the rendered\n// unresolvable note when the resolve then fails — an accepted noise cost, since the note names\n// the artifact failure itself, never the token as a departed id.\n// The id-shape pre-filter: the gate pays the artifact resolve only for an unknown token that\n// could plausibly BE a finding id (the pipeline's ids are kebab-case identifiers and the\n// synthesized f-/s- base64url forms). A backticked shell command, path, or URL never fires it.\n// An id-shaped junk word still fires — the documented necessary-not-sufficient trade-off.\nconst ID_SHAPE_RE = /^[A-Za-z0-9][A-Za-z0-9_-]*$/;\n\nexport const mentionsOutsideKnown = (\n reachable: readonly IssueCommentRow[],\n currentIds: readonly string[],\n): boolean => {\n const known = new Set(currentIds);\n const escapedToRaw = escapedIdIndex(currentIds);\n for (const c of reachable) {\n for (const m of c.body.matchAll(ID_TOKEN_RE)) {\n const token = m[1];\n if (token === undefined) continue;\n const raw = known.has(token) ? token : escapedToRaw.get(token);\n if ((raw === undefined || !known.has(raw)) && ID_SHAPE_RE.test(token)) return true;\n }\n }\n return false;\n};\n\n// The pure comment→discussion grouping: every non-sticky comment on the PR, grouped by the\n// backtick-quoted ids it mentions — capped 6 newest-first per id. The orphan bucket holds ONLY\n// tokens the PRIOR sticky's findings actually carried (priorIds), never shape-guessed prose: a\n// backtick token that was never a finding id is not published as one. Extracted pure so the caps\n// and the dedupe are unit-testable without an API mock.\nexport const buildStickyDiscussion = (\n reachable: readonly IssueCommentRow[],\n currentIds: readonly string[],\n priorIds: readonly string[],\n): StickyDiscussion => {\n const known = new Set(currentIds);\n const departed = new Set(priorIds);\n const escapedToRaw = escapedIdIndex([...currentIds, ...priorIds]);\n const byFinding = Object.fromEntries(\n currentIds.map((id): [string, DiscussionLink[]] => [id, []]),\n );\n const orphaned = new Map<string, DiscussionLink[]>();\n const latestAt = new Map<string, string>();\n for (const c of reachable) {\n const link = { author: c.author, when: c.created.slice(0, 10), url: c.url, at: c.created };\n // One link per (comment, token): a reply quoting the same id twice must not crowd the cap.\n const pushed = new Set<string>();\n for (const m of c.body.matchAll(ID_TOKEN_RE)) {\n const token = m[1];\n if (token === undefined || pushed.has(token)) continue;\n pushed.add(token);\n const rawKnown = known.has(token);\n const alias = rawKnown ? undefined : escapedToRaw.get(token);\n const aliasIsKnown = alias !== undefined && known.has(alias);\n const rawDeparted = departed.has(token);\n if (rawKnown) {\n byFinding[token]?.push(link);\n } else if (aliasIsKnown) {\n // A token that is BOTH a current id's display alias and a departed raw id is ambiguous —\n // it stays unmatched rather than silently winning for either side.\n if (!rawDeparted) byFinding[alias]?.push(link);\n } else if (rawDeparted) {\n const key = token;\n const links = orphaned.get(key);\n if (links === undefined) orphaned.set(key, [link]);\n else links.push(link);\n const latest = latestAt.get(key);\n if (latest === undefined || c.created.localeCompare(latest) > 0)\n latestAt.set(key, c.created);\n } else if (alias !== undefined && departed.has(alias)) {\n // The token is a DEPARTED id's display spelling — filed under the departed raw id, the\n // same attribution the orphan bucket's contract promises.\n const key = alias;\n const links = orphaned.get(key);\n if (links === undefined) orphaned.set(key, [link]);\n else links.push(link);\n const latest = latestAt.get(key);\n if (latest === undefined || c.created.localeCompare(latest) > 0)\n latestAt.set(key, c.created);\n }\n }\n }\n // Map-built then Object.fromEntries: a `__proto__`-named id must record its cut like any other\n // key, which a bare {}-literal assignment silently swallows.\n const truncated = new Map<string, number>();\n for (const [id, links] of Object.entries(byFinding)) {\n links.reverse();\n if (links.length > PER_FINDING_LINKS) {\n truncated.set(id, links.length);\n links.splice(PER_FINDING_LINKS);\n }\n }\n const orphanedTruncated = new Map<string, number>();\n for (const [token, links] of orphaned) {\n links.reverse();\n if (links.length > PER_FINDING_LINKS) {\n orphanedTruncated.set(token, links.length);\n links.splice(PER_FINDING_LINKS);\n }\n }\n // Bound the orphan bucket at the 8 NEWEST departed ids (by their latest reply's FULL timestamp —\n // the date-only display string would tie same-day replies and let the stable sort cut the newer\n // one), matching the newest-first discipline the per-finding lists keep.\n const orphanedTotal = orphaned.size;\n const byLatestReply = [...orphaned.entries()].sort((a, b) =>\n (latestAt.get(b[0]) ?? \"\").localeCompare(latestAt.get(a[0]) ?? \"\"),\n );\n return {\n byFinding,\n orphaned: Object.fromEntries(byLatestReply.slice(0, ORPHAN_TOKEN_CAP)),\n orphanedTotal,\n truncated: Object.fromEntries(truncated),\n orphanedTruncated: Object.fromEntries(orphanedTruncated),\n };\n};\n\n// The prior findings document's finding + systemic ids — the full departed set the orphan bucket may\n// hold (a departed systemic id orphans exactly like a departed finding id). Tolerant over the\n// resolved shape: a non-document yields no ids, so the bucket fails open to empty.\nexport const priorIdsFrom = (doc: unknown): readonly string[] => {\n if (typeof doc !== \"object\" || doc === null || Array.isArray(doc)) return [];\n const rec = doc as Record<string, unknown>;\n // The id spelling with the LEGACY code fallback — a pre-0.10 prior document (findings with a\n // code and no id) must still feed the departed set, or its replies pay the resolve and then\n // render nowhere.\n const idsOf = (field: string, systemic: boolean): readonly string[] =>\n (Array.isArray(rec[field]) ? rec[field] : []).flatMap((raw) => {\n const item = typeof raw === \"object\" && raw !== null ? asRecord(raw) : null;\n if (item === null) return [];\n const title = typeof item[\"title\"] === \"string\" ? item[\"title\"] : \"\";\n const resolved = resolveRuleId({\n ...(typeof item[\"id\"] === \"string\" ? { id: item[\"id\"] } : {}),\n ...(typeof item[\"code\"] === \"string\" ? { code: item[\"code\"] } : {}),\n ...(typeof item[\"path\"] === \"string\" ? { path: item[\"path\"] } : {}),\n title,\n });\n // The upcast's own fallback for a code-less systemic (no path to synthesize from).\n const id = resolved ?? (systemic && title !== \"\" ? synthesizedSystemicId(title) : undefined);\n return id !== undefined ? [id] : [];\n });\n return [...idsOf(\"findings\", false), ...idsOf(\"systemic_problems\", true)];\n};\n\n// Best-effort append to a runner file: a write failure warns with the given label and never fails\n// the round. The path is a parameter, so the effect is the only thing here that is not pure.\nconst appendBestEffort = (path: string | undefined, label: string, body: string): void => {\n if (path === undefined || path === \"\") return;\n try {\n appendFileSync(path, body);\n } catch (err) {\n process.stderr.write(`Warning: could not write ${label}: ${errMsg(err)}\\n`);\n }\n};\n\n// The posted signal travels through the step's GITHUB_OUTPUT file — the runner publishes it as the\n// step's output when the step completes. Written INSIDE upsertSticky so every sticky landing (the\n// main path and the notice paths alike) signals itself, and written as posted=false on the\n// deliberate no-write exits so a never-landed run never reads as landed.\nconst writePostedSignal = (value: boolean): void => {\n appendBestEffort(\n process.env[\"GITHUB_OUTPUT\"],\n \"the posted signal to GITHUB_OUTPUT\",\n `posted=${value ? \"true\" : \"false\"}\\n`,\n );\n};\n\n// The job's run summary is the review's long-lived twin: a sticky is overwritten as rounds iterate,\n// while each run's summary keeps the review as it stood for that run (issue #205). The template\n// renders OUTSIDE the best-effort write: a failing template is a defect that should surface, and the\n// sticky rendered from the same input a moment earlier, so this throwing means something is\n// genuinely wrong. Only the write is best-effort.\nconst appendRunSummary = (summaryPath: string | undefined, body: () => string): void => {\n if (summaryPath === undefined || summaryPath === \"\") return;\n const rendered = body();\n appendBestEffort(summaryPath, \"the run summary\", `\\n${rendered}\\n`);\n};\n\n// Trust by author identity (bot login), not the marker alone. Returns null only when a NEW comment's\n// response couldn't be parsed — there is then no id to re-patch with the review link.\nconst upsertSticky = async (\n repo: string,\n prNumber: number,\n existing: { readonly id: number; readonly body: string } | null,\n body: string,\n ghApi: GhApi,\n signal = false,\n): Promise<{ readonly id: number; readonly url: string | undefined } | null> => {\n if (existing !== null) {\n const patched = await patchComment(repo, existing.id, body, ghApi);\n process.stderr.write(\n `Updated sticky comment #${String(existing.id)} on PR #${String(prNumber)}\\n`,\n );\n if (signal) writePostedSignal(true);\n return { id: existing.id, url: patched?.html_url };\n }\n const posted = await postComment(repo, prNumber, body, ghApi);\n process.stderr.write(`Posted new sticky comment on PR #${String(prNumber)}\\n`);\n if (signal && posted !== null) writePostedSignal(true);\n return posted ? { id: posted.id, url: posted.html_url } : null;\n};\n\n// Only the id is needed — every prior bot review is superseded regardless of the commit it reviewed.\ninterface BotReviewRef {\n readonly id: number;\n}\n\nconst isBotReview = (r: unknown): r is { id: number; user: { login: string }; state: string } =>\n typeof r === \"object\" &&\n r !== null &&\n typeof (r as { id?: unknown }).id === \"number\" &&\n typeof (r as { state?: unknown }).state === \"string\" &&\n typeof (r as { user?: { login?: unknown } }).user?.login === \"string\";\n\nconst fetchBotReviews = async (\n repo: string,\n prNumber: number,\n botLogin: string,\n ghApi: GhApi,\n): Promise<readonly BotReviewRef[]> => {\n const stdout = await ghApi([`repos/${repo}/pulls/${String(prNumber)}/reviews`, \"--paginate\"]);\n let reviews: unknown;\n try {\n reviews = JSON.parse(stdout || \"[]\");\n } catch {\n return [];\n }\n if (!Array.isArray(reviews)) return [];\n return reviews\n .filter(isBotReview)\n .filter((r) => r.user.login === botLogin && r.state !== \"DISMISSED\")\n .map((r) => ({ id: r.id }));\n};\n\n// Best-effort: a dismissal failure is logged, never fails the job.\nconst dismissReviews = async (\n repo: string,\n prNumber: number,\n ids: readonly number[],\n ghApi: GhApi,\n): Promise<void> => {\n for (const id of ids) {\n try {\n await ghApi(\n [\n `repos/${repo}/pulls/${String(prNumber)}/reviews/${String(id)}/dismissals`,\n \"-X\",\n \"PUT\",\n \"--input\",\n \"-\",\n ],\n // GitHub caps a dismissal message at 140 chars.\n JSON.stringify({ message: \"Superseded by a new review for an updated commit.\" }),\n );\n } catch (err) {\n process.stderr.write(\n `Warning: failed to dismiss prior review #${String(id)} on PR #${String(prNumber)}: ${errMsg(err)}\\n`,\n );\n }\n }\n};\n\n// Capped at the first 100 threads (×100 comments each); hasNextPage flags a PR that exceeds it.\nconst REVIEW_THREAD_COMMENTS_QUERY =\n \"query($owner:String!,$name:String!,$pr:Int!){repository(owner:$owner,name:$name){pullRequest(number:$pr){reviewThreads(first:100){pageInfo{hasNextPage}nodes{comments(first:100){nodes{id isMinimized author{login}}}}}}}}\";\n\n// Reversible — minimized as OUTDATED, not deleted.\nconst MINIMIZE_COMMENT_MUTATION =\n \"mutation($id:ID!){minimizeComment(input:{subjectId:$id,classifier:OUTDATED}){minimizedComment{isMinimized}}}\";\n\n// GraphQL reports the bare login (github-actions), so match with and without the REST [bot] suffix.\nconst priorBotCommentId = (c: unknown, logins: readonly string[]): string | null => {\n if (typeof c !== \"object\" || c === null) return null;\n const o = c as { id?: unknown; isMinimized?: unknown; author?: { login?: unknown } | null };\n const login = o.author?.login;\n return typeof o.id === \"string\" &&\n o.isMinimized !== true &&\n typeof login === \"string\" &&\n logins.includes(login)\n ? o.id\n : null;\n};\n\nconst priorBotCommentIds = (\n raw: string,\n botLogin: string,\n): { readonly ids: readonly string[]; readonly truncated: boolean } => {\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return { ids: [], truncated: false };\n }\n const conn = (\n parsed as {\n data?: {\n repository?: {\n pullRequest?: {\n reviewThreads?: { nodes?: unknown; pageInfo?: { hasNextPage?: unknown } };\n };\n };\n };\n }\n ).data?.repository?.pullRequest?.reviewThreads;\n const truncated = conn?.pageInfo?.hasNextPage === true;\n const nodes = conn?.nodes;\n if (!Array.isArray(nodes)) return { ids: [], truncated };\n const logins = [botLogin.replace(/\\[bot\\]$/, \"\"), botLogin];\n const ids = nodes.flatMap((t) => {\n const cnodes = (t as { comments?: { nodes?: unknown } }).comments?.nodes;\n return Array.isArray(cnodes)\n ? cnodes.map((c) => priorBotCommentId(c, logins)).filter((id): id is string => id !== null)\n : [];\n });\n return { ids, truncated };\n};\n\n// Snapshot BEFORE posting the fresh review, so the set is exactly the prior (stale) comments.\n// Best-effort: a listing failure logs and returns [].\nconst listPriorBotCommentIds = async (\n repo: string,\n prNumber: number,\n botLogin: string,\n ghApi: GhApi,\n): Promise<readonly string[]> => {\n const slash = repo.indexOf(\"/\");\n if (slash <= 0) return [];\n const owner = repo.slice(0, slash);\n const name = repo.slice(slash + 1);\n let raw: string;\n try {\n raw = await ghApi([\n \"graphql\",\n \"-f\",\n `query=${REVIEW_THREAD_COMMENTS_QUERY}`,\n \"-f\",\n `owner=${owner}`,\n \"-f\",\n `name=${name}`,\n \"-F\",\n `pr=${String(prNumber)}`,\n ]);\n } catch (err) {\n process.stderr.write(\n `Warning: could not list review threads to minimize stale comments on PR #${String(prNumber)}: ${errMsg(err)}\\n`,\n );\n return [];\n }\n const { ids, truncated } = priorBotCommentIds(raw, botLogin);\n if (truncated) {\n process.stderr.write(\n `Note: PR #${String(prNumber)} has more than 100 review threads — only the first 100 were scanned for stale bot comments\\n`,\n );\n }\n return ids;\n};\n\n// Best-effort: a minimize failure is logged, never fails the post.\nconst minimizeComments = async (\n prNumber: number,\n ids: readonly string[],\n ghApi: GhApi,\n): Promise<void> => {\n let minimized = 0;\n for (const id of ids) {\n try {\n await ghApi([\"graphql\", \"-f\", `query=${MINIMIZE_COMMENT_MUTATION}`, \"-f\", `id=${id}`]);\n minimized += 1;\n } catch (err) {\n process.stderr.write(\n `Warning: failed to minimize a stale review comment on PR #${String(prNumber)}: ${errMsg(err)}\\n`,\n );\n }\n }\n if (minimized > 0) {\n process.stderr.write(\n `Minimized ${String(minimized)} stale inline comment(s) from superseded reviews on PR #${String(prNumber)}\\n`,\n );\n }\n};\n\nexport const post = async (\n input: PostInput,\n ghApi: GhApi = runGhApi,\n readArtifact: ArtifactReader = ghArtifactReader,\n): Promise<void> => {\n // Phase 1: reads + rendering, no writes yet.\n const candidates = await fetchPrCandidates(input.repo, input.headSha, ghApi);\n const resolution = resolvePr(candidates, input.headBranch);\n if (resolution.kind === \"none\") {\n process.stderr.write(`No open PR for ${input.headSha} — nothing to post\\n`);\n writePostedSignal(false);\n process.exit(0);\n }\n if (resolution.kind === \"not-open\") {\n process.stderr.write(\n `PR #${String(resolution.prNumber)} for ${input.headSha} is not open (state: ${resolution.state}) — nothing to post\\n`,\n );\n writePostedSignal(false);\n process.exit(0);\n }\n const prNumber = resolution.prNumber;\n\n const [diff, commentRows] = await Promise.all([\n fetchDiff(input.repo, prNumber, ghApi),\n fetchIssueCommentRows(input.repo, prNumber, ghApi),\n ]);\n const existingSticky = selectBotComment(commentRows, input.botLogin, DEFAULT_MARKER);\n\n // An incomplete result (a notice, not a completed review) must never overwrite a sticky that\n // already shows a completed review — else a superseded/killed/late run buries a real review under a\n // \"did not complete\" that reads as a clean pass. A completed result always writes; an in-progress\n // placeholder is not \"complete\" (it lacks the marker), so its own commenter may still write.\n const existingComplete = existingSticky !== null && parseReviewComplete(existingSticky.body);\n const wouldBuryCompleted = (incomplete: boolean): boolean => incomplete && existingComplete;\n\n // \"The sticky reflects a completed FULL review\": the isFullReviewSticky predicate (route marker\n // wins, round history as the pre-marker fallback), plus, for a sticky with no route or round\n // signal at all, the two completed-review signals of the pre-marker era — review-complete on the\n // sticky itself, or the carried completed-ancestor marker (a notice carries that ANCESTRY marker,\n // never review-complete itself). This deliberately does NOT require review-complete: the announce\n // placeholder strips it while preserving the route and round markers, and an empty mechanic must\n // not bury the full review the placeholder still records.\n const priorIsFullReview = (body: string): boolean =>\n isFullReviewSticky(body) ||\n (parseReviewedRoute(body) === null &&\n (parseReviewComplete(body) ||\n (parseCompletedAncestor(body) && !parseMechanicAncestor(body))));\n\n // An EMPTY CI-fix mechanic pass must not bury a completed FULL review either: it completes with\n // genuinely empty findings ({verdict: \"comment\", findings: []}), so it is not \"incomplete\" and\n // wouldBuryCompleted can't see it — yet replacing a full review's sticky with \"No findings — clean\n // review.\" is the same false clean pass class (issue #127). A mechanic WITH findings still\n // supersedes (its fixes are the actionable output on a red CI). The route comes from the review\n // job (passed through as --route; the envelope is the fallback for standalone callers), so the\n // guard also fires when the result envelope was lost in transit.\n const emptyMechanicWouldBury = (route: string | null | undefined, incomplete: boolean): boolean =>\n route === \"mechanic\" &&\n !incomplete &&\n findings.findings.length === 0 &&\n existingSticky !== null &&\n priorIsFullReview(existingSticky.body);\n\n // The full-review convergence history carried in the sticky's marker (it survives the announce\n // placeholder via carryForwardMarkers). A completed FULL review appends this round below; a CI-fix\n // mechanic pass and every notice carry it forward unchanged so the trajectory is never lost.\n // The prior round trajectory + the convergence to carry forward, read from the JSON convergence field\n // the pipeline stamps into the blob (issue #174), with a one-time fallback to a pre-feature sticky's\n // legacy rounds + compact signal markers. Carried VERBATIM into a non-round post — recomputing at the\n // current threshold would flip a prior round's `converged` when the operator changes\n // convergence_threshold mid-PR.\n const priorDoc = existingSticky !== null ? parseFindingsMarker(existingSticky.body) : null;\n const priorBody = existingSticky?.body ?? \"\";\n // The trajectory to append to + the recurrence detectors read (priorTrajectory reads the JSON\n // convergence, else the legacy rounds marker — so a legacy prior with only a rounds marker still\n // carries its codes); and the convergence to carry forward on a non-round post (carriedConvergence).\n const priorTraj = priorTrajectory(priorDoc, priorBody);\n const priorConv = carriedConvergence(priorDoc, priorBody);\n // The completed-round count never regresses: nextRoundNumber takes the max round across the trajectory\n // and the carried convergence (a legacy sticky whose compact signal ran ahead of a filtered rounds\n // marker still advances, issue #141), and announce labels its in-progress line with the SAME derivation\n // so the placeholder's round and this round's stamp can't disagree (issue #188 review).\n const priorRoundCount = nextRoundNumber(priorTraj, priorConv?.rounds ?? []) - 1;\n\n // The agent's document carries no convergence of its own (issue #217 review r7): the pipeline stamps\n // it, and the compact marker beside the findings link carries the SAME stamped object, so a reader of\n // the comment never needs the artifact for the stop signal. A notice / CI-fix pass carries the prior\n // convergence forward, so the trajectory + last score survive a non-round post; a first-run notice\n // with no completed round carries none. convergence is pipeline-owned and ALWAYS overwritten: any\n // value the agent echoed is replaced by the pipeline's (or by undefined, which serializes to an\n // omitted key), so a draft can never smuggle a self-declared score/converged into the document.\n const stampConvergence = (doc: Findings, conv: Convergence | null): Findings => ({\n ...doc,\n convergence: conv ?? undefined,\n });\n // The error rides HERE rather than at the main path's call site, so the notice and lost-envelope\n // paths — which also post a body built from this — say it too. Once per post, not once per surface.\n // When no --json-url can name an artifact and the existing sticky carries a findings marker, the\n // rendered body carries the PRIOR review's findings LINK forward — through findingsBlob, so EVERY\n // rendered body (main, final patch, the empty-diff/corrupt/lost-envelope paths) carries it, and\n // the template places it after the sticky's leading markers so findBotComment still identifies\n // the comment. The freeze guard above still wins for a completed full-review sticky\n // (leaveInPlace); every OTHER marker-carrying sticky — placeholder, mechanic, pre-route — gets\n // the carry instead of a markerless overwrite (issue #235 + #236 r1-r3). Only the LINK form is\n // carried here — re-embedding the base64 form would put an unbounded blob back into the body\n // that is posted unshed against GitHub's 65536 limit, the 422 class the link form exists to\n // prevent. (The notice paths DO re-emit a carried embedded marker verbatim: their bodies are\n // short, and the pre-#217 blob was size-gated when written.)\n let warnedNoJsonUrl = false;\n const findingsBlob = (doc: Findings): string => {\n if (input.jsonUrl) return findingsMarkerPair(input.jsonUrl, doc.convergence);\n const carriedLink = existingSticky !== null ? findingsArtifactUrl(existingSticky.body) : null;\n if (carriedLink !== null) {\n // The prior link is carried: the machine channel survives, though this run names no NEW\n // artifact — the sticky's findings remain the prior round's.\n return findingsMarkerPair(carriedLink, doc.convergence);\n }\n if (!warnedNoJsonUrl) {\n warnedNoJsonUrl = true;\n process.stderr.write(\n \"::error::no --json-url was supplied and the existing sticky carries no findings marker to carry forward, so this comment names no findings artifact — the review's prose is intact but its machine channel is gone, and the next round cannot seed from it\\n\",\n );\n }\n return findingsMarkerPair(undefined, doc.convergence);\n };\n // NOTE: leaveInPlace must NEVER read `verbatimReRaised` — it is also called from the empty-diff\n // and corrupt-findings guards, which run BEFORE the const initializes; a read there throws a\n // TDZ ReferenceError and crashes the post (issue #151 review r4 — a real regression in r3). The\n // post-filter call sites log the drops themselves.\n const leaveInPlace = (message?: string): never => {\n process.stderr.write(\n message ??\n \"Review did not complete and the sticky already reflects a completed review — leaving it in place\\n\",\n );\n // The preserved sticky IS the landed review — signal it, so a deliberate leave never reads as\n // never-posted and never rides the exit-0 fallback.\n writePostedSignal(true);\n process.exit(0);\n };\n\n // The leave paths cannot write a note — the preserved sticky still surfaces each dropped finding\n // and its reply thread — so the one place that names the drops in the run log, shared by every\n // post-filter leave site (issue #151 review r5). The count is the TRUE pre-dedup dropped-finding\n // count, never the deduped entry list (issue #151 review r7).\n const logAnsweredDrops = (): void => {\n if (verbatimReRaised.length > 0) {\n process.stderr.write(\n `${String(droppedCount)} verbatim re-raise(s) of answered findings were treated as answered — the preserved sticky shows each finding and its prior reply\\n`,\n );\n }\n };\n\n // When the guard fires on a real completed review, leaving it in place is right — it IS the\n // terminal content. When it fires on the announce PLACEHOLDER (which strips review-complete), a\n // bare leave would strand a stale \"Code review in progress\" as the terminal state, so post a\n // compact honest notice instead, carrying the preserved full review's markers forward so the seed\n // chain and trajectory survive the swap. Callers pass the sticky the guard already established\n // exists (TS can't see the closure's narrowing).\n const emptyMechanicLeaveOrNote = async (sticky: {\n readonly id: number;\n readonly body: string;\n }): Promise<void> => {\n if (existingComplete) {\n logAnsweredDrops();\n leaveInPlace(EMPTY_MECHANIC_LEAVE_MESSAGE);\n }\n const priorSha = parseReviewedSha(sticky.body);\n const dropNote = answeredDropNote;\n const body = formatMarkdown(\n noticeBody(\n `${DEFAULT_MARKER}\\n\\n⚠️ **CI-fix pass completed with no findings** for \\`${input.headSha.slice(0, 7)}\\`${\n input.unverifiedNoLogs === true\n ? ' — **but no failing-job logs were available**, so it worked from the diff and any local reproduction of the checks, and \"no findings\" is not evidence of none'\n : \"\"\n } — the completed full review of \\`${priorSha ? priorSha.slice(0, 7) : \"an earlier commit\"}\\` is preserved below.${dropNote ? `\\n\\n${dropNote}` : \"\"}`,\n sticky.body,\n ),\n );\n await upsertSticky(input.repo, prNumber, sticky, body, ghApi, true);\n process.exit(0);\n };\n\n const prices = JSON.parse(readFileSync(input.pricesPath, \"utf-8\")) as unknown;\n const decodedPrices = PriceMapCodec.decode(prices);\n if (decodedPrices._tag === \"Left\") {\n throw new Error(`Price map at ${input.pricesPath} does not match the expected shape`);\n }\n const template = readFileSync(input.templatePath, \"utf-8\");\n const inlineRequested = input.inline === true;\n // Loaded before the notice paths: their convergence stamps read the route, exactly like the main\n // path (issue #224's mechanic pin must hold on EVERY write path).\n const envelope = loadEnvelope(input.envelopePath);\n\n const reachable =\n existingSticky !== null ? discussionRows(commentRows, existingSticky.id, input.botLogin) : [];\n // The discussion orphan gate excludes ONLY a mechanic prior: its own findings are not this\n // review's departed findings. Every other prior feeds the bucket — a full review, a pre-rounds\n // sticky (no route marker, but its embedded blob still resolves), and a placeholder (whose\n // carried link resolves the last full review's document).\n const priorIsMechanic =\n existingSticky !== null &&\n (parseReviewedRoute(existingSticky.body) === \"mechanic\" ||\n parseMechanicAncestor(existingSticky.body));\n\n // The notice overwrites the sticky with no findings of its own — the pointer trail a replied-to\n // prior sticky carries must survive the overwrite. Resolved and grouped ONLY when a notice\n // actually exits (the rare path); a normal round never pays this. The prior document's ids are\n // the whole departed set for a notice (the notice reports nothing), and only a full-review prior\n // may feed it — a mechanic pass's own findings are not this review's departed findings.\n const noticeDiscussion = async (): Promise<{\n readonly orphanedDiscussion: Readonly<Record<string, readonly DiscussionLink[]>>;\n readonly orphanedTotal: number;\n readonly orphanedTruncated: Readonly<Record<string, number>>;\n readonly orphanedUnresolvable: boolean;\n }> => {\n if (existingSticky === null) {\n return {\n orphanedDiscussion: {},\n orphanedTotal: 0,\n orphanedTruncated: {},\n orphanedUnresolvable: false,\n };\n }\n const wantsPrior = !priorIsMechanic && mentionsOutsideKnown(reachable, []);\n const resolved = wantsPrior\n ? await resolvePriorFindings(existingSticky.body, readArtifact)\n : null;\n const built = buildStickyDiscussion(reachable, [], priorIdsFrom(resolved));\n // \"Unresolvable\" claims an artifact failed — it must never fire for a marker-less prior\n // (a first-run placeholder), where there is no artifact to fail.\n const hadMarker = carriedFindingsMarker(existingSticky.body) !== null;\n return {\n orphanedDiscussion: built.orphaned,\n orphanedTotal: built.orphanedTotal,\n orphanedTruncated: built.orphanedTruncated,\n orphanedUnresolvable: wantsPrior && hadMarker && resolved === null,\n };\n };\n\n const renderNotice = (\n message: string,\n discussion: Awaited<ReturnType<typeof noticeDiscussion>>,\n ): string => {\n // The notice carries the prior convergence forward IN its blob so the trajectory + last score\n // survive; render's incomplete gate keeps the badge/trajectory off the human surface, so a carried\n // \"converged\" is never shown beside a run that produced no verdict (issue #141 review r2). A\n // MECHANIC notice stamps the never-converged pin instead — CI failed, whatever the prior said\n // (issue #224: the pin holds on every write path, not just the main one).\n const noticeConvergence =\n (input.route ?? envelope?.route) === \"mechanic\"\n ? mechanicConvergence(\n priorConv,\n input.convergenceThreshold ?? DEFAULT_CONVERGENCE_THRESHOLD,\n )\n : priorConv;\n const findings = stampConvergence(incompleteFindings(`### ⚠️ ${message}`), noticeConvergence);\n // The notice's own blob holds no findings — stamping its link would point the NEXT round's\n // resolve at an empty document and sever the departed set the trail needs. The prior sticky's\n // findings marker is carried verbatim instead — BOTH forms via the shared extractor, never a\n // hand-rolled link-only carry — with the notice's own convergence stamp beside it.\n const noticeFindingsPointer = (doc: Findings): string => {\n const carried = existingSticky !== null ? carriedFindingsMarker(existingSticky.body) : null;\n if (carried === null) return findingsBlob(doc);\n // The prior's provenance rides beside its findings marker: a mechanic-origin prior must stay\n // mechanic through the notice, or the next round's orphan gate reads its findings as a\n // departed full review's.\n const provenance = existingSticky !== null ? carriedAncestryMarkers(existingSticky.body) : \"\";\n return [carriedMarkerPointer(carried, doc.convergence), provenance]\n .filter((p) => p !== \"\")\n .join(\"\\n\\n\");\n };\n return formatMarkdown(\n render({\n findings,\n envelope: null,\n incomplete: true,\n prices: decodedPrices.right,\n pricesProvided: input.pricesProvided,\n template,\n route: input.route,\n reviewedSha: input.headSha,\n effort: input.effort,\n sameRootNotes: {},\n roundCount: priorRoundCount,\n convergenceRound: false,\n runUrl: input.runUrl,\n jsonUrl: input.jsonUrl,\n findingsPointer: noticeFindingsPointer(findings),\n postedAt: input.postedAt,\n orphanedDiscussion: discussion.orphanedDiscussion,\n orphanedTotal: discussion.orphanedTotal,\n orphanedTruncated: discussion.orphanedTruncated,\n orphanedUnresolvable: discussion.orphanedUnresolvable,\n }),\n );\n };\n\n if (isEmptyDiff(diff)) {\n if (wouldBuryCompleted(true)) leaveInPlace();\n const discussion = await noticeDiscussion();\n await upsertSticky(\n input.repo,\n prNumber,\n existingSticky,\n renderNotice(\"The diff for this PR is empty — nothing to review.\", discussion),\n ghApi,\n true,\n );\n process.exit(0);\n }\n\n const findingsResult = loadFindings(input.findingsPath);\n if (findingsResult.kind !== \"ok\") {\n if (wouldBuryCompleted(true)) leaveInPlace();\n const discussion = await noticeDiscussion();\n await upsertSticky(\n input.repo,\n prNumber,\n existingSticky,\n renderNotice(noticeMessageFor(findingsResult), discussion),\n ghApi,\n true,\n );\n process.exit(0);\n }\n // The \"already answered\" state (issue #151): the prior inline findings whose threads a human reply\n // answered, fetched live (the threads persist on GitHub; no carried marker needed). A verbatim\n // re-raise of an answered finding — identical title and reasoning, no new evidence by definition —\n // is treated as closed: dropped from this review's findings, counts, inline comments, and round\n // signal, and NAMED in the sticky (never silently). A re-raise with changed evidence is kept and\n // annotated with the prior answer's link. A failed fetch degrades to an empty registry (the review\n // posts unfiltered); the seed already told the agent what not to re-raise.\n const loadedFindings = findingsResult.findings;\n // The answered-thread fetch runs only when a review will actually be filtered — an empty-diff or\n // corrupt-findings post exits above without paying for the paginated history (issue #151 review\n // r3), and a FIRST-EVER review (no bot sticky at all, so no bot threads can exist) provably has\n // an empty registry (issue #151 review r4).\n // ALWAYS fetch on a filterable post: a missing sticky does not prove an empty thread history (a\n // maintainer can delete the sticky while the threads remain; pre-sticky reviews leave threads\n // with no sticky at all), so the round-4 sticky-absence skip — which could silently starve the\n // registry — is inverted and removed (issue #151 review r7). The empty-diff/corrupt-findings\n // early exits above still avoid the fetch entirely.\n const threadComments = await fetchThreadComments(ghApi, input.repo, prNumber);\n const answeredRegistry =\n threadComments === null ? [] : answeredRegistryFrom(threadComments, input.botLogin);\n const answeredFilter = applyAnswered(loadedFindings.findings, answeredRegistry);\n const reRaisedNotes = answeredFilter.reRaisedNotes;\n const verbatimReRaised = answeredFilter.verbatimReRaised;\n const droppedCount = answeredFilter.droppedCount;\n // Everything downstream (counts, rounds, signal, inline, the embedded blob) reads the FILTERED\n // document — a closed verbatim re-raise is gone from the review, not just from the prose.\n // [...spread] restores the codec's mutable array type. A DROPPED re-raise's code is also\n // stripped from any systemic problem's finding_ids — a \"ties together\" list must not dangle a\n // finding that is no longer in the document. Scoped to the actual drops: a systemic whose codes\n // were never dropped passes through untouched (issue #151 review r1).\n // Both the dropped entries' codes AND the dropped FINDINGS' resolved ids: a title-matched drop of\n // a fresh-id finding keys the entry's synthesized code, but the systemic list names the finding's\n // own id — stripping by entry code alone would dangle it.\n const droppedIds = new Set([\n ...verbatimReRaised.flatMap((e) => (e.code !== \"\" ? [e.code] : [])),\n ...answeredFilter.droppedFindingIds.filter((id) => id !== \"\"),\n ]);\n // A dropped code is stripped only when NO KEPT finding still carries it — the drop removed one\n // instance of a mechanism, not the mechanism itself (issue #151 review r2).\n const keptCodes = new Set(answeredFilter.findings.map((f) => f.id));\n const trulyDropped = new Set([...droppedIds].filter((c) => !keptCodes.has(c)));\n const systemic =\n trulyDropped.size === 0\n ? (loadedFindings.systemic_problems ?? [])\n : (loadedFindings.systemic_problems ?? []).map((s) => {\n if (s.finding_ids === undefined) return s;\n const codes = s.finding_ids.filter((c) => !trulyDropped.has(c));\n return codes.length === s.finding_ids.length ? s : { ...s, finding_ids: codes };\n });\n const findings: Findings = {\n ...loadedFindings,\n findings: [...answeredFilter.findings],\n ...(systemic.length > 0 ? { systemic_problems: systemic } : {}),\n };\n // Nit visibility floor (issue #164): split the human-visible findings from the below-floor nits.\n // The blob (`findings`) stays COMPLETE — the machine channel and the next-round seed keep every nit,\n // so a hidden nit reads as already adjudicated and is never re-raised as fresh (a policy-suppressed\n // nit has no external anchor the way an answered-drop's live GitHub thread does, so it MUST remain in\n // the blob). Only the HUMAN surfaces filter: no inline comment, no visible stray, a collapsed aside;\n // the severity histogram and the rounds trajectory stay FULL (a nit contributes 0 to the score, and\n // an all-suppressed round must not read as \"clean\"). Stickiness, one round deep, re-derived from the\n // prior sticky's blob: a nit matching a prior round's below-floor nit (by code, else title) stays\n // hidden even if its score wobbled up — only a promotion to >= minor un-hides it — so a hidden nit\n // never flickers into view. The prior blob is read ONLY from a completed FULL-REVIEW sticky\n // (isFullReviewSticky) — route-aware like the seed chain, since a mechanic pass writes its OWN\n // findings blob and its nits are not this review's prior round; a notice/placeholder carries an empty\n // or prior blob and is handled the same way. Best-effort: an old/missing/oversized/non-review prior\n // yields no keys, so stickiness fails open to visible.\n // Resolved rather than decoded: the prior sticky's marker names the findings artifact (issue #217),\n // so this fetches it — and still reads an embedded blob on a sticky written before that change.\n // One resolve serves BOTH consumers — the nit stickiness keys and the discussion orphan gate —\n // and the resolve is a download plus an unzip subprocess on the critical path before the sticky\n // write, so it is paid only when one of them can use it. The nit keys only ever match a nit; the\n // orphan bucket is non-empty only when a reply names an id-shaped token this round does not\n // report (with no prior ids the bucket is empty either way, so that gate skips a fetch it could\n // not use, never an output it could change).\n // The PROVISIONAL known set (every finding id + the systemics) gates the fetch BEFORE the nit\n // split: the split's stickiness reads the prior document, so the exact set cannot be computed\n // until the resolve has happened. The provisional set is a superset of the exact one, so a round\n // pays the fetch a second time below ONLY for the tokens the split narrows out — the ids of\n // inline-posted findings.\n const broadCurrentIds = [\n ...findings.findings.map((f) => f.id).filter((id) => id !== \"\"),\n ...(findings.systemic_problems ?? [])\n .map((s) => s.id)\n .filter((id): id is string => id !== undefined && id !== \"\"),\n ];\n const roundHasNit = findings.findings.some((f) => f.severity === \"nit\");\n const nitWantsPrior =\n roundHasNit &&\n existingSticky !== null &&\n (isFullReviewSticky(existingSticky.body) || isFullReviewAncestry(existingSticky.body));\n const broadWantsPrior =\n existingSticky !== null && !priorIsMechanic && mentionsOutsideKnown(reachable, broadCurrentIds);\n const resolvedPrior =\n existingSticky !== null && (nitWantsPrior || broadWantsPrior)\n ? await resolvePriorFindings(existingSticky.body, readArtifact)\n : null;\n const priorDocForNits = nitWantsPrior ? resolvedPrior : null;\n const priorSuppressedKeys = new Set(\n priorBelowFloorNits(priorDocForNits, input.nitVisibilityFloor).map((n) =>\n answeredNoteKey({ id: n.id ?? \"\", title: n.title }),\n ),\n );\n const isSuppressedNit = (f: Finding): boolean =>\n f.severity === \"nit\" &&\n (isBelowVisibilityFloor(f, input.nitVisibilityFloor) ||\n // ALL THREE key forms the prior side can emit: the resolved id (a coded or same-path\n // synthesized prior), the answeredNoteKey form (an empty-id prior), and the bare title: key\n // (a pathless codeless prior).\n priorSuppressedKeys.has(resolveFindingId(f)) ||\n priorSuppressedKeys.has(answeredNoteKey(f)) ||\n priorSuppressedKeys.has(`title:${f.title}`));\n const suppressedNits = findings.findings.filter(isSuppressedNit);\n const visibleFindings = findings.findings.filter((f) => !isSuppressedNit(f));\n // The drop note, shared by every surface that renders the filtered findings: the TRUE pre-dedup\n // count (issue #151 review r5), plus — when the drops emptied the round — a line reconciling the\n // draft's verdict with the empty kept counts, so the sticky never reads \"changes requested\"\n // beside a converged signal without the explanation (issue #151 review r5).\n const answeredDropNote =\n answeredReRaiseNote(verbatimReRaised, droppedCount) +\n (verbatimReRaised.length > 0 && findings.findings.length === 0\n ? \"\\n> _The stop signal reflects the kept findings — this round carries none._\"\n : \"\");\n\n // The EXACT known set — the ids this sticky's discussion surfaces actually render: the visible\n // strays, the below-floor nits (the suppressed aside has a discussion slot), and the systemics.\n // An inline-posted finding's id is deliberately absent: the sticky renders no surface for it,\n // and its conversation lives on the inline thread itself.\n // One partition per round: the inline split below and buildInlineComments share it.\n const inlinePartition =\n input.inline === true && envelope !== null\n ? partitionFindings(visibleFindings, indexDiff(diff))\n : null;\n const straysForDiscussion = inlinePartition?.strays ?? visibleFindings;\n const currentIds = [\n ...straysForDiscussion.map((f) => f.id).filter((id) => id !== \"\"),\n ...suppressedNits.map((f) => f.id).filter((id) => id !== \"\"),\n ...(findings.systemic_problems ?? [])\n .map((s) => s.id)\n .filter((id): id is string => id !== undefined && id !== \"\"),\n ];\n // When a reply named an unknown token but the prior document could not be resolved (an expired\n // artifact, a transport failure), the trail loss is named on the surface, never silent. Only\n // ever claimed when the prior actually carries a findings marker — a marker-less prior has no\n // artifact to fail.\n const orphanResolveFailed =\n existingSticky !== null &&\n broadWantsPrior &&\n carriedFindingsMarker(existingSticky.body) !== null &&\n resolvedPrior === null;\n // The departed set is the prior document's ids MINUS every id still live this round — an\n // inline-posted finding's id persists in the prior doc while the finding is still current, so it\n // must never be published under the \"no longer reports\" header.\n const broadLive = new Set(broadCurrentIds);\n const departedIds = priorIdsFrom(resolvedPrior).filter((id) => !broadLive.has(id));\n\n // The discussion aside's reply chain (issue #246): built from the rows ALREADY fetched for the\n // sticky lookup — pure, so a round pays one history fetch total. Built whenever a sticky exists,\n // including zero-stray rounds: the orphaned bucket is exactly the case where the last stray left\n // the report, and the overwrite (issue #205) would otherwise drop the pointer trail. Hoisted above\n // the lost-envelope branch so that surface carries the same trail as the main path.\n const stickyDiscussion =\n existingSticky !== null\n ? buildStickyDiscussion(reachable, currentIds, departedIds)\n : { byFinding: {}, orphaned: {}, orphanedTotal: 0, truncated: {}, orphanedTruncated: {} };\n const discussionByFinding = stickyDiscussion.byFinding;\n const orphanedDiscussion = stickyDiscussion.orphaned;\n const orphanedTotal = stickyDiscussion.orphanedTotal;\n const discussionTruncated = stickyDiscussion.truncated;\n const orphanedTruncated = stickyDiscussion.orphanedTruncated;\n\n const testReport = input.testReportPath ? loadTestReport(input.testReportPath) : undefined;\n const clocDiff = input.clocDiffPath ? loadClocDiff(input.clocDiffPath) : undefined;\n\n // The route the review job stamped, read the same way render does — `input.route` first, then the\n // envelope — so the workflow's --route passthrough and standalone callers both work, and the\n // sticky's route marker, the guard, and the rounds logic can never disagree.\n const effectiveRoute = input.route ?? envelope?.route;\n\n if (envelope === null) {\n // The envelope carried the incomplete flag; with it lost, derive incompleteness from the verdict\n // (render does the same) so an error-verdict findings doc here still reads as a notice and — via\n // the guard below — can't bury a completed review, which this branch previously skipped.\n const envelopelessIncomplete = isIncompleteFindings(findings);\n if (wouldBuryCompleted(envelopelessIncomplete)) {\n logAnsweredDrops();\n leaveInPlace();\n }\n // The route is passed through as --route, so an empty mechanic with a lost envelope still\n // cannot bury a completed full review (issue #127).\n if (emptyMechanicWouldBury(effectiveRoute, envelopelessIncomplete) && existingSticky !== null)\n await emptyMechanicLeaveOrNote(existingSticky);\n // A lost envelope is not a completed round, so the prior convergence is carried forward in the\n // blob unchanged rather than a new round being built (issue #174) — except on the mechanic\n // route, whose pin applies here exactly as on the main path (issue #224).\n const stampedFindings = stampConvergence(\n findings,\n effectiveRoute === \"mechanic\"\n ? mechanicConvergence(\n priorConv,\n input.convergenceThreshold ?? DEFAULT_CONVERGENCE_THRESHOLD,\n )\n : priorConv,\n );\n // This branch lists every visible finding, exactly like the inline-off default, so it can exceed\n // GitHub's comment limit the same way — and here a 422 is the difference between a notice and\n // nothing at all.\n const body = formatMarkdown(\n render({\n findings: stampedFindings,\n envelope: null,\n incomplete: envelopelessIncomplete,\n prices: decodedPrices.right,\n pricesProvided: input.pricesProvided,\n template,\n route: effectiveRoute,\n reviewedSha: input.headSha,\n repo: input.headRepo || input.repo,\n effort: input.effort,\n sameRootNotes: {},\n // The answered-state honesty rules apply on EVERY surface that renders the filtered\n // findings — the lost-envelope branch lists every VISIBLE finding (no inline review exists to\n // carry them) so the kept re-raises' annotations actually render, and names the drops\n // exactly like the main path (issues #151 review r1 + r2). The nit visibility floor applies\n // here too (issue #164): below-floor nits are hidden from the human list and shown only in the\n // collapsed aside — the floor is a human-visibility policy, not an inline-comment policy, so it\n // must hold on the surface that lists findings without an inline review.\n strays: visibleFindings,\n suppressedNits,\n nitVisibilityFloor: input.nitVisibilityFloor,\n answeredNotes: reRaisedNotes,\n answeredReRaiseNote: answeredDropNote,\n roundCount: priorRoundCount,\n convergenceRound: false,\n testReport,\n clocDiff,\n inlineDisposition: inlineRequested ? { kind: \"no-envelope\" } : { kind: \"disabled\" },\n runUrl: input.runUrl,\n unverifiedNoLogs: input.unverifiedNoLogs,\n jsonUrl: input.jsonUrl,\n findingsPointer: findingsBlob(stampedFindings),\n postedAt: input.postedAt,\n discussionByFinding,\n orphanedDiscussion,\n orphanedTotal,\n discussionTruncated,\n orphanedTruncated,\n orphanedUnresolvable: orphanResolveFailed,\n }),\n );\n await upsertSticky(input.repo, prNumber, existingSticky, body, ghApi, true);\n // The body this branch posts, whatever shape it took, also goes to the run summary.\n appendRunSummary(process.env[\"GITHUB_STEP_SUMMARY\"], () => body);\n if (inlineRequested) {\n process.stderr.write(\n \"Warning: inline: true was requested, but the result envelope is missing — inline comments cannot be built; the findings are in the sticky and the run summary instead\\n\",\n );\n }\n process.stderr.write(\n \"Result envelope missing or malformed — posted sticky summary without usage/cost data\\n\",\n );\n process.exit(0);\n }\n\n // Read once the lost-envelope branch has passed — that branch posts and exits, and an ENOENT here\n // would have taken its notice with it — but still before anything on THIS path is written, so a\n // misconfigured template fails loudly rather than half-way through posting.\n const inlineTemplate = inlineRequested ? readFileSync(input.inlineTemplatePath, \"utf-8\") : \"\";\n\n // A completed review carries real telemetry; adapt (and the workflow's notice wrap) flag a run that\n // produced only a notice. Don't let such a notice bury an existing completed review or post a stray\n // empty inline review over it — leave the real review in place.\n const thisIncomplete = envelope.incomplete === true || isIncompleteFindings(findings);\n if (wouldBuryCompleted(thisIncomplete)) {\n logAnsweredDrops();\n leaveInPlace();\n }\n\n if (emptyMechanicWouldBury(effectiveRoute, thisIncomplete) && existingSticky !== null)\n await emptyMechanicLeaveOrNote(existingSticky);\n\n // A convergence round is a COMPLETED FULL review (effectiveRoute read above — `input.route` first,\n // then the envelope — the same way render does). A mechanic pass or any incomplete/failed run\n // carries the trajectory forward unchanged (it is a CI fix or a non-review, not a round). The\n // verdict guard (isReviewVerdict, render's badge uses the same predicate) also gates the append\n // here, so an out-of-contract \"error\" verdict that somehow carries findings never counts as a\n // round: the trajectory, the badge, and the blob's convergence stay one decision. A same-head CI\n // retry simply appends again — an identical chip reads as \"no change\", which is accurate; a\n // reviewed-sha-keyed replace is unsafe because a mechanic stamps a new head without adding a\n // round, so the last round need not be its head. The same-root annotation is a property of a\n // REVIEW round — a mechanic pass is a CI-fix pass, not a round, so it carries no notes — and names\n // the most recent prior round (excluding a same-head retry) each of this round's recurring codes\n // appeared in.\n const isRound =\n isConvergenceRound(effectiveRoute, thisIncomplete) && isReviewVerdict(findings.verdict);\n const sameRootNotes = isRound\n ? computeSameRootNotes(priorTraj, findings.findings, input.headSha.slice(0, 12))\n : {};\n\n // With inline off there is no diff-anchored surface, so the split does not apply: every visible\n // finding is a stray and the sticky carries them all, exactly as it does when the envelope is lost.\n const {\n comments: rawComments,\n strays,\n inDiff,\n } = inlineRequested\n ? buildInlineComments(visibleFindings, diff, {\n ...(inlinePartition !== null ? { partition: inlinePartition } : {}),\n inlineTemplate,\n models: envelope.models.map((m) => m.model),\n findings,\n jsonUrl: input.jsonUrl,\n sameRootNotes,\n answeredNotes: reRaisedNotes,\n })\n : { comments: [], strays: visibleFindings, inDiff: [] };\n const { comments, longFiles } = checkLongSuggestions(rawComments);\n for (const wf of longFiles) {\n process.stderr.write(\n `Warning: suggestion in ${wf} exceeds ${String(MAX_SUGGESTION_LINES)} lines — omitted from inline to avoid 422\\n`,\n );\n }\n\n // All prior bot reviews, fetched to supersede below — a re-run on the same commit still posts a\n // fresh review rather than being skipped.\n const botReviews = await fetchBotReviews(input.repo, prNumber, input.botLogin, ghApi);\n\n // The \"posted\" disposition is only ever built from the actual post result below, never optimistically.\n const initialDisposition: InlineDisposition | undefined = !inlineRequested\n ? { kind: \"disabled\" }\n : comments.length === 0 && strays.length > 0\n ? { kind: \"none-in-diff\" }\n : undefined;\n\n const currentCounts = computeSeverityCounts(findings.findings);\n\n // This round's mechanism-frequency map (findings + the codes systemic problems tie together) and the\n // true completed-round number, which numbers itself after the carried count. buildConvergence appends\n // this round's score + codes + head SHA to the carried trajectory (prior rounds verbatim) when the run\n // completes a full-review round. A mechanic pass, a notice, or an incomplete run is NOT a round: it\n // carries the prior convergence (the last completed round's, verbatim) forward, so the trajectory + last\n // score survive; render's incomplete gate keeps that off the human surface, so a carried \"converged\" is\n // never shown beside a run that produced no verdict (issue #141 reviews r2 + r4).\n const currentCodes = computeIdCounts(findings.findings, findings.systemic_problems ?? []);\n const roundNumber = priorRoundCount + 1;\n const convergence = isRound\n ? buildConvergence(\n findings,\n input.convergenceThreshold,\n priorTraj,\n roundNumber,\n currentCodes,\n input.headSha.slice(0, 12),\n )\n : effectiveRoute === \"mechanic\"\n ? // A mechanic pass means CI failed — whatever the carried prior says, its own stamp must\n // never read \"converged\". The threshold-relative critical floor keeps the carried triple\n // consistent at every threshold; null (no marker) when no prior round exists (issue #224).\n mechanicConvergence(priorConv, input.convergenceThreshold ?? DEFAULT_CONVERGENCE_THRESHOLD)\n : priorConv;\n const stampedFindings = stampConvergence(findings, convergence);\n const currentRoundCount = isRound ? roundNumber : priorRoundCount;\n\n const findingsMarker = findingsBlob(stampedFindings);\n\n const commonRenderInput: Omit<RenderInput, \"inlineDisposition\" | \"reviewUrl\"> = {\n findings: stampedFindings,\n envelope,\n incomplete: thisIncomplete,\n prices: decodedPrices.right,\n pricesProvided: input.pricesProvided,\n template,\n route: effectiveRoute,\n reviewedSha: input.headSha,\n repo: input.headRepo || input.repo,\n effort: input.effort,\n testReport,\n clocDiff,\n severityCounts: currentCounts,\n sameRootNotes,\n answeredNotes: reRaisedNotes,\n answeredReRaiseNote: answeredDropNote,\n discussionByFinding,\n orphanedDiscussion,\n orphanedTotal,\n discussionTruncated,\n orphanedTruncated,\n orphanedUnresolvable: orphanResolveFailed,\n roundCount: currentRoundCount,\n convergenceThreshold: input.convergenceThreshold,\n nitVisibilityFloor: input.nitVisibilityFloor,\n convergenceRound: isRound,\n strays,\n suppressedNits,\n runUrl: input.runUrl,\n unverifiedNoLogs: input.unverifiedNoLogs,\n jsonUrl: input.jsonUrl,\n findingsPointer: findingsMarker,\n postedAt: input.postedAt,\n pricedAt: input.pricedAt,\n };\n const longFilesNote =\n longFiles.length > 0\n ? `\\n\\n---\\n\\n> **Note:** ${String(longFiles.length)} suggestion(s) exceeded GitHub's ~10-line inline suggestion limit and were omitted from the inline comments; the affected findings remain in the review.\\n`\n : \"\";\n // Called twice: before the review exists (no disposition claim) and after (with reviewUrl + truth).\n const renderBody = (\n inlineDisposition: InlineDisposition | undefined,\n reviewUrl?: string,\n straysOverride?: readonly Finding[],\n unanchoredCount?: number,\n unanchoredStrays?: readonly Finding[],\n discussionOverride?: Pick<\n RenderInput,\n | \"discussionByFinding\"\n | \"orphanedDiscussion\"\n | \"orphanedTotal\"\n | \"discussionTruncated\"\n | \"orphanedTruncated\"\n >,\n ): string =>\n formatMarkdown(\n render({\n ...commonRenderInput,\n ...(straysOverride ? { strays: straysOverride } : {}),\n ...(unanchoredCount !== undefined ? { unanchoredCount } : {}),\n ...(unanchoredStrays !== undefined && unanchoredStrays.length > 0\n ? { unanchoredStrays }\n : {}),\n ...(discussionOverride ?? {}),\n inlineDisposition,\n reviewUrl,\n }) + longFilesNote,\n );\n\n // The body is posted unshed: GitHub rejects one over 65536 chars, and postComment/patchComment let\n // that 422 propagate, so an oversized body fails the job with the announce placeholder still up.\n // Inline off makes that reachable — every finding's prose now renders into this one comment, where\n // the in-diff ones used to be separate posts. Shedding is issue #214; tolerating a failed write\n // after the sticky is up is issue #223. The embedded document is gone from this body (issue #217),\n // which removed the largest fixed cost it had — an oversized round is now a matter of finding prose,\n // not of a ~32KB blob. Each sticky-listed stray's permalink adds a URL line (~55–130 chars) to this\n // budgeted-by-nobody section, so a nit-heavy inline-off round sits closer to the limit (issue #231 r1).\n // A body with no --json-url carries no findings marker, and upserting it would overwrite the last\n // pointer to the prior findings document. The guard refuses only when the pointer is actually\n // load-bearing: a COMPLETED full-review sticky whose markers gather would seed from. The\n // review-complete requirement exempts the announce placeholder, which carries the route and the\n // markers forward but strips review-complete — it must be replaced by an honest notice, not\n // frozen (post.ts's empty-mechanic path handles it). A mechanic/notice sticky is never a seed\n // either. An expired artifact link is not resolvability-checked here — a fetch in the write path\n // is the wrong trade — so an expired link can still freeze a round; the run log's ::error:: names\n // why (issue #233 r2 + r5 + r6).\n if (\n !input.jsonUrl &&\n existingSticky !== null &&\n parseReviewComplete(existingSticky.body) &&\n parseReviewedRoute(existingSticky.body) === \"full review\" &&\n hasFindingsMarker(existingSticky.body)\n ) {\n leaveInPlace(\n \"no --json-url was supplied and the existing sticky still carries the prior findings document's marker (embedded or link) — leaving it in place rather than severing the seed chain\\n\",\n );\n }\n\n // Phase 2: writes — sticky first, inline second. The carry is a property of the rendered body\n // (findingsBlob above), so every write site gets it for free.\n const stickyRef = await upsertSticky(\n input.repo,\n prNumber,\n existingSticky,\n renderBody(initialDisposition),\n ghApi,\n true,\n );\n // Snapshot stale comments BEFORE posting the fresh ones; timing (not commit SHA) separates them.\n const priorInlineComments = await listPriorBotCommentIds(\n input.repo,\n prNumber,\n input.botLogin,\n ghApi,\n );\n\n // Post first, THEN dismiss: the PR is never left review-less if the process dies between the two.\n // The review object is posted whatever `inline` says — it is the trail from the PR to the sticky and\n // to the run. With inline off it is body-only; the dismiss and minimize below run either way, so\n // flipping a repo to inline=false also clears the threads a previous round left on the diff.\n const {\n url: reviewUrl,\n posted: reviewObjectPosted,\n inlinePosted,\n unposted,\n } = await postInlineReview(\n {\n repo: input.repo,\n prNumber,\n headSha: input.headSha,\n stickyUrl: stickyRef?.url,\n runUrl: input.runUrl,\n },\n comments,\n inDiff,\n ghApi,\n );\n process.stderr.write(\n reviewObjectPosted\n ? inlineRequested\n ? `Posted a review with ${String(inlinePosted)} inline comment(s) on PR #${String(prNumber)}\\n`\n : `Posted a body-only review on PR #${String(prNumber)}; the findings are in the sticky\\n`\n : inlinePosted > 0\n ? `No review object posted this round on PR #${String(prNumber)}, but ${String(inlinePosted)} inline comment(s) anchored — the sticky carries the review\\n`\n : `No review object posted this round on PR #${String(prNumber)} — the sticky carries the review\\n`,\n );\n\n // The dismiss and minimize are gated on a BREADCRUMB review being POSTED this round: when the\n // POST failed, the prior round's reviews and threads are the only diff-anchored review objects\n // and must stay — a permanent failure (a short-scoped token, a recurring stale SHA) must not\n // clear them every round (issue #223). (The POST's success, not the parsed url — an unparseable\n // response still means the object exists.)\n const priorReviewIds = botReviews.map((r) => r.id);\n if (reviewObjectPosted && priorReviewIds.length > 0) {\n await dismissReviews(input.repo, prNumber, priorReviewIds, ghApi);\n }\n if (reviewObjectPosted || inlinePosted > 0) {\n await minimizeComments(prNumber, priorInlineComments, ghApi);\n }\n\n // Re-render the sticky to the truth: \"posted N\" is the count that ACTUALLY anchored, any\n // GitHub-rejected in-diff findings join the strays, and none-anchored says \"inline unavailable\",\n // never a false \"posted\". Best-effort — the sticky and review are already posted.\n const unanchoredCount = unposted.length;\n const finalStrays = unanchoredCount > 0 ? [...unposted, ...strays] : strays;\n // GitHub-rejected in-diff findings render on the final sticky as strays — the discussion grouping\n // was built before their rejection was knowable, so it is rebuilt with their ids in the known set:\n // their asides render, and their replies never land in the \"no longer reports\" bucket.\n const finalDiscussion =\n unanchoredCount > 0\n ? buildStickyDiscussion(\n reachable,\n [...currentIds, ...unposted.map((f) => f.id).filter((id) => id !== \"\")],\n departedIds,\n )\n : null;\n const finalDiscussionOverride =\n finalDiscussion !== null\n ? {\n discussionByFinding: finalDiscussion.byFinding,\n orphanedDiscussion: finalDiscussion.orphaned,\n orphanedTotal: finalDiscussion.orphanedTotal,\n discussionTruncated: finalDiscussion.truncated,\n orphanedTruncated: finalDiscussion.orphanedTruncated,\n }\n : undefined;\n if (stickyRef !== null && (inlinePosted > 0 || unanchoredCount > 0)) {\n const finalDisposition: InlineDisposition =\n inlinePosted > 0\n ? { kind: \"posted\", count: inlinePosted, sha: input.headSha }\n : { kind: \"inline-unavailable\" };\n try {\n await patchComment(\n input.repo,\n stickyRef.id,\n renderBody(\n finalDisposition,\n reviewUrl,\n finalStrays,\n unanchoredCount,\n unposted,\n finalDiscussionOverride,\n ),\n ghApi,\n );\n process.stderr.write(\n `Updated sticky comment #${String(stickyRef.id)} to reflect the review\\n`,\n );\n } catch (err) {\n process.stderr.write(\n `Warning: failed to update the sticky summary after the review: ${errMsg(err)}\\n`,\n );\n }\n }\n\n // Same findings, same options, same template — the run summary differs from the sticky in one\n // thing: it carries every finding, because it has no diff to anchor any of them to. That set is\n // `visibleFindings`, which the in-diff/stray split partitions and neither half holds: taking it\n // whole keeps the document's severity order, and cannot list a rejected finding twice. The\n // disposition says which document this is, so the headings do not describe the sticky's contents\n // over the summary's.\n appendRunSummary(process.env[\"GITHUB_STEP_SUMMARY\"], () =>\n renderBody(\n { kind: \"whole-document\", inlineCount: inlinePosted, rejectedCount: unanchoredCount },\n reviewUrl,\n visibleFindings,\n undefined,\n // The rejected-anchor invariant holds on EVERY surface, the run summary included — this\n // document deliberately carries every finding, so the GitHub-rejected ones must keep their\n // path-only links here too (issue #231 r2). Unconditional: renderBody's own gate treats an\n // empty array exactly like absence, so the ternary was a duplicated decision (issue #231 r3).\n unposted,\n // The summary is the sticky's long-lived twin — a rejected finding's rebuilt discussion\n // trail renders here exactly as on the final patch.\n finalDiscussionOverride,\n ),\n );\n};\n\nexport interface AnnounceInput {\n readonly repo: string;\n readonly headSha: string;\n readonly botLogin: string;\n readonly runUrl: string;\n readonly headBranch?: string;\n}\n\n// The notice bodies (announce placeholder, did-not-complete, superseded) share one shape: the sticky\n// marker, a lead line, and — when a prior sticky exists — its machine-readable markers carried forward\n// verbatim, so replacing the summary prose never strips the re-review seed the review job reads back\n// (embedded findings + reviewed-sha). Each body builds its own lead; this helper owns the shared tail.\nconst noticeBody = (lead: string, existingBody: string | undefined): string => {\n const carried = existingBody ? carryForwardMarkers(existingBody) : \"\";\n return carried ? `${lead}\\n\\n${carried}` : lead;\n};\n\n// Whether a sticky body references THIS run's URL — matched by the run id (shared grammar with\n// checkrun's runIdFromUrl) with a non-digit boundary so a successor whose numeric run id has this one\n// as a prefix (…/runs/123 vs …/runs/1234) is not mistaken for this run. Falls back to a plain substring\n// when the run URL carries no run id.\nconst bodyRefsRun = (body: string, runUrl: string): boolean => {\n const runId = runIdFromUrl(runUrl);\n return runId === null\n ? body.includes(runUrl)\n : new RegExp(`/actions/runs/${runId}(?!\\\\d)`).test(body);\n};\n\n// The placeholder body: a \"review in progress\" line linking the run, plus — when the sticky it replaces\n// carried a completed review — the prior convergence trajectory with a pending \"⏳\" cell for the round\n// now running (issue #180), so the iterations → convergence progression stays visible while the review\n// runs. The commenter job overwrites this with the real summary when the review completes.\nconst announceBody = (\n headSha: string,\n runUrl: string,\n existingBody: string | undefined,\n): string => {\n const priorDoc = existingBody !== undefined ? parseFindingsMarker(existingBody) : null;\n const prior = existingBody !== undefined ? carriedConvergence(priorDoc, existingBody) : null;\n // The running round is the SAME derivation post uses to number its appended round (nextRoundNumber),\n // so the placeholder's label matches what post will stamp — by construction (issue #188 review).\n const progress =\n prior !== null\n ? inProgressConvergence(\n prior,\n nextRoundNumber(priorTrajectory(priorDoc, existingBody ?? \"\"), prior.rounds ?? []),\n )\n : \"\";\n return noticeBody(\n `${DEFAULT_MARKER}\\n\\n🔄 **Code review in progress** for \\`${headSha.slice(0, 7)}\\` — see the [workflow run](${runUrl}) for progress; this comment is updated with the review when it completes.${progress ? `\\n\\n${progress}` : \"\"}`,\n existingBody,\n );\n};\n\n// Post (or update) the sticky the moment a review starts, so a workflow_run review — which runs from\n// the default branch and is otherwise invisible on the PR — is visibly under way. Shares post's PR\n// resolution and sticky upsert; the review job holds no write token, so it can't do this itself.\nexport const announce = async (input: AnnounceInput, ghApi: GhApi = runGhApi): Promise<void> => {\n const candidates = await fetchPrCandidates(input.repo, input.headSha, ghApi);\n const resolution = resolvePr(candidates, input.headBranch);\n if (resolution.kind !== \"open\") {\n process.stderr.write(\n `No open PR for ${input.headSha} — nothing to announce (${resolution.kind})\\n`,\n );\n return;\n }\n const existing = await findBotComment(\n input.repo,\n resolution.prNumber,\n input.botLogin,\n DEFAULT_MARKER,\n ghApi,\n );\n // If the sticky already reflects a COMPLETED review OF THIS HEAD, leave it — overwriting it with the\n // in-progress placeholder would hide a finished review (a CI re-run of an already-reviewed commit,\n // or the review+comment pipeline racing ahead of this job). Both conditions matter: a same-head\n // INCOMPLETE notice (which also stamps reviewed-sha) must be replaced by the placeholder on a re-run,\n // and a prior head's sha still gets replaced regardless. `review-complete` is the discriminator the\n // commenter guard uses too, so both write paths agree on what \"completed\" means.\n if (\n existing !== null &&\n parseReviewComplete(existing.body) &&\n parseReviewedSha(existing.body) === input.headSha.toLowerCase()\n ) {\n process.stderr.write(\n `Sticky already reflects a completed review of ${input.headSha} — leaving it in place\\n`,\n );\n return;\n }\n await upsertSticky(\n input.repo,\n resolution.prNumber,\n existing,\n announceBody(input.headSha, input.runUrl, existing?.body),\n ghApi,\n );\n};\n\nconst incompleteBody = (\n headSha: string,\n runUrl: string,\n existingBody: string | undefined,\n): string =>\n noticeBody(\n `${DEFAULT_MARKER}\\n\\n⚠️ **Code review did not complete** for \\`${headSha.slice(0, 7)}\\` — the review job failed ([run](${runUrl})). Re-request the review; do not treat this round as spent.`,\n existingBody,\n );\n\n// A review run CANCELLED is not an operational failure — issue #139. Distinct sentence, no action\n// needed, and it must NOT read as a crash: no \"did not complete\", no \"Re-request\", and it never\n// carries the review-complete marker. The wording is deliberately soft about WHY it was cancelled —\n// `needs.review.result == 'cancelled'` also fires for a manual cancel, so the sticky must not assert\n// \"a newer review run started\" as fact, and the run it links is this (cancelled) one, not a \"latest\"\n// run it cannot name. The superseding run's own announce (or the commenter) replaces it.\nconst cancelledBody = (headSha: string, runUrl: string, existingBody: string | undefined): string =>\n noticeBody(\n `${DEFAULT_MARKER}\\n\\n↩️ **Code review superseded** for \\`${headSha.slice(0, 7)}\\` — this run was cancelled before completing, typically because a newer review run started on this branch. No action needed. [View the cancelled run](${runUrl}) for the record.`,\n existingBody,\n );\n\nexport interface ReportIncompleteInput extends AnnounceInput {\n // Issue #139: this run was CANCELLED by a superseding run on the same branch — post the\n // informational \"superseded\" sticky instead of the failure notice.\n readonly cancelled?: boolean;\n}\n\n// The human-readable half of failure attribution (the check-run is the machine half): a review that\n// died leaves NO comment, so a separate always()-job posts this. Shares announce's PR resolution and\n// sticky upsert; the guard is stronger — it never buries a completed review OF ANY head, so a failed\n// run reporting late (after a superseding run already finished) can't clobber the real review. A\n// CANCELLED run (issue #139) posts the superseded notice instead, and the same guards keep it from\n// clobbering a newer run's live placeholder.\nexport const reportIncomplete = async (\n input: ReportIncompleteInput,\n ghApi: GhApi = runGhApi,\n): Promise<void> => {\n const candidates = await fetchPrCandidates(input.repo, input.headSha, ghApi);\n const resolution = resolvePr(candidates, input.headBranch);\n if (resolution.kind !== \"open\") {\n process.stderr.write(\n `No open PR for ${input.headSha} — nothing to report (${resolution.kind})\\n`,\n );\n return;\n }\n const existing = await findBotComment(\n input.repo,\n resolution.prNumber,\n input.botLogin,\n DEFAULT_MARKER,\n ghApi,\n );\n if (existing !== null && parseReviewComplete(existing.body)) {\n process.stderr.write(`Sticky already reflects a completed review — leaving it in place\\n`);\n return;\n }\n // The sticky exists but is NOT this run's own placeholder — it belongs to a superseding run whose\n // announce already posted a live \"in progress\" for a newer head. Overwriting it with \"did not\n // complete\" would be a false alarm for a review that is actively running. This run's own placeholder\n // (or a prior failure notice this run posted) embeds this run's URL, so its presence is the signal\n // that overwriting is safe. The run id is matched with a non-digit boundary so a successor whose\n // numeric run id has this one as a prefix (123 vs 1234) is not mistaken for this run.\n if (existing !== null && !bodyRefsRun(existing.body, input.runUrl)) {\n process.stderr.write(`Sticky belongs to another run — leaving it in place\\n`);\n return;\n }\n // A CANCELLED run with NO placeholder at all (cancelled before its announce, or a manual cancel with\n // nothing ever posted) must not CREATE a lone \"superseded\" sticky — nothing superseded it. Only a\n // run that announced (or already posted its own notice) replaces its placeholder. A superseding run\n // will post its own review, so a missing sticky is not a gap.\n if (input.cancelled && existing === null) {\n process.stderr.write(`Cancelled review has no sticky to supersede — leaving it absent\\n`);\n return;\n }\n await upsertSticky(\n input.repo,\n resolution.prNumber,\n existing,\n input.cancelled\n ? cancelledBody(input.headSha, input.runUrl, existing?.body)\n : incompleteBody(input.headSha, input.runUrl, existing?.body),\n ghApi,\n );\n};\n","// Parses a ChatOps trigger comment (\"/code-review [24m] [$1.00] <instructions>\") into structured\n// review overrides, and resolves the PR head from the comment's PR NUMBER via the API (never from a\n// SHA in the comment). The untrusted comment is parsed here, in type-safe code, not in workflow bash.\n\nimport * as t from \"io-ts\";\nimport type { GhApi } from \"./gh.js\";\nimport { runGhApi } from \"./gh.js\";\n\nexport interface CommandArgs {\n // null ⇒ the commenter did not specify it; the reusable workflow keeps its configured default.\n readonly durationSec: number | null;\n readonly usd: number | null;\n readonly instructions: string;\n // Human-readable adjustments (a clamp hit, a truncation) for the CI log — the sticky footer shows\n // the values actually used, so these are diagnostics, not the user-facing signal.\n readonly notes: readonly string[];\n}\n\nexport type CommandParse =\n { readonly kind: \"not-a-command\" } | { readonly kind: \"command\"; readonly args: CommandArgs };\n\nexport interface ParseOptions {\n readonly trigger: string;\n // null ⇒ no clamp (a comment could then request an unbounded wall/budget — callers set a ceiling).\n readonly maxDurationSec: number | null;\n readonly maxUsd: number | null;\n readonly maxInstructionsLen: number;\n}\n\nconst DURATION_RE = /^(\\d+)(h|m|s)$/;\nconst USD_RE = /^\\$(\\d+(?:\\.\\d+)?)$/;\n\nconst toSeconds = (n: number, unit: string): number =>\n unit === \"h\" ? n * 3600 : unit === \"m\" ? n * 60 : n;\n\n// null when the body does not begin with the trigger as a WHOLE token (so \"/code-reviewer\" is not a\n// hit); otherwise the remainder after the trigger, leading whitespace and all.\nconst stripTrigger = (body: string, trigger: string): string | null => {\n const trimmed = body.replace(/^\\s+/, \"\");\n if (!trimmed.startsWith(trigger)) return null;\n const after = trimmed.slice(trigger.length);\n return after === \"\" || /^\\s/.test(after) ? after : null;\n};\n\n// Consume leading whitespace-delimited tokens that are a duration or a dollar amount (each at most\n// once, either order); stop at the first token that is neither (or a duplicate). The untouched\n// remainder — from that token on, its own leading whitespace included — is the instructions.\nconst scanLeading = (\n s: string,\n acc: { readonly durationSec: number | null; readonly usd: number | null },\n): { readonly durationSec: number | null; readonly usd: number | null; readonly rest: string } => {\n const m = /^(\\s*)(\\S+)([\\s\\S]*)$/.exec(s);\n if (m === null) return { ...acc, rest: \"\" };\n const [, , token = \"\", tail = \"\"] = m;\n const dm = DURATION_RE.exec(token);\n if (dm && acc.durationSec === null)\n return scanLeading(tail, {\n ...acc,\n durationSec: toSeconds(Number.parseInt(dm[1] ?? \"\", 10), dm[2] ?? \"s\"),\n });\n const um = USD_RE.exec(token);\n if (um && acc.usd === null)\n return scanLeading(tail, { ...acc, usd: Number.parseFloat(um[1] ?? \"\") });\n return { ...acc, rest: s };\n};\n\nconst clampDuration = (\n requested: number | null,\n ceiling: number | null,\n): { readonly value: number | null; readonly notes: readonly string[] } =>\n requested !== null && ceiling !== null && requested > ceiling\n ? {\n value: ceiling,\n notes: [\n `requested duration ${String(requested)}s exceeds the ${String(ceiling)}s ceiling — clamped to ${String(ceiling)}s`,\n ],\n }\n : { value: requested, notes: [] };\n\nconst clampUsd = (\n requested: number | null,\n ceiling: number | null,\n): { readonly value: number | null; readonly notes: readonly string[] } =>\n requested !== null && ceiling !== null && requested > ceiling\n ? {\n value: ceiling,\n notes: [\n `requested $${requested.toFixed(2)} exceeds the $${ceiling.toFixed(2)} ceiling — clamped to $${ceiling.toFixed(2)}`,\n ],\n }\n : { value: requested, notes: [] };\n\nconst capInstructions = (\n text: string,\n maxLen: number,\n): { readonly value: string; readonly notes: readonly string[] } =>\n text.length > maxLen\n ? {\n value: text.slice(0, maxLen),\n notes: [\n `instructions truncated from ${String(text.length)} to ${String(maxLen)} characters`,\n ],\n }\n : { value: text, notes: [] };\n\nexport const parseCommandArgs = (body: string, options: ParseOptions): CommandParse => {\n const afterTrigger = stripTrigger(body, options.trigger);\n if (afterTrigger === null) return { kind: \"not-a-command\" };\n const scan = scanLeading(afterTrigger, { durationSec: null, usd: null });\n const duration = clampDuration(scan.durationSec, options.maxDurationSec);\n const usd = clampUsd(scan.usd, options.maxUsd);\n const instructions = capInstructions(scan.rest.trim(), options.maxInstructionsLen);\n return {\n kind: \"command\",\n args: {\n durationSec: duration.value,\n usd: usd.value,\n instructions: instructions.value,\n notes: [...duration.notes, ...usd.notes, ...instructions.notes],\n },\n };\n};\n\nconst PrHeadCodec = t.type({\n head_sha: t.string,\n head_ref: t.string,\n head_repo: t.union([t.string, t.null]),\n state: t.string,\n});\n\nexport const resolvePrHead = async (\n repo: string,\n prNumber: number,\n ghApi: GhApi,\n): Promise<t.TypeOf<typeof PrHeadCodec>> => {\n const stdout = await ghApi([\n `repos/${repo}/pulls/${String(prNumber)}`,\n \"--jq\",\n \"{head_sha: .head.sha, head_ref: .head.ref, head_repo: .head.repo.full_name, state: .state}\",\n ]);\n const decoded = PrHeadCodec.decode(JSON.parse(stdout) as unknown);\n if (decoded._tag === \"Left\") {\n throw new Error(`PR head for #${String(prNumber)} did not match the expected shape`);\n }\n return decoded.right;\n};\n\nexport interface CommandInput {\n readonly repo: string;\n readonly prNumber: number;\n readonly body: string;\n readonly options: ParseOptions;\n}\n\nexport type CommandResult =\n | { readonly kind: \"skip\"; readonly reason: string }\n | {\n readonly kind: \"run\";\n readonly headSha: string;\n readonly headBranch: string;\n readonly headRepo: string;\n readonly args: CommandArgs;\n };\n\nexport const parseCommand = async (\n input: CommandInput,\n ghApi: GhApi = runGhApi,\n): Promise<CommandResult> => {\n const parse = parseCommandArgs(input.body, input.options);\n if (parse.kind === \"not-a-command\") {\n return {\n kind: \"skip\",\n reason: `comment does not begin with the trigger \"${input.options.trigger}\"`,\n };\n }\n const head = await resolvePrHead(input.repo, input.prNumber, ghApi).catch((err: unknown) =>\n err instanceof Error ? err : new Error(String(err)),\n );\n if (head instanceof Error) {\n return {\n kind: \"skip\",\n reason: `could not resolve PR #${String(input.prNumber)}: ${head.message}`,\n };\n }\n if (head.state !== \"open\") {\n return {\n kind: \"skip\",\n reason: `PR #${String(input.prNumber)} is not open (state: ${head.state})`,\n };\n }\n return {\n kind: \"run\",\n headSha: head.head_sha,\n headBranch: head.head_ref,\n headRepo: head.head_repo ?? input.repo,\n args: parse.args,\n };\n};\n\n// A heredoc delimiter guaranteed not to equal any line of the (untrusted) instructions, so the value\n// can't break out of its $GITHUB_OUTPUT block and forge later outputs (e.g. should_run=true). A\n// 128-bit random tag never collides in practice; the bounded recursion is belt-and-braces.\nexport const safeHeredocDelim = (\n instructions: string,\n randomHex: () => string,\n attemptsLeft = 8,\n): string => {\n const candidate = `GHOUT_${randomHex()}`;\n if (!instructions.split(\"\\n\").includes(candidate)) return candidate;\n if (attemptsLeft <= 0) throw new Error(\"could not derive a collision-free heredoc delimiter\");\n return safeHeredocDelim(instructions, randomHex, attemptsLeft - 1);\n};\n\nexport const renderCommandOutputs = (result: CommandResult, delim: string): string => {\n if (result.kind === \"skip\") return \"should_run=false\\n\";\n const { headSha, headBranch, headRepo, args } = result;\n return `${[\n \"should_run=true\",\n `head_sha=${headSha}`,\n `head_branch=${headBranch}`,\n `head_repo=${headRepo}`,\n `duration=${args.durationSec === null ? \"\" : `${String(args.durationSec)}s`}`,\n `usd=${args.usd === null ? \"\" : args.usd.toFixed(2)}`,\n `instructions<<${delim}`,\n args.instructions,\n delim,\n ].join(\"\\n\")}\\n`;\n};\n","// Manages the ChatOps acknowledgement reaction on a PR/issue comment: 👀 on receipt, swapped to 🚀\n// (or 😕) on completion. Reactions are cosmetic, so the CLI wrapper never fails a job over them.\n\nimport * as t from \"io-ts\";\nimport type { GhApi } from \"./gh.js\";\nimport { runGhApi } from \"./gh.js\";\nimport { errMsg, tryParseJson } from \"./util.js\";\n\n// GitHub's fixed reaction vocabulary — there is no ✅; 🚀 (rocket) reads as \"review shipped\".\nexport const REACTIONS = [\n \"+1\",\n \"-1\",\n \"laugh\",\n \"confused\",\n \"heart\",\n \"hooray\",\n \"rocket\",\n \"eyes\",\n] as const;\nexport type Reaction = (typeof REACTIONS)[number];\nexport const isReaction = (s: string): s is Reaction =>\n (REACTIONS as readonly string[]).includes(s);\n\nconst ReactionCodec = t.type({ id: t.number, content: t.string });\n\nexport interface ReactInput {\n readonly repo: string;\n readonly commentId: number;\n readonly add?: Reaction;\n readonly remove?: Reaction;\n}\n\nconst reactionsPath = (repo: string, commentId: number): string =>\n `repos/${repo}/issues/comments/${String(commentId)}/reactions`;\n\nconst removeReactions = async (\n repo: string,\n commentId: number,\n content: Reaction,\n ghApi: GhApi,\n): Promise<void> => {\n // --paginate WITHOUT --jq concatenates pages as `[..][..]` (invalid JSON) once a comment has >100\n // reactions; flatten to one record per line via --jq and decode line by line, like pr.ts. Each\n // undecodable line is logged and skipped rather than silently swallowed.\n const stdout = await ghApi([\n reactionsPath(repo, commentId),\n \"--paginate\",\n \"--jq\",\n \".[] | {id, content}\",\n ]);\n for (const line of stdout.split(\"\\n\").filter((l) => l.trim() !== \"\")) {\n const parsed = tryParseJson(line);\n const decoded = parsed.ok ? ReactionCodec.decode(parsed.value) : undefined;\n if (decoded === undefined || decoded._tag === \"Left\") {\n process.stderr.write(\"code-review react: could not decode a reaction entry — skipping\\n\");\n continue;\n }\n if (decoded.right.content !== content) continue;\n // The token may delete only its OWN reactions; a 403 on someone else's is expected, not fatal.\n await ghApi([\n \"--method\",\n \"DELETE\",\n `${reactionsPath(repo, commentId)}/${String(decoded.right.id)}`,\n ]).catch((err: unknown) =>\n process.stderr.write(\n `code-review react: could not remove reaction ${String(decoded.right.id)} (${errMsg(err)}) — skipping\\n`,\n ),\n );\n }\n};\n\n// Add first, then remove, so the comment is never momentarily unmarked during a 👀→🚀 swap.\nexport const react = async (input: ReactInput, ghApi: GhApi = runGhApi): Promise<void> => {\n if (input.add !== undefined) {\n await ghApi([\n \"--method\",\n \"POST\",\n reactionsPath(input.repo, input.commentId),\n \"-f\",\n `content=${input.add}`,\n ]);\n }\n if (input.remove !== undefined) {\n await removeReactions(input.repo, input.commentId, input.remove, ghApi);\n }\n};\n","// Resolves and waits for a PR head's CI workflow run, so the on-demand comment trigger routes on the\n// SAME real CI conclusion the workflow_run trigger would: success → full review, failure → mechanic\n// with that run's failing-job logs. Without this the comment path reviews blind to CI — throwing away\n// the differentiator. The head SHA is trusted (resolved from the PR number via the API), so it is\n// safe in the query; the workflow name is trusted caller config.\n\nimport { performance } from \"node:perf_hooks\";\nimport * as t from \"io-ts\";\nimport { PathReporter } from \"io-ts/lib/PathReporter.js\";\nimport type { GhApi } from \"./gh.js\";\nimport { runGhApi } from \"./gh.js\";\nimport { parseJsonl } from \"./transcript.js\";\nimport { errMsg } from \"./util.js\";\n\nconst RunCodec = t.type({\n id: t.number,\n name: t.union([t.string, t.null]),\n status: t.union([t.string, t.null]),\n conclusion: t.union([t.string, t.null]),\n run_number: t.number,\n});\n\nexport interface CiRun {\n readonly id: number;\n // queued | in_progress | requested | waiting | pending | completed\n readonly status: string;\n // success | failure | cancelled | timed_out | ... — null until status is completed\n readonly conclusion: string | null;\n}\n\nexport interface CiLookup {\n // The matched run, or null if the named workflow has no run for this head SHA yet.\n readonly run: CiRun | null;\n // Distinct workflow names that DID run for this head SHA — lets a caller tell a mistyped\n // workflowName (which otherwise just times out) from \"the named CI simply has not queued yet\".\n readonly seenNames: readonly string[];\n}\n\n// One projected run object per row across ALL pages: `--paginate` WITHOUT `--jq` concatenates each\n// page's `{workflow_runs: […]}` object into a stream JSON.parse rejects, so only the first page (≤100\n// runs) was ever read — a head SHA with many workflows or re-runs could push the awaited run out of\n// view and the comment path would decline with no diagnostic. `--jq` unwraps `.workflow_runs[]` and\n// streams NDJSON parseJsonl reads line by line, the shape gather/post already use.\nconst RUN_JQ =\n \".workflow_runs[] | {id: .id, name: .name, status: .status, conclusion: .conclusion, run_number: .run_number}\";\n\n// The latest run of the named CI workflow for this head SHA. NOT filtered by triggering event: CI may\n// run on `push` as well as `pull_request`, and the head SHA already pins the commit. Latest = highest\n// run_number, so a re-run supersedes. `run` is null when the named workflow has no run yet (the\n// comment may fire before CI even queues). A row that doesn't match the run shape is dropped rather\n// than aborting the lookup — an empty result then reads as \"not queued yet\" and the caller declines.\nexport const resolveCiRun = async (\n repo: string,\n headSha: string,\n workflowName: string,\n ghApi: GhApi,\n): Promise<CiLookup> => {\n const endpoint = `repos/${repo}/actions/runs?head_sha=${headSha}&per_page=100`;\n const rows = parseJsonl(await ghApi([endpoint, \"--paginate\", \"--jq\", RUN_JQ]));\n const decoded = rows.map((row) => RunCodec.decode(row));\n const runs = decoded.flatMap((d) => (d._tag === \"Right\" ? [d.right] : []));\n // A row that fails the codec is dropped rather than aborting the lookup, but a drop is never normal:\n // a partial drift can silently drop the newest run and route on a stale one, and a total drift reads\n // as an empty result that declines only after a full timeout. So name every drop, with the first\n // failure's field-level detail, so the drifted field is diagnosable without reproducing the call.\n const dropped = decoded.length - runs.length;\n if (dropped > 0) {\n const firstDrift = decoded.find((d) => d._tag === \"Left\");\n const detail =\n firstDrift === undefined ? \"\" : ` (${PathReporter.report(firstDrift).join(\"; \")})`;\n process.stderr.write(\n `Warning: ${String(dropped)} of ${String(rows.length)} workflow-run row(s) from ${endpoint} failed to decode${detail} — excluded from the lookup\\n`,\n );\n }\n const latest = runs\n .filter((r) => r.name === workflowName)\n .reduce<t.TypeOf<typeof RunCodec> | null>(\n (best, r) => (best === null || r.run_number > best.run_number ? r : best),\n null,\n );\n return {\n run:\n latest === null\n ? null\n : { id: latest.id, status: latest.status ?? \"unknown\", conclusion: latest.conclusion },\n seenNames: [...new Set(runs.flatMap((r) => (r.name === null ? [] : [r.name])))],\n };\n};\n\nexport type CiOutcome =\n | { readonly kind: \"concluded\"; readonly conclusion: string; readonly runId: number }\n // No conclusive CI result within the timeout — the run never appeared or never completed. The\n // caller declines to review rather than fabricate a conclusion. seenNames carries the workflow\n // names that DID run, so a mistyped ci_workflow can be diagnosed instead of silently timing out.\n | {\n readonly kind: \"timed-out\";\n readonly runId: number | null;\n readonly seenNames: readonly string[];\n };\n\nexport interface AwaitOptions {\n readonly workflowName: string;\n readonly pollIntervalMs: number;\n readonly timeoutMs: number;\n}\n\nexport interface AwaitDeps {\n readonly ghApi: GhApi;\n readonly sleep: (ms: number) => Promise<void>;\n readonly elapsedMs: () => number;\n}\n\nexport const awaitCiConclusion = async (\n repo: string,\n headSha: string,\n options: AwaitOptions,\n deps: AwaitDeps = { ghApi: runGhApi, sleep: defaultSleep, elapsedMs: monotonicElapsed() },\n): Promise<CiOutcome> => {\n // `--paginate` fetches one page per HTTP request, so a transient blip on any page rejects the whole\n // lookup. Contain it to a diagnostic + empty result rather than let it unwind and abort the wait:\n // the loop is meant to be resilient, so a failed poll should retry until the run settles or the\n // timeout declines, never crash mid-wait.\n const safeResolve = async (): Promise<CiLookup> => {\n try {\n return await resolveCiRun(repo, headSha, options.workflowName, deps.ghApi);\n } catch (err) {\n process.stderr.write(\n `Warning: CI-run lookup for ${headSha} failed (${errMsg(err)}) — retrying until the timeout\\n`,\n );\n return { run: null, seenNames: [] };\n }\n };\n const poll = async (\n lastSeenNames: readonly string[],\n lastRunId: number | null,\n ): Promise<CiOutcome> => {\n const { run, seenNames } = await safeResolve();\n // A run momentarily reports `completed` with a null conclusion before GitHub settles it; treating\n // that as concluded would fabricate a routing decision, so keep polling until the conclusion lands\n // (or the timeout declines) rather than collapsing it to a made-up \"unknown\" the caller can act on.\n if (run !== null && run.status === \"completed\" && run.conclusion !== null)\n return { kind: \"concluded\", conclusion: run.conclusion, runId: run.id };\n // A caught error zeroes this poll's view, so carry the last non-empty observation forward — else a\n // transient failure on the very iteration that times out would erase the run id and workflow names\n // earlier polls saw, misleading the mistyped-workflow-vs-not-queued-yet diagnostic renderCiOutputs\n // depends on.\n const runId = run === null ? lastRunId : run.id;\n const names = seenNames.length > 0 ? seenNames : lastSeenNames;\n if (deps.elapsedMs() >= options.timeoutMs)\n return { kind: \"timed-out\", runId, seenNames: names };\n await deps.sleep(options.pollIntervalMs);\n return poll(names, runId);\n };\n return poll([], null);\n};\n\nexport const defaultSleep = (ms: number): Promise<void> =>\n new Promise((resolvePromise) => setTimeout(resolvePromise, ms));\n\n// performance.now() is monotonic — unlike Date.now(), an NTP/VM wall-clock step back mid-poll can't\n// make elapsedMs() decrease and stall the timeout check the loop depends on.\nexport const monotonicElapsed = (): (() => number) => {\n const start = performance.now();\n return () => performance.now() - start;\n};\n\n// ci_settled distinguishes \"we know the CI result\" from \"we gave up waiting\" so the gate can decline\n// the review on a non-settle rather than run it on a guessed conclusion.\nexport const renderCiOutputs = (outcome: CiOutcome): string =>\n outcome.kind === \"concluded\"\n ? `ci_settled=true\\nci_conclusion=${outcome.conclusion}\\nci_run_id=${String(outcome.runId)}\\n`\n : `ci_settled=false\\nci_run_id=${outcome.runId === null ? \"\" : String(outcome.runId)}\\n`;\n","// Shares post's PR resolution so the review and comment jobs never split-brain on which PR.\n\nimport { writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport * as t from \"io-ts\";\nimport { execFileWithTimeout, subprocessTimeoutMs } from \"./exec.js\";\nimport type { GhApi } from \"./gh.js\";\nimport { runGhApi } from \"./gh.js\";\nimport { ghArtifactReader, resolvePriorFindings, type ArtifactReader } from \"./artifact.js\";\nimport { isFullReviewAncestry } from \"./surface.js\";\nimport { fetchDiff, fetchPrCandidates, resolvePr } from \"./pr.js\";\nimport { parseJsonl } from \"./transcript.js\";\nimport {\n answeredRegistryFrom,\n encodeAnsweredEntry,\n ThreadCommentCodec,\n THREAD_COMMENT_JQ,\n} from \"./answered.js\";\nimport { annotationSafe, BODY_CLIP_CHARS, clipText, errMsg } from \"./util.js\";\n\nexport interface GatherInput {\n readonly repo: string;\n readonly headSha: string;\n readonly headBranch?: string;\n // The repo's default branch — the trusted base the review checks out and the reference point for\n // the full (triage) diff. A PR whose base is a different branch is \"stacked\".\n readonly defaultBranch: string;\n readonly runId: string;\n readonly conclusion: string;\n readonly botLogin: string;\n readonly outDir: string;\n}\n\nexport type GatherResult =\n | { readonly kind: \"skip\" }\n | {\n readonly kind: \"gathered\";\n readonly pr: number;\n readonly conclusion: string;\n readonly diffSize: number;\n // The PR's base is not the default branch (a stacked PR): the review scope (base...head) is a\n // strict subset of what gets checked out + triaged (default...head), so the review prompt frames\n // the extra changes as already-reviewed context.\n readonly stacked: boolean;\n // The review-scope base commit (the pr.diff endpoint), exposed so a downstream step can run\n // `cloc --git --diff <baseSha> <head>` over exactly the PR's own change (issue #182).\n readonly baseSha: string;\n // Failing-job logs actually written for the fast-fix route to read. Zero means that route has\n // nothing but the diff, which every downstream surface has to say rather than imply (#154).\n readonly stagedJobLogs: number;\n // Failing jobs the run reported, which the cap can leave larger than stagedJobLogs. Carried so\n // the fast-fix route is TOLD it is reading a subset, rather than reporting the break fixed on\n // the strength of the logs it happened to get.\n readonly failingJobs: number;\n };\n\nexport const renderOutputs = (result: GatherResult): string => {\n switch (result.kind) {\n case \"skip\":\n return \"skip=true\\n\";\n case \"gathered\":\n return `pr=${String(result.pr)}\\nconclusion=${result.conclusion}\\ndiff_size=${String(result.diffSize)}\\nstacked=${String(result.stacked)}\\nbase_sha=${result.baseSha}\\nstaged_job_logs=${String(result.stagedJobLogs)}\\nfailing_jobs=${String(result.failingJobs)}\\n`;\n }\n};\n\nexport type GitRun = (args: readonly string[]) => Promise<string>;\n\nexport const runGit: GitRun = (args) =>\n execFileWithTimeout({\n command: \"git\",\n args,\n label: `git ${args.join(\" \")}`,\n timeoutMs: subprocessTimeoutMs(),\n });\n\nconst PrMetaCodec = t.type({\n changed_files: t.number,\n base_sha: t.string,\n base_ref: t.string,\n title: t.string,\n body: t.union([t.string, t.null]),\n});\ntype PrMeta = t.TypeOf<typeof PrMetaCodec>;\n\nconst IssueCommentCodec = t.intersection([\n t.type({\n id: t.number,\n body: t.union([t.string, t.null]),\n user: t.type({ login: t.string }),\n }),\n t.partial({\n created_at: t.union([t.string, t.null]),\n author_association: t.union([t.string, t.null]),\n }),\n]);\ntype IssueComment = t.TypeOf<typeof IssueCommentCodec>;\n\nconst JobCodec = t.type({\n id: t.number,\n // A null name (an API edge) degrades to a nameless entry rather than aborting the whole gather —\n // the identity the reproduction steer needs is best-effort, never load-bearing.\n name: t.union([t.string, t.null]),\n conclusion: t.union([t.string, t.null]),\n});\n\n// One job per row across all pages, for the same reason the conversation fetches project with --jq:\n// `--paginate` alone concatenates each page into an invalid `{..}{..}` stream. Unpaginated, a failing\n// job past the first page is invisible — and everything this route reports (the staged count, the\n// \"(N failing job(s) reported)\" line, the unverified stamp) would be computed from a truncated list.\n// `name` rides along so a zero-logs pass can still tell the agent WHICH jobs failed (failed_jobs.json),\n// not just how many.\nconst JOBS_JQ = \".jobs[] | {id: .id, name: .name, conclusion: .conclusion}\";\n\nconst fetchPrMeta = async (repo: string, prNumber: number, ghApi: GhApi): Promise<PrMeta> => {\n const stdout = await ghApi([\n `repos/${repo}/pulls/${String(prNumber)}`,\n \"--jq\",\n \"{changed_files: .changed_files, base_sha: .base.sha, base_ref: .base.ref, title: .title, body: .body}\",\n ]);\n const decoded = PrMetaCodec.decode(JSON.parse(stdout) as unknown);\n if (decoded._tag === \"Left\") {\n throw new Error(`PR metadata for #${String(prNumber)} did not match the expected shape`);\n }\n return decoded.right;\n};\n\nconst fetchApiDiff = async (\n repo: string,\n prNumber: number,\n ghApi: GhApi,\n): Promise<string | null> => {\n try {\n return await fetchDiff(repo, prNumber, ghApi);\n } catch {\n return null;\n }\n};\n\n// The review checks out the PR head; the untrusted surface a checkout exposes over the trusted\n// default branch is exactly `default...head`. So triage scans THIS diff (not the PR's base...head),\n// and it is the same diff for a normal PR (base === default). Compare API with a git-diff fallback\n// (fetch the head, diff from the checked-out default-branch tip) mirroring the pr.diff path.\nconst fetchFullDiff = async (\n repo: string,\n defaultBranch: string,\n headSha: string,\n ghApi: GhApi,\n gitRun: GitRun,\n): Promise<string> => {\n try {\n const diff = await ghApi([\n `repos/${repo}/compare/${defaultBranch}...${headSha}`,\n \"-H\",\n \"Accept: application/vnd.github.v3.diff\",\n ]);\n if (diff.length > 0) return diff;\n process.stderr.write(\n `compare diff for ${defaultBranch}...${headSha} was empty — falling back to git diff\\n`,\n );\n } catch (err) {\n process.stderr.write(`compare diff fetch failed (${errMsg(err)}) — falling back to git diff\\n`);\n }\n await gitRun([\"fetch\", \"origin\", headSha]);\n // Three-dot, matching the compare API's semantics (merge-base...head): the checked-out default\n // branch is HEAD, so this is the same untrusted surface the compare primary computes.\n const base = (await gitRun([\"rev-parse\", \"HEAD\"])).trim();\n return gitRun([\"diff\", `${base}...${headSha}`]);\n};\n\nconst CommitCodec = t.type({\n sha: t.string,\n message: t.string,\n author: t.union([t.string, t.null]),\n email: t.union([t.string, t.null]),\n});\nconst COMMIT_JQ =\n \".commits[] | {sha: .sha, message: .commit.message, author: .commit.author.name, email: .commit.author.email}\";\n\n// Commit messages + author identities of every commit in `default...head`. Once the head is checked\n// out, `git log` exposes these to the reviewing agent, so they are an untrusted surface triage must\n// scan for injection. FAIL CLOSED: a fetch failure propagates (never a silent empty scan) — the\n// caller must not expose commit messages it could not vet.\nconst fetchCompareCommits = async (\n repo: string,\n defaultBranch: string,\n headSha: string,\n ghApi: GhApi,\n): Promise<readonly t.TypeOf<typeof CommitCodec>[]> => {\n const rows = parseJsonl(\n await ghApi([\n `repos/${repo}/compare/${defaultBranch}...${headSha}`,\n \"--paginate\",\n \"--jq\",\n COMMIT_JQ,\n ]),\n );\n const decoded = rows.map((row) => CommitCodec.decode(row));\n const commits = decoded.flatMap((d) => (d._tag === \"Right\" ? [d.right] : []));\n // A dropped row is a scan gap, not a no-op: a checkout's `git log` still exposes that commit's\n // message to the agent, so name any drop rather than let an unscanned message pass silently.\n const dropped = decoded.length - commits.length;\n if (dropped > 0) {\n process.stderr.write(\n `Warning: ${String(dropped)} of ${String(rows.length)} commit row(s) failed to decode — their messages are NOT in the triage scan though a checkout's git log still exposes them\\n`,\n );\n }\n return commits;\n};\n\n// One object per row across all pages: `--paginate` WITHOUT `--jq` concatenates each page's JSON\n// array into an invalid `[..][..]` stream JSON.parse rejects, silently losing the prior review (and\n// the conversation) on any PR past the first page; the `--jq` projection streams NDJSON parseJsonl\n// reads line by line — the shape post.ts's findBotComment already uses.\nconst COMMENT_JQ =\n \".[] | {id: .id, body: .body, user: {login: .user.login}, created_at: .created_at, author_association: .author_association}\";\n// The review-comments fetch feeds TWO consumers from one projection: the conversation (human\n// replies, via ReviewCommentCodec) and the answered-findings registry (thread structure + the bot's\n// own comments, via ThreadCommentCodec) — the richer THREAD_COMMENT_JQ shape serves both, the\n// conversation codec tolerating the extra fields.\nconst REVIEW_COMMENT_JQ = THREAD_COMMENT_JQ;\nconst REVIEW_JQ =\n \".[] | {body: .body, user: {login: .user.login}, submitted_at: .submitted_at, author_association: .author_association, state: .state}\";\n\nconst ReviewCommentCodec = t.intersection([\n t.type({ body: t.union([t.string, t.null]), user: t.type({ login: t.string }) }),\n t.partial({\n created_at: t.union([t.string, t.null]),\n author_association: t.union([t.string, t.null]),\n path: t.union([t.string, t.null]),\n line: t.union([t.number, t.null]),\n }),\n]);\ntype ReviewComment = t.TypeOf<typeof ReviewCommentCodec>;\n\nconst ReviewCodec = t.intersection([\n t.type({ body: t.union([t.string, t.null]), user: t.type({ login: t.string }) }),\n t.partial({\n submitted_at: t.union([t.string, t.null]),\n author_association: t.union([t.string, t.null]),\n state: t.union([t.string, t.null]),\n }),\n]);\ntype Review = t.TypeOf<typeof ReviewCodec>;\n\n// Fetch + stream-parse a paginated endpoint; null on any transport error (named on stderr so a\n// degraded channel is diagnosable), so a failed fetch never aborts the review — the conversation is\n// best-effort context.\nconst fetchJsonlRows = async (\n ghApi: GhApi,\n endpoint: string,\n jq: string,\n): Promise<readonly unknown[] | null> => {\n try {\n return parseJsonl(await ghApi([endpoint, \"--paginate\", \"--jq\", jq]));\n } catch (err) {\n process.stderr.write(\n `Warning: could not fetch ${endpoint} (${errMsg(err)}) — omitting it from the review context\\n`,\n );\n return null;\n }\n};\n\n// Decode row by row, dropping only the rows that don't validate (e.g. a deleted account's null login)\n// rather than letting one malformed row fail the whole channel the way an atomic `t.array` decode\n// would. null still propagates a failed fetch (rows === null); a bad row is silently skipped.\nconst decodeArrayOrNull = <A>(\n codec: t.Type<A>,\n rows: readonly unknown[] | null,\n): readonly A[] | null => {\n if (rows === null) return null;\n return rows.flatMap((row) => {\n const decoded = codec.decode(row);\n return decoded._tag === \"Right\" ? [decoded.right] : [];\n });\n};\n\n// The bot's own last comment — its embedded findings marker seeds the re-review draft (seed-draft).\nconst priorReviewFrom = (\n comments: readonly IssueComment[],\n botLogin: string,\n): { readonly id: number; readonly body: string | null } | null => {\n const byBot = comments.filter((c) => c.user.login === botLogin);\n const last = byBot[byBot.length - 1];\n return last ? { id: last.id, body: last.body } : null;\n};\n\n// The untrusted PR discussion staged for the review agent to TRIAGE as claims — so a re-review can\n// recognize a finding the author already answered without OBEYING the comment. Everyone but the\n// review bot (its own output is seeded back via prior_review), bounded to the most recent items per\n// channel with each body clipped so a long thread can't blow the agent's context; the workflow frames\n// these files as claims-to-verify, never as instructions.\nconst MAX_CONVERSATION_COMMENTS = 50;\n\n// The shared surrogate-safe clip (util.ts) at the shared body cap — one constant with render's\n// carried-field clip so the two caps cannot drift (issue #217 review r7).\nconst clip = (body: string): string => clipText(body, BODY_CLIP_CHARS);\n\n// Drop the review bot and empty bodies, keep the most recent MAX (logging when it caps), then project.\nconst boundedHuman = <\n A extends { readonly user: { readonly login: string }; readonly body: string | null },\n B,\n>(\n items: readonly A[],\n botLogin: string,\n label: string,\n project: (item: A & { readonly body: string }) => B,\n): readonly B[] => {\n const human = items.filter(\n (a): a is A & { readonly body: string } =>\n a.user.login !== botLogin && typeof a.body === \"string\" && a.body.trim() !== \"\",\n );\n const kept = human.slice(-MAX_CONVERSATION_COMMENTS);\n if (kept.length < human.length) {\n process.stderr.write(\n `Note: PR has ${String(human.length)} ${label} — feeding the review the most recent ${String(MAX_CONVERSATION_COMMENTS)}\\n`,\n );\n }\n return kept.map(project);\n};\n\nconst issueCommentsFrom = (comments: readonly IssueComment[], botLogin: string) =>\n boundedHuman(comments, botLogin, \"discussion comments\", (c) => ({\n author: c.user.login,\n author_association: c.author_association ?? null,\n created_at: c.created_at ?? null,\n body: clip(c.body),\n }));\n\nconst reviewCommentsFrom = (comments: readonly ReviewComment[], botLogin: string) =>\n boundedHuman(comments, botLogin, \"inline review comments\", (c) => ({\n author: c.user.login,\n author_association: c.author_association ?? null,\n created_at: c.created_at ?? null,\n path: c.path ?? null,\n line: c.line ?? null,\n body: clip(c.body),\n }));\n\nconst reviewsFrom = (reviews: readonly Review[], botLogin: string) =>\n boundedHuman(reviews, botLogin, \"review submissions\", (r) => ({\n author: r.user.login,\n author_association: r.author_association ?? null,\n submitted_at: r.submitted_at ?? null,\n state: r.state ?? null,\n body: clip(r.body),\n }));\n\n// Jobs-list failure is fatal; a per-log download failure degrades — logs are advisory, and partial\n// logs plus the diff beat a dead review. Returns how many landed: on the fast-fix route the logs are\n// the whole premise, so zero of them is worth saying out loud rather than leaving the agent to infer\n// it from an empty directory (issue #154).\n// A matrix build can fail in hundreds of jobs, and each log is a separate sequential API call whose\n// bytes land on disk before the review starts — uncapped, that turns a gather step with no timeout\n// into minutes of downloading for a route that exists to be fast. The first failures in run order are\n// kept because a matrix usually fails from one root, and the earliest job to hit it is the one whose\n// log still shows the original error rather than a cascade.\nconst MAX_STAGED_JOB_LOGS = 20;\n\nconst downloadFailingJobLogs = async (\n repo: string,\n runId: string,\n outDir: string,\n ghApi: GhApi,\n): Promise<{ readonly staged: number; readonly failing: number }> => {\n const rows = parseJsonl(\n await ghApi([`repos/${repo}/actions/runs/${runId}/jobs`, \"--paginate\", \"--jq\", JOBS_JQ]),\n );\n const decoded = t.array(JobCodec).decode(rows);\n if (decoded._tag === \"Left\") {\n throw new Error(`Jobs list for run ${runId} did not match the expected shape`);\n }\n const failing = decoded.right.filter((j) => j.conclusion === \"failure\");\n const selected = failing.slice(0, MAX_STAGED_JOB_LOGS);\n let staged = 0;\n for (const job of selected) {\n try {\n const log = await ghApi([`repos/${repo}/actions/jobs/${String(job.id)}/logs`]);\n // GitHub serves a \"no log available\" placeholder body when a job produced none (a killed\n // runner, no step output). A placeholder is NOT failure evidence: counting it as staged\n // would fire the all-staged steer and skip the unverified stamp on exactly the rounds that\n // must not present themselves as evidenced.\n if (log.trim() === \"no log available\" || log.trim() === \"\") {\n process.stderr.write(\n `Warning: job ${String(job.id)} has no log available (placeholder body) — not staged\n`,\n );\n continue;\n }\n writeFileSync(join(outDir, `job_${String(job.id)}.log`), log);\n staged += 1;\n } catch (err) {\n process.stderr.write(\n `Warning: failed to download logs for job ${String(job.id)}: ${errMsg(err)} — continuing with the logs retrieved so far\\n`,\n );\n }\n }\n // The failing jobs' identities ride along even when their log bodies cannot: a zero-logs mechanic\n // pass still knows WHICH jobs failed (name + conclusion), so its reproduction instruction has a\n // defined target instead of a bare count. A null name stays null — best-effort, never load-bearing.\n writeFileSync(\n join(outDir, \"failed_jobs.json\"),\n `${JSON.stringify(\n failing.map((j) => ({ name: j.name, conclusion: j.conclusion })),\n null,\n 2,\n )}\\n`,\n );\n if (failing.length > selected.length) {\n process.stderr.write(\n `::warning::${annotationSafe(`${String(failing.length)} failing job(s) in run ${runId}; staged ${String(staged)} of the first ${String(selected.length)} log(s) — the review does not see the rest`)}\\n`,\n );\n }\n if (staged === 0) {\n // stderr, like every other annotation here: this command's STDOUT is the step's $GITHUB_OUTPUT,\n // so a line written there would not render as an annotation and would corrupt the outputs.\n // ::warning:: rather than a plain line because this says the fast-fix route is about to reason\n // without its primary evidence source — the failing logs — which is the thing it exists to read.\n const reported =\n failing.length > 0\n ? `${String(failing.length)} failing job(s) reported`\n : \"no job concluded 'failure' (timeouts or cancellations)\";\n process.stderr.write(\n `::warning::${annotationSafe(\n `No failing-job logs could be staged for run ${runId} (${reported}) — the review must reproduce the failures itself${\n failing.length > 0 ? \" (the failing jobs are listed in failed_jobs.json)\" : \"\"\n }`,\n )}\\n`,\n );\n }\n return { staged, failing: failing.length };\n};\n\nexport const gather = async (\n input: GatherInput,\n ghApi: GhApi = runGhApi,\n gitRun: GitRun = runGit,\n readArtifact: ArtifactReader = ghArtifactReader,\n): Promise<GatherResult> => {\n const candidates = await fetchPrCandidates(input.repo, input.headSha, ghApi);\n const resolution = resolvePr(candidates, input.headBranch);\n if (resolution.kind === \"none\") {\n process.stderr.write(`No open PR for ${input.headSha} — nothing to review\\n`);\n return { kind: \"skip\" };\n }\n if (resolution.kind === \"not-open\") {\n process.stderr.write(\n `PR #${String(resolution.prNumber)} for ${input.headSha} is not open (state: ${resolution.state}) — nothing to review\\n`,\n );\n return { kind: \"skip\" };\n }\n const prNumber = resolution.prNumber;\n\n const meta = await fetchPrMeta(input.repo, prNumber, ghApi);\n\n const stacked = meta.base_ref !== input.defaultBranch;\n\n // pr.diff (base...head) is the review SCOPE — the PR's own change; its endpoint + git-diff fallback\n // are unchanged.\n const prDiff = await (async () => {\n const apiDiff = await fetchApiDiff(input.repo, prNumber, ghApi);\n if (apiDiff !== null && !(apiDiff.length === 0 && meta.changed_files > 0)) return apiDiff;\n process.stderr.write(\n `PR diff fetch failed or was empty for ${String(meta.changed_files)} changed files — falling back to git diff\\n`,\n );\n await gitRun([\"fetch\", \"origin\", input.headSha]);\n return gitRun([\"diff\", meta.base_sha, input.headSha]);\n })();\n\n // full.diff (default...head) is the surface a head checkout exposes over the trusted base — what\n // triage scans and what the checkout produces. Same as pr.diff for a normal PR (base === default);\n // a superset for a stacked one, so only then is a separate fetch needed. commits.json carries the\n // messages/authors a checked-out `git log` exposes, scanned by triage alongside the diff.\n const fullDiff = stacked\n ? await fetchFullDiff(input.repo, input.defaultBranch, input.headSha, ghApi, gitRun)\n : prDiff;\n const commits = await fetchCompareCommits(input.repo, input.defaultBranch, input.headSha, ghApi);\n\n writeFileSync(join(input.outDir, \"full.diff\"), fullDiff);\n writeFileSync(join(input.outDir, \"pr.diff\"), prDiff);\n writeFileSync(join(input.outDir, \"commits.json\"), JSON.stringify(commits));\n writeFileSync(\n join(input.outDir, \"pr_context.json\"),\n JSON.stringify({ title: meta.title, body: meta.body }),\n );\n\n // The three conversation fetches are independent — run them together rather than one after another.\n const [issueRows, reviewCommentRows, reviewRows] = await Promise.all([\n fetchJsonlRows(ghApi, `repos/${input.repo}/issues/${String(prNumber)}/comments`, COMMENT_JQ),\n fetchJsonlRows(\n ghApi,\n `repos/${input.repo}/pulls/${String(prNumber)}/comments`,\n REVIEW_COMMENT_JQ,\n ),\n fetchJsonlRows(ghApi, `repos/${input.repo}/pulls/${String(prNumber)}/reviews`, REVIEW_JQ),\n ]);\n const issueComments = decodeArrayOrNull(IssueCommentCodec, issueRows);\n const reviewComments = decodeArrayOrNull(ReviewCommentCodec, reviewCommentRows);\n const threadComments = decodeArrayOrNull(ThreadCommentCodec, reviewCommentRows);\n const reviews = decodeArrayOrNull(ReviewCodec, reviewRows);\n\n const prior = issueComments === null ? null : priorReviewFrom(issueComments, input.botLogin);\n writeFileSync(\n join(input.outDir, \"prior_review.json\"),\n prior === null ? \"null\" : JSON.stringify(prior),\n );\n // The prior round's findings document, RESOLVED here rather than by seed-draft. The sticky names an\n // artifact instead of carrying the document (issue #217), and fetching it needs the token — which\n // THIS step has and the agentic-review step deliberately does not: that step runs the jailed agent\n // over untrusted PR code, so handing it a repo token to read an artifact would be a bad trade. A\n // failed resolve stages null and the seed degrades to no prior context, exactly like a first round.\n // Two gates, because the seed chain is route-aware on both sides. THIS run must be a full review —\n // the workflow's mechanic branch invokes seed-draft with no --prior-findings at all, so a CI-fix\n // round following a completed review (the routine case that route exists for) would otherwise\n // download and unzip an artifact nothing is ever handed. And the PRIOR must be a full review, since\n // seed-draft discards a mechanic pass's findings: they are not the previous round's.\n const seedsFromPrior =\n input.conclusion === \"success\" &&\n prior !== null &&\n prior.body !== null &&\n isFullReviewAncestry(prior.body);\n const resolvedPrior = seedsFromPrior\n ? await resolvePriorFindings(prior.body, readArtifact)\n : null;\n // The staged file must always be valid JSON. The normalization is defensive against the\n // resolver's contract drifting — a future non-object resolve would make JSON.stringify return\n // undefined and throw in writeFileSync — but it also makes the invariant local to this write\n // rather than borrowed from resolvePriorFindings (issue #233 r4 + r5).\n const priorFindings =\n resolvedPrior !== null && typeof resolvedPrior === \"object\" ? resolvedPrior : null;\n writeFileSync(\n join(input.outDir, \"prior_findings.json\"),\n priorFindings === null ? \"null\" : JSON.stringify(priorFindings),\n );\n // The \"already answered\" registry (issue #151): the prior inline findings whose threads a human\n // reply answered — staged for seed-draft to deliver beside the prior context, so the next-round\n // agent sees what it must not re-raise verbatim. Best-effort like the conversation: a failed fetch\n // yields [] (the agent then relies on the conversation alone).\n const answered =\n threadComments === null ? [] : answeredRegistryFrom(threadComments, input.botLogin);\n writeFileSync(\n join(input.outDir, \"answered.json\"),\n JSON.stringify(answered.map(encodeAnsweredEntry)),\n );\n writeFileSync(\n join(input.outDir, \"pr_conversation.json\"),\n JSON.stringify({\n issue_comments:\n issueComments === null ? [] : issueCommentsFrom(issueComments, input.botLogin),\n review_comments:\n reviewComments === null ? [] : reviewCommentsFrom(reviewComments, input.botLogin),\n reviews: reviews === null ? [] : reviewsFrom(reviews, input.botLogin),\n }),\n );\n\n const jobLogs =\n input.conclusion === \"failure\"\n ? await downloadFailingJobLogs(input.repo, input.runId, input.outDir, ghApi)\n : { staged: 0, failing: 0 };\n\n return {\n kind: \"gathered\",\n pr: prNumber,\n conclusion: input.conclusion,\n diffSize: Buffer.byteLength(prDiff, \"utf8\"),\n stacked,\n baseSha: meta.base_sha,\n stagedJobLogs: jobLogs.staged,\n failingJobs: jobLogs.failing,\n };\n};\n","// Extraction ladder: recovers a schema-conforming candidate (findings or triage) from a native\n// agent-CLI envelope when structured-output enforcement is imperfect or absent. Security rationale:\n// a rung wins only on EXACTLY ONE distinct schema-validating candidate (fenced blocks deduped by\n// canonical value first), which defeats block-injection; disagreeing candidates are refused. Every\n// candidate must pass BOTH gates — ajv (shape + additionalProperties:false) and the registry's io-ts\n// codec (cross-field invariants ajv can't express, e.g. end_line >= start_line).\n\nimport { readFileOrNull, tryParseJson } from \"./util.js\";\nimport { resolve, schemaPathFor, defaultVersion } from \"./registry.js\";\nimport { validateAgainstSchema } from \"./validate.js\";\n\nexport type ExtractKind = \"findings\" | \"triage\";\n\nexport interface ExtractInput {\n readonly kind: ExtractKind;\n // findings only — a documented no-op for triage.\n readonly agentFilePath?: string;\n // Last valid draft snapshot, tried after agentFilePath and before the native envelope.\n readonly agentFileFallbackPath?: string;\n readonly native: unknown;\n}\n\nexport type LadderOutcome =\n | { readonly kind: \"ok\"; readonly version: string; readonly candidate: unknown }\n | { readonly kind: \"error-envelope\"; readonly detail: string }\n | { readonly kind: \"none\"; readonly detail: string }\n | { readonly kind: \"ambiguous\"; readonly detail: string };\n\ninterface NativeForExtraction {\n readonly result: unknown;\n readonly structuredOutput: unknown;\n readonly isError: unknown;\n readonly subtype: unknown;\n readonly apiErrorStatus: unknown;\n}\n\nconst fieldOf = (raw: unknown, key: string): unknown =>\n typeof raw === \"object\" && raw !== null && key in raw\n ? (raw as Record<string, unknown>)[key]\n : undefined;\n\nconst parseNativeForExtraction = (raw: unknown): NativeForExtraction => ({\n result: fieldOf(raw, \"result\"),\n structuredOutput: fieldOf(raw, \"structured_output\"),\n isError: fieldOf(raw, \"is_error\"),\n subtype: fieldOf(raw, \"subtype\"),\n apiErrorStatus: fieldOf(raw, \"api_error_status\"),\n});\n\nconst isNullish = (value: unknown): boolean => value === null || value === undefined;\n\nconst isErrorEnvelope = (native: NativeForExtraction): boolean =>\n native.isError === true ||\n (!isNullish(native.subtype) && native.subtype !== \"success\") ||\n !isNullish(native.apiErrorStatus);\n\nconst describeErrorEnvelope = (native: NativeForExtraction): string => {\n const parts: readonly string[] = [\n ...(native.isError === true ? [\"is_error=true\"] : []),\n ...(!isNullish(native.subtype) && native.subtype !== \"success\"\n ? [`subtype=${JSON.stringify(native.subtype)}`]\n : []),\n ...(!isNullish(native.apiErrorStatus)\n ? [`api_error_status=${JSON.stringify(native.apiErrorStatus)}`]\n : []),\n ];\n return `agent run did not complete successfully (${parts.join(\", \")})`;\n};\n\nexport const withDefaultSchemaVersion = (candidate: unknown): unknown =>\n typeof candidate === \"object\" &&\n candidate !== null &&\n !Array.isArray(candidate) &&\n !(\"schema_version\" in candidate)\n ? { ...candidate, schema_version: defaultVersion(\"findings\") }\n : candidate;\n\nconst normalizeCandidate = (kind: ExtractKind, candidate: unknown): unknown =>\n kind === \"findings\" ? withDefaultSchemaVersion(candidate) : candidate;\n\nconst candidateVersion = (kind: ExtractKind, candidate: unknown): string | undefined => {\n if (kind !== \"findings\") return undefined;\n const version = fieldOf(candidate, \"schema_version\");\n return typeof version === \"string\" ? version : undefined;\n};\n\nconst safeSchemaPathFor = (kind: ExtractKind, version: string | undefined): string | null => {\n try {\n return schemaPathFor(kind, version);\n } catch {\n return null;\n }\n};\n\ninterface GatedCandidate {\n readonly version: string;\n // Pre-registry-normalize (identical for alpha) — what the extract CLI prints, per the registry seam.\n readonly candidate: unknown;\n}\n\n// Sort keys recursively so two values differing only in key order canonicalize equal.\nconst canonicalize = (value: unknown): unknown =>\n Array.isArray(value)\n ? value.map(canonicalize)\n : value !== null && typeof value === \"object\"\n ? Object.fromEntries(\n Object.entries(value as Record<string, unknown>)\n .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))\n .map(([k, v]) => [k, canonicalize(v)]),\n )\n : value;\n\n// A model re-emitting its answer verbatim is benign, not a conflict; candidates differing in any\n// value stay distinct, so the injection defense (refusing a survivor among disagreeing candidates) holds.\nconst dedupCandidates = (candidates: readonly GatedCandidate[]): readonly GatedCandidate[] => {\n const seen = new Set<string>();\n return candidates.filter((c) => {\n const key = JSON.stringify(canonicalize(c.candidate));\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n};\n\n// Both gates: ajv (shape + injection defense) then the registry's io-ts codec (materialization +\n// cross-field invariants). Null when either rejects.\nconst gateCandidate = (kind: ExtractKind, rawCandidate: unknown): GatedCandidate | null => {\n const candidate = normalizeCandidate(kind, rawCandidate);\n const schemaPath = safeSchemaPathFor(kind, candidateVersion(kind, candidate));\n if (schemaPath === null) return null;\n if (!validateAgainstSchema(candidate, schemaPath).valid) return null;\n const resolution = resolve(kind, candidate);\n return resolution.kind === \"ok\" ? { version: resolution.version, candidate } : null;\n};\n\nconst candidateFromJsonText = (kind: ExtractKind, text: string | null): GatedCandidate | null => {\n if (text === null) return null;\n const parsed = tryParseJson(text);\n return parsed.ok ? gateCandidate(kind, parsed.value) : null;\n};\n\ninterface FenceScanState {\n readonly blocks: readonly string[];\n readonly openLength: number | null;\n readonly buffer: readonly string[];\n}\n\nconst FENCE_OPEN = /^\\s*(`{3,})/;\nconst FENCE_MARKER_ONLY = /^`+$/;\n\n// Line-based by design — no regex spans more than one line, so no catastrophic-backtracking surface.\nconst scanLine = (state: FenceScanState, line: string): FenceScanState => {\n if (state.openLength === null) {\n const opened = FENCE_OPEN.exec(line)?.[1]?.length;\n return opened !== undefined ? { blocks: state.blocks, openLength: opened, buffer: [] } : state;\n }\n const trimmed = line.trim();\n const closes = FENCE_MARKER_ONLY.test(trimmed) && trimmed.length >= state.openLength;\n return closes\n ? { blocks: [...state.blocks, state.buffer.join(\"\\n\")], openLength: null, buffer: [] }\n : { ...state, buffer: [...state.buffer, line] };\n};\n\nexport const scanFencedBlocks = (text: string): readonly string[] =>\n text.split(\"\\n\").reduce(scanLine, { blocks: [], openLength: null, buffer: [] }).blocks;\n\n// Operator-facing trace for stderr/logs (never the fail-closed reasons, which stay generic): e.g. a\n// null structured_output points at a CLI not enforcing --json-schema.\nexport const ladderFailureDiagnostics = (input: ExtractInput): string => {\n const native = parseNativeForExtraction(input.native);\n const preview = (s: string): string => {\n const flat = s.replace(/\\s+/g, \" \").trim();\n return flat.length > 200 ? `${flat.slice(0, 200)}…` : flat;\n };\n const lines: string[] = [];\n if (input.kind === \"findings\") {\n lines.push(\n input.agentFilePath === undefined\n ? \"agent-file rung: no --agent-file given\"\n : `agent-file rung: ${input.agentFilePath} did not validate (or was unreadable)`,\n );\n if (input.agentFileFallbackPath !== undefined)\n lines.push(\n `last-valid rung: ${input.agentFileFallbackPath} did not validate (or was absent)`,\n );\n }\n lines.push(\n isNullish(native.structuredOutput)\n ? \"structured_output rung: absent (null) — the CLI's --json-schema likely did not enforce\"\n : \"structured_output rung: present but did not validate against the schema\",\n );\n lines.push(\n typeof native.result === \"string\"\n ? `result rung: ${String(native.result.length)} chars, ${String(scanFencedBlocks(native.result).length)} fenced JSON block(s), none validated; preview: ${preview(native.result)}`\n : \"result rung: absent or not a string\",\n );\n return lines.join(\"\\n\");\n};\n\nexport const describeLadderFailure = (outcome: Exclude<LadderOutcome, { kind: \"ok\" }>): string => {\n switch (outcome.kind) {\n case \"error-envelope\":\n return `review did not complete: ${outcome.detail}`;\n case \"none\":\n return `could not recover a validating candidate: ${outcome.detail}`;\n case \"ambiguous\":\n return `ambiguous candidates: ${outcome.detail}`;\n }\n};\n\nconst okOutcome = (gated: GatedCandidate): LadderOutcome => ({\n kind: \"ok\",\n version: gated.version,\n candidate: gated.candidate,\n});\n\n// Pure aside from an optional --agent-file read.\nexport const extractStructured = (input: ExtractInput): LadderOutcome => {\n const native = parseNativeForExtraction(input.native);\n\n // The agent-file and its last-valid snapshot are self-validated deliverables written OUTSIDE the\n // worktree (a PR can't plant them) and checkpointed by us during the run, so they outrank an error\n // envelope: a run that errored (max-turns, a captured API error) after producing a valid draft\n // should still post it, not \"did not complete\". The error-envelope short-circuit below still guards\n // the less-trusted native rungs (structured_output/result).\n if (input.kind === \"findings\") {\n for (const path of [input.agentFilePath, input.agentFileFallbackPath]) {\n if (path === undefined) continue;\n const fromFile = candidateFromJsonText(input.kind, readFileOrNull(path));\n if (fromFile) return okOutcome(fromFile);\n }\n }\n\n if (isErrorEnvelope(native)) {\n return { kind: \"error-envelope\", detail: describeErrorEnvelope(native) };\n }\n\n if (native.structuredOutput !== undefined) {\n const fromStructured = gateCandidate(input.kind, native.structuredOutput);\n if (fromStructured) return okOutcome(fromStructured);\n }\n\n if (typeof native.result === \"string\") {\n const fromResult = candidateFromJsonText(input.kind, native.result.trim());\n if (fromResult) return okOutcome(fromResult);\n\n const fencedCandidates = dedupCandidates(\n scanFencedBlocks(native.result)\n .map((block) => candidateFromJsonText(input.kind, block))\n .filter((gated): gated is GatedCandidate => gated !== null),\n );\n\n const [survivor, ...rest] = fencedCandidates;\n if (survivor !== undefined && rest.length === 0) return okOutcome(survivor);\n if (survivor !== undefined) {\n return {\n kind: \"ambiguous\",\n detail: `${String(fencedCandidates.length)} distinct fenced JSON blocks each validate against the ${input.kind} schema — refusing to pick one`,\n };\n }\n }\n\n const fallbackRung = input.agentFileFallbackPath ? \", last-valid snapshot\" : \"\";\n return {\n kind: \"none\",\n detail: `no --agent-file${fallbackRung}, structured_output, JSON result, or fenced block validated against the ${input.kind} schema`,\n };\n};\n","// Maps a coding-agent CLI's native result envelope onto the abstract envelope. An absent native\n// (undefined/null — the caller couldn't read/parse it, e.g. a wall-clock kill hit `claude -p`\n// mid-flush) still recovers findings from --agent-file and refills telemetry from the transcript\n// fallback; a present-but-wrong-shaped native is a Left. Never throws.\n\nimport * as t from \"io-ts\";\nimport type { Either } from \"fp-ts/Either\";\nimport { resolve } from \"./registry.js\";\nimport { extractStructured, describeLadderFailure } from \"./extract.js\";\nimport { DEFAULT_SCHEMA_VERSION, incompleteFindings } from \"./schema.js\";\nimport type { Findings, ModelUsageEntry, ResultEnvelope } from \"./schema.js\";\nimport { modelIdentity } from \"./util.js\";\n\n// No value-level fp-ts import: a bare \"fp-ts/Either\" subpath import breaks under strict Node ESM\n// (fp-ts ships no \"exports\" map), so Either values are plain tagged literals, as in validate.ts.\nconst left = <A>(message: string): Either<string, A> => ({ _tag: \"Left\", left: message });\nconst right = <A>(value: A): Either<string, A> => ({ _tag: \"Right\", right: value });\n\nexport type AdapterName = \"claude-code\";\n\nexport const isAdapterName = (name: string): name is AdapterName => name === \"claude-code\";\n\nconst ClaudeCodeModelUsageEntryCodec = t.intersection([\n t.type({\n inputTokens: t.number,\n outputTokens: t.number,\n }),\n t.partial({\n cacheReadInputTokens: t.number,\n cacheCreationInputTokens: t.number,\n costUSD: t.number,\n }),\n]);\n\nexport const ClaudeCodeEnvelopeCodec = t.intersection([\n t.type({\n modelUsage: t.record(t.string, ClaudeCodeModelUsageEntryCodec),\n num_turns: t.number,\n duration_ms: t.number,\n }),\n t.partial({\n total_cost_usd: t.union([t.number, t.null]),\n structured_output: t.unknown,\n }),\n]);\n\ntype ClaudeCodeEnvelope = t.TypeOf<typeof ClaudeCodeEnvelopeCodec>;\n\nconst sumUsage = (into: ModelUsageEntry, entry: ModelUsageEntry): ModelUsageEntry => ({\n ...into,\n input_tokens: into.input_tokens + entry.input_tokens,\n output_tokens: into.output_tokens + entry.output_tokens,\n ...(into.cache_read_tokens !== undefined || entry.cache_read_tokens !== undefined\n ? { cache_read_tokens: (into.cache_read_tokens ?? 0) + (entry.cache_read_tokens ?? 0) }\n : {}),\n ...(into.cache_write_tokens !== undefined || entry.cache_write_tokens !== undefined\n ? { cache_write_tokens: (into.cache_write_tokens ?? 0) + (entry.cache_write_tokens ?? 0) }\n : {}),\n});\n\n// The agent keys modelUsage by the CONFIGURED model id, so it carries any context-window suffix the\n// caller declared. Keying the fold by the model's identity (see modelIdentity) both canonicalizes it\n// and folds together the rows a mixed configuration splits, in one pass; order follows first\n// appearance, as it did when this was a plain map.\nconst mapModelUsage = (modelUsage: ClaudeCodeEnvelope[\"modelUsage\"]): ModelUsageEntry[] => [\n ...Object.entries(modelUsage)\n .reduce<Map<string, ModelUsageEntry>>((byModel, [configuredModelId, entry]) => {\n const model = modelIdentity(configuredModelId);\n const mapped: ModelUsageEntry = {\n model,\n input_tokens: entry.inputTokens,\n output_tokens: entry.outputTokens,\n ...(entry.cacheReadInputTokens !== undefined\n ? { cache_read_tokens: entry.cacheReadInputTokens }\n : {}),\n ...(entry.cacheCreationInputTokens !== undefined\n ? { cache_write_tokens: entry.cacheCreationInputTokens }\n : {}),\n };\n const prior = byModel.get(model);\n return byModel.set(model, prior === undefined ? mapped : sumUsage(prior, mapped));\n }, new Map())\n .values(),\n];\n\nexport interface TranscriptTelemetry {\n readonly models: readonly ModelUsageEntry[];\n readonly turns: number;\n readonly durationMs: number;\n}\n\n// transcriptFallback is a THUNK — the read can be megabytes on a large fan-out, so callers pass it\n// only when a transcript path was given.\nexport interface RunMeta {\n readonly route?: string;\n readonly effort?: string;\n readonly transcriptFallback?: () => TranscriptTelemetry;\n // Last valid draft snapshot, recovered when the live agent-file no longer validates (e.g. a\n // wall-kill truncated it).\n readonly agentFileFallbackPath?: string;\n // The agent-file still holds the pipeline's pre-seed SENTINEL (the agent died without writing a\n // review), decided by the caller from the file's content — the sentinel never validates, so no\n // rung can recover it as a review (issue #127). The flag only refines the \"did not complete\"\n // notice's message; the ladder still runs, so a real review living in the native envelope is\n // recovered rather than discarded with the seed.\n readonly seedUnrevised?: boolean;\n}\n\n// Every ladder outcome maps onto a findings result, never a fatal one — a findings miss must not\n// drop telemetry.\ntype FindingsOutcome =\n | { readonly kind: \"ok\"; readonly version: string; readonly findings: Findings }\n | { readonly kind: \"telemetry-only\"; readonly reason: string };\n\nconst findingsOutcome = (\n native: unknown,\n agentFilePath: string | undefined,\n agentFileFallbackPath: string | undefined,\n): FindingsOutcome => {\n const ladder = extractStructured({\n kind: \"findings\",\n native,\n agentFilePath,\n agentFileFallbackPath,\n });\n if (ladder.kind !== \"ok\")\n return { kind: \"telemetry-only\", reason: describeLadderFailure(ladder) };\n // Re-resolving materializes the typed, normalized value the ladder deliberately didn't keep.\n const resolution = resolve(\"findings\", ladder.candidate);\n return resolution.kind === \"ok\"\n ? { kind: \"ok\", version: resolution.version, findings: resolution.value }\n : {\n kind: \"telemetry-only\",\n reason:\n \"internal error: the extraction ladder validated a candidate the registry then rejected\",\n };\n};\n\ninterface Telemetry {\n readonly models: ModelUsageEntry[];\n readonly turns: number;\n readonly duration_ms: number;\n readonly vendor_cost_usd: number | null;\n readonly route?: string;\n readonly effort?: string;\n}\n\nconst withMeta = (base: Omit<Telemetry, \"route\" | \"effort\">, meta: RunMeta): Telemetry => ({\n ...base,\n ...(meta.route ? { route: meta.route } : {}),\n ...(meta.effort ? { effort: meta.effort } : {}),\n});\n\n// Each field from whichever source is authoritative for it — NOT always the transcript:\n// - Wall + turns: the transcript when available. The native envelope reports only the main agent's\n// active time/turns and wildly under-reports a fan-out (a 12-subagent ~12-min run reads as \"5\n// turns, 42s\"); the transcript tree spans the whole session.\n// - Per-model usage: native-authoritative when present. Summing the transcript's per-message usage\n// under-counts output badly (measured ~5.7× low), so DO NOT \"simplify\" this to always-transcript;\n// the transcript refills usage ONLY when the native has none (a `timeout` kill left it empty).\n// The vendor's own cost figure is carried through from the native whenever it had one.\nconst resolveTelemetry = (\n native: {\n models: ModelUsageEntry[];\n turns: number;\n durationMs: number;\n vendorCostUsd: number | null;\n },\n meta: RunMeta,\n): Telemetry => {\n // A thunk that throws degrades to \"no transcript\" (the native's own figures) — never fails adapt.\n const fb = ((): TranscriptTelemetry | undefined => {\n try {\n return meta.transcriptFallback?.();\n } catch {\n return undefined;\n }\n })();\n // Wall + turns move together — never one source for turns and another for the wall.\n const wallTurns =\n fb !== undefined && fb.durationMs > 0\n ? { turns: fb.turns, duration_ms: fb.durationMs }\n : { turns: native.turns, duration_ms: native.durationMs };\n return withMeta(\n {\n models: native.models.length > 0 ? native.models : fb ? [...fb.models] : native.models,\n ...wallTurns,\n vendor_cost_usd: native.vendorCostUsd,\n },\n meta,\n );\n};\n\nconst nativeTelemetry = (native: ClaudeCodeEnvelope, meta: RunMeta): Telemetry =>\n resolveTelemetry(\n {\n models: mapModelUsage(native.modelUsage),\n turns: native.num_turns,\n durationMs: native.duration_ms,\n vendorCostUsd: native.total_cost_usd ?? null,\n },\n meta,\n );\n\n// Native absent/unreadable (a wall-clock kill can leave no parseable envelope): the transcript\n// fallback refills real spend when present, else zeros. The findings ladder still runs (its\n// --agent-file rung needs no native), so a checkpointed $DRAFT survives the cutoff.\nconst absentTelemetry = (meta: RunMeta): Telemetry =>\n resolveTelemetry({ models: [], turns: 0, durationMs: 0, vendorCostUsd: null }, meta);\n\n// A ladder miss becomes a \"did not complete\" notice, never a discarded envelope.\nconst buildEnvelope = (\n telemetry: Telemetry,\n native: unknown,\n agentFilePath: string | undefined,\n agentFileFallbackPath: string | undefined,\n seedUnrevised: boolean,\n): ResultEnvelope => {\n // The sentinel never validates, so the ladder cannot recover the pre-seed from the agent-file or\n // last-valid rungs — but it still runs: a REAL review the agent produced in the native envelope\n // (structured_output/result) is recovered, not discarded with the seed. Only the miss is\n // re-worded: the untouched sentinel names the cause precisely (issue #127).\n // The run's completion instant (issue #170), stamped once here so cost recomputation prices a\n // time-slotted model deterministically at the run's UTC time rather than at each command's wall clock.\n const generated_at = new Date().toISOString();\n const outcome = findingsOutcome(native, agentFilePath, agentFileFallbackPath);\n switch (outcome.kind) {\n case \"ok\":\n return {\n schema_version: outcome.version,\n findings: outcome.findings,\n generated_at,\n ...telemetry,\n };\n case \"telemetry-only\": {\n const reason = seedUnrevised\n ? \"the review agent did not write a review (its draft is still the pre-seeded sentinel)\"\n : outcome.reason;\n return {\n schema_version: DEFAULT_SCHEMA_VERSION,\n findings: incompleteFindings(`### ⚠️ Review did not complete\\n\\n${reason}`),\n incomplete: true,\n generated_at,\n ...telemetry,\n };\n }\n }\n};\n\n// native undefined/null ⇒ the caller couldn't read/parse the envelope: emit a no-telemetry envelope\n// and still recover findings from --agent-file, rather than failing the run. A present but\n// wrong-shaped native is a Left (a real adapter mismatch).\nexport const adapt = (\n adapterName: AdapterName,\n native: unknown,\n agentFilePath?: string,\n meta: RunMeta = {},\n): Either<string, ResultEnvelope> => {\n switch (adapterName) {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- exhaustive by design; AdapterName grows (e.g. \"opencode\") without collapsing this switch to an if\n case \"claude-code\": {\n if (native === undefined || native === null)\n return right(\n buildEnvelope(\n absentTelemetry(meta),\n undefined,\n agentFilePath,\n meta.agentFileFallbackPath,\n meta.seedUnrevised === true,\n ),\n );\n const decoded = ClaudeCodeEnvelopeCodec.decode(native);\n if (decoded._tag === \"Left\")\n return left(\"native envelope does not match the Claude Code output shape\");\n return right(\n buildEnvelope(\n nativeTelemetry(decoded.right, meta),\n native,\n agentFilePath,\n meta.agentFileFallbackPath,\n meta.seedUnrevised === true,\n ),\n );\n }\n }\n};\n","// The review agent's whole hook discipline as one --settings file (data, not shell): the Stop\n// deliverable gate + the two budget hooks (one self-dispatching command wired to both tool events).\n\nimport { defaultHookCommand } from \"./stop-gate.js\";\nimport { budgetHookCommand } from \"./budget.js\";\n\ninterface CommandHook {\n readonly type: \"command\";\n readonly command: string;\n}\ninterface HookEntry {\n readonly hooks: readonly CommandHook[];\n}\n\n// PreToolUse/PostToolBatch carry no matcher — they run for every tool; the CLI decides per tool_name.\nexport interface ReviewHookSettings {\n readonly hooks: {\n readonly Stop: readonly HookEntry[];\n readonly PreToolUse: readonly HookEntry[];\n readonly PostToolBatch: readonly HookEntry[];\n };\n}\n\nexport interface ComposeSettingsOptions {\n readonly draftPath: string;\n readonly stop: {\n readonly kind?: string;\n readonly schema?: string;\n readonly schemaVersion?: string;\n readonly maxNudges?: string;\n readonly counter?: string;\n };\n readonly budget: {\n readonly budgetUsd?: string;\n readonly wall?: string;\n readonly prices?: string;\n readonly reserveFrac?: string;\n readonly reserveGrowth?: string;\n readonly reserveUsd?: string;\n readonly reserveWall?: string;\n };\n}\n\n// The budget command self-dispatches on the stdin event, so it is built once and wired to both.\nexport const composeReviewSettings = (opts: ComposeSettingsOptions): ReviewHookSettings => {\n const budgetCommand = budgetHookCommand(opts.draftPath, opts.budget);\n return {\n hooks: {\n Stop: [\n { hooks: [{ type: \"command\", command: defaultHookCommand(opts.draftPath, opts.stop) }] },\n ],\n PreToolUse: [{ hooks: [{ type: \"command\", command: budgetCommand }] }],\n PostToolBatch: [{ hooks: [{ type: \"command\", command: budgetCommand }] }],\n },\n };\n};\n","// The untrusted review agent's network jail as one sandbox-runtime (`srt`) settings file (data, not\n// shell). The allowlist is the model endpoint the CLI actually dials plus the GitHub API/host and any\n// consumer-supplied hosts; the host-side proxy denies everything else. Filesystem isolation is off —\n// the threat this closes is network exfil of the burner key, not the throwaway runner's disk — so the\n// jail confines only egress while the agent still reads the worktree and writes its draft freely.\n\nexport interface SandboxConfig {\n readonly network: {\n readonly allowedDomains: readonly string[];\n readonly deniedDomains: readonly string[];\n };\n readonly filesystem: {\n readonly allowRead: readonly string[];\n readonly denyRead: readonly string[];\n readonly allowWrite: readonly string[];\n readonly denyWrite: readonly string[];\n };\n}\n\n// GitHub hosts the agent may reach when it shells out to gh/git during a review.\nconst GITHUB_HOSTS = [\"api.github.com\", \"github.com\"] as const;\n\n// The model host from api_base_url (ANTHROPIC_BASE_URL) — the single source of truth for the endpoint\n// the CLI dials, rather than a hardcoded vendor. Bare hostname (no scheme/port/path) to match the\n// proxy's hostname rule. Throws rather than yield an empty entry that would deny the model itself.\nexport const deriveModelHost = (apiBaseUrl: string): string => {\n const host = URL.canParse(apiBaseUrl) ? new URL(apiBaseUrl).hostname : \"\";\n if (host === \"\") {\n throw new Error(\n `could not derive the model host from api_base_url ${JSON.stringify(apiBaseUrl)} — expected a URL like https://api.deepseek.com/anthropic`,\n );\n }\n return host;\n};\n\n// Built-in model-provider host suffixes the derived allowlist entry is expected to match. The jail\n// auto-derives its sole egress allowlist from api_base_url, so a typo'd or stale value now fails OPEN —\n// it dials, and hands MODEL_API_KEY to, whatever host that variable names (the old fixed, PR-reviewed\n// allowlist failed CLOSED instead). A derived host outside these providers (and any consumer-declared\n// host) is warned about loudly by the `sandbox-config` command, or rejected under `--strict-host`.\nconst KNOWN_MODEL_HOST_SUFFIXES = [\"anthropic.com\", \"deepseek.com\"] as const;\n\n// True when host is a SUBDOMAIN of a built-in provider (the model API always lives on a subdomain like\n// api.*, so the bare registrable domain is itself treated as a typo — e.g. a dropped \"api.\" — and the\n// `.`-prefixed suffix keeps the boundary honest, so notanthropic.com and api.anthropic.com.evil.com are\n// both unknown), or an EXACT match for a consumer-declared host. A consumer on another provider declares\n// their host so it passes while a typo of it (a different exact string) does not. Both sides are\n// normalized (lowercased, trailing FQDN dot dropped) so a case/dot variant of a declared host still\n// matches — deriveModelHost returns a URL-parser-lowercased hostname while a declared token is as typed.\nexport const isKnownModelHost = (host: string, declared: readonly string[] = []): boolean => {\n const normalize = (h: string): string => h.replace(/\\.$/, \"\").toLowerCase();\n const target = normalize(host);\n return (\n declared.some((d) => normalize(d) === target) ||\n KNOWN_MODEL_HOST_SUFFIXES.some((suffix) => target.endsWith(`.${suffix}`))\n );\n};\n\n// The consumer's extra_endpoints: the same whitespace-separated host[:port] list they already pass to\n// harden-runner. Ports are dropped — the proxy matches on hostname (the only form validated on the\n// runner), and for HTTPS-only egress a port scope adds nothing.\nexport const parseExtraEndpoints = (extra: string): readonly string[] =>\n extra\n .split(/\\s+/)\n .map((token) => token.replace(/:\\d+$/, \"\"))\n .filter((token) => token.length > 0);\n\nexport const buildSandboxConfig = (opts: {\n readonly apiBaseUrl: string;\n readonly extra?: string;\n}): SandboxConfig => ({\n network: {\n allowedDomains: [\n ...new Set([\n deriveModelHost(opts.apiBaseUrl),\n ...GITHUB_HOSTS,\n ...parseExtraEndpoints(opts.extra ?? \"\"),\n ]),\n ],\n deniedDomains: [],\n },\n filesystem: { allowRead: [], denyRead: [], allowWrite: [\"/\"], denyWrite: [] },\n});\n","// The `scope` workflow input — the languages/inputs a project accepts — surfaced to the review agent\n// so it can triage \"is this input a program the project accepts?\" BEFORE assigning severities (issue\n// #139). Pure parse + grammar; the CLI's `check-scope` command is the only caller, so the grammar the\n// prompt is built from and the grammar the tests pin are the same code.\n\nimport { UNSAFE_IN_SUMMARY } from \"./notice.js\";\n\n// A scope value is spliced into the review agent's system prompt, so the characters that break prompt\n// structure are rejected — the same render-safety denylist notice.ts uses for summary text (newline/\n// carriage-return start a new block, a backtick closes a code span, `<`/`>` close an HTML comment, `|`\n// breaks a markdown table). The value is trusted consumer config, but a malformed splice would silently\n// corrupt the instruction. Everything else printable and structure-safe is accepted (C++, C#, C/C++,\n// Objective-C). A multi-word name is not a unit here — whitespace separates tokens, so spell a\n// multi-word name with a dash (e.g. \"visual-basic\") or list its words separately.\n\nexport type ScopeParse =\n // Empty/whitespace — no declared scope; the reviewer infers it from the README's first paragraph.\n | { readonly kind: \"absent\" }\n | { readonly kind: \"ok\"; readonly languages: readonly string[] }\n // Malformed — the CLI fails loudly so a config typo surfaces, never a corrupted prompt.\n | { readonly kind: \"invalid\"; readonly reason: string };\n\n// Whitespace, commas, and semicolons are interchangeable separators (\"C C++\", \"c, c++\", \"python; rust\").\n// The separator consumes surrounding whitespace, so a split token carries none (no per-token trim).\nconst SCOPE_SEPARATOR_RE = /[\\s,;]+/;\n\nexport const parseScope = (raw: string | undefined): ScopeParse => {\n const trimmed = raw?.trim();\n if (trimmed === undefined || trimmed === \"\") return { kind: \"absent\" };\n if (UNSAFE_IN_SUMMARY.test(trimmed)) {\n return {\n kind: \"invalid\",\n reason:\n 'scope contains a character (newline, carriage return, backtick, \"<\", \">\", or \"|\") that would corrupt the review prompt — use plain language names/tags',\n };\n }\n // De-duplicate preserving first-seen order; a value that was only separators (\" , ; \") declares\n // nothing, so it reads as absent rather than an empty scope.\n const languages = Array.from(new Set(trimmed.split(SCOPE_SEPARATOR_RE).filter((t) => t !== \"\")));\n return languages.length === 0 ? { kind: \"absent\" } : { kind: \"ok\", languages };\n};\n","#!/usr/bin/env node\n// CLI entry point — the citty subcommands wired in `main` at the bottom.\n\n/* eslint-disable @typescript-eslint/require-await */\n// citty requires async run() even when the body has no explicit await\n\nimport { defineCommand, runMain } from \"citty\";\nimport { copyFileSync, readFileSync, statSync, writeFileSync } from \"node:fs\";\nimport { randomBytes } from \"node:crypto\";\nimport { resolve } from \"node:path\";\nimport type { Either } from \"fp-ts/Either\";\nimport { render, isConvergenceRound, isReviewVerdict } from \"./render.js\";\nimport { buildInlineComments, renderStraysSection } from \"./inline.js\";\nimport { computeCost, parseInstant } from \"./cost.js\";\nimport { readTranscriptTree, sumTranscriptUsage } from \"./transcript.js\";\nimport {\n evaluateBudgetHook,\n parseWallMs,\n parseFraction,\n parseEpochSecMs,\n anchoredElapsedMs,\n deadlineEpochSec,\n mainHasWrittenDraft,\n isSeedSentinel,\n SEED_SENTINEL,\n priorContextPath,\n priorAnswersPath,\n priorSuppressedPath,\n lastValidPath,\n isSubagentHookInput,\n DEFAULT_RESERVE,\n DEADLINE_ENV,\n} from \"./budget.js\";\nimport { decodeAnsweredEntry, isAnsweredDrop, type StagedAnsweredEntry } from \"./answered.js\";\nimport { validateAgainstSchema, unsafeUnwrap } from \"./validate.js\";\nimport { formatUtc } from \"./format.js\";\nimport {\n ResultEnvelopeCodec,\n FindingsCodec,\n PriceMapCodec,\n ScopeMetastasisCodec,\n TestSummaryCodec,\n isIncompleteFindings,\n RECOVERABLE_OPTIONAL_FIELDS,\n DEFAULT_SCHEMA_VERSION,\n anchoredSchemaVersionPattern,\n resolveFindingId,\n} from \"./schema.js\";\nimport type { Triage, Finding, Findings, PriceMap } from \"./schema.js\";\nimport {\n buildConvergence,\n computeScopeMetastasis,\n SURFACE_SCHEMA_VERSION,\n isBelowVisibilityFloor,\n isFullReviewAncestry,\n parseReviewedSha,\n priorTrajectory,\n priorBelowFloorNits,\n stripSurfaceFields,\n parseFindingsMarker,\n} from \"./surface.js\";\nimport {\n buildNoticeEnvelope,\n buildUnknownNoticeEnvelope,\n isNoticeKind,\n parseAgentAllowlist,\n NOTICE_KINDS,\n} from \"./notice.js\";\nimport { announce, loadClocDiff, post, reportIncomplete } from \"./post.js\";\nimport { type CheckIntent, checkRun } from \"./checkrun.js\";\nimport { parseCommand, renderCommandOutputs, safeHeredocDelim } from \"./command.js\";\nimport { react, isReaction, REACTIONS } from \"./react.js\";\nimport type { Reaction } from \"./react.js\";\nimport { awaitCiConclusion, renderCiOutputs } from \"./ci.js\";\nimport { gather, renderOutputs } from \"./gather.js\";\nimport { adapt, isAdapterName } from \"./adapt.js\";\nimport type { AdapterName, TranscriptTelemetry } from \"./adapt.js\";\nimport { extractStructured, describeLadderFailure, ladderFailureDiagnostics } from \"./extract.js\";\nimport type { ExtractKind, LadderOutcome } from \"./extract.js\";\nimport {\n schemaPathFor,\n declaredVersion,\n resolveTolerantFindings,\n defaultVersion,\n} from \"./registry.js\";\nimport type { SchemaKind } from \"./registry.js\";\nimport { validatePatch } from \"./patch.js\";\nimport {\n decideGate,\n draftState,\n readNudges,\n bumpNudges,\n defaultHookCommand,\n stopHookSettings,\n} from \"./stop-gate.js\";\nimport { composeReviewSettings } from \"./settings.js\";\nimport {\n buildSandboxConfig,\n deriveModelHost,\n isKnownModelHost,\n parseExtraEndpoints,\n} from \"./sandbox.js\";\nimport { parseScope } from \"./scope.js\";\nimport { annotationSafe, asRecord, errMsg, readFileOrNull, tryParseJson } from \"./util.js\";\n\n// The seed's upcast (the registry's resolveTolerantFindings — the ONE place the migration policy\n// lives): the ajv gate then validates the UPCAST value, never the raw doc: validating the raw legacy\n// doc against the 0.10 schema would reject every pre-0.10 prior and seed the sentinel-only cold\n// re-review the migration exists to prevent.\nconst resolvedPriorValue = resolveTolerantFindings;\n\nconst readJSON = (path: string): unknown => {\n try {\n return JSON.parse(readFileSync(resolve(path), \"utf-8\")) as unknown;\n } catch (err) {\n return fail(`Cannot read ${path}: ${errMsg(err)}`);\n }\n};\n\nconst fail = (msg: string): never => {\n process.stderr.write(`${msg}\\n`);\n process.exit(1);\n};\n\n/** Tolerant `readJSON`: returns `undefined` (never exits) when the file is unreadable, empty, or not\n * valid JSON, naming the specific cause on stderr. Used only for `adapt`'s native envelope, which a\n * wall-clock kill can leave empty/truncated — `adapt` then degrades to no telemetry rather than\n * crashing the review step. */\nconst readJSONOrAbsent = (path: string): unknown => {\n const read = ((): { readonly text: string } | { readonly error: string } => {\n try {\n return { text: readFileSync(resolve(path), \"utf-8\") };\n } catch (err) {\n return { error: errMsg(err) };\n }\n })();\n if (\"error\" in read) {\n process.stderr.write(\n `code-review: native envelope ${path} could not be read (${read.error}) — proceeding with no native telemetry\\n`,\n );\n return undefined;\n }\n if (read.text.trim() === \"\") {\n process.stderr.write(\n `code-review: native envelope ${path} is empty — proceeding with no native telemetry\\n`,\n );\n return undefined;\n }\n try {\n return JSON.parse(read.text) as unknown;\n } catch (err) {\n process.stderr.write(\n `code-review: native envelope ${path} is not valid JSON (${errMsg(err)}) — proceeding with no native telemetry\\n`,\n );\n return undefined;\n }\n};\n\n// The optional sandbox config a notice names its allowlist from. A MISSING/unreadable file is the\n// normal early-failure case (the jail is set up after triage), so it stays silent and is treated as\n// absent. A file that is PRESENT but unparseable is the diagnostic case this feature exists for (a\n// truncated or agent-tampered config), so it warns rather than vanishing. Either way ⇒ undefined, and\n// the notice omits the allowlist rather than crashing the assemble step.\nconst readSandboxConfigForNotice = (path: string): unknown => {\n const text = readFileOrNull(resolve(path));\n if (text === null) return undefined;\n const parsed = tryParseJson(text);\n if (!parsed.ok) {\n process.stderr.write(\n `::warning::${annotationSafe(`code-review notice: ${path} is present but not valid JSON — omitting the agent allowlist from the notice`)}\\n`,\n );\n return undefined;\n }\n return parsed.value;\n};\n\nconst readStdinJSON = (): unknown => {\n if (process.stdin.isTTY) return null;\n const raw = ((): string => {\n try {\n return readFileSync(0, \"utf-8\");\n } catch {\n return \"\";\n }\n })();\n if (raw.trim() === \"\") return null;\n const parsed = tryParseJson(raw);\n return parsed.ok ? parsed.value : null;\n};\n\nconst decode = <A>(either: Either<unknown, A>, label: string): A => {\n try {\n return unsafeUnwrap(either);\n } catch {\n return fail(`${label} does not match expected shape`);\n }\n};\n\n/** Unwrap an adapter's Either, surfacing its own message rather than a generic one. */\nconst unwrapAdapt = <A>(either: Either<string, A>): A => {\n try {\n if (either._tag === \"Left\") throw new Error(either.left);\n return either.right;\n } catch (err) {\n return fail(errMsg(err));\n }\n};\n\n/** Telemetry from a session transcript tree (main + subagents) for the true wall + turns the native\n * envelope under-reports, and for per-model usage when the native envelope is empty. A\n * missing/unreadable transcript yields empty models + a zero span, which `adapt` treats as \"no\n * transcript\". */\nconst transcriptFallbackFrom = (path: string): TranscriptTelemetry => {\n const tree = readTranscriptTree(resolve(path));\n if (tree.missing)\n process.stderr.write(\n `code-review adapt: transcript ${path} is unreadable — no telemetry fallback\\n`,\n );\n const usage = sumTranscriptUsage(tree.entries);\n return { models: usage.models, turns: usage.turns, durationMs: usage.durationMs };\n};\n\n/** Resolve a path bundled with the package (schema/, templates/) — same pattern as validate's default schema. */\nconst bundledPath = (...segments: string[]): string =>\n resolve(import.meta.dirname, \"..\", ...segments);\n\n// The repo's single version reader — the CLI's --version print and the copy-paste drift guard\n// (src/version-pins.test.ts) must model \"the repo's version\" identically.\nexport const readPackageVersion = (): string =>\n (JSON.parse(readFileSync(bundledPath(\"package.json\"), \"utf-8\")) as { version: string }).version;\n\nconst packageVersion = readPackageVersion();\n\nconst resolveTemplatePath = (templateArg: string | undefined): string =>\n templateArg ? resolve(templateArg) : bundledPath(\"templates\", \"comment.eta\");\n\nconst resolveInlineTemplatePath = (templateArg: string | undefined): string =>\n templateArg ? resolve(templateArg) : bundledPath(\"templates\", \"inline.eta\");\n\n// `provided` = a real caller map; `absent` = the bundled all-zero example. The render layer is told\n// which, so an absent map reports cost as N/A, never a false $0.00.\ntype PriceResolution =\n | { readonly kind: \"provided\"; readonly path: string }\n | { readonly kind: \"absent\"; readonly path: string };\n\nconst resolvePrices = (pricesArg: string | undefined): PriceResolution => {\n if (pricesArg) return { kind: \"provided\", path: resolve(pricesArg) };\n process.stderr.write(\n \"code-review: no --prices given — cost will be reported as N/A (no price map to recompute from)\\n\",\n );\n return { kind: \"absent\", path: bundledPath(\"schema\", \"prices.example.json\") };\n};\n\nconst TEST_REPORT_DESCRIPTION =\n 'Path to a JSON test summary: {\"passed\": number, \"failed\": number, \"total\": number, \"failures\"?: [{\"name\": string, \"message\"?: string}]}';\n\nconst CLOC_DIFF_DESCRIPTION =\n \"Path to a raw `cloc --git --diff <base> <head>` table, rendered verbatim in the sticky's cloc collapsible. Best-effort: an absent, unreadable, or empty file omits the collapsible.\";\n\nconst CONVERGENCE_THRESHOLD_DESCRIPTION =\n \"Advisory convergence tolerance: the per-finding convergence score (each finding's severity floor + confidence-and-likelihood-weighted headroom; ceilings critical 4 · major 2 · minor 1 · nit 0) at or below which the sticky reads as converged. The floor values and the systemic-likelihood rule are documented in the README and the findings schema (default: 1)\";\n\nconst NIT_VISIBILITY_FLOOR_DESCRIPTION =\n \"Nit visibility floor: nits whose confidence × likelihood falls below this are hidden from humans (no inline comment; a collapsed aside in the sticky) but kept in the machine blob as adjudicated. In [0, 1] (default: 0.25)\";\n\nconst renderCmd = defineCommand({\n meta: {\n name: \"render\",\n description: \"Render a code-review comment from findings + usage + prices\",\n },\n args: {\n findings: {\n type: \"positional\",\n description: \"Path to findings JSON\",\n required: true,\n },\n template: {\n type: \"string\",\n description: \"Path to Eta template file (default: bundled templates/comment.eta)\",\n },\n usage: {\n type: \"string\",\n description: \"Path to result envelope JSON (from agent CLI)\",\n required: true,\n },\n prices: {\n type: \"string\",\n description:\n \"Path to price map JSON (default: bundled schema/prices.example.json — all zero)\",\n },\n \"reviewed-sha\": {\n type: \"string\",\n description: \"SHA of the last reviewed commit\",\n },\n route: {\n type: \"string\",\n description:\n \"Review route label; overrides the envelope's route when set (default: read from the envelope)\",\n },\n effort: {\n type: \"string\",\n description:\n \"Effort label; overrides the envelope's effort when set (default: read from the envelope)\",\n },\n \"test-report\": {\n type: \"string\",\n description: TEST_REPORT_DESCRIPTION,\n },\n \"cloc-diff\": {\n type: \"string\",\n description: CLOC_DIFF_DESCRIPTION,\n },\n \"convergence-threshold\": {\n type: \"string\",\n description: CONVERGENCE_THRESHOLD_DESCRIPTION,\n },\n \"nit-visibility-floor\": {\n type: \"string\",\n description: NIT_VISIBILITY_FLOOR_DESCRIPTION,\n },\n },\n run: async ({ args }) => {\n const findings = decode(FindingsCodec.decode(readJSON(args.findings)), \"findings\");\n const envelope = decode(ResultEnvelopeCodec.decode(readJSON(args.usage)), \"envelope\");\n const templatePath = resolveTemplatePath(args.template);\n const priceResolution = resolvePrices(args.prices);\n const prices = decode(PriceMapCodec.decode(readJSON(priceResolution.path)), \"prices\");\n const template = readFileSync(templatePath, \"utf-8\");\n const testReport = args[\"test-report\"]\n ? decode(TestSummaryCodec.decode(readJSON(args[\"test-report\"])), \"test report\")\n : undefined;\n const clocDiff = args[\"cloc-diff\"] ? loadClocDiff(args[\"cloc-diff\"]) : undefined;\n // The render command renders ONE run with no PR history, so render's fallback (which requires a\n // completed round in the history) would show no convergence at all. A completed full-review run\n // IS round 1 of its conversation: pass its own counts as the history — the badge, the\n // trajectory, and the blob's stop signal all agree on it, and the shared predicates make this\n // the same decision post makes (issue #141 reviews r2 + r4).\n const route = args.route || envelope.route || null;\n const isRound =\n isConvergenceRound(route, envelope.incomplete === true || isIncompleteFindings(findings)) &&\n isReviewVerdict(findings.verdict);\n const threshold = parseConvergenceThreshold(args[\"convergence-threshold\"]);\n // The render command previews ONE run with no PR history. A completed full-review run IS round 1 of\n // its conversation, so stamp its convergence (issue #174): the badge, the numeric trajectory, and the\n // blob all read the same stored score, the same decision post makes (issue #141 reviews r2 + r4).\n // Mirror post's stamp: convergence is pipeline-owned and always overwritten, so a draft's echoed\n // value never rides the preview blob — a round previews a fresh round-1 stamp, a non-round none.\n // post's mechanic stamp needs the prior trajectory this command has no access to, so a mechanic\n // preview stamps none — exactly what post stamps for a no-prior mechanic (mechanicConvergence null).\n const stampedFindings = {\n ...findings,\n convergence: isRound ? buildConvergence(findings, threshold) : undefined,\n };\n // The `render` command previews the sticky CHROME (verdict, counts, convergence, cost) — it has no\n // diff, so it never places findings inline vs stray and shows no per-finding detail. It therefore\n // validates --nit-visibility-floor (issue #164) but does NOT apply the visible split or the\n // suppression aside: rendering shelved nits while the visible findings have no detail line would\n // invert the feature. The human/visible split is post's job — it has the diff and the prior sticky.\n const output = render({\n findings: stampedFindings,\n envelope,\n prices,\n pricesProvided: priceResolution.kind === \"provided\",\n template,\n reviewedSha: args[\"reviewed-sha\"],\n route: args.route,\n effort: args.effort,\n testReport,\n clocDiff,\n convergenceThreshold: threshold,\n nitVisibilityFloor: parseNitVisibilityFloor(args[\"nit-visibility-floor\"]),\n convergenceRound: isRound,\n postedAt: formatUtc(new Date()),\n pricedAt: new Date(),\n });\n process.stdout.write(output);\n // The standalone render command names no findings artifact (there is no --json-url flag), so\n // its output carries no machine channel — the same ::error:: post emits, because a preview that\n // looks like a review is worse than one that says what it lacks (issue #233 r2).\n process.stderr.write(\n \"::error::no --json-url was supplied, so this comment names no findings artifact — the review's prose is intact but its machine channel is gone, and the next round cannot seed from it\\n\",\n );\n },\n});\n\nconst inlineCmd = defineCommand({\n meta: {\n name: \"inline\",\n description: \"Build GitHub reviews comments[] payload from findings + diff\",\n },\n args: {\n findings: {\n type: \"positional\",\n description: \"Path to findings JSON\",\n required: true,\n },\n diff: {\n type: \"string\",\n description: \"Path to PR diff file\",\n required: true,\n },\n template: {\n type: \"string\",\n description: \"Path to inline comment Eta template (default: bundled templates/inline.eta)\",\n },\n \"nit-visibility-floor\": {\n type: \"string\",\n description: NIT_VISIBILITY_FLOOR_DESCRIPTION,\n },\n },\n run: async ({ args }) => {\n const findings = decode(FindingsCodec.decode(readJSON(args.findings)), \"findings\");\n const diff = readFileSync(resolve(args.diff), \"utf-8\");\n const inlineTemplate = readFileSync(resolveInlineTemplatePath(args.template), \"utf-8\");\n // Apply the FIXED-floor part of the nit-visibility split (issue #164): a below-floor nit gets no\n // inline comment. This standalone payload builder has no prior sticky, so no one-round stickiness\n // (post applies that); it also has no sticky to carry the collapsed aside, so a suppressed nit is\n // simply absent here — the aside is post's surface.\n const floor = parseNitVisibilityFloor(args[\"nit-visibility-floor\"]);\n const visibleFindings = findings.findings.filter((f) => !isBelowVisibilityFloor(f, floor));\n const { comments, strays } = buildInlineComments(visibleFindings, diff, {\n inlineTemplate,\n findings,\n });\n process.stdout.write(\n JSON.stringify({ comments, strays, stray_markdown: renderStraysSection(strays) }, null, 2),\n );\n },\n});\n\nconst costCmd = defineCommand({\n meta: {\n name: \"cost\",\n description: \"Recompute USD cost from the envelope's models array + price map\",\n },\n args: {\n envelope: {\n type: \"positional\",\n description: \"Path to result envelope JSON\",\n required: true,\n },\n prices: {\n type: \"string\",\n description: \"Path to price map JSON\",\n required: true,\n },\n },\n run: async ({ args }) => {\n const envelope = decode(ResultEnvelopeCodec.decode(readJSON(args.envelope)), \"envelope\");\n const prices = decode(PriceMapCodec.decode(readJSON(args.prices)), \"prices\");\n // Price a saved envelope at the RUN's own instant (issue #170), so re-running `cost` later prices\n // the same envelope to the same slot deterministically — not at whatever wall clock it is re-run at.\n const report = computeCost(\n envelope.models,\n prices,\n parseInstant(envelope.generated_at) ?? new Date(),\n );\n process.stdout.write(JSON.stringify(report, null, 2));\n },\n});\n\nconst checkCostCmd = defineCommand({\n meta: {\n name: \"check-cost\",\n description:\n \"Sum real USD spend from a Claude Code transcript tree (main + subagents) against a price map\",\n },\n args: {\n transcript: {\n type: \"positional\",\n description: \"Path to the session transcript JSONL (the hook's transcript_path)\",\n required: true,\n },\n prices: {\n type: \"string\",\n description:\n \"Path to price map JSON (default: bundled schema/prices.example.json — token totals stay real, cost reads as $0)\",\n },\n },\n run: async ({ args }) => {\n const tree = readTranscriptTree(resolve(args.transcript));\n if (tree.missing) {\n process.stderr.write(\n `code-review check-cost: transcript ${args.transcript} is unreadable — reporting zero spend\\n`,\n );\n }\n const usage = sumTranscriptUsage(tree.entries);\n const priceResolution = resolvePrices(args.prices);\n const prices = decode(PriceMapCodec.decode(readJSON(priceResolution.path)), \"prices\");\n // Price at the transcript's last activity instant (deterministic — re-running `check-cost` on the\n // same transcript prices the same slot), not the invocation wall clock (issue #170 review r2).\n const report = computeCost(\n usage.models,\n prices,\n usage.lastTsMs !== null ? new Date(usage.lastTsMs) : new Date(),\n );\n process.stdout.write(\n `${JSON.stringify(\n {\n ...report,\n turns: usage.turns,\n durationMs: usage.durationMs,\n transcripts: tree.files,\n pricesProvided: priceResolution.kind === \"provided\",\n },\n null,\n 2,\n )}\\n`,\n );\n },\n});\n\n/** Read + decode a price map, degrading to null (cost axis disabled) on any failure — the budget\n * hook fires on every tool call, so it must never process-exit the way the strict `readJSON` does. */\nconst tryReadPrices = (path: string): PriceMap | null => {\n try {\n const decoded = PriceMapCodec.decode(JSON.parse(readFileSync(resolve(path), \"utf-8\")));\n return decoded._tag === \"Right\" ? decoded.right : null;\n } catch {\n return null;\n }\n};\n\n/** A non-negative, finite dollar amount, or null (absent/unparseable). `0` is kept, not nulled: as a\n * budget it disables the cost axis (decideBudget requires budgetUsd > 0); as a reserve floor it means\n * no flat floor. */\nconst parseBudgetUsd = (raw: string | undefined): number | null => {\n if (raw === undefined) return null;\n const n = Number.parseFloat(raw);\n return Number.isFinite(n) && n >= 0 ? n : null;\n};\n\n/** Parse `--convergence-threshold`: a non-negative decimal, or undefined when absent/blank (the render\n * layer then applies DEFAULT_CONVERGENCE_THRESHOLD as the SSOT default). An unset optional workflow\n * input expands to \"\" — treat empty/whitespace as absent so the step falls back to the default rather\n * than hard-failing under `set -euo pipefail`. Match the whole string before parsing — `parseFloat`\n * alone silently accepts a numeric prefix (`\"1,5\"`→1, `\"0x10\"`→0) — and reject a non-finite result\n * (a 309+-digit string parses to Infinity, which would make `score <= threshold` always true, a false\n * \"converged\"); a malformed value must fail loudly, the same class the prefix guard covers. */\nconst parseConvergenceThreshold = (raw: string | undefined): number | undefined => {\n const trimmed = raw?.trim();\n if (trimmed === undefined || trimmed === \"\") return undefined;\n if (!/^\\d+(\\.\\d+)?$/.test(trimmed)) {\n fail(`--convergence-threshold must be a non-negative number; got \"${trimmed}\"`);\n }\n const n = Number.parseFloat(trimmed);\n if (!Number.isFinite(n)) {\n fail(`--convergence-threshold is too large to be a meaningful tolerance; got \"${trimmed}\"`);\n }\n return n;\n};\n\n/** Parse `--nit-visibility-floor`: a decimal in [0, 1], or undefined when absent/blank (the render/post\n * layer then applies DEFAULT_NIT_VISIBILITY_FLOOR as the SSOT default). Same empty-string-is-absent\n * handling as --convergence-threshold (an unset optional workflow input expands to \"\"). Bounded to\n * [0, 1] because the value it gates — confidence × likelihood — is itself in [0, 1]: a value above 1\n * would silently hide EVERY nit (a fat-fingered \"25\" meant as \"0.25\"), so it fails loudly instead. */\nconst parseNitVisibilityFloor = (raw: string | undefined): number | undefined => {\n const trimmed = raw?.trim();\n if (trimmed === undefined || trimmed === \"\") return undefined;\n if (!/^\\d+(\\.\\d+)?$/.test(trimmed)) {\n fail(`--nit-visibility-floor must be a number in [0, 1]; got \"${trimmed}\"`);\n }\n const n = Number.parseFloat(trimmed);\n if (!Number.isFinite(n) || n < 0 || n > 1) {\n fail(\n `--nit-visibility-floor must be in [0, 1] (it gates confidence × likelihood); got \"${trimmed}\"`,\n );\n }\n return n;\n};\n\n/** seed-draft's best-effort floor parse: like parseNitVisibilityFloor but NEVER exits — seed-draft's\n * always-exit-0 contract forbids the process-exiting `fail` (it runs under the review job's `set -e`).\n * An absent/blank/malformed/out-of-range value degrades to undefined (priorBelowFloorNits then applies\n * the SSOT default); a genuine misconfiguration is still caught loudly at post, where the floor is\n * actually enforced. */\nconst parseNitVisibilityFloorLenient = (raw: string | undefined): number | undefined => {\n const trimmed = raw?.trim();\n if (trimmed === undefined || trimmed === \"\" || !/^\\d+(\\.\\d+)?$/.test(trimmed)) return undefined;\n const n = Number.parseFloat(trimmed);\n return Number.isFinite(n) && n >= 0 && n <= 1 ? n : undefined;\n};\n\n/** The `transcript_path` a hook payload carries, when present. */\nconst transcriptPathOf = (input: unknown): string | undefined => {\n const tp = (\n typeof input === \"object\" && input !== null ? (input as Record<string, unknown>) : {}\n )[\"transcript_path\"];\n return typeof tp === \"string\" ? tp : undefined;\n};\n\nconst statMtimeMsOrNull = (path: string): number | null => {\n try {\n return statSync(path).mtimeMs;\n } catch {\n return null;\n }\n};\n\nconst statSizeOrNull = (path: string): number | null => {\n try {\n return statSync(path).size;\n } catch {\n return null;\n }\n};\n\n/** Snapshot the draft to its last-valid sidecar when it passes the same extraction ladder `adapt`\n * will read it back through, so `adapt`'s fallback rung only ever sees a document it accepts.\n * The pre-seed sentinel never validates, so the untouched seed can never be checkpointed here.\n * Best-effort — a snapshot miss never perturbs the hook's stdout decision. */\nexport const snapshotIfValid = (draftPath: string): void => {\n try {\n // Skip the ladder when the draft is not newer than the snapshot already taken: the hook fires\n // on every main-agent PostToolBatch, and re-validating an unchanged draft each batch is the\n // same per-event I/O class the lazy-thunk change elsewhere eliminated.\n const snapPath = lastValidPath(draftPath);\n const draftMtime = statMtimeMsOrNull(draftPath);\n if (draftMtime === null) return;\n const snapMtime = statMtimeMsOrNull(snapPath);\n if (snapMtime !== null && draftMtime <= snapMtime) return;\n // Validate the LIVE draft only (no agentFileFallbackPath): passing the snapshot as a fallback\n // here would let a valid snapshot rescue an invalid live draft through the ladder, then copy that\n // invalid draft over the good snapshot — corrupting the last-valid state we exist to preserve.\n if (\n extractStructured({ kind: \"findings\", native: undefined, agentFilePath: draftPath }).kind ===\n \"ok\"\n )\n copyFileSync(draftPath, snapPath);\n } catch (err) {\n process.stderr.write(\n `code-review: could not snapshot the last-valid draft (${errMsg(err)}) — any prior snapshot is unchanged\\n`,\n );\n }\n};\n\nconst budgetHookCmd = defineCommand({\n meta: {\n name: \"budget-hook\",\n description:\n \"Self-dispatching Claude Code budget hook: on PostToolBatch steer the agent to converge as spend/wall-clock nears the budget; on PreToolUse deny budget-burning tools under the hard reserve, gate subagent spawns until the main agent has drafted, and run permitted spawns in the background. Reads the hook payload on stdin; degrades to a no-op on error.\",\n },\n args: {\n draft: {\n type: \"string\",\n description:\n \"Path to the findings draft that is the sole permitted write target under forced convergence\",\n required: true,\n },\n \"budget-usd\": {\n type: \"string\",\n description:\n \"Dollar budget for the run; the cost axis is measured against it (needs --prices)\",\n },\n wall: {\n type: \"string\",\n description: \"Wall-clock budget (e.g. 20m, 1200s, 2h); the time axis is measured against it\",\n },\n prices: {\n type: \"string\",\n description:\n \"Price map JSON to recompute real spend from the transcript (omit to disable the cost axis)\",\n },\n \"reserve-frac\": {\n type: \"string\",\n description:\n \"Base wind-down headroom as a fraction of each budget: converge once less than this remains (default: 0.15; the soft steer tier reserves 2× this)\",\n },\n \"reserve-growth\": {\n type: \"string\",\n description:\n \"How much the reserve grows as a budget is spent — added at full usage, so convergence lands earlier the longer the run has gone (default: 0.25; 0 = flat reserve)\",\n },\n \"reserve-usd\": {\n type: \"string\",\n description:\n \"Flat dollar wind-down floor, whichever is larger with --reserve-frac (default: 0.02)\",\n },\n \"reserve-wall\": {\n type: \"string\",\n description:\n \"Flat wall-clock wind-down floor (e.g. 2m, 120s), whichever is larger with --reserve-frac (default: 2m)\",\n },\n },\n run: async ({ args }) => {\n try {\n const draftPath = resolve(args.draft);\n const input = readStdinJSON();\n const transcriptPath = transcriptPathOf(input);\n const tree = transcriptPath ? readTranscriptTree(resolve(transcriptPath)) : undefined;\n const usage = tree ? sumTranscriptUsage(tree.entries) : undefined;\n const prices = args.prices ? tryReadPrices(args.prices) : null;\n const spentUsd =\n prices !== null && usage\n ? // Price at the transcript's last activity instant, not the wall clock (issue #170 review\n // r2). Silent warn: this budget-steering cost is recomputed on EVERY tool event, so a\n // misconfigured slot map would otherwise flood stderr; the final post's cost render warns.\n computeCost(\n usage.models,\n prices,\n usage.lastTsMs !== null ? new Date(usage.lastTsMs) : new Date(),\n () => undefined,\n ).totalCostUSD\n : null;\n // The absolute anchor (set by the review job, inherited by every hook incl. fan-out subagents)\n // is the true remaining wall; the per-transcript first timestamp is only the fallback — it\n // reads ≈0 in a fresh subagent and leaves the fan-out unsteered.\n const wallMs = args.wall ? parseWallMs(args.wall) : null;\n const output = evaluateBudgetHook(input, {\n spentUsd,\n budgetUsd: parseBudgetUsd(args[\"budget-usd\"]),\n elapsedMs: anchoredElapsedMs({\n deadlineMs: parseEpochSecMs(process.env[DEADLINE_ENV]),\n wallMs,\n firstTsMs: usage?.firstTsMs ?? null,\n nowMs: Date.now(),\n }),\n wallMs,\n reserve: {\n frac: parseFraction(args[\"reserve-frac\"], DEFAULT_RESERVE.frac),\n growth: parseFraction(args[\"reserve-growth\"], DEFAULT_RESERVE.growth),\n flatUsd: parseBudgetUsd(args[\"reserve-usd\"]) ?? DEFAULT_RESERVE.flatUsd,\n flatMs: args[\"reserve-wall\"]\n ? (parseWallMs(args[\"reserve-wall\"]) ?? DEFAULT_RESERVE.flatMs)\n : DEFAULT_RESERVE.flatMs,\n },\n draftPath,\n // Lazy: the spawn gate is the only consumer, and the hook fires on every tool event.\n mainDraftWritten: (): boolean => mainHasWrittenDraft(readFileOrNull(draftPath)),\n });\n // Only the main agent writes the draft (single-writer), so a subagent batch never introduces a\n // new valid state to preserve — snapshot on the main agent's PostToolBatch only.\n if (asRecord(input)?.[\"hook_event_name\"] === \"PostToolBatch\" && !isSubagentHookInput(input))\n snapshotIfValid(draftPath);\n process.stdout.write(`${JSON.stringify(output)}\\n`);\n } catch (err) {\n process.stderr.write(`code-review budget-hook: degrading to no-op — ${errMsg(err)}\\n`);\n process.stdout.write(\"{}\\n\");\n }\n },\n});\n\nconst printSettingsCmd = defineCommand({\n meta: {\n name: \"print-settings\",\n description:\n \"Emit one Claude Code --settings JSON composing the Stop deliverable gate and the budget hooks (PreToolUse convergence + PostToolBatch steer) from one self-dispatching command\",\n },\n args: {\n draft: {\n type: \"string\",\n description:\n \"Path to the findings draft the agent must produce — the Stop gate's target and the only write allowed under forced convergence\",\n required: true,\n },\n kind: {\n type: \"string\",\n description: \"Schema kind for the Stop gate: findings | triage | prices (default: findings)\",\n },\n schema: {\n type: \"string\",\n description: \"Path to a schema file for the Stop gate (wins over --kind)\",\n },\n \"schema-version\": {\n type: \"string\",\n description: \"Schema major.minor for the Stop gate (default: the draft's declared version)\",\n },\n \"max-nudges\": {\n type: \"string\",\n description: \"Stop-gate nudge budget before relenting (default: 5)\",\n },\n counter: {\n type: \"string\",\n description: \"Path for the Stop-gate nudge counter (default: <draft>.nudges)\",\n },\n \"budget-usd\": {\n type: \"string\",\n description: \"Dollar budget the cost axis is measured against (needs --prices)\",\n },\n wall: {\n type: \"string\",\n description: \"Wall-clock budget the time axis is measured against (e.g. 20m, 1200s)\",\n },\n prices: {\n type: \"string\",\n description: \"Price map JSON to recompute real spend from the transcript\",\n },\n \"reserve-frac\": {\n type: \"string\",\n description:\n \"Base wind-down headroom as a fraction of each budget (default: 0.15; soft tier is 2×)\",\n },\n \"reserve-growth\": {\n type: \"string\",\n description:\n \"How much the reserve grows as a budget is spent, converging earlier the longer the run has gone (default: 0.25; 0 = flat)\",\n },\n \"reserve-usd\": {\n type: \"string\",\n description:\n \"Flat dollar wind-down floor, whichever is larger with --reserve-frac (default: 0.02)\",\n },\n \"reserve-wall\": {\n type: \"string\",\n description:\n \"Flat wall-clock wind-down floor (e.g. 2m), whichever is larger with --reserve-frac (default: 2m)\",\n },\n },\n run: async ({ args }) => {\n if (args.kind && ![\"findings\", \"triage\", \"prices\"].includes(args.kind))\n fail(`--kind must be one of findings|triage|prices (got '${args.kind}')`);\n const settings = composeReviewSettings({\n draftPath: resolve(args.draft),\n stop: {\n kind: args.kind,\n schema: args.schema,\n schemaVersion: args[\"schema-version\"],\n maxNudges: args[\"max-nudges\"],\n counter: args.counter,\n },\n budget: {\n budgetUsd: args[\"budget-usd\"],\n wall: args.wall,\n prices: args.prices,\n reserveFrac: args[\"reserve-frac\"],\n reserveGrowth: args[\"reserve-growth\"],\n reserveUsd: args[\"reserve-usd\"],\n reserveWall: args[\"reserve-wall\"],\n },\n });\n process.stdout.write(`${JSON.stringify(settings)}\\n`);\n },\n});\n\nconst deadlineCmd = defineCommand({\n meta: {\n name: \"deadline\",\n description:\n \"Print the run's absolute deadline as Unix epoch seconds (now + --wall) — exported as CODE_REVIEW_DEADLINE_EPOCH so every budget hook (main and subagents) measures the same remaining wall\",\n },\n args: {\n wall: {\n type: \"string\",\n description:\n \"Wall-clock budget for the run (e.g. 24m, 1200s, 2h) — the deadline is now + this\",\n required: true,\n },\n },\n run: async ({ args }) => {\n const wallMs = parseWallMs(args.wall);\n if (wallMs === null) {\n fail(`--wall must be a duration like 24m, 1200s, or 2h (got '${args.wall}')`);\n } else {\n process.stdout.write(`${String(deadlineEpochSec(wallMs, Date.now()))}\\n`);\n }\n },\n});\n\n/** The version to derive when neither --schema nor --schema-version is given: findings carries its\n * version in-data; triage/prices have no in-data signal (see registry.ts), so undefined selects the\n * registry default (latest) for the kind. */\nconst derivedSchemaVersion = (kind: SchemaKind, raw: unknown): string | undefined =>\n kind === \"findings\" ? declaredVersion(raw) : undefined;\n\n/** A bundled schema rendered for a CLI/agent to read: pretty-printed with the top-level `$schema`\n * draft declaration stripped. `claude -p --json-schema` silently disables enforcement when a schema\n * carries `$schema`, and the field DESCRIPTIONS are the authoritative spec the agent must follow, so\n * this is the form both `print-schema` and `validate --explain` emit. When `pinVersion` is set (the\n * caller resolved the LIVE findings schema — no version override, no legacy-stamped explain), the\n * schema_version's pattern is narrowed to the in-force minor so `--json-schema` enforces exactly\n * the versions the registry dispatches to the live entry — the FROZEN legacy copies keep their\n * tolerant shape, and the schema FILES stay version-tolerant: the registry dispatches on the\n * declared version, only the live enforcement copy pins. */\nexport const printableSchema = (schemaPath: string, pinVersion: boolean): string => {\n const schema = JSON.parse(readFileSync(schemaPath, \"utf-8\")) as Record<string, unknown>;\n const enforcementSchema = Object.fromEntries(\n Object.entries(schema).filter(([key]) => key !== \"$schema\"),\n );\n if (!pinVersion) return JSON.stringify(enforcementSchema, null, 2);\n const properties = enforcementSchema[\"properties\"];\n const schemaVersion =\n typeof properties === \"object\" && properties !== null\n ? (properties as Record<string, unknown>)[\"schema_version\"]\n : undefined;\n if (typeof schemaVersion === \"object\" && schemaVersion !== null) {\n (properties as Record<string, unknown>)[\"schema_version\"] = {\n ...(schemaVersion as Record<string, unknown>),\n pattern: anchoredSchemaVersionPattern(DEFAULT_SCHEMA_VERSION),\n };\n }\n return JSON.stringify(enforcementSchema, null, 2);\n};\n\nconst validateCmd = defineCommand({\n meta: {\n name: \"validate\",\n description: \"Validate a findings/triage/prices JSON document against the canonical schema\",\n },\n args: {\n document: {\n type: \"positional\",\n description: \"Path to the JSON document to validate (of the given --kind)\",\n required: true,\n },\n kind: {\n type: \"string\",\n description:\n \"Schema kind to validate against: findings | triage | prices (default: findings)\",\n },\n schema: {\n type: \"string\",\n description:\n \"Path to a schema file (wins over --kind; default: the bundled schema derived from --kind, --schema-version, the document's declared schema_version, or the bundled latest)\",\n },\n \"schema-version\": {\n type: \"string\",\n description:\n \"Schema major.minor version to validate against (default: the document's declared schema_version for findings, or the kind's latest)\",\n },\n explain: {\n type: \"boolean\",\n description:\n \"On failure, also print the schema after the errors — its field descriptions are the authoritative spec, so the document can be fixed in one pass instead of by trial and error\",\n },\n },\n run: async ({ args }) => {\n const kind = requireSchemaKind(args.kind || \"findings\");\n const documentRaw = readJSON(args.document);\n const schemaPath = args.schema\n ? resolve(args.schema)\n : requireSchemaPath(kind, args[\"schema-version\"] || derivedSchemaVersion(kind, documentRaw));\n const { valid, errors } = validateAgainstSchema(documentRaw, schemaPath);\n if (valid) {\n process.stdout.write(\"✅ valid\\n\");\n } else {\n process.stderr.write(\"❌ invalid\\n\");\n for (const e of errors) process.stderr.write(` - ${e}\\n`);\n if (args.explain) {\n process.stderr.write(\n `\\nThe ${kind} document must conform to this schema (the field descriptions are the authoritative spec — match the property names exactly):\\n${printableSchema(schemaPath, kind === \"findings\" && schemaPath === schemaPathFor(kind))}\\n`,\n );\n }\n process.exit(1);\n }\n },\n});\n\n// A decoded prior blob the pipeline stamped (surface version 0.8.0) — its scope_metastasis was\n// pipeline-stamped and is authoritative. Only 0.8.0 ever stamped the field: issue #150 added\n// scope_metastasis in the same commit that bumped the surface version 0.7.0 → 0.8.0, so a 0.7.0 blob\n// predates the field and any entry it carries is an echo, not a stamp; a draft blob's is likewise at\n// most an agent echo. Guards non-objects.\nconst isSurfaceStampedDoc = (doc: unknown): boolean =>\n typeof doc === \"object\" &&\n doc !== null &&\n !Array.isArray(doc) &&\n (doc as Record<string, unknown>)[\"schema_version\"] === SURFACE_SCHEMA_VERSION;\n\n// The prior document with the agent-echoable scope_metastasis removed — a stale echo would over-report\n// recurrence, so the seed re-derives it fresh below. The pipeline-stamped convergence is KEPT: it is the\n// last completed round's own trajectory (correct context, not a stale echo), and the review agent's only\n// view of prior state is this seed, so it must carry the convergence signal (issue #174). A no-op on a\n// non-object; mirrors the stripSurfaceFields filter idiom.\nconst withoutScopeMetastasis = (doc: unknown): unknown =>\n typeof doc === \"object\" && doc !== null && !Array.isArray(doc)\n ? Object.fromEntries(Object.entries(doc).filter(([key]) => key !== \"scope_metastasis\"))\n : doc;\n\nconst seedDraftCmd = defineCommand({\n meta: {\n name: \"seed-draft\",\n description:\n \"Initialize $DRAFT before the review runs: write a NON-REVIEW SENTINEL (no recovery path can validate it as a review), and deliver the decoded findings of a prior review OUT-OF-BAND to a read-only context file beside the draft when one exists and still validates (incremental re-review). Skips a prior that never completed (an error-verdict notice) or that a CI-fix mechanic pass produced — the seed chain is route-aware. Prints the mode to stdout (prior-same|prior-new when prior context was delivered, by whether the prior review examined this same commit; empty-had-prior when a prior review exists but its findings could not be loaded; empty on a first review; none when even the sentinel write failed) and always exits 0\",\n },\n args: {\n prior: {\n type: \"string\",\n description:\n \"Path to the prior-review JSON gather staged ({ id, body }, or the literal null); its embedded base64 findings marker is decoded and delivered as re-review context when it validates against the schema\",\n },\n \"prior-findings\": {\n type: \"string\",\n description:\n \"Path to the gather-staged prior findings document (prior_findings.json). gather resolves it — from the sticky's embedded blob, or by fetching the artifact the marker names — because gather holds the repo token and this step deliberately does not: it runs the jailed agent over untrusted PR code. Absent or null falls back to decoding an embedded blob out of --prior, which needs no token\",\n },\n \"prior-answers\": {\n type: \"string\",\n description:\n \"Path to the gather-staged answered-findings registry (answered.json) — the prior inline findings whose threads a human reply answered (issue #151). Delivered out-of-band to the .prior-answers sidecar beside the prior context so the next-round agent sees the already-answered state; best-effort, never fails the seed\",\n },\n \"nit-visibility-floor\": {\n type: \"string\",\n description:\n \"The nit visibility floor (issue #164), matched to the commenter's: the prior review's below-floor nits (confidence × likelihood below it) are re-derived from --prior and delivered to the .prior-suppressed sidecar as adjudicated context, so the next-round agent does not re-raise them as fresh nits; best-effort, never fails the seed. Empty ⇒ the default\",\n },\n \"head-sha\": {\n type: \"string\",\n description:\n \"Current head SHA, compared against the prior review's embedded reviewed-sha to distinguish a same-commit re-review from a new-commit one; an unknown or mismatched prior SHA is treated as a new commit\",\n },\n out: {\n type: \"string\",\n description: \"Path to write the sentinel $DRAFT to (an absolute path outside the worktree)\",\n required: true,\n },\n kind: {\n type: \"string\",\n description: \"Schema kind to validate the prior findings against (default: findings)\",\n },\n schema: {\n type: \"string\",\n description: \"Path to a schema file (wins over --kind/--schema-version)\",\n },\n \"schema-version\": {\n type: \"string\",\n description:\n \"Schema major.minor to validate the prior findings against (default: the kind's latest — an older-shaped prior review then delivers no context)\",\n },\n },\n run: async ({ args }) => {\n const outPath = resolve(args.out);\n const kindArg = args.kind || \"findings\";\n const kind: SchemaKind = isSchemaKind(kindArg) ? kindArg : \"findings\";\n if (kind !== kindArg) {\n process.stderr.write(\n `Warning: unknown --kind \"${kindArg}\" — validating against \"findings\"\\n`,\n );\n }\n\n // seed-draft is best-effort and must NEVER fail the review step (the workflow runs it under\n // `set -e`), so every path below either seeds or degrades — none uses the process-exiting\n // require* helpers. The only outcome that skips seeding is a sentinel write that itself throws\n // (e.g. a bad --out directory), which is warned and still exits 0: the agent then creates\n // $DRAFT itself, exactly as if no seeding ran.\n const writeSentinel = (): boolean => {\n try {\n writeFileSync(outPath, SEED_SENTINEL);\n process.stderr.write(\n `Seeded ${outPath} with the non-review sentinel — the agent must replace it with its review\\n`,\n );\n return true;\n } catch (err) {\n process.stderr.write(\n `Warning: could not write the seed sentinel to ${outPath} (${errMsg(err)}) — the agent will create $DRAFT itself\\n`,\n );\n return false;\n }\n };\n\n // The whole prior comment body gather staged, tolerating a missing/absent/\"null\"/malformed\n // file: it carries the embedded findings (delivered as context below when they still validate),\n // the reviewed-sha that distinguishes a same-commit re-review from a new-commit one, and the\n // route of the review that produced it.\n const priorBody = ((): string | null => {\n if (!args.prior) return null;\n const raw = ((): unknown => {\n try {\n return JSON.parse(readFileSync(resolve(args.prior), \"utf-8\")) as unknown;\n } catch {\n return null;\n }\n })();\n return typeof raw === \"object\" &&\n raw !== null &&\n \"body\" in raw &&\n typeof raw.body === \"string\"\n ? raw.body\n : null;\n })();\n // Resolved by GATHER, not here: the sticky names an artifact (issue #217) and fetching it needs\n // the repo token, which this step does not have and must not have — it runs the jailed agent over\n // untrusted PR code. gather stages the document; this reads it. The embedded fallback keeps a\n // pre-#217 sticky working with no staged file and no token at all.\n const stagedPrior = ((): unknown => {\n if (!args[\"prior-findings\"]) return null;\n try {\n return JSON.parse(readFileSync(resolve(args[\"prior-findings\"]), \"utf-8\")) as unknown;\n } catch {\n return null;\n }\n })();\n const parsedPrior =\n stagedPrior !== null\n ? stagedPrior\n : priorBody === null\n ? null\n : parseFindingsMarker(priorBody);\n // A legacy 0.8.0 surfaced blob had its scope_metastasis PIPELINE-stamped fresh every round, so a\n // carried entry is authoritative that round (a 0.7.0 blob predates the field, so its entry is not\n // a stamp — isSurfaceStampedDoc gates on 0.8.0 alone); the post-#156 blob is the agent's own\n // document (a draft version) and carries no pipeline stamp, so any scope_metastasis in it is the agent\n // ECHOING the entry the prior seed attached to its context — stale the moment the recurrence\n // changes. Drop that echo up front (the surface peel-back keeps a legacy blob's authoritative\n // entry) so the recurrence signal comes solely from the carried-trajectory re-derivation below,\n // never a carried copy that can outlive the streak it claims.\n const strippedPrior =\n parsedPrior === null\n ? null\n : stripSurfaceFields(\n isSurfaceStampedDoc(parsedPrior) ? parsedPrior : withoutScopeMetastasis(parsedPrior),\n );\n // The answered registry decoded ONCE, up front: the seed's pre-filter below and the sidecar\n // write at the end both consume it (issue #233 r2). null = no usable registry (the flag absent,\n // or the staged file malformed — the old contract: a malformed file warns and writes NO\n // sidecar, issue #151).\n const answeredRegistry = ((): readonly StagedAnsweredEntry[] | null => {\n if (!args[\"prior-answers\"]) return null;\n try {\n const raw = JSON.parse(readFileSync(resolve(args[\"prior-answers\"]), \"utf-8\")) as unknown;\n if (!Array.isArray(raw)) throw new Error(\"expected an array\");\n const decoded = raw.flatMap((row) => {\n const entry = decodeAnsweredEntry(row);\n return entry === null ? [] : [entry];\n });\n // A dropped row is a gap in the answered state, not a silent no-op: the agent would read\n // \"no answers\" for a thread that WAS answered (issue #151 review r1).\n if (decoded.length < raw.length) {\n process.stderr.write(\n `Warning: ${String(raw.length - decoded.length)} of ${String(raw.length)} answered-registry row(s) failed to decode — the seed's answered state is incomplete\\n`,\n );\n }\n return decoded;\n } catch (err) {\n process.stderr.write(\n `Warning: could not read the answered-findings registry ${args[\"prior-answers\"]} (${errMsg(err)}) — no prior-answers sidecar\\n`,\n );\n return null;\n }\n })();\n\n // The agent-facing scope_metastasis entry is derivable from the carried convergence trajectory —\n // the same computation post() ran when it stamped it — so the seed re-attaches it: the next-round agent\n // must see the recurrence signal. A legacy blob whose stripped doc still carries the authoritative\n // pipeline stamp keeps it. The re-attach is best-effort: if the in-force schema (a consumer-pinned\n // custom --schema predating the field) rejects the adorned doc, the un-adorned prior is seeded\n // instead — losing the recurrence entry beats losing ALL prior context.\n const priorFindings = ((): unknown => {\n if (\n strippedPrior === null ||\n typeof strippedPrior !== \"object\" ||\n Array.isArray(strippedPrior)\n )\n return strippedPrior;\n // The registry upcast runs FIRST (code → id, or the synthesized id), so the answered pre-filter\n // below and the scope_metastasis carry both see the 0.10 shape — a raw legacy prior's findings\n // have no `id`, and the pre-filter can only match an answered entry through one. A doc the\n // upcast rejects (a malformed carried field) falls through raw: the adorn below and the gate's\n // barePrior recovery still handle it.\n const resolved = resolvedPriorValue(strippedPrior);\n // The artifact holds the agent's PRE-FILTER draft — uploaded before post's answered-filter\n // dropped verbatim re-raises — so the seed applies the SAME drop via the SAME shared\n // predicate (isAnsweredDrop, issue #233 r2): a finding the prior round closed as answered is\n // not open, and showing it as open wastes the next round on a claim post will suppress anyway.\n const doc: Record<string, unknown> =\n resolved === null\n ? (strippedPrior as Record<string, unknown>)\n : {\n ...resolved,\n findings:\n answeredRegistry !== null && answeredRegistry.length > 0\n ? resolved.findings.filter((f) => {\n const resolvedId = resolveFindingId(f);\n return !answeredRegistry.some((e) => isAnsweredDrop(resolvedId, f, e));\n })\n : resolved.findings,\n };\n // A carried entry only counts when it VALIDATES as the entry shape — for a draft blob it is\n // already dropped (only a legacy pipeline-stamped blob reaches here with one), and an explicit\n // null, an array, or a malformed object (all possible in a corrupt blob; genuine posts omit the\n // key on null) falls through to the trajectory recovery like an absent one (issues #150\n // review r3 + r4). The derivation is also gated on the prior's verdict exactly like post's\n // stamp (isRound requires a review verdict): an error-verdict prior never carries a\n // re-derived entry (issue #150 review r4).\n const carried = doc[\"scope_metastasis\"];\n if (ScopeMetastasisCodec.decode(carried)._tag === \"Right\") return doc;\n if (doc[\"verdict\"] === \"error\") return doc;\n const computed = computeScopeMetastasis(priorTrajectory(parsedPrior, priorBody ?? \"\"));\n return computed === null ? doc : { ...doc, scope_metastasis: computed };\n })();\n\n // Validate + write WITHOUT the process-exiting require* helpers: any failure (bad\n // --schema-version, unreadable schema, non-matching shape, unwritable $DRAFT) degrades to the\n // sentinel-only seed so the always-exit-0 contract holds. The prior findings are NEVER written\n // into $DRAFT — only the sentinel goes there; the prior travels out-of-band to\n // priorContextPath, which no recovery path reads back (issue #127).\n // The answered-findings registry (issue #151), delivered beside the prior context: the prior\n // inline findings whose threads a human reply answered, so the next-round agent knows what it\n // must not re-raise verbatim. Best-effort and independent of whether the prior findings seeded —\n // even a prior that never completed (a notice) still has answered threads. A malformed staged\n // file warns and writes nothing; the workflow references the sidecar as possibly absent.\n if (answeredRegistry !== null) {\n writeFileSync(priorAnswersPath(outPath), `${JSON.stringify(answeredRegistry, null, 2)}\\n`);\n process.stderr.write(\n `Seeded ${priorAnswersPath(outPath)} with ${String(answeredRegistry.length)} answered finding(s) as context\\n`,\n );\n }\n\n // The prior round's below-visibility-floor nits (issue #164), re-derived from the SAME prior blob\n // the commenter split on — delivered as adjudicated context so the next-round agent does not\n // re-raise them as fresh nits. Best-effort and independent of whether the prior findings seeded:\n // a first review, an old blob without likelihood, or a link/omitted blob simply yields none. The\n // floor is read from the same workflow input the commenter uses, so seed and post agree within a\n // run. Correctness does not depend on this note — the blob keeps every nit and post re-suppresses a\n // re-raised still-nit by stickiness — it only spares the agent the wasted re-mining.\n // Gated exactly like the prior-context seed below (isFullReviewAncestry): a mechanic (CI-fix)\n // pass writes its OWN findings blob, so deriving \"prior round's below-floor nits\" from it would\n // deliver a CI-fix pass's nits as adjudicated prior-round context. Only a completed FULL review\n // is a prior round. The floor is parsed LENIENTLY — seed-draft must exit 0, so it cannot call\n // the process-exiting parseNitVisibilityFloor (post enforces the floor loudly).\n if (parsedPrior !== null && isFullReviewAncestry(priorBody ?? \"\")) {\n try {\n const belowFloor = priorBelowFloorNits(\n parsedPrior,\n parseNitVisibilityFloorLenient(args[\"nit-visibility-floor\"]),\n );\n if (belowFloor.length > 0) {\n writeFileSync(priorSuppressedPath(outPath), `${JSON.stringify(belowFloor, null, 2)}\\n`);\n process.stderr.write(\n `Seeded ${priorSuppressedPath(outPath)} with ${String(belowFloor.length)} below-floor nit(s) as adjudicated context\\n`,\n );\n }\n } catch (err) {\n process.stderr.write(\n `Warning: could not derive the prior below-floor nits (${errMsg(err)}) — no prior-suppressed sidecar\\n`,\n );\n }\n }\n\n const seededFromPrior =\n priorFindings === null\n ? false\n : ((): boolean => {\n try {\n const schemaPath = args.schema\n ? resolve(args.schema)\n : schemaPathFor(kind, args[\"schema-version\"]);\n // ALWAYS validate — no short-circuit: a natively-carried 0.8.0 entry must face the\n // in-force schema like any other doc. When that schema (or the codec) rejects the doc\n // solely because of a RECOVERABLE optional field (scope_metastasis, convergence, or\n // change_size — a consumer-pinned custom --schema predating one, an older pinned CLI in\n // the merge-to-release window, or a corrupt blob-carried entry), fall back to the\n // field-stripped doc: losing those fields beats losing ALL prior context (issue #150\n // review r2 + #174 + #182 review r2). Shares post's recovery set (SSOT) so the two\n // recovery sites can never diverge. Covers BOTH gates (ajv + codec) — and both run on\n // the UPCAST value (resolvedPriorValue), never the raw legacy doc.\n const barePrior =\n typeof priorFindings === \"object\" && !Array.isArray(priorFindings)\n ? Object.fromEntries(\n Object.entries(priorFindings as Record<string, unknown>).filter(\n ([key]) => !RECOVERABLE_OPTIONAL_FIELDS.has(key),\n ),\n )\n : priorFindings;\n const accepts = (doc: unknown): Findings | null => {\n const resolved = resolvedPriorValue(doc);\n return resolved !== null && validateAgainstSchema(resolved, schemaPath).valid\n ? resolved\n : null;\n };\n const seedDoc =\n accepts(priorFindings) ??\n ((): Findings | null => {\n const bare = accepts(barePrior);\n if (bare === null) return null;\n process.stderr.write(\n `Note: the in-force schema rejects a carried recoverable field (scope_metastasis/convergence/change_size) — seeding the prior without it (issue #150 review r2 / #182 review r2)\\n`,\n );\n return bare;\n })();\n if (seedDoc === null) return false;\n // Skip a prior that never completed (verdict \"error\" + no findings — the notice\n // signature, isIncompleteFindings) and a prior that is not unmistakably a completed\n // FULL review (route-aware seed chain): a CI-fix mechanic pass must not sit in the\n // seed chain as if it were the previous review. The route marker wins; a route-less\n // body counts as full-review ancestry ONLY through the carried completed-ancestor\n // marker (and never mechanic ancestry) — round history can't identify the last\n // review (a mechanic carries a full review's rounds forward), so any other no-route\n // prior is unknown and skipped: one cold review is cheaper than a false prior.\n if (isIncompleteFindings(seedDoc)) return false;\n if (!isFullReviewAncestry(priorBody ?? \"\")) return false;\n writeFileSync(outPath, SEED_SENTINEL);\n writeFileSync(priorContextPath(outPath), `${JSON.stringify(seedDoc, null, 2)}\\n`);\n process.stderr.write(\n `Seeded ${outPath} with the sentinel and wrote the prior review (${String(seedDoc.findings.length)} finding(s)) to ${priorContextPath(outPath)} as context\\n`,\n );\n return true;\n } catch (err) {\n process.stderr.write(\n `Warning: could not seed from the prior review (${errMsg(err)}) — seeding the sentinel only\\n`,\n );\n return false;\n }\n })();\n\n // prior-same/prior-new split on whether the seeded review examined this exact commit; an unknown\n // prior SHA (older comment, or the all-zeros placeholder) falls to prior-new so the agent\n // re-checks against the current diff rather than assuming the code is unchanged. When nothing\n // could be seeded, empty-had-prior still tells the agent a prior review exists (vs a true first\n // review), and none marks even the sentinel write failing.\n const mode = ((): string => {\n if (seededFromPrior) {\n const priorSha = priorBody === null ? null : parseReviewedSha(priorBody);\n return args[\"head-sha\"] && priorSha && priorSha === args[\"head-sha\"].toLowerCase()\n ? \"prior-same\"\n : \"prior-new\";\n }\n if (!writeSentinel()) return \"none\";\n return priorBody === null ? \"empty\" : \"empty-had-prior\";\n })();\n process.stdout.write(`${mode}\\n`);\n },\n});\n\nconst adaptCmd = defineCommand({\n meta: {\n name: \"adapt\",\n description: \"Map a native agent-CLI result envelope onto the abstract SPEC envelope\",\n },\n args: {\n native: {\n type: \"positional\",\n description: \"Path to the native result envelope JSON (from the agent CLI)\",\n required: true,\n },\n adapter: {\n type: \"string\",\n description: 'Adapter to use (currently: \"claude-code\")',\n required: true,\n },\n \"agent-file\": {\n type: \"string\",\n description:\n \"Path to a file the agent was told to write its own validated findings JSON to (wins over the native envelope's structured_output/result when it validates)\",\n },\n \"agent-file-fallback\": {\n type: \"string\",\n description:\n \"Path to the last-valid findings snapshot, tried after --agent-file and before the native envelope; recovers the last valid state when a wall-clock kill left --agent-file truncated, so the review posts that instead of a 'did not complete' notice\",\n },\n route: {\n type: \"string\",\n description:\n 'Review route label to stamp into the envelope (e.g. \"full review\" or \"mechanic\")',\n },\n effort: {\n type: \"string\",\n description: 'Effort label to stamp into the envelope (e.g. \"max\" or \"low\")',\n },\n transcript: {\n type: \"string\",\n description:\n \"Path to the session transcript (main .jsonl). Its tree (main + subagents) gives the true wall + turn count the native envelope under-reports, and refills per-model usage when the native envelope is empty (e.g. after a wall-clock kill)\",\n },\n },\n run: async ({ args }) => {\n // The agent-file still holds the pre-seeded SENTINEL when the agent never wrote its own review\n // (content check — the same isSeedSentinel test the budget hook uses via the budget.ts SSOT, so\n // a coarse-timestamp filesystem can't misclassify a fresh draft). The sentinel never validates,\n // so it can't be recovered as a review; the flag only refines the \"did not complete\" message.\n // A missing draft is inert (there is no seed to recover), and a non-seeded caller sees nothing.\n // Size-gated: only a sentinel-sized file (plus a trailing-newline tolerance) can be the\n // sentinel, so a real review — the largest input read back — is never read twice per run.\n const agentFile = args[\"agent-file\"];\n const agentFileSize = agentFile ? statSizeOrNull(agentFile) : null;\n const seedUnrevised =\n agentFileSize !== null &&\n agentFileSize <= Buffer.byteLength(SEED_SENTINEL) + 2 &&\n isSeedSentinel(readFileOrNull(agentFile));\n const envelope = unwrapAdapt(\n adapt(requireAdapterName(args.adapter), readJSONOrAbsent(args.native), agentFile, {\n route: args.route,\n effort: args.effort,\n agentFileFallbackPath: args[\"agent-file-fallback\"],\n seedUnrevised,\n ...(args.transcript\n ? {\n transcriptFallback: (): TranscriptTelemetry =>\n transcriptFallbackFrom(args.transcript),\n }\n : {}),\n }),\n );\n process.stdout.write(`${JSON.stringify(envelope, null, 2)}\\n`);\n },\n});\n\nconst noticeCmd = defineCommand({\n meta: {\n name: \"notice\",\n description:\n \"Emit an abstract envelope for a run that produced no completed review (security block, triage error, setup failure, checkout failure, or empty run) — flagged incomplete so the commenter renders it honestly and won't bury a real review\",\n },\n args: {\n kind: {\n type: \"positional\",\n description: `One of: ${NOTICE_KINDS.join(\", \")} (an unrecognized kind renders a generic incomplete notice rather than failing — the pinned CLI is older than the workflow)`,\n required: true,\n },\n reasons: {\n type: \"string\",\n description:\n \"security-blocked / triage-error only: the triage's fail-closed reason string (empty/omitted ⇒ the no-reason wording)\",\n },\n \"sandbox-config\": {\n type: \"string\",\n description:\n \"no-output / triage-error only: path to the agent's sandbox-runtime settings (sandbox.json); its network.allowedDomains is named in the notice so an egress-blocked review self-diagnoses. Missing or unreadable ⇒ the allowlist is omitted (an early failure runs before the jail is set up).\",\n },\n },\n // An unrecognized kind degrades to a generic incomplete notice instead of exiting non-zero: a\n // `notice <kind>` call under the workflow's `set -euo pipefail` must never crash the assemble\n // step into posting nothing, and an unknown kind almost always means version skew, not a typo.\n run: ({ args }) => {\n if (!isNoticeKind(args.kind)) {\n process.stderr.write(\n `::warning::code-review notice: unrecognized kind \"${annotationSafe(args.kind)}\" — the pinned CLI is older than the workflow calling it; rendering a generic incomplete notice\\n`,\n );\n process.stdout.write(`${JSON.stringify(buildUnknownNoticeEnvelope(args.kind), null, 2)}\\n`);\n return;\n }\n // Read the sandbox config only for the kinds that name the allowlist (a jailed agent ran), so the\n // \"no-output / triage-error only\" contract is enforced by the handler, not just documented.\n const namesAllowlist = args.kind === \"no-output\" || args.kind === \"triage-error\";\n const agentAllowlist =\n namesAllowlist && args[\"sandbox-config\"]\n ? parseAgentAllowlist(readSandboxConfigForNotice(args[\"sandbox-config\"]))\n : [];\n process.stdout.write(\n `${JSON.stringify(buildNoticeEnvelope(args.kind, args.reasons, agentAllowlist), null, 2)}\\n`,\n );\n },\n});\n\nconst isExtractSchemaKind = (s: string): s is ExtractKind => s === \"findings\" || s === \"triage\";\n\n// no \"prices\" — unlike print-schema's kinds.\nconst requireExtractSchemaKind = (name: string): ExtractKind =>\n isExtractSchemaKind(name)\n ? name\n : fail(`Unknown kind \"${name}\" for extract — expected one of: findings, triage`);\n\n/** Fail-closed triage synthesized when the ladder can't recover a validated triage verdict — never\n * defaults to safe. */\nconst failClosedTriage = (outcome: Exclude<LadderOutcome, { kind: \"ok\" }>): Triage => ({\n safe: false,\n reasons: describeLadderFailure(outcome),\n});\n\nconst extractCmd = defineCommand({\n meta: {\n name: \"extract\",\n description:\n \"Recover findings/triage JSON from a native agent-CLI result envelope via the deterministic extraction ladder\",\n },\n args: {\n native: {\n type: \"positional\",\n description: \"Path to the native result envelope JSON (from the agent CLI)\",\n required: true,\n },\n adapter: {\n type: \"string\",\n description: 'Adapter whose native envelope shape to extract from (currently: \"claude-code\")',\n required: true,\n },\n kind: {\n type: \"string\",\n description: \"Schema kind to extract: findings | triage\",\n required: true,\n },\n \"agent-file\": {\n type: \"string\",\n description:\n \"Path to a file the agent was told to write its own validated JSON to (findings only — a documented no-op for triage)\",\n },\n },\n run: async ({ args }) => {\n requireAdapterName(args.adapter);\n const kind = requireExtractSchemaKind(args.kind);\n const input = { kind, native: readJSON(args.native), agentFilePath: args[\"agent-file\"] };\n const outcome = extractStructured(input);\n\n if (outcome.kind === \"ok\") {\n process.stdout.write(`${JSON.stringify(outcome.candidate, null, 2)}\\n`);\n return;\n }\n // A recovery miss is otherwise opaque (only the generic reason reaches the comment); trace what\n // each rung saw to stderr so the CI log alone explains the failure — no local repro needed.\n if (outcome.kind === \"none\" || outcome.kind === \"ambiguous\") {\n process.stderr.write(`extract: recovery failed —\\n${ladderFailureDiagnostics(input)}\\n`);\n }\n if (kind === \"triage\") {\n process.stdout.write(`${JSON.stringify(failClosedTriage(outcome), null, 2)}\\n`);\n return;\n }\n fail(describeLadderFailure(outcome));\n },\n});\n\nconst withoutPatch = (finding: Finding): Finding => {\n const copy = { ...finding };\n delete copy.patch;\n return copy;\n};\n\nconst readFileLines = (path: string): readonly string[] | null => {\n try {\n const rawLines = readFileSync(path, \"utf-8\").split(\"\\n\");\n return rawLines.length > 0 && rawLines[rawLines.length - 1] === \"\"\n ? rawLines.slice(0, -1)\n : rawLines;\n } catch {\n return null;\n }\n};\n\n/** Align/keep/drop one finding's `patch` against the real file at `<repoRoot>/<finding.path>`:\n * aligned to the patch's removed range, kept as-is for a pure insertion, or dropped (logged) when\n * the file can't be read or the patch doesn't apply. Never throws; a no-patch finding passes through. */\nconst validateFinding = (finding: Finding, repoRoot: string): Finding => {\n if (finding.patch === undefined) return finding;\n const lines = readFileLines(resolve(repoRoot, finding.path));\n if (lines === null) {\n process.stderr.write(\n `validate-patches: ${finding.path}: could not read file at \"${repoRoot}\" — dropping patch\\n`,\n );\n return withoutPatch(finding);\n }\n const result = validatePatch(finding.patch, lines);\n switch (result.kind) {\n case \"anchored\":\n return { ...finding, start_line: result.startLine, end_line: result.endLine };\n case \"keep\":\n // Applies cleanly but has no removed range to anchor a suggestion — leave the finding's own\n // start_line/end_line as the inline anchor; the renderer projects the patch to a ```patch block.\n return finding;\n case \"drop\":\n process.stderr.write(\n `validate-patches: ${finding.path}:${String(finding.start_line)}: ${result.reason} — dropping patch\\n`,\n );\n return withoutPatch(finding);\n }\n};\n\nconst validatePatchesCmd = defineCommand({\n meta: {\n name: \"validate-patches\",\n description:\n \"Validate each finding's patch against the real PR-head tree: align the finding's range and keep the patch when it anchors, keep it unaligned for a pure insertion, or drop it when it doesn't apply\",\n },\n args: {\n findings: {\n type: \"positional\",\n description: \"Path to findings JSON\",\n required: true,\n },\n \"repo-root\": {\n type: \"string\",\n description:\n \"Directory to resolve each finding's path against — the review job's checked-out, clean PR-head tree (default: .)\",\n },\n },\n run: async ({ args }) => {\n const findings = decode(FindingsCodec.decode(readJSON(args.findings)), \"findings\");\n const repoRoot = args[\"repo-root\"] ? resolve(args[\"repo-root\"]) : process.cwd();\n const validated = {\n ...findings,\n findings: findings.findings.map((f) => validateFinding(f, repoRoot)),\n };\n process.stdout.write(`${JSON.stringify(validated, null, 2)}\\n`);\n },\n});\n\nconst requireAdapterName = (name: string): AdapterName =>\n isAdapterName(name) ? name : fail(`Unknown adapter \"${name}\" — supported: claude-code`);\n\nconst isSchemaKind = (s: string): s is SchemaKind =>\n s === \"findings\" || s === \"triage\" || s === \"prices\";\n\nconst requireSchemaKind = (name: string): SchemaKind =>\n isSchemaKind(name)\n ? name\n : fail(`Unknown schema \"${name}\" — expected one of: findings, triage, prices`);\n\nconst requireSchemaPath = (kind: SchemaKind, version: string | undefined): string => {\n try {\n return schemaPathFor(kind, version);\n } catch (err) {\n return fail(errMsg(err));\n }\n};\n\nconst printSchemaCmd = defineCommand({\n meta: {\n name: \"print-schema\",\n description:\n \"Print a bundled schema JSON, ready to hand to a CLI's --json-schema (the $schema draft declaration is stripped)\",\n },\n args: {\n name: {\n type: \"positional\",\n description: \"Schema to print: findings | triage | prices\",\n required: true,\n },\n \"schema-version\": {\n type: \"string\",\n description: \"Schema major.minor version to print (default: latest)\",\n },\n },\n run: async ({ args }) => {\n const schemaKind = requireSchemaKind(args.name);\n const schemaPath = requireSchemaPath(schemaKind, args[\"schema-version\"]);\n process.stdout.write(\n `${printableSchema(schemaPath, schemaKind === \"findings\" && schemaPath === schemaPathFor(schemaKind))}\\n`,\n );\n },\n});\n\nconst defaultVersionCmd = defineCommand({\n meta: {\n name: \"default-version\",\n description:\n \"Print the in-force schema version the installed registry resolves by default — the value a draft should stamp as schema_version\",\n },\n args: {\n kind: {\n type: \"string\",\n description: \"Schema kind (findings | triage | prices); default: findings\",\n },\n },\n run: async ({ args }) => {\n const kind = requireSchemaKind(args.kind || \"findings\");\n process.stdout.write(`${defaultVersion(kind)}\\n`);\n },\n});\n\nconst MAX_NUDGES_DEFAULT = 5;\n\n/** Drain the Stop-hook payload on stdin so the caller never sees EPIPE; its content is unused (the\n * decision comes from the draft on disk). Skips on a TTY, where readFileSync(0) would block forever\n * waiting for an EOF that never comes; the real Stop hook writes then closes, so a held-open pipe\n * isn't the production path. */\nconst drainStdin = (): void => {\n if (process.stdin.isTTY) return;\n try {\n readFileSync(0);\n } catch {\n // no stdin\n }\n};\n\n/** Parse `--max-nudges`: a strict positive integer (`>= 1`). A loose `Number.parseInt` accepts\n * `\"5abc\"`/`\"0x5\"` and `0 >= 0` allows on the first call — both silently DISABLE the gate. Reject\n * anything not matching `^\\d+$`, and reject `< 1`, loudly: a gate that never blocks must be an\n * explicit choice (omit the hook), never a typo. */\nconst requireMaxNudges = (raw: string | undefined): number => {\n if (raw === undefined) return MAX_NUDGES_DEFAULT;\n if (!/^\\d+$/.test(raw)) {\n fail(`--max-nudges must be a non-negative integer; got \"${raw}\"`);\n }\n const n = Number.parseInt(raw, 10);\n if (n < 1) {\n fail(`--max-nudges must be >= 1 — a gate that never blocks must be omitted, not set to ${raw}`);\n }\n return n;\n};\n\nconst stopGateCmd = defineCommand({\n meta: {\n name: \"stop-gate\",\n description:\n \"Claude Code Stop-hook gate: refuse to let the agent end its turn until --draft validates against the schema (bounded by --max-nudges). With --print-settings, emit the --settings JSON that wires this as the Stop hook.\",\n },\n args: {\n draft: {\n type: \"string\",\n description: \"Path to the findings document the agent must produce and keep valid\",\n required: true,\n },\n kind: {\n type: \"string\",\n description:\n \"Schema kind to validate against: findings | triage | prices (default: findings)\",\n },\n schema: { type: \"string\", description: \"Path to a schema file (wins over --kind)\" },\n \"schema-version\": {\n type: \"string\",\n description: \"Schema major.minor to validate against (default: the draft's declared version)\",\n },\n \"max-nudges\": {\n type: \"string\",\n description: `Times to block before relenting so the step fails downstream as before (default: ${String(MAX_NUDGES_DEFAULT)})`,\n },\n counter: {\n type: \"string\",\n description: \"Path for the nudge counter (default: <draft>.nudges)\",\n },\n \"print-settings\": {\n type: \"boolean\",\n description: \"Print the Stop-hook settings JSON that wires this gate, then exit\",\n },\n },\n run: async ({ args }) => {\n const draftPath = resolve(args.draft);\n\n if (args[\"print-settings\"]) {\n const command = defaultHookCommand(draftPath, {\n kind: args.kind,\n schema: args.schema,\n schemaVersion: args[\"schema-version\"],\n maxNudges: args[\"max-nudges\"],\n counter: args.counter,\n });\n process.stdout.write(`${JSON.stringify(stopHookSettings(command))}\\n`);\n return;\n }\n\n drainStdin();\n\n const kind = requireSchemaKind(args.kind || \"findings\");\n const maxNudges = requireMaxNudges(args[\"max-nudges\"]);\n const counterPath = args.counter ? resolve(args.counter) : `${draftPath}.nudges`;\n\n // schemaPathFor throws (rather than the process-exiting requireSchemaPath) so that a draft\n // declaring an unsupported schema_version is caught by draftState and treated as invalid —\n // i.e. a block with a helpful message — instead of crashing the hook and letting the agent stop.\n const state = draftState(draftPath, (parsed) =>\n args.schema\n ? resolve(args.schema)\n : schemaPathFor(kind, args[\"schema-version\"] || derivedSchemaVersion(kind, parsed)),\n );\n\n const nudges = readNudges(counterPath);\n const decision = decideGate(state, nudges, maxNudges, draftPath, kind);\n if (decision.kind === \"block\") {\n // CRITICAL ordering: bump the counter FIRST, and emit the block ONLY after the increment is\n // durably persisted. If the write fails, do NOT block — a block we can't bound loops forever\n // (the counter never advances → `nudges >= maxNudges` is never reached). Allow the stop and\n // log: a missed nudge is far less bad than an unbounded block loop.\n try {\n bumpNudges(counterPath, nudges);\n } catch (err) {\n process.stderr.write(\n `stop-gate: cannot persist nudge counter at ${counterPath} → allowing to avoid an unbounded block loop: ${errMsg(err)}\\n`,\n );\n return;\n }\n process.stdout.write(`${JSON.stringify({ decision: \"block\", reason: decision.reason })}\\n`);\n }\n },\n});\n\nconst gatherCmd = defineCommand({\n meta: {\n name: \"gather\",\n description:\n \"Resolve the PR from the CI head SHA and gather review inputs (diff with git-diff fallback, PR context, prior bot review, untrusted PR conversation to triage, failing-job logs and the failing jobs' identities in failed_jobs.json) as files for the review agent\",\n },\n args: {\n repo: { type: \"string\", description: \"Repository (owner/name)\", required: true },\n \"head-sha\": {\n type: \"string\",\n description: \"Trusted head SHA to resolve the PR (from workflow_run.head_sha)\",\n required: true,\n },\n \"head-branch\": {\n type: \"string\",\n description: \"Head branch to disambiguate the PR when multiple share a commit\",\n },\n \"default-branch\": {\n type: \"string\",\n description:\n \"The repo's default branch — the trusted base the review checks out, and the reference for the full (triage) diff; a PR based on any other branch is treated as stacked\",\n required: true,\n },\n \"run-id\": {\n type: \"string\",\n description:\n \"CI run id (from workflow_run.id); its failing jobs' logs are downloaded on failure\",\n required: true,\n },\n conclusion: {\n type: \"string\",\n description:\n \"CI conclusion (e.g. success | failure); failure triggers failing-job log download\",\n required: true,\n },\n \"bot-login\": {\n type: \"string\",\n description:\n \"Bot login whose last PR comment is captured as prior review (default: github-actions[bot])\",\n },\n \"out-dir\": {\n type: \"string\",\n description: \"Directory to write gathered files into (default: current directory)\",\n },\n },\n run: async ({ args }) => {\n const result = await gather({\n repo: args.repo,\n headSha: args[\"head-sha\"],\n headBranch: args[\"head-branch\"],\n defaultBranch: args[\"default-branch\"],\n runId: args[\"run-id\"],\n conclusion: args.conclusion,\n botLogin: args[\"bot-login\"] || \"github-actions[bot]\",\n outDir: args[\"out-dir\"] ? resolve(args[\"out-dir\"]) : process.cwd(),\n });\n process.stdout.write(renderOutputs(result));\n },\n});\n\nconst postCmd = defineCommand({\n meta: {\n name: \"post\",\n description:\n \"Post a complete review (inline comments + sticky summary) from findings + envelope + diff\",\n },\n args: {\n findings: {\n type: \"positional\",\n description: \"Path to findings JSON\",\n required: true,\n },\n \"head-sha\": {\n type: \"string\",\n description: \"Trusted head SHA to resolve the PR (from workflow_run.head_sha)\",\n required: true,\n },\n repo: {\n type: \"string\",\n description: \"Repository (owner/name)\",\n required: true,\n },\n usage: {\n type: \"string\",\n description: \"Path to result envelope JSON (from agent CLI)\",\n required: true,\n },\n prices: {\n type: \"string\",\n description:\n \"Path to price map JSON (default: bundled schema/prices.example.json — all zero)\",\n },\n template: {\n type: \"string\",\n description:\n \"Path to Eta template file for the summary comment (default: bundled templates/comment.eta)\",\n },\n \"inline-template\": {\n type: \"string\",\n description: \"Path to inline comment Eta template (default: bundled templates/inline.eta)\",\n },\n route: {\n type: \"string\",\n description:\n \"Review route label; overrides the envelope's route when set (default: read from the envelope)\",\n },\n \"bot-login\": {\n type: \"string\",\n description: \"Bot login to trust for sticky comment upsert (default: github-actions[bot])\",\n },\n \"head-branch\": {\n type: \"string\",\n description: \"Head branch to disambiguate PR when multiple share a commit\",\n },\n effort: {\n type: \"string\",\n description:\n \"Effort label; overrides the envelope's effort when set (default: read from the envelope)\",\n },\n \"test-report\": {\n type: \"string\",\n description: TEST_REPORT_DESCRIPTION,\n },\n \"cloc-diff\": {\n type: \"string\",\n description: CLOC_DIFF_DESCRIPTION,\n },\n \"run-url\": {\n type: \"string\",\n description:\n \"Workflow run URL (transcript/traces), rendered as a link in the LLM Disclosure aside and in the review-object body\",\n },\n \"json-url\": {\n type: \"string\",\n description:\n \"URL to the machine-readable findings JSON artifact, pointed at from the sticky and each inline comment\",\n },\n \"convergence-threshold\": {\n type: \"string\",\n description: CONVERGENCE_THRESHOLD_DESCRIPTION,\n },\n \"nit-visibility-floor\": {\n type: \"string\",\n description: NIT_VISIBILITY_FLOOR_DESCRIPTION,\n },\n inline: {\n type: \"boolean\",\n description:\n \"Also render findings as inline review comments on the diff. Off by default: an inline thread cannot be revised by a later round, so stale threads accumulate. The review object is posted either way; with this off the sticky lists the findings instead\",\n },\n \"unverified-no-logs\": {\n type: \"boolean\",\n description:\n \"Mark the review unverified: the fast-fix route ran with no failing-job logs staged, so its findings came from the diff alone. The caller decides this — the logs are staged in the review job, not here\",\n },\n },\n run: async ({ args }) => {\n const priceResolution = resolvePrices(args.prices);\n await post({\n repo: args.repo,\n // The workflow's post step threads HEAD_REPO env (the fork's owner/name) — a finding\n // permalink targets the tree the reviewed SHA lives in (issue #231 r1). Absent/empty ⇒ the\n // base repo. Env rather than a flag: an older pinned CLI simply ignores it.\n headRepo: process.env[\"HEAD_REPO\"] || undefined,\n headSha: args[\"head-sha\"],\n botLogin: args[\"bot-login\"] || \"github-actions[bot]\",\n findingsPath: args.findings,\n envelopePath: args.usage,\n pricesPath: priceResolution.path,\n pricesProvided: priceResolution.kind === \"provided\",\n templatePath: resolveTemplatePath(args.template),\n inlineTemplatePath: resolveInlineTemplatePath(args[\"inline-template\"]),\n route: args.route,\n headBranch: args[\"head-branch\"],\n effort: args.effort,\n testReportPath: args[\"test-report\"],\n clocDiffPath: args[\"cloc-diff\"],\n runUrl: args[\"run-url\"],\n jsonUrl: args[\"json-url\"],\n convergenceThreshold: parseConvergenceThreshold(args[\"convergence-threshold\"]),\n nitVisibilityFloor: parseNitVisibilityFloor(args[\"nit-visibility-floor\"]),\n inline: args.inline,\n unverifiedNoLogs: args[\"unverified-no-logs\"],\n postedAt: formatUtc(new Date()),\n pricedAt: new Date(),\n });\n },\n});\n\nconst announceCmd = defineCommand({\n meta: {\n name: \"announce\",\n description:\n \"Post (or update) the sticky the moment a review starts — an in-progress placeholder linking the run — so a workflow_run review, which runs from the default branch and is otherwise invisible on the PR, is visibly under way. Preserves a prior sticky's embedded findings + reviewed-sha markers so the re-review seed survives the swap.\",\n },\n args: {\n \"head-sha\": {\n type: \"string\",\n description: \"Trusted head SHA to resolve the PR (from workflow_run.head_sha)\",\n required: true,\n },\n repo: {\n type: \"string\",\n description: \"Repository (owner/name)\",\n required: true,\n },\n \"run-url\": {\n type: \"string\",\n description: \"Workflow run URL the placeholder links to\",\n required: true,\n },\n \"bot-login\": {\n type: \"string\",\n description:\n \"Bot login to trust for the sticky comment upsert (default: github-actions[bot])\",\n },\n \"head-branch\": {\n type: \"string\",\n description: \"Head branch to disambiguate the PR when multiple share a commit\",\n },\n },\n run: async ({ args }) => {\n // Best-effort, like `react`: the in-progress sticky is cosmetic, so a transient API error must\n // warn and exit 0 rather than fail its job (the review + real comment proceed regardless).\n await announce({\n repo: args.repo,\n headSha: args[\"head-sha\"],\n botLogin: args[\"bot-login\"] || \"github-actions[bot]\",\n runUrl: args[\"run-url\"],\n headBranch: args[\"head-branch\"],\n }).catch((err: unknown) =>\n // `::warning::` so a persistently broken announce shows up in the run's annotations, not only\n // buried in the step log — `announce` otherwise reports success while having posted nothing.\n process.stderr.write(\n `::warning::code-review announce: could not post the in-progress sticky (${annotationSafe(errMsg(err))}) — continuing (cosmetic)\\n`,\n ),\n );\n },\n});\n\nconst isCheckIntent = (s: string): s is CheckIntent =>\n s === \"in_progress\" || s === \"neutral\" || s === \"failure\" || s === \"cancelled\";\n\nconst checkRunCmd = defineCommand({\n meta: {\n name: \"check-run\",\n description:\n \"Upsert the native 'Code review' check-run on the head SHA — the attribution surface that appears in the PR's own checks list and (writing to the base repo) works for fork PRs too. `in_progress` at review start, `neutral` when the review completes, `failure` when it didn't, `cancelled` when a cancelled review settles its own check (matched by details_url, so it never touches a superseding run's check). Forward-only: `failure`/`cancelled` never overwrite a completed review.\",\n },\n args: {\n repo: { type: \"string\", description: \"Repository (owner/name)\", required: true },\n \"head-sha\": {\n type: \"string\",\n description: \"Head SHA the check-run is anchored to\",\n required: true,\n },\n status: {\n type: \"positional\",\n description: \"One of: in_progress, neutral, failure, cancelled\",\n required: true,\n },\n \"run-url\": {\n type: \"string\",\n description:\n \"Workflow run URL the check-run's details link to (also the ownership key for `cancelled`)\",\n required: true,\n },\n },\n run: async ({ args }) => {\n if (!isCheckIntent(args.status)) {\n // Best-effort like `announce`: the check-run is an attribution aid, so an unknown status (version\n // skew) warns and exits 0 rather than failing the job the review otherwise proceeds through.\n process.stderr.write(\n `::warning::code-review check-run: unrecognized status \"${annotationSafe(args.status)}\" — expected in_progress, neutral, failure, or cancelled; skipping\\n`,\n );\n return;\n }\n await checkRun({\n repo: args.repo,\n headSha: args[\"head-sha\"],\n intent: args.status,\n runUrl: args[\"run-url\"],\n }).catch((err: unknown) =>\n process.stderr.write(\n `::warning::code-review check-run: could not upsert the check-run (${annotationSafe(errMsg(err))}) — continuing (attribution aid)\\n`,\n ),\n );\n },\n});\n\nconst reportIncompleteCmd = defineCommand({\n meta: {\n name: \"report-incomplete\",\n description:\n \"Post (or update) the sticky when a review job hard-failed and posted nothing — an attributed 'did not complete' notice linking the run, telling the reader to re-request; with --cancelled, the informational 'superseded — no action needed' notice instead (issue #139). Never buries a completed review, and never overwrites a superseding run's live in-progress placeholder.\",\n },\n args: {\n repo: { type: \"string\", description: \"Repository (owner/name)\", required: true },\n \"head-sha\": {\n type: \"string\",\n description: \"Trusted head SHA to resolve the PR (from workflow_run.head_sha)\",\n required: true,\n },\n \"run-url\": {\n type: \"string\",\n description: \"Workflow run URL the notice links to\",\n required: true,\n },\n \"bot-login\": {\n type: \"string\",\n description:\n \"Bot login to trust for the sticky comment upsert (default: github-actions[bot])\",\n },\n \"head-branch\": {\n type: \"string\",\n description: \"Head branch to disambiguate the PR when multiple share a commit\",\n },\n cancelled: {\n type: \"boolean\",\n description:\n \"This run was CANCELLED before completing (typically superseded by a newer run on the same branch) — post the informational 'superseded' notice, not the failure notice (issue #139)\",\n },\n },\n run: async ({ args }) => {\n await reportIncomplete({\n repo: args.repo,\n headSha: args[\"head-sha\"],\n botLogin: args[\"bot-login\"] || \"github-actions[bot]\",\n runUrl: args[\"run-url\"],\n headBranch: args[\"head-branch\"],\n cancelled: args.cancelled,\n }).catch((err: unknown) =>\n process.stderr.write(\n `::warning::code-review report-incomplete: could not post the notice (${annotationSafe(errMsg(err))}) — continuing\\n`,\n ),\n );\n },\n});\n\n/** Parse a `--max-duration`/ceiling flag to whole seconds; a bad value is trusted-config error, so\n * fail loudly rather than silently disabling the clamp. undefined ⇒ no ceiling. */\nconst requireCeilingSec = (raw: string | undefined): number | null => {\n if (raw === undefined) return null;\n const ms = parseWallMs(raw);\n if (ms === null)\n return fail(`--max-duration must be a duration like 60m, 3600s, or 1h (got \"${raw}\")`);\n return Math.floor(ms / 1000);\n};\n\nconst requireCeilingUsd = (raw: string | undefined): number | null => {\n if (raw === undefined) return null;\n const n = Number.parseFloat(raw.replace(/^\\$/, \"\"));\n if (!Number.isFinite(n) || n < 0) fail(`--max-usd must be a non-negative number (got \"${raw}\")`);\n return n;\n};\n\nconst requireMaxInstructions = (raw: string | undefined): number => {\n if (raw === undefined) return 4000;\n if (!/^\\d+$/.test(raw)) fail(`--max-instructions must be a non-negative integer (got \"${raw}\")`);\n return Number.parseInt(raw, 10);\n};\n\nconst requirePositiveInt = (raw: string, flag: string): number => {\n const n = Number.parseInt(raw, 10);\n return Number.isInteger(n) && n > 0 && /^\\d+$/.test(raw)\n ? n\n : fail(`${flag} must be a positive integer; got \"${raw}\"`);\n};\n\nconst requireWallMs = (raw: string | undefined, flag: string, fallback: string): number => {\n const ms = parseWallMs(raw || fallback);\n return ms === null\n ? fail(`${flag} must be a duration like 30m, 15s, or 1h (got \"${raw ?? \"\"}\")`)\n : ms;\n};\n\nconst parseCommandCmd = defineCommand({\n meta: {\n name: \"parse-command\",\n description:\n 'Resolve a PR\\'s head (SHA/branch/repo) from its NUMBER via the API and parse a ChatOps trigger comment (\"/code-review [24m] [$1.00] <instructions>\") into $GITHUB_OUTPUT lines. The untrusted comment is parsed here in type-safe code, never in workflow bash, and the head is resolved from the trusted PR number, never from the comment text. Emits should_run=false (and nothing else) when the comment is not the trigger, the PR is closed, or resolution fails.',\n },\n args: {\n repo: { type: \"string\", description: \"Repository (owner/name)\", required: true },\n pr: {\n type: \"string\",\n description: \"PR number (from github.event.issue.number — trusted event data)\",\n required: true,\n },\n \"comment-body\": {\n type: \"string\",\n description:\n \"The comment body to parse (default: the CODE_REVIEW_COMMENT_BODY env var — the safe way to pass untrusted text without shell interpolation)\",\n },\n trigger: {\n type: \"string\",\n description: 'Trigger token the comment must begin with (default: \"/code-review\")',\n },\n \"max-duration\": {\n type: \"string\",\n description:\n \"Ceiling the requested duration is clamped to (e.g. 60m); omit for no clamp — a comment could then request an unbounded wall, so set this\",\n },\n \"max-usd\": {\n type: \"string\",\n description: \"Ceiling the requested USD budget is clamped to (e.g. 5); omit for no clamp\",\n },\n \"max-instructions\": {\n type: \"string\",\n description: \"Max characters of free-form instructions kept (default: 4000)\",\n },\n },\n run: async ({ args }) => {\n const body = args[\"comment-body\"] || process.env[\"CODE_REVIEW_COMMENT_BODY\"] || \"\";\n const result = await parseCommand({\n repo: args.repo,\n prNumber: requirePositiveInt(args.pr, \"--pr\"),\n body,\n options: {\n trigger: args.trigger || \"/code-review\",\n maxDurationSec: requireCeilingSec(args[\"max-duration\"]),\n maxUsd: requireCeilingUsd(args[\"max-usd\"]),\n maxInstructionsLen: requireMaxInstructions(args[\"max-instructions\"]),\n },\n });\n if (result.kind === \"skip\") {\n process.stderr.write(`code-review parse-command: not running — ${result.reason}\\n`);\n process.stdout.write(renderCommandOutputs(result, \"UNUSED\"));\n return;\n }\n for (const note of result.args.notes)\n process.stderr.write(`code-review parse-command: ${note}\\n`);\n const delim = safeHeredocDelim(result.args.instructions, () => randomBytes(16).toString(\"hex\"));\n process.stdout.write(renderCommandOutputs(result, delim));\n },\n});\n\nconst requireReaction = (name: string): Reaction =>\n isReaction(name) ? name : fail(`Unknown reaction \"${name}\" — one of: ${REACTIONS.join(\", \")}`);\n\nconst reactCmd = defineCommand({\n meta: {\n name: \"react\",\n description:\n \"Add and/or remove a GitHub reaction on a PR/issue comment — the ChatOps acknowledgement (👀 on receipt, swapped to 🚀 on completion). Cosmetic: warns and exits 0 on any API error so a reaction never fails the job.\",\n },\n args: {\n repo: { type: \"string\", description: \"Repository (owner/name)\", required: true },\n \"comment-id\": {\n type: \"string\",\n description: \"Comment id to react on (github.event.comment.id)\",\n required: true,\n },\n add: { type: \"string\", description: `Reaction to add: ${REACTIONS.join(\" | \")}` },\n remove: {\n type: \"string\",\n description: \"Reaction (of the token owner) to remove after adding — for the 👀→🚀 swap\",\n },\n },\n run: async ({ args }) => {\n const commentId = requirePositiveInt(args[\"comment-id\"], \"--comment-id\");\n const add = args.add ? requireReaction(args.add) : undefined;\n const remove = args.remove ? requireReaction(args.remove) : undefined;\n if (add === undefined && remove === undefined)\n fail(\"react: nothing to do — pass --add and/or --remove\");\n await react({ repo: args.repo, commentId, add, remove }).catch((err: unknown) =>\n process.stderr.write(\n `code-review react: reaction update failed (${errMsg(err)}) — continuing (reactions are cosmetic)\\n`,\n ),\n );\n },\n});\n\nconst awaitCiCmd = defineCommand({\n meta: {\n name: \"await-ci\",\n description:\n \"Wait for the PR head's CI workflow run to conclude, then emit its REAL conclusion + run id to $GITHUB_OUTPUT (ci_settled, ci_conclusion, ci_run_id). The on-demand comment trigger uses this so it routes on the same CI result the CI-completion trigger would — success → full review, failure → mechanic with that run's logs — instead of reviewing blind. Polls until the run completes or the timeout elapses; ci_settled=false ⇒ no conclusive result (caller should decline to review, not guess).\",\n },\n args: {\n repo: { type: \"string\", description: \"Repository (owner/name)\", required: true },\n \"head-sha\": {\n type: \"string\",\n description: \"PR head SHA to find the CI run for (resolved from the trusted PR number)\",\n required: true,\n },\n \"ci-workflow\": {\n type: \"string\",\n description: 'CI workflow name to wait for — the name: of your CI workflow (default: \"CI\")',\n },\n timeout: {\n type: \"string\",\n description: \"Give up waiting after this wall (default: 30m)\",\n },\n \"poll-interval\": {\n type: \"string\",\n description: \"How often to re-check the run status (default: 15s)\",\n },\n },\n run: async ({ args }) => {\n const workflowName = args[\"ci-workflow\"] || \"CI\";\n const outcome = await awaitCiConclusion(args.repo, args[\"head-sha\"], {\n workflowName,\n pollIntervalMs: requireWallMs(args[\"poll-interval\"], \"--poll-interval\", \"15s\"),\n timeoutMs: requireWallMs(args.timeout, \"--timeout\", \"30m\"),\n });\n process.stderr.write(\n outcome.kind === \"concluded\"\n ? `code-review await-ci: CI run ${String(outcome.runId)} (\"${workflowName}\") concluded \"${outcome.conclusion}\"\\n`\n : `code-review await-ci: no run named \"${workflowName}\" concluded before the timeout — not reviewing.${\n outcome.seenNames.length > 0\n ? ` Workflow names seen for this head SHA: ${outcome.seenNames.join(\", \")} — check --ci-workflow matches one.`\n : \" No workflow runs were seen for this head SHA at all.\"\n }\\n`,\n );\n process.stdout.write(renderCiOutputs(outcome));\n },\n});\n\nconst checkScopeCmd = defineCommand({\n meta: {\n name: \"check-scope\",\n description:\n \"Validate + normalize the workflow's `scope` input — the languages/inputs the project accepts (issue #139). Prints the normalized space-separated language list for splicing into the review prompt, or nothing when the scope is empty (the reviewer then infers it from the README's first paragraph). A structurally malformed value is rejected rather than spliced in as-is.\",\n },\n args: {\n scope: {\n type: \"string\",\n description:\n 'The raw scope value — whitespace/comma/semicolon-separated language names (e.g. \"C C++\"); empty ⇒ absent',\n },\n },\n run: ({ args }) => {\n const parsed = parseScope(args.scope);\n switch (parsed.kind) {\n case \"absent\":\n return;\n case \"invalid\":\n return fail(`check-scope: ${parsed.reason}`);\n case \"ok\":\n process.stdout.write(`${parsed.languages.join(\" \")}\\n`);\n }\n },\n});\n\nconst sandboxConfigCmd = defineCommand({\n meta: {\n name: \"sandbox-config\",\n description:\n \"Emit the sandbox-runtime (srt) settings that jail the untrusted review agent's egress: allow the model host (derived from api_base_url), the GitHub API/host, and the consumer's extra_endpoints; deny all else; filesystem isolation off\",\n },\n args: {\n \"api-base-url\": {\n type: \"string\",\n description:\n \"The model endpoint the CLI dials (ANTHROPIC_BASE_URL) — its host is allowlisted\",\n required: true,\n },\n extra: {\n type: \"string\",\n description:\n \"Whitespace-separated host[:port] list of extra domains to allow (the extra_endpoints input)\",\n },\n out: {\n type: \"string\",\n description: \"Write the settings JSON here instead of stdout\",\n },\n \"known-model-host\": {\n type: \"string\",\n description:\n \"Additional model HOST(S) to treat as known (space-separated bare hostnames, not URLs) — the consumer's declared host(s) for a provider outside the built-in set; a derived host outside the built-ins and this list warns (or fails under --strict-host)\",\n },\n \"strict-host\": {\n type: \"boolean\",\n description:\n \"Fail (instead of warning) when the model host derived from api_base_url is not a well-known or declared host — closes the fail-open-on-typo gap where a mistyped api_base_url would still be allowlisted and sent the key\",\n },\n },\n run: ({ args }) => {\n // The jail derives its ONLY egress allowlist entry from api_base_url; a typo now fails OPEN (dials\n // whatever it names). Warn loudly on an unknown host so a misconfiguration is visible in the setup\n // log, or hard-fail under --strict-host. A consumer on a provider outside the built-in set declares\n // it via --known-model-host so it passes while a typo of it does not.\n const modelHost = deriveModelHost(args[\"api-base-url\"]);\n // Both --known-model-host AND --extra count as declared: extra_endpoints already allowlists a\n // consumer's self-hosted model host through this same jail (and the reusable documents that use),\n // so treating it as known avoids warning on a host the admin explicitly vouched for.\n const declaredHosts = [\n ...(args[\"known-model-host\"] ? parseExtraEndpoints(args[\"known-model-host\"]) : []),\n ...(args.extra ? parseExtraEndpoints(args.extra) : []),\n ];\n if (!isKnownModelHost(modelHost, declaredHosts)) {\n const message = `code-review sandbox-config: derived model host \"${modelHost}\" is not a well-known or declared host — the jail will allow egress to it and send MODEL_API_KEY there; verify api_base_url is correct`;\n // Both paths surface as GitHub annotations (::error:: hard-fails, ::warning:: continues), so the\n // same condition is visible the same way whether or not --strict-host is set.\n if (args[\"strict-host\"]) {\n process.stderr.write(`::error::${annotationSafe(message)}\\n`);\n process.exit(1);\n }\n process.stderr.write(`::warning::${annotationSafe(message)}\\n`);\n }\n const config = buildSandboxConfig({ apiBaseUrl: args[\"api-base-url\"], extra: args.extra });\n const json = `${JSON.stringify(config, null, 2)}\\n`;\n if (args.out) {\n writeFileSync(resolve(args.out), json);\n } else {\n process.stdout.write(json);\n }\n },\n});\n\nexport const main = defineCommand({\n meta: {\n name: \"code-review\",\n version: packageVersion,\n description: \"Deterministic commenter for agentic PR review\",\n },\n subCommands: {\n gather: gatherCmd,\n \"parse-command\": parseCommandCmd,\n react: reactCmd,\n \"await-ci\": awaitCiCmd,\n render: renderCmd,\n inline: inlineCmd,\n post: postCmd,\n announce: announceCmd,\n \"check-run\": checkRunCmd,\n \"check-scope\": checkScopeCmd,\n \"report-incomplete\": reportIncompleteCmd,\n cost: costCmd,\n \"check-cost\": checkCostCmd,\n validate: validateCmd,\n \"seed-draft\": seedDraftCmd,\n adapt: adaptCmd,\n notice: noticeCmd,\n extract: extractCmd,\n \"validate-patches\": validatePatchesCmd,\n \"print-schema\": printSchemaCmd,\n \"default-version\": defaultVersionCmd,\n \"stop-gate\": stopGateCmd,\n \"budget-hook\": budgetHookCmd,\n \"print-settings\": printSettingsCmd,\n deadline: deadlineCmd,\n \"sandbox-config\": sandboxConfigCmd,\n },\n});\n\n// Skip auto-invocation under the test runner — tests drive `main` directly via citty's runCommand.\nif (!process.env[\"VITEST\"]) {\n await runMain(main);\n}\n"]}
1
+ {"version":3,"sources":["../src/util.ts","../src/schema.ts","../src/released.ts","../src/cost.ts","../src/patch.ts","../src/surface.ts","../src/comment-chain.ts","../src/transcript.ts","../src/answered.ts","../src/render.ts","../src/diff.ts","../src/inline.ts","../src/validate.ts","../src/stop-gate.ts","../src/budget.ts","../src/format.ts","../src/notice.ts","../src/registry.ts","../src/exec.ts","../src/gh.ts","../src/artifact.ts","../src/pr.ts","../src/checkrun.ts","../src/post.ts","../src/command.ts","../src/react.ts","../src/ci.ts","../src/gather.ts","../src/extract.ts","../src/adapt.ts","../src/settings.ts","../src/sandbox.ts","../src/scope.ts","../src/index.ts"],"names":["identity","record","key","run","t","t2","type","answeredNote","Eta","readFileSync","basename","join","dirname","resolvePath","resolve","execFile","findings","stampedFindings","reviewUrl","unanchoredCount","t3","t4","t5","t6","writeFileSync","scanLine","t7","output"],"mappings":"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","file":"index.js","sourcesContent":["import { readFileSync } from \"node:fs\";\n\nexport const asRecord = (u: unknown): Record<string, unknown> | null =>\n typeof u === \"object\" && u !== null && !Array.isArray(u) ? (u as Record<string, unknown>) : null;\n\nexport const errMsg = (e: unknown): string => (e instanceof Error ? e.message : String(e));\n\n// A GitHub Actions workflow command (`::warning::…`) is single-line: a CR/LF in the message ends the\n// annotation early, and a following `::…::` in the remainder would be parsed as another command.\n// Collapse line breaks so an untrusted interpolation (e.g. `gh` stderr) can't break out of one.\nexport const annotationSafe = (msg: string): string => msg.replaceAll(/[\\r\\n]+/g, \" \");\n\n// A caller declares a model's real context window to the agent CLI by suffixing the id it configures\n// (`deepseek-v4-pro[1m]`). The CLI strips that before the request and it is absent from the price\n// map, so it is a directive rather than part of the model's identity — but the CLI does key its own\n// usage telemetry by the configured id. Every ingress that reads a model id from the agent\n// canonicalizes it here: carried through, it misses the price map, prices the run at $0, and voids\n// the spend clamp that steers off those same entries.\nexport const modelIdentity = (configuredModelId: string): string =>\n configuredModelId.replace(/\\[[12]m\\]$/i, \"\");\n\nexport type ParseResult = { readonly ok: true; readonly value: unknown } | { readonly ok: false };\n\n// Clip a body to `max` chars without splitting a code point (a lone high surrogate at the cut is\n// dropped so the kept prefix stays well-formed UTF-16). Shared by gather's conversation bodies and\n// the answered-registry reply excerpts.\nexport const clipText = (body: string, max: number): string => {\n if (body.length <= max) return body;\n const cut = body.slice(0, max);\n const safe = /[\\uD800-\\uDBFF]$/.test(cut) ? cut.slice(0, -1) : cut;\n return `${safe}\\n… [truncated]`;\n};\n\n// The shared clip cap for bodies that travel whole: gather clips each conversation body to it, and\n// render clips each carried suppressed-nit field to it. One constant so the two caps cannot drift\n// (the carried clip must match the conversation clip the seeded agent already saw, issue #217\n// review r7).\nexport const BODY_CLIP_CHARS = 4000;\n\nexport const tryParseJson = (text: string): ParseResult => {\n try {\n return { ok: true, value: JSON.parse(text) as unknown };\n } catch {\n return { ok: false };\n }\n};\n\nexport const readFileOrNull = (path: string): string | null => {\n try {\n return readFileSync(path, \"utf-8\");\n } catch {\n return null;\n }\n};\n","// These codecs ARE the source of truth for the data shapes (types via t.TypeOf<>); no hand-written\n// DTO types exist elsewhere — import types from here.\n\nimport * as t from \"io-ts\";\nimport { createHash } from \"node:crypto\";\n\nconst SeverityCodec = t.union([\n t.literal(\"critical\"),\n t.literal(\"major\"),\n t.literal(\"minor\"),\n t.literal(\"nit\"),\n]);\n\nconst SideCodec = t.union([t.literal(\"RIGHT\"), t.literal(\"LEFT\")]);\n\nconst VerdictCodec = t.union([\n t.literal(\"approve\"),\n t.literal(\"comment\"),\n t.literal(\"changes\"),\n t.literal(\"error\"),\n]);\n\nconst LineNumber = t.refinement(\n t.number,\n (n): n is number => Number.isInteger(n) && n >= 1,\n \"LineNumber\",\n);\n\nconst Confidence = t.refinement(t.number, (n): n is number => n >= 0 && n <= 1, \"Confidence\");\nconst Likelihood = t.refinement(t.number, (n): n is number => n >= 0 && n <= 1, \"Likelihood\");\n\n// A convergence score/threshold must be FINITE: io-ts's t.number accepts Infinity/NaN (JSON.parse(\"1e400\")\n// yields Infinity), which JSON.stringify then coerces to null — silently dropping the carried convergence\n// on the next hop. parseSurfaceSignal guards the same vector; the convergence codec must too.\nconst FiniteNumber = t.refinement(t.number, (n): n is number => Number.isFinite(n), \"FiniteNumber\");\n\n// A non-negative price (USD per 1M tokens). Mirrors prices.schema.json's `minimum: 0` so the codec\n// gate rejects a negative rate exactly as the ajv gate does — else a negative price prices negative cost.\nconst NonNegativePrice = t.refinement(t.number, (n): n is number => n >= 0, \"NonNegativePrice\");\n\n// Mirrors findings.schema.json's schema_version.pattern exactly, so resolve() never accepts a value\n// the ajv gate would reject (e.g. a truncated \"0.2\" or an over-long \"0.2.0.0\").\nconst SEMVER_SUFFIX =\n \"(?:-[0-9A-Za-z-]+(?:\\\\.[0-9A-Za-z-]+)*)?(?:\\\\+[0-9A-Za-z-]+(?:\\\\.[0-9A-Za-z-]+)*)?\";\nconst SCHEMA_VERSION_RE = new RegExp(`^(0|[1-9]\\\\d*)\\\\.(\\\\d+)\\\\.(\\\\d+)${SEMVER_SUFFIX}$`);\n\n// The enforcement copy printableSchema injects: the general pattern narrowed to the in-force minor,\n// admitting exactly the stamps (patch, prerelease, build) the registry dispatches to the live entry.\nexport const anchoredSchemaVersionPattern = (version: string): string =>\n `^${version.split(\".\").slice(0, 2).join(\"\\\\.\")}\\\\.[0-9]+${SEMVER_SUFFIX}$`;\n\nconst SchemaVersion = t.refinement(\n t.string,\n (s): s is string => SCHEMA_VERSION_RE.test(s),\n \"SchemaVersion\",\n);\n\n// Mirrors ajv-formats' `uri` format (an absolute, RFC 3986 URI) so the codec gate and the ajv gate\n// agree on code_url — the extraction ladder runs both gates, and post's decode-only path must not\n// accept what ajv rejects. Verified against ajv-formats over the URI corpus; the whitespace check\n// closes the one divergence (URL() auto-encodes raw spaces that a URI cannot contain).\nconst UriString = t.refinement(\n t.string,\n (s): s is string => !/\\s/.test(s) && URL.canParse(s),\n \"UriString\",\n);\n\n// The ONE strict+exact discipline shared by every strict-keyed codec in this file: the ajv gate\n// rejects unknown keys (additionalProperties: false), while t.exact strips them SILENTLY on both\n// encode and decode — so without the refinement the codec gate would accept-and-drop exactly what\n// the ajv gate rejects. The refinement makes the codec gate reject instead, with the key set derived\n// from the passed members. `members` MUST be exactly the shape's prop-bearing leaves (each shape's\n// own component codecs): an omitted leaf would silently reject that leaf's fields on every decode —\n// the key set cannot drift only if the list cannot.\nconst strictExact = <C extends t.HasProps>(\n name: string,\n shape: C,\n members: readonly { props: t.Props }[],\n): t.ExactC<t.RefinementC<C>> => {\n const keys = new Set(members.flatMap((m) => Object.keys(m.props)));\n return t.exact(\n t.refinement(shape, (x): x is t.TypeOf<C> => Object.keys(x).every((k) => keys.has(k)), name),\n );\n};\n\n// The stable mechanism identifier pair, shared by findings and systemic problems so the two shapes\n// can never diverge on it. The `id` itself is REQUIRED on a finding (trackability across rounds and\n// discussions); the optional half of the pair is the URL documenting the rule it names.\nconst RuleUrlCodec = t.partial({\n code_url: UriString,\n});\n\n// The finding's REQUIRED fields minus its identity, shared by BOTH suites: the 0.10 shape adds\n// `id` required (FindingIdRequired), the legacy shape adds the tolerant LegacyRuleCodec instead.\nconst FindingCoreRequired = t.type({\n path: t.string,\n start_line: LineNumber,\n end_line: LineNumber,\n severity: SeverityCodec,\n title: t.string,\n description: t.string,\n reasoning: t.string,\n confidence: Confidence,\n likelihood: Likelihood,\n});\n\nconst FindingIdRequired = t.type({ id: t.string });\n\nconst FindingOptional = t.partial({\n side: SideCodec,\n recommendation: t.string,\n patch: t.string,\n});\n\n// ONE line-anchor gate shared by BOTH finding shapes — they differ only in their identity field.\n// Applied as a WRAPPER refinement around each shape (not an intersection member), so an inner shape\n// failure short-circuits with the outer context (`0.findings.0`) — an intersection member would fail\n// under a bare numeric index and dump the whole finding into the stop-gate message the next-round\n// agent reads.\nconst EndGeStart = <C extends t.HasProps>(shape: C): t.RefinementC<C> =>\n t.refinement(shape, (f): f is t.TypeOf<C> => f.end_line >= f.start_line, \"EndGeStart\");\n\n// Strict-key refinement (see strictExact): t.exact would silently strip unknown keys, so the\n// codec gate must reject exactly what ajv rejects instead of accepting-and-dropping — a removed\n// `code` key must not pass one gate and fail the other.\nconst FindingShape = t.intersection([\n FindingCoreRequired,\n FindingIdRequired,\n RuleUrlCodec,\n FindingOptional,\n]);\n\nexport const FindingCodec = strictExact(\"FindingStrict\", EndGeStart(FindingShape), [\n FindingCoreRequired,\n FindingIdRequired,\n RuleUrlCodec,\n FindingOptional,\n]);\n\n// Cross-cutting observations that tie findings together, with no required line anchor — mirrors\n// findings.schema.json's systemic_problems items exactly, reusing the shared rule-identifier pair.\n// severity/reasoning/confidence are required (owner direction on #134).\nconst SystemicRequired = t.type({\n title: t.string,\n description: t.string,\n severity: SeverityCodec,\n reasoning: t.string,\n confidence: Confidence,\n likelihood: Likelihood,\n});\n\nconst SystemicOptional = t.partial({\n id: t.string,\n finding_ids: t.array(t.string),\n paths: t.array(t.string),\n});\n\nconst SystemicProblemShape = t.intersection([SystemicRequired, RuleUrlCodec, SystemicOptional]);\n\n// The schema declares additionalProperties: false; strictExact makes the codec gate reject exactly\n// what the ajv gate rejects instead of silently stripping (the extraction ladder runs both gates).\nexport const SystemicProblemCodec = strictExact(\"SystemicProblemStrict\", SystemicProblemShape, [\n SystemicRequired,\n RuleUrlCodec,\n SystemicOptional,\n]);\n\n// Shared by BOTH suites' recurring items (issue #150): the 0.10 shape requires `id`, the legacy\n// shape swaps it for the tolerant code/id pair.\nconst ConsecutiveRounds = t.refinement(\n t.number,\n (n): n is number => Number.isSafeInteger(n) && n >= 1,\n \"ConsecutiveRounds\",\n);\nconst StartRound = t.refinement(\n t.number,\n (n): n is number => Number.isSafeInteger(n) && n >= 1,\n \"StartRound\",\n);\n\nconst RecurringShape = t.type({\n id: t.string,\n consecutive_rounds: ConsecutiveRounds,\n start_round: StartRound,\n});\n\n// The schema declares additionalProperties: false on recurring items; strictExact makes the codec\n// gate reject exactly what the ajv gate rejects instead of silently stripping (a seed-echoing draft\n// smuggling an extra key into a recurring item must not pass one gate and fail the other).\nconst RecurringCodec = strictExact(\"RecurringStrict\", RecurringShape, [RecurringShape]);\n\n// The scope-metastasis entry (issue #150): per-code consecutive-round recurrence counts plus the\n// decision prompt, computed from the rounds history. The agent never writes it — the re-review seed\n// re-derives it from the carried convergence trajectory and delivers it to the next-round agent — but\n// the draft schema tolerates it so a seed-echoing agent's draft still validates.\nconst ScopeMetastasisShape = t.type({\n decision_prompt: t.string,\n recurring: t.array(RecurringCodec),\n});\n\nexport const ScopeMetastasisCodec = strictExact(\"ScopeMetastasisStrict\", ScopeMetastasisShape, [\n ScopeMetastasisShape,\n]);\n\n// One round's trajectory entry (issue #174): the round number and its convergence score, plus the\n// mechanism-frequency map and reviewed head SHA the recurrence signals read. Prior rounds are carried\n// verbatim, so a threshold change never rewrites a past score.\nconst RoundNumber = t.refinement(\n t.number,\n (n): n is number => Number.isSafeInteger(n) && n >= 1,\n \"RoundNumber\",\n);\n\n// t.record decodes by plain assignment into a fresh object, and assigning a number to `__proto__`\n// hits the inherited accessor and silently no-ops — a reviewer-supplied `__proto__` id (which every\n// writer-side map preserves via Object.fromEntries) would vanish on the round-trip. The custom codec\n// rebuilds the map with Object.fromEntries, so the decode preserves exactly the keys the writer wrote.\n// Values: negative counts are REJECTED (the ajv gates carry minimum: 0, and the codec gate mirrors\n// them), while a 0-valued entry is DROPPED — 0 means \"no findings this round\" and every round reader\n// treats it as absence, so the decode and the readers agree without rejecting the whole document.\nconst idFrequencyCodec = (\n name: string,\n): t.Type<Readonly<Record<string, number>>, Readonly<Record<string, number>>> =>\n new t.Type<Readonly<Record<string, number>>, Readonly<Record<string, number>>>(\n name,\n (u): u is Readonly<Record<string, number>> =>\n typeof u === \"object\" && u !== null && !Array.isArray(u),\n (u, c) => {\n if (typeof u !== \"object\" || u === null || Array.isArray(u)) return t.failure(u, c);\n const entries: [string, number][] = [];\n for (const [k, v] of Object.entries(u as Record<string, unknown>)) {\n if (typeof v !== \"number\" || !Number.isSafeInteger(v) || v < 0) return t.failure(v, c);\n if (v === 0) continue;\n entries.push([k, v]);\n }\n return t.success(Object.fromEntries(entries));\n },\n (a) => a,\n );\n\nconst IdFrequency = idFrequencyCodec(\"IdFrequency\");\n\nconst ConvergenceRoundRequired = t.type({ round: RoundNumber });\nconst ConvergenceRoundOptional = t.partial({\n score: FiniteNumber,\n ids: IdFrequency,\n sha: t.string,\n});\nconst ConvergenceRoundShape = t.intersection([ConvergenceRoundRequired, ConvergenceRoundOptional]);\n\nexport const ConvergenceRoundCodec = strictExact(\"ConvergenceRoundStrict\", ConvergenceRoundShape, [\n ConvergenceRoundRequired,\n ConvergenceRoundOptional,\n]);\n\n// The convergence signal (issue #174): the current round's score, the threshold it is judged against,\n// whether it converged, and the per-round trajectory. Pipeline-stamped like scope_metastasis — the\n// agent never writes it; the pipeline computes the score deterministically from the findings and stamps\n// it so the JSON document is the sole source of the convergence data a decoding agent reads, no\n// side-channel marker. score AND threshold are both carried so the number is interpretable on its own.\nconst ConvergenceCoreShape = t.type({\n score: FiniteNumber,\n threshold: FiniteNumber,\n converged: t.boolean,\n});\n\nconst ConvergenceOptional = t.partial({ rounds: t.array(ConvergenceRoundCodec) });\nconst ConvergenceShape = t.intersection([ConvergenceCoreShape, ConvergenceOptional]);\n\nexport const ConvergenceCodec = strictExact(\"ConvergenceStrict\", ConvergenceShape, [\n ConvergenceCoreShape,\n ConvergenceOptional,\n]);\n\n// The change-size breakdown (issue #182): per-role added/removed line counts. UNLIKE\n// convergence/scope_metastasis (pipeline-stamped), this IS the agent's own judgment — a LOW-effort\n// path bucketing of the diff into code / tests / docs (a tests dir / *.test.* is tests, *.md / docs/\n// is docs, everything else is code; no file introspection). All roles optional and best-effort; an\n// absent role renders nothing. The deterministic cloc table beside it is pipeline-seeded, not here.\nconst LineDelta = t.refinement(\n t.number,\n (n): n is number => Number.isInteger(n) && n >= 0,\n \"LineDelta\",\n);\nconst ChangeLinesCodec = t.exact(t.type({ added: LineDelta, removed: LineDelta }));\nexport const ChangeSizeCodec = t.exact(\n t.partial({ code: ChangeLinesCodec, tests: ChangeLinesCodec, docs: ChangeLinesCodec }),\n);\n\nexport const FindingsCodec = t.exact(\n t.intersection([\n t.type({\n schema_version: SchemaVersion,\n summary: t.string,\n verdict: VerdictCodec,\n findings: t.array(FindingCodec),\n }),\n t.partial({\n systemic_problems: t.array(SystemicProblemCodec),\n // Pipeline-stamped only (issue #150); see ScopeMetastasisCodec.\n scope_metastasis: ScopeMetastasisCodec,\n // Pipeline-stamped only (issue #174); see ConvergenceCodec.\n convergence: ConvergenceCodec,\n // Agent-written best-effort (issue #182); see ChangeSizeCodec.\n change_size: ChangeSizeCodec,\n }),\n ]),\n);\n\n// The optional document fields safe to strip to RECOVER a findings doc when the in-force schema or the\n// codec rejects it — rather than lose the whole review (post's loadFindings) or all prior seed context\n// (the seed's barePrior fallback). PIPELINE_STAMPED_FIELDS are re-derived/re-stamped after load; the\n// agent's best-effort chrome (change_size, issue #182) is dropped because it never affects the verdict.\n// ONE definition so the two recovery sites can never diverge on the key set (issue #182 review r2).\nexport const PIPELINE_STAMPED_FIELDS: ReadonlySet<string> = new Set([\n \"convergence\",\n \"scope_metastasis\",\n]);\nexport const RECOVERABLE_OPTIONAL_FIELDS: ReadonlySet<string> = new Set([\n ...PIPELINE_STAMPED_FIELDS,\n \"change_size\",\n]);\n\n// The content-derived identity a finding WITHOUT an id resolves to: deterministic across rounds (the\n// same path + title always synthesizes the same id), so a pre-id finding re-raised next round keys to\n// the same ledger entry. A systemic problem has no path; its synthesized id keys on the title alone.\nconst synthesizedId = (parts: readonly string[], prefix: string): string =>\n `${prefix}${createHash(\"sha256\").update(parts.join(\"\\u0000\")).digest(\"base64url\").slice(0, 12)}`;\n\nexport const synthesizedFindingId = (path: string, title: string): string =>\n synthesizedId([path, title], \"f-\");\n\nexport const synthesizedSystemicId = (title: string): string => synthesizedId([title], \"s-\");\n\n// Exactly the shape synthesizedFindingId emits (`f-` + 12 base64url chars) — the answered matcher's\n// title second chance applies ONLY to entries whose code was synthesized (the pre-0.10 codeless\n// pair), so a reviewer-supplied id that merely starts with `f-` can never open the fallback.\nexport const isSynthesizedFindingId = (id: string): boolean => /^f-[A-Za-z0-9_-]{12}$/.test(id);\n\n// The ONE resolution a finding's id goes through: an explicit id wins, and an empty one resolves to\n// the same synthesized id the legacy upcast derives — shared by the answered-registry builder and the\n// answered match, so the two sides can never disagree on what an empty id means.\nexport const resolveFindingId = (f: { id: string; path: string; title: string }): string =>\n f.id !== \"\" ? f.id : synthesizedFindingId(f.path, f.title);\n\n// The ONE legacy-spelling precedence for a RAW record (id → code → synthesized when a path exists):\n// shared by the legacy upcast, the answered-registry marker reader, and the below-floor nit reader,\n// so the three raw-document sites can never drift on which spelling wins. undefined only when the\n// record carries no usable spelling AND no path to synthesize from (a systemic's shape).\nexport const resolveRuleId = (rec: {\n readonly id?: string;\n readonly code?: string;\n readonly path?: string;\n readonly title: string;\n}): string | undefined =>\n rec.id !== undefined && rec.id !== \"\"\n ? rec.id\n : rec.code !== undefined && rec.code !== \"\"\n ? rec.code\n : rec.path !== undefined\n ? synthesizedFindingId(rec.path, rec.title)\n : undefined;\n\n// The ONE \"usable counts map\" predicate every round reader shares: every entry a positive safe\n// integer — a present-but-malformed/empty/all-zero map is absence, so a valid legacy `codes` map\n// sitting beside a bad `ids` takes over wherever a round's mechanism map is read (the round readers\n// and the legacy upcast both apply it, so they can never disagree on what a usable map is).\nexport const usableCountsMap = (v: unknown): Readonly<Record<string, number>> | undefined => {\n if (typeof v !== \"object\" || v === null || Array.isArray(v)) return undefined;\n const entries = Object.entries(v as Record<string, unknown>).filter(\n (e): e is [string, number] =>\n typeof e[1] === \"number\" && Number.isSafeInteger(e[1]) && e[1] > 0,\n );\n return entries.length === 0 ? undefined : Object.fromEntries(entries);\n};\n\n// The ONE dual-spelling resolution for a round's mechanism map: when BOTH spellings carry usable\n// maps, their entries MERGE — the current `ids` spelling wins every shared key (the writer stopped\n// emitting `codes`, so a stale legacy count must never displace the current one), and `codes`\n// supplies only the keys `ids` lacks, so a merely-usable `ids` cannot discard a more complete\n// legacy map's names. Shared by the legacy upcast, the surface convergence migration, and\n// parseRounds so the dual-spelling readers can never drift.\nexport const mergedCountsMaps = (\n ids: unknown,\n codes: unknown,\n): Readonly<Record<string, number>> | undefined => {\n const idsMap = usableCountsMap(ids);\n const codesMap = usableCountsMap(codes);\n if (idsMap === undefined) return codesMap;\n if (codesMap === undefined) return idsMap;\n // Object spread defines `__proto__` as an OWN data property (CreateDataProperty), the same\n // prototype-pollution invariant the idFrequencyCodec's fromEntries rebuild holds.\n return { ...codesMap, ...idsMap };\n};\n\n// The pre-0.10 shape (schema/v0.9/findings.schema.json): findings carried an OPTIONAL `code` and no\n// `id`. Decoded only as a migration input — the registry's pre-0.10 entries normalize it to the 0.10\n// shape (code → id, or the synthesized content-derived id when a finding carried none). `id` is\n// accepted too: the legacy route is tolerant-in/strict-out, so a doc that already carries one passes\n// it through untouched.\nconst LegacyRuleCodec = t.partial({\n code: t.string,\n id: t.string,\n code_url: UriString,\n});\n\nconst FindingShapeV09 = t.intersection([FindingCoreRequired, LegacyRuleCodec, FindingOptional]);\n\n// The legacy finding stays tolerant-in on KEYS — no strict-key gate, unlike its 0.10 counterpart —\n// because the legacy route's contract is tolerant-in/strict-out (normalizeV09 rewrites to the strict\n// 0.10 shape); only the end>=start anchor and the exact-strip run here.\nconst FindingCodecV09 = t.exact(EndGeStart(FindingShapeV09));\n\nconst SystemicV09Optional = t.partial({\n finding_codes: t.array(t.string),\n finding_ids: t.array(t.string),\n paths: t.array(t.string),\n});\n\nconst SystemicV09Shape = t.intersection([SystemicRequired, LegacyRuleCodec, SystemicV09Optional]);\n\nconst SystemicProblemCodecV09 = strictExact(\"SystemicV09Strict\", SystemicV09Shape, [\n SystemicRequired,\n LegacyRuleCodec,\n SystemicV09Optional,\n]);\n\n// The legacy recurring item stays tolerant-in on KEYS — like the legacy finding, no strict-key\n// gate — because the legacy route's contract is tolerant-in/strict-out (normalizeV09 rewrites the\n// items to the strict 0.10 shape, dropping a code/id-less item entirely).\nconst RecurringV09Identity = t.partial({ code: t.string, id: t.string });\nconst RecurringV09Counts = t.type({\n consecutive_rounds: ConsecutiveRounds,\n start_round: StartRound,\n});\nconst RecurringV09Shape = t.intersection([RecurringV09Identity, RecurringV09Counts]);\n\nconst ScopeMetastasisV09Shape = t.type({\n decision_prompt: t.string,\n recurring: t.array(RecurringV09Shape),\n});\n\nconst ScopeMetastasisCodecV09 = strictExact(\"ScopeMetastasisV09Strict\", ScopeMetastasisV09Shape, [\n ScopeMetastasisV09Shape,\n]);\n\nconst CodeFrequencyV09 = idFrequencyCodec(\"CodeFrequencyV09\");\n\nconst ConvergenceRoundV09Optional = t.partial({\n score: FiniteNumber,\n codes: CodeFrequencyV09,\n ids: CodeFrequencyV09,\n sha: t.string,\n});\n\nconst ConvergenceRoundV09Shape = t.intersection([\n ConvergenceRoundRequired,\n ConvergenceRoundV09Optional,\n]);\n\nconst ConvergenceRoundCodecV09 = strictExact(\n \"ConvergenceRoundV09Strict\",\n ConvergenceRoundV09Shape,\n [ConvergenceRoundRequired, ConvergenceRoundV09Optional],\n);\n\nconst ConvergenceV09Optional = t.partial({ rounds: t.array(ConvergenceRoundCodecV09) });\nconst ConvergenceV09Shape = t.intersection([ConvergenceCoreShape, ConvergenceV09Optional]);\n\nconst ConvergenceCodecV09 = strictExact(\"ConvergenceV09Strict\", ConvergenceV09Shape, [\n ConvergenceCoreShape,\n ConvergenceV09Optional,\n]);\n\nconst FindingsV09Shape = t.intersection([\n t.type({\n // Any pre-0.10 minor — the registry dispatches on major.minor before decoding, so the codec\n // accepts every legacy patch version (0.4.x through 0.9.x) through the one tolerant shape.\n // SchemaVersion keeps the F3 strictness: a patch-less \"0.4\" or over-long \"0.4.0.0\" still fails\n // the codec gate exactly as the ajv gate rejects it.\n schema_version: SchemaVersion,\n summary: t.string,\n verdict: VerdictCodec,\n findings: t.array(FindingCodecV09),\n }),\n t.partial({\n systemic_problems: t.array(SystemicProblemCodecV09),\n scope_metastasis: ScopeMetastasisCodecV09,\n convergence: ConvergenceCodecV09,\n change_size: ChangeSizeCodec,\n }),\n]);\n\nexport const FindingsCodecV09 = t.exact(FindingsV09Shape);\n\n// The registry's 0.9 upcast: a 0.9 document becomes a valid 0.10 document. `code` maps to `id`; a\n// finding (or systemic) without one gains the synthesized content-derived id, so pre-id findings\n// stay trackable across the migration boundary.\nexport const normalizeV09 = (doc: t.TypeOf<typeof FindingsCodecV09>): Findings => {\n const findings = doc.findings.map(({ code, id, ...f }) => ({\n ...f,\n id:\n resolveRuleId({ id, code, path: f.path, title: f.title }) ??\n synthesizedFindingId(f.path, f.title),\n }));\n const systemic_problems = doc.systemic_problems?.map(\n ({ code, id, finding_codes, finding_ids, ...s }) => ({\n ...s,\n id: resolveRuleId({ id, code, title: s.title }) ?? synthesizedSystemicId(s.title),\n ...(finding_ids !== undefined && finding_ids.length > 0\n ? { finding_ids }\n : finding_codes !== undefined\n ? { finding_ids: finding_codes }\n : {}),\n }),\n );\n const scope_metastasis =\n doc.scope_metastasis === undefined\n ? undefined\n : {\n decision_prompt: doc.scope_metastasis.decision_prompt,\n // A legacy recurring item carrying neither code nor id names nothing — drop it rather than\n // synthesize an id with nothing to key it on.\n recurring: doc.scope_metastasis.recurring.flatMap((r) => {\n const carried = r.id !== undefined && r.id !== \"\" ? r.id : r.code;\n return carried === undefined || carried === \"\"\n ? []\n : [\n {\n id: carried,\n consecutive_rounds: r.consecutive_rounds,\n start_round: r.start_round,\n },\n ];\n }),\n };\n const convergence =\n doc.convergence === undefined\n ? undefined\n : {\n score: doc.convergence.score,\n threshold: doc.convergence.threshold,\n converged: doc.convergence.converged,\n ...(doc.convergence.rounds !== undefined\n ? {\n rounds: doc.convergence.rounds.map((r) => {\n // mergedCountsMaps: the upcast, the surface migration, and parseRounds\n // share ONE dual-spelling resolution, so a merely-usable new spelling can never\n // discard a more complete legacy one (or diverge from the marker channel).\n const ids = mergedCountsMaps(r.ids, r.codes);\n return {\n round: r.round,\n ...(r.score !== undefined ? { score: r.score } : {}),\n ...(ids !== undefined ? { ids } : {}),\n ...(r.sha !== undefined ? { sha: r.sha } : {}),\n };\n }),\n }\n : {}),\n };\n return {\n schema_version: DEFAULT_SCHEMA_VERSION,\n summary: doc.summary,\n verdict: doc.verdict,\n findings,\n ...(systemic_problems !== undefined ? { systemic_problems } : {}),\n ...(scope_metastasis !== undefined ? { scope_metastasis } : {}),\n ...(convergence !== undefined ? { convergence } : {}),\n ...(doc.change_size !== undefined ? { change_size: doc.change_size } : {}),\n };\n};\n\nexport const TriageCodec = t.type({\n safe: t.boolean,\n reasons: t.string,\n});\n\n// Abstract, vendor-neutral result envelope (SPEC §6.1) — not any adapter's native shape.\nconst TokenCount = t.refinement(\n t.number,\n (n): n is number => Number.isInteger(n) && n >= 0,\n \"TokenCount\",\n);\n\nexport const ModelUsageEntryCodec = t.intersection([\n t.type({\n model: t.string,\n input_tokens: TokenCount,\n output_tokens: TokenCount,\n }),\n t.partial({\n cache_read_tokens: TokenCount,\n cache_write_tokens: TokenCount,\n }),\n]);\n\nexport const ResultEnvelopeCodec = t.intersection([\n t.type({\n schema_version: t.string,\n findings: FindingsCodec,\n models: t.array(ModelUsageEntryCodec),\n turns: TokenCount,\n duration_ms: TokenCount,\n }),\n t.partial({\n vendor_cost_usd: t.union([t.number, t.null]),\n route: t.string,\n effort: t.string,\n // The ISO-8601 UTC instant the run completed (stamped by `adapt` when it built this envelope, issue\n // #170). Cost recomputation prices a time-slotted model at THIS instant, so the same envelope prices\n // to the same slot deterministically wherever it is re-rendered — not at each command's wall clock.\n // Absent on a pre-#170 envelope (cost then falls back to the caller's instant).\n generated_at: t.string,\n // The run produced a notice rather than a completed review (security-gate block, agent kill, no\n // recoverable findings). An empty `findings` array alone can't say this — a genuine clean review\n // is also empty — so the render suppresses \"clean review\" and the sticky precedence guard refuses\n // to bury a completed review under it. Absent ⇒ a completed review.\n incomplete: t.boolean,\n }),\n]);\n\nconst FlatModelPricesShape = t.type({\n in: NonNegativePrice,\n out: NonNegativePrice,\n cache_read: NonNegativePrice,\n cache_write: NonNegativePrice,\n});\n\n// The prices codecs mirror the ajv gate exactly, the same two-gates-agree discipline as the rest of\n// this file's strictExact codecs (issue #170 review): a key-set refinement rejects unknown keys on\n// DECODE (ajv's additionalProperties:false) — so a hybrid entry that carries BOTH flat fields and\n// `slots` is rejected by both variants and the union never ambiguates, rather than decoding as flat\n// while being priced as slotted.\nconst FlatModelPricesCodec = strictExact(\"FlatModelPricesStrict\", FlatModelPricesShape, [\n FlatModelPricesShape,\n]);\n\n// HH:MM in UTC (00:00–23:59). The pattern string is byte-identical to prices.schema.json's slot-time\n// pattern so the codec + ajv gates cannot silently disagree (issue #170 review).\nconst UTC_HHMM_RE = /^([01][0-9]|2[0-3]):[0-5][0-9]$/;\nconst UtcHHMM = t.refinement(t.string, (s): s is string => UTC_HHMM_RE.test(s), \"UtcHHMM\");\n\n// One UTC time-of-day slot (issue #170): a [utc_from, utc_to) half-open window — wrapping past midnight\n// when utc_to <= utc_from — carrying the same per-token fields as the flat shape. cost.ts selects the\n// slot covering the run's UTC instant; a model's slots must partition the 24h day with no gap or overlap.\nconst PriceSlotAnchor = t.type({ utc_from: UtcHHMM, utc_to: UtcHHMM });\nconst PriceSlotShape = t.intersection([PriceSlotAnchor, FlatModelPricesShape]);\nconst PriceSlotCodec = strictExact(\"PriceSlotStrict\", PriceSlotShape, [\n PriceSlotAnchor,\n FlatModelPricesShape,\n]);\n\n// `slots` must be non-empty (the ajv gate's minItems: 1) — an empty array is a misconfiguration, not a\n// zero-cost model.\nconst NonEmptyPriceSlots = t.refinement(\n t.array(PriceSlotCodec),\n (a): a is t.TypeOf<typeof PriceSlotCodec>[] => a.length >= 1,\n \"NonEmptyPriceSlots\",\n);\n// `weekend_slots` overrides `slots` on Saturdays and Sundays, BEIJING time — DeepSeek bills off-peak\n// all weekend from 2026-08-23 (issue #216). Optional and additive: a map without it behaves exactly as\n// before. Two arrays rather than a weekday field on a slot, because that shape would make a\n// partition-with-a-Saturday-gap newly expressible. Each array is independently a 24h partition and the\n// existing \"exactly one covering slot\" check applies unchanged — but only to whichever array a given\n// run selects, so a broken `weekend_slots` stays quiet until a weekend run reaches it. The warning\n// names the array it consulted for that reason.\nconst SlottedRequired = t.type({ slots: NonEmptyPriceSlots });\nconst SlottedOptional = t.partial({ weekend_slots: NonEmptyPriceSlots });\nconst SlottedShape = t.intersection([SlottedRequired, SlottedOptional]);\nconst SlottedModelPricesCodec = strictExact(\"SlottedModelPricesStrict\", SlottedShape, [\n SlottedRequired,\n SlottedOptional,\n]);\n\n// A model's price is EITHER flat (one all-day rate — unchanged, fully backward-compatible) OR a set of\n// UTC time-of-day slots (issue #170), for a provider with peak/off-peak rates (DeepSeek). Both variants\n// are strict-keyed (above), so the union rejects a hybrid entry instead of silently resolving it to one.\nexport const ModelPricesCodec = t.union([FlatModelPricesCodec, SlottedModelPricesCodec]);\n\nexport const PriceMapCodec = t.type({\n _updated: t.string,\n _unit: t.string,\n models: t.record(t.string, ModelPricesCodec),\n});\n\n// Format-agnostic test summary (SPEC §5.1 item 4, REQ-CO-9) — any conforming test report shape.\nexport const TestFailureCodec = t.intersection([\n t.type({ name: t.string }),\n t.partial({ message: t.string }),\n]);\n\nexport const TestSummaryCodec = t.intersection([\n t.type({\n passed: t.number,\n failed: t.number,\n total: t.number,\n }),\n t.partial({\n failures: t.array(TestFailureCodec),\n }),\n]);\n\n// Used when an adapter's native output omits schema_version; the registry sources its findings\n// defaultVersion from this.\nexport const DEFAULT_SCHEMA_VERSION = \"0.10.0\";\n\nexport type Finding = t.TypeOf<typeof FindingCodec>;\nexport type SystemicProblem = t.TypeOf<typeof SystemicProblemCodec>;\nexport type Findings = t.TypeOf<typeof FindingsCodec>;\nexport type ScopeMetastasis = t.TypeOf<typeof ScopeMetastasisCodec>;\nexport type Convergence = t.TypeOf<typeof ConvergenceCodec>;\nexport type ChangeSize = t.TypeOf<typeof ChangeSizeCodec>;\nexport type ConvergenceRound = t.TypeOf<typeof ConvergenceRoundCodec>;\nexport type ConvergenceCore = t.TypeOf<typeof ConvergenceCoreShape>;\nexport type Verdict = t.TypeOf<typeof VerdictCodec>;\n\n// The findings shape for a run that produced no code-review verdict — an operational failure, a\n// security refusal, or an empty diff with nothing to review. `verdict: \"error\"` is the machine-readable\n// signal that the blob a consumer decodes is NOT a clean pass (verdict \"comment\", findings []), so an\n// agent following the decode-the-JSON contract cannot mistake \"no verdict was produced\" for \"nothing\n// found\". A completed review carries approve/comment/changes.\nexport const incompleteFindings = (summary: string): Findings => ({\n schema_version: DEFAULT_SCHEMA_VERSION,\n summary,\n verdict: \"error\",\n findings: [],\n});\n\n// The one predicate for \"this findings doc is a no-verdict notice, not a completed review\", shared by\n// render and the sticky-precedence guard so the rule lives in a single place. Requires an EMPTY\n// findings array: a doc that carries real findings is a real review whatever its verdict says, so a\n// spurious \"error\" verdict alongside findings can never silently suppress them.\nexport const isIncompleteFindings = (findings: Findings): boolean =>\n findings.verdict === \"error\" && findings.findings.length === 0;\nexport type Triage = t.TypeOf<typeof TriageCodec>;\nexport type Severity = t.TypeOf<typeof SeverityCodec>;\nexport type Side = t.TypeOf<typeof SideCodec>;\nexport type ModelUsageEntry = t.TypeOf<typeof ModelUsageEntryCodec>;\nexport type ResultEnvelope = t.TypeOf<typeof ResultEnvelopeCodec>;\nexport type FlatModelPrices = t.TypeOf<typeof FlatModelPricesCodec>;\nexport type PriceSlot = t.TypeOf<typeof PriceSlotCodec>;\nexport type ModelPrices = t.TypeOf<typeof ModelPricesCodec>;\nexport type PriceMap = t.TypeOf<typeof PriceMapCodec>;\nexport type TestFailure = t.TypeOf<typeof TestFailureCodec>;\nexport type TestSummary = t.TypeOf<typeof TestSummaryCodec>;\n","// The release date, stamped by scripts/bump_version.py at release time. The staleness signal for\n// the price map (issue #220): a map whose `_updated` predates this date cannot reflect pricing the\n// CLI ships — the warn fires exactly when a consumer rolled the CLI but not the prices.\nexport const RELEASED = \"2026-09-27\";\n","// Recomputes USD (the CLI's vendor_cost_usd is vendor-priced); warnings threaded via a `warn` sink.\n\nimport type {\n PriceMap,\n ModelUsageEntry,\n ModelPrices,\n FlatModelPrices,\n PriceSlot,\n} from \"./schema.js\";\nimport { RELEASED } from \"./released.js\";\nimport { annotationSafe } from \"./util.js\";\n\nexport interface CostLine {\n readonly model: string;\n readonly inputTokens: number;\n readonly outputTokens: number;\n readonly cacheReadTokens: number;\n readonly cacheWriteTokens: number;\n readonly costUSD: number;\n // False when the model missed the price map entirely (issue #221): the render layer shows N/A\n // for the row instead of a confident $0.00. costUSD stays a plain number (0) — provenance is\n // carried beside it, never as a sentinel, so the render layer keeps owning presentation.\n readonly known: boolean;\n}\n\nexport interface CostReport {\n readonly lines: readonly CostLine[];\n readonly totalInputTokens: number;\n readonly totalOutputTokens: number;\n readonly totalCacheReadTokens: number;\n readonly totalCacheWriteTokens: number;\n readonly totalCostUSD: number;\n // The aggregate's provenance, computed beside the other rollups: false when ANY line missed\n // the map. An EMPTY report is true — no usage was consumed, so $0 spent is the honest figure\n // and the budget cap stays engaged (an unpriced line is the only unmeasurable shape; an empty\n // report is not a coverage failure).\n readonly allKnown: boolean;\n}\n\nexport type Warn = (message: string) => void;\n\nconst defaultWarn: Warn = (message) => {\n process.stderr.write(`${message}\\n`);\n};\n\n// A parseable UTC instant from an ISO string, or undefined — so an unparseable/no-offset generated_at\n// (issue #170 review r2) falls back to the caller's instant rather than pricing at an Invalid Date.\nexport const parseInstant = (iso: string | undefined): Date | undefined => {\n if (iso === undefined) return undefined;\n // A date-TIME with no UTC designator (Z or ±offset) is parsed as LOCAL time by Date — ambiguous and\n // slot-wrong. Reject a T-bearing instant that lacks an explicit offset (adapt stamps toISOString(),\n // always Z; a date-only value is unambiguous UTC midnight and is allowed).\n if (iso.includes(\"T\") && !/(Z|[+-]\\d{2}:?\\d{2})$/.test(iso)) return undefined;\n const d = new Date(iso);\n return Number.isNaN(d.getTime()) ? undefined : d;\n};\n\nconst utcMinuteOfDay = (at: Date): number => at.getUTCHours() * 60 + at.getUTCMinutes();\n\nconst hhmmToMinutes = (hhmm: string): number => {\n const [h, m] = hhmm.split(\":\");\n return Number(h) * 60 + Number(m);\n};\n\nconst hhmmOf = (minute: number): string =>\n `${String(Math.floor(minute / 60)).padStart(2, \"0\")}:${String(minute % 60).padStart(2, \"0\")}`;\n\n// A [utc_from, utc_to) half-open UTC window contains `minute`; when utc_to <= utc_from the window wraps\n// past midnight (e.g. 22:00→02:00 covers the late night and early morning). A degenerate utc_from ==\n// utc_to therefore covers the FULL day (wrap branch), matching the schema's \"utc_to <= utc_from wraps\".\nconst slotCovers = (slot: PriceSlot, minute: number): boolean => {\n const from = hhmmToMinutes(slot.utc_from);\n const to = hhmmToMinutes(slot.utc_to);\n return from < to ? minute >= from && minute < to : minute >= from || minute < to;\n};\n\n// The flat per-token rate for a model at the run's UTC instant (issue #170): a flat entry as-is; a\n// slotted entry's covering slot. A slotted map that leaves the instant uncovered (a gap) or double-\n// covers it (an overlap) — or a slotted model priced with no instant supplied — is a misconfiguration:\n// warn LOUDLY (like the unknown-model path) and return null so cost falls back to $0 for that model,\n// never crashing and never silently mis-pricing.\n// Weekend-ness is a property of the BEIJING date, not the UTC one — the provider states the rule in\n// Beijing time (see the schema's weekend_slots description, which is the spec). Beijing keeps no\n// daylight saving, so a fixed +8 is exact rather than an approximation (issue #216).\nconst BEIJING_OFFSET_MINUTES = 8 * 60;\n\nconst isBeijingWeekend = (instant: Date): boolean => {\n const day = new Date(instant.getTime() + BEIJING_OFFSET_MINUTES * 60_000).getUTCDay();\n return day === 0 || day === 6;\n};\n\nconst resolveFlatPrices = (\n model: string,\n p: ModelPrices,\n pricedAt: Date | undefined,\n warn: Warn,\n): FlatModelPrices | null => {\n if (!(\"slots\" in p)) return p;\n if (pricedAt === undefined) {\n warn(\n `code-review cost: model \"${annotationSafe(model)}\" has time-slotted prices but no run instant was supplied to select a slot; cost for this model renders as N/A`,\n );\n return null;\n }\n const minute = utcMinuteOfDay(pricedAt);\n const weekendSlots = p.weekend_slots;\n const useWeekend = weekendSlots != null && isBeijingWeekend(pricedAt);\n const slots = useWeekend ? weekendSlots : p.slots;\n const covering = slots.filter((s) => slotCovers(s, minute));\n if (covering.length === 1) return covering[0] ?? null;\n warn(\n `code-review cost: model \"${annotationSafe(model)}\" — ${String(covering.length)} price slots in \\`${useWeekend ? \"weekend_slots\" : \"slots\"}\\` cover ${hhmmOf(minute)} UTC (expected exactly 1); that array must partition the 24h day with no gap or overlap; cost for this model renders as N/A`,\n );\n return null;\n};\n\nconst computeModelCost = (\n entry: ModelUsageEntry,\n prices: PriceMap,\n pricedAt: Date | undefined,\n warn: Warn,\n): CostLine => {\n // Own-property only: a bare lookup would resolve prototype-chain names (`constructor`) as\n // priced — the t.record hazard schema.ts documents for the same class.\n const p = Object.hasOwn(prices.models, entry.model) ? prices.models[entry.model] : undefined;\n const cacheRead = entry.cache_read_tokens ?? 0;\n const cacheWrite = entry.cache_write_tokens ?? 0;\n const zero: CostLine = {\n model: entry.model,\n inputTokens: entry.input_tokens,\n outputTokens: entry.output_tokens,\n cacheReadTokens: cacheRead,\n cacheWriteTokens: cacheWrite,\n costUSD: 0,\n known: true,\n };\n if (!p) {\n warn(\n // annotationSafe: a model id is an unvalidated t.string — a CR/LF in it must not emit a\n // second line the Actions runner parses as a workflow command.\n `code-review cost: unknown model \"${annotationSafe(entry.model)}\" — no entry in price map; cost for this model renders as N/A`,\n );\n return { ...zero, known: false };\n }\n const rate = resolveFlatPrices(entry.model, p, pricedAt, warn);\n // Both \"cannot price this row\" exits agree on provenance: an unpriceable row must not render a\n // confident $0.00 either (issue #221 review r1).\n if (rate === null) return { ...zero, known: false };\n const costUSD =\n (entry.input_tokens * rate.in +\n entry.output_tokens * rate.out +\n cacheRead * rate.cache_read +\n cacheWrite * rate.cache_write) /\n 1_000_000;\n return { ...zero, costUSD };\n};\n\nexport const computeCost = (\n models: readonly ModelUsageEntry[],\n prices: PriceMap,\n // The run's UTC instant, used to select a time-slotted model's rate (issue #170). Undefined is fine\n // for a flat price map (ignored); a slotted model priced without it degrades to $0 with a warning.\n pricedAt?: Date,\n warn: Warn = defaultWarn,\n): CostReport => {\n const lines = models.map((entry) => computeModelCost(entry, prices, pricedAt, warn));\n\n return {\n lines,\n totalInputTokens: lines.reduce((s, l) => s + l.inputTokens, 0),\n totalOutputTokens: lines.reduce((s, l) => s + l.outputTokens, 0),\n totalCacheReadTokens: lines.reduce((s, l) => s + l.cacheReadTokens, 0),\n totalCacheWriteTokens: lines.reduce((s, l) => s + l.cacheWriteTokens, 0),\n totalCostUSD: lines.reduce((s, l) => s + l.costUSD, 0),\n allKnown: lines.every((l) => l.known),\n };\n};\n\n// A zero-padded ISO calendar date, or undefined — round-tripped through Date so a rolled-over\n// day (2026-02-31 → 2026-03-03) is rejected, not silently compared. Exported: the render layer\n// uses it to tell a nonconforming stamp apart from a valid one (the sticky must not present a\n// smoothed invalid value as validated).\nexport const parseIsoDate = (stamp: string): string | undefined => {\n if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(stamp)) return undefined;\n const parsed = new Date(`${stamp}T00:00:00Z`);\n return !Number.isNaN(parsed.getTime()) && parsed.toISOString().slice(0, 10) === stamp\n ? stamp\n : undefined;\n};\n\n// The budget hook's announce/clear decision, pure and testable: announce when a report with\n// unpriced lines exists and the marker (the human was told) is absent; clear the marker when the\n// axis is engaged again; otherwise nothing. index.ts skips the whole block for subagents and\n// performs the side effects (each hook invocation is a fresh process, so the marker file beside\n// the draft is the state).\nexport const costAxisAnnouncement = (\n report: CostReport | null,\n markerExists: boolean,\n): \"announce\" | \"clear\" | \"none\" => {\n if (report === null) return \"none\";\n if (!report.allKnown) return markerExists ? \"none\" : \"announce\";\n return markerExists ? \"clear\" : \"none\";\n};\n\n// The staleness signal (issue #220): a price map cannot know a vendor changed its rates, so the\n// only signal available is how old the snapshot is. A map predating THIS CLI's release date is\n// suspicious by construction — the consumer rolled the CLI but not the prices (the roll carries\n// both) — so warn exactly then, with no threshold to tune. Lives beside computeCost, not inside\n// it: computeCost has no notion of provenance, and the callers (post, the cost CLIs) own loudness.\n// A null map is the deliberate no-pricing choice (the bundled example) — never stale. A stamp\n// that does not parse as a calendar date degrades the staleness axis instead of aborting: a\n// merely mis-stamped map must not kill the round.\nexport const warnStalePrices = (prices: PriceMap | null, warn: Warn = defaultWarn): void => {\n if (prices === null) return;\n const updated = parseIsoDate(prices._updated);\n if (updated === undefined) return;\n if (updated > new Date().toISOString().slice(0, 10)) {\n warn(\n `::warning:: code-review cost: the price map's _updated (${prices._updated}) is in the future — a typo'd year silences the staleness check permanently; re-verify and re-stamp`,\n );\n return;\n }\n if (updated >= RELEASED) return;\n // The stamp reaching this line passed parseIsoDate (zero-padded ISO, CR/LF-free by\n // construction), so it interpolates unwrapped; RELEASED is a repo constant.\n warn(\n `::warning:: code-review cost: the price map was last verified ${prices._updated}, before this CLI's release (${RELEASED}) — the map may miss pricing this CLI ships; re-verify against the provider's pricing page`,\n );\n};\n","// A review agent's own unified-diff patch is either validated against the real PR-head file (to\n// align a finding's range and confirm it still applies) or projected into a GitHub suggestion — two\n// pure functions over one shared hunk parser (SSOT). Assumes LF line endings (the review runs on\n// Linux); CRLF is out of scope.\n\nexport type ValidateResult =\n | { readonly kind: \"anchored\"; readonly startLine: number; readonly endLine: number }\n | { readonly kind: \"keep\"; readonly reason: string }\n | { readonly kind: \"drop\"; readonly reason: string };\n\nexport type SuggestionResult = string | { readonly kind: \"drop\"; readonly reason: string };\n\ntype BodyLine =\n | { readonly kind: \"context\"; readonly text: string }\n | { readonly kind: \"removed\"; readonly text: string }\n | { readonly kind: \"added\"; readonly text: string };\n\nconst HUNK_HEADER_RE = /^@@ -(\\d+)(?:,\\d+)? \\+\\d+(?:,\\d+)? @@/;\n\nconst hunkOldStart = (line: string): number | null => {\n const raw = HUNK_HEADER_RE.exec(line)?.[1];\n return raw !== undefined ? Number(raw) : null;\n};\n\nconst classifyBodyLine = (line: string): BodyLine | null => {\n if (line.startsWith(\" \")) return { kind: \"context\", text: line.slice(1) };\n if (line.startsWith(\"-\")) return { kind: \"removed\", text: line.slice(1) };\n if (line.startsWith(\"+\")) return { kind: \"added\", text: line.slice(1) };\n return null;\n};\n\nconst trimmedMiddle = (body: readonly BodyLine[]): readonly BodyLine[] => {\n const first = body.findIndex((l) => l.kind !== \"context\");\n if (first === -1) return [];\n const last = body.findLastIndex((l) => l.kind !== \"context\");\n return body.slice(first, last + 1);\n};\n\n// Zero-or-more removed then zero-or-more added, no context, no interleaving.\nconst isContiguousChange = (middle: readonly BodyLine[]): boolean => {\n if (middle.some((l) => l.kind === \"context\")) return false;\n const firstAdded = middle.findIndex((l) => l.kind === \"added\");\n if (firstAdded === -1) return true;\n return (\n middle.slice(0, firstAdded).every((l) => l.kind === \"removed\") &&\n middle.slice(firstAdded).every((l) => l.kind === \"added\")\n );\n};\n\ninterface RemovedRange {\n readonly lineNumber: number;\n readonly firstRemoved: number | null;\n readonly lastRemoved: number | null;\n}\n\n// The old-side line number advances on context and removed lines, not added ones.\nconst removedRange = (body: readonly BodyLine[], oldStart: number): RemovedRange =>\n body.reduce<RemovedRange>(\n (acc, line) =>\n line.kind === \"added\"\n ? acc\n : {\n lineNumber: acc.lineNumber + 1,\n firstRemoved:\n line.kind === \"removed\" && acc.firstRemoved === null\n ? acc.lineNumber\n : acc.firstRemoved,\n lastRemoved: line.kind === \"removed\" ? acc.lineNumber : acc.lastRemoved,\n },\n { lineNumber: oldStart, firstRemoved: null, lastRemoved: null },\n );\n\nconst drop = (reason: string): { readonly kind: \"drop\"; readonly reason: string } => ({\n kind: \"drop\",\n reason,\n});\n\nconst keep = (reason: string): { readonly kind: \"keep\"; readonly reason: string } => ({\n kind: \"keep\",\n reason,\n});\n\ntype ParsedHunk =\n | { readonly kind: \"ok\"; readonly oldStart: number; readonly body: readonly BodyLine[] }\n | { readonly kind: \"drop\"; readonly reason: string };\n\n// SSOT shared by validatePatch and patchToSuggestion; drops on != 1 hunk or a malformed body line.\nconst parseHunk = (patch: string): ParsedHunk => {\n const rawLines = patch.split(\"\\n\");\n // A trailing newline splits into a trailing \"\" element — not a line of content.\n const lines =\n rawLines.length > 0 && rawLines[rawLines.length - 1] === \"\" ? rawLines.slice(0, -1) : rawLines;\n\n const headerHits = lines.reduce<readonly { readonly index: number; readonly oldStart: number }[]>(\n (acc, line, index) => {\n const oldStart = hunkOldStart(line);\n return oldStart !== null ? [...acc, { index, oldStart }] : acc;\n },\n [],\n );\n if (headerHits.length !== 1) {\n return drop(`expected exactly one hunk, got ${String(headerHits.length)}`);\n }\n const hit = headerHits[0];\n if (hit === undefined) return drop(\"malformed hunk header\");\n\n // Header-preceding lines (diff --git/index/---/+++) are never examined; a trailing\n // \"\\" marker carries no content.\n const bodyRaw = lines.slice(hit.index + 1).filter((line) => !line.startsWith(\"\\\\\"));\n const classified = bodyRaw.map(classifyBodyLine);\n if (classified.some((line) => line === null)) return drop(\"malformed hunk body line\");\n const body = classified.filter((line): line is BodyLine => line !== null);\n\n return { kind: \"ok\", oldStart: hit.oldStart, body };\n};\n\n// fileLines are 0-indexed and WITHOUT trailing newlines. Anchors when the removed lines give a range,\n// keeps a pure insertion (no range) for the renderer's ```patch fallback, drops on a context mismatch.\nexport const validatePatch = (patch: string, fileLines: readonly string[]): ValidateResult => {\n const parsed = parseHunk(patch);\n if (parsed.kind === \"drop\") return parsed;\n const { oldStart, body } = parsed;\n\n const oldSideTexts = body.filter((l) => l.kind !== \"added\").map((l) => l.text);\n const expected = fileLines.slice(oldStart - 1, oldStart - 1 + oldSideTexts.length);\n const oldSideMatches =\n expected.length === oldSideTexts.length &&\n expected.every((line, i) => line === oldSideTexts[i]);\n if (!oldSideMatches) {\n return drop(\n `patch context does not match the file at lines ${String(oldStart)}..${String(oldStart + oldSideTexts.length - 1)}`,\n );\n }\n\n if (!isContiguousChange(trimmedMiddle(body))) {\n return drop(\"change is not a single contiguous block\");\n }\n\n const removedCount = body.filter((l) => l.kind === \"removed\").length;\n const addedCount = body.filter((l) => l.kind === \"added\").length;\n if (removedCount === 0 && addedCount === 0) return drop(\"hunk contains no changes\");\n if (removedCount === 0) {\n return keep(\"pure insertion applies cleanly but has no removed range to anchor a suggestion\");\n }\n\n const { firstRemoved, lastRemoved } = removedRange(body, oldStart);\n if (firstRemoved === null || lastRemoved === null) return drop(\"malformed hunk body\");\n\n return { kind: \"anchored\", startLine: firstRemoved, endLine: lastRemoved };\n};\n\n// The added lines alone (no file needed). An all-deletion hunk yields \"\" (delete the range); a pure\n// insertion has nothing to replace.\nexport const patchToSuggestion = (patch: string): SuggestionResult => {\n const parsed = parseHunk(patch);\n if (parsed.kind === \"drop\") return parsed;\n const { body } = parsed;\n\n if (!isContiguousChange(trimmedMiddle(body))) {\n return drop(\"change is not a single contiguous block\");\n }\n\n const removedCount = body.filter((l) => l.kind === \"removed\").length;\n const addedLines = body.filter((l) => l.kind === \"added\");\n if (removedCount === 0 && addedLines.length === 0) return drop(\"hunk contains no changes\");\n if (removedCount === 0) return drop(\"pure insertion can't be expressed as a suggestion\");\n\n return addedLines.map((l) => l.text).join(\"\\n\");\n};\n","// Single source of truth for the bits every render surface (sticky, inline comment, review body)\n// must agree on: severity→emoji, the machine-readable findings-json marker, and patch→suggestion\n// projection. Pure.\n\nimport {\n ConvergenceCodec,\n DEFAULT_SCHEMA_VERSION,\n mergedCountsMaps,\n resolveFindingId,\n resolveRuleId,\n usableCountsMap,\n} from \"./schema.js\";\nimport type {\n ChangeSize,\n Convergence,\n ConvergenceCore,\n ConvergenceRound,\n Finding,\n Findings,\n ScopeMetastasis,\n Severity,\n SystemicProblem,\n} from \"./schema.js\";\nimport type { IdCounts, IdStreak, RoundRecord, SeverityCounts } from \"./types.js\";\nimport { patchToSuggestion } from \"./patch.js\";\n\n// The recurrence signals (streaks, scope metastasis, same-root) read only a round's mechanism map,\n// head SHA, and round number — never its score or severity counts — so this structural shape lets both\n// the JSON trajectory (ConvergenceRound) and a legacy parsed rounds marker (RoundRecord) flow through\n// the same detectors without an adapter.\ntype RecurrenceRound = {\n readonly ids?: IdCounts;\n readonly sha?: string;\n readonly round?: number;\n};\n\nexport const severityEmoji = (s: string): string => {\n switch (s) {\n case \"critical\":\n return \"🔴\";\n case \"major\":\n return \"🟠\";\n case \"minor\":\n return \"🔵\";\n case \"nit\":\n return \"⚪\";\n default:\n return \"❓\";\n }\n};\n\n// The canonical location of the findings schema — the moving `main` ref (mirrors findings.schema.json's\n// own $id). No version tag is cut yet; a tagged schema pins its own $id (schema/VERSIONING.md), so a\n// decoding agent starts here and, if its document's schema_version names a different version, fetches\n// that one — the URL below is NOT version-pinned.\nconst FINDINGS_SCHEMA_URL =\n \"https://raw.githubusercontent.com/JPHutchins/code-review/main/schema/findings.schema.json\";\n\n// One constant, carried onto every surface: a rendered review, a status notice, one inline comment.\n// It says nothing about what either side CONTAINS because that varies by route, envelope and round,\n// and three rounds of review found each such claim false somewhere (issues #171, #217). Read the\n// text; do not paraphrase it here. Uses em dashes, never \"--\", so the HTML comment\n// stays well-formed. Exported so the surfaces and their tests share one SSOT for the text (it is\n// carried forward verbatim by carryForwardMarkers) — the text below is that SSOT; do not restate it\n// here.\nexport const AGENTS_STOP_DIRECTIVE = `<!-- AGENTS: STOP — this comment names a code-review findings document in the marker, and usually renders that same review as prose. Read the prose when it is there: it is the cheaper read. Fetch the document when the prose is not the review (this comment may be a status notice), when the prose is only part of it (findings anchored to diff lines, and those threads carry their own finding rather than a link — the workflow run's summary renders the review whole), or when you need a field the prose does not render — decode the marker where the comment carries it instead (an inline thread's finding, or a pre-#217 sticky). Read the document's schema_version and fetch the schema for THAT version before acting — a schema's own $id is its canonical URL, and the URL below is the current version, not a pinned one: ${FINDINGS_SCHEMA_URL} — then parse the WHOLE findings document, not only the fields you recognize. -->`;\n\n// The marker names the findings artifact; it never carries the document. The embedded base64 form is\n// still READ (parseFindingsMarker) because every sticky written before this change holds one; a\n// carried pre-#217 marker may also be re-emitted verbatim by a notice path, never freshly written:\n// the blob was ~50% of a sticky's bytes and the size branch it needed was what made an oversized\n// review silently lose its re-review seed (issue #217).\nconst encodeMarker = (jsonUrl: string): string =>\n `${AGENTS_STOP_DIRECTIVE}\\n<!-- code-review:findings-json ${jsonUrl} -->`;\n\n// Decode a base64-in-HTML-comment marker payload, shared by the findings + rounds markers; undefined\n// on any malformed input so callers degrade rather than throw on the render path.\nconst decodeBase64Json = (b64: string): unknown => {\n try {\n return JSON.parse(Buffer.from(b64, \"base64\").toString(\"utf-8\"));\n } catch {\n return undefined;\n }\n};\n\nexport const findingsPointer = (jsonUrl: string): string => encodeMarker(jsonUrl);\n\n// Per-finding counterpart, and the ONE place a payload still travels in a comment. The answered\n// registry (issue #151) identifies a thread by decoding the finding out of its root comment, and it\n// must keep working across rounds: an answer given in round 1 still closes a verbatim re-raise in\n// round 8. A link cannot do that — this round's artifact does not contain round 1's finding — so the\n// thread carries its own finding, self-contained, exactly as before. It is one finding (~1KB), not the\n// whole document, and only on the opt-in inline surface (issue #217).\n//\n// Two thresholds, one valve. The inline template re-renders the SAME fields as prose, so the comment\n// holds the payload AND roughly the payload again — past the SOFT bound the inline renderer clips\n// that prose (marked, never silent) while the marker keeps embedding the WHOLE finding, which is\n// what keeps the answered registry working (issue #233 r1 + r2). Past the HARD bound (the\n// whole-document embed's old EMBED_LIMIT) no embed fits at all, so the marker names the artifact\n// instead — and only THAT band breaks the registry, for a finding pathological enough that no\n// comment could hold it. With no URL there is nothing to name, so the embed stays the only channel.\n// Dedupes the hard-valve warning per finding identity within one process (issue #236 r3).\nconst warnedValveFindings = new Set<string>();\n\nexport const INLINE_PROSE_CLIP_THRESHOLD_CHARS = 30_000;\n// The hard valve sits below the whole-document embed's old EMBED_LIMIT: the inline body is payload\n// + directive + clipped prose, and the clipped reasoning gains a `> ` prefix per rendered line — the\n// worst RENDERED case must stay under the comment limit, not just the raw parts (issue #235).\nexport const INLINE_EMBED_LIMIT_CHARS = 38_000;\nexport const findingPayload = (finding: Finding, schemaVersion: string): string =>\n Buffer.from(\n JSON.stringify({ schema_version: schemaVersion, findings: [finding] }),\n \"utf-8\",\n ).toString(\"base64\");\n\n// The heading and the permalink render the same line range with different separators (an en dash\n// for display, \"-L\" for the URL anchor) — ONE collapse decision shared by both, so the two\n// surfaces cannot drift (issue #231 r1).\nexport const lineRange = (startLine: number, endLine: number, separator: string): string =>\n startLine === endLine ? String(startLine) : `${String(startLine)}${separator}${String(endLine)}`;\n\nexport const findingPointer = (\n finding: Finding,\n schemaVersion: string,\n jsonUrl?: string,\n): string => {\n const payload = findingPayload(finding, schemaVersion);\n if (payload.length > INLINE_EMBED_LIMIT_CHARS) {\n if (jsonUrl !== undefined) {\n return `${AGENTS_STOP_DIRECTIVE}\\n<!-- code-review:findings-json ${jsonUrl} -->`;\n }\n // No URL to name and the payload cannot fit: omit the marker entirely — the pre-#217 behavior —\n // with a loud warning naming the finding, rather than embedding a comment GitHub is guaranteed\n // to reject (the 422 aborts the inline post; issue #235). Deduped per finding identity — a\n // fan-out round hits the valve once per comment, and the log must stay readable (issue #236 r3).\n const identity = `${finding.path}:${String(finding.start_line)}`;\n if (!warnedValveFindings.has(identity)) {\n warnedValveFindings.add(identity);\n process.stderr.write(\n `::warning::the finding at ${identity} has a payload past the inline comment limit and no --json-url was supplied to name the artifact — the comment carries no findings marker\\n`,\n );\n }\n return \"\";\n }\n return `${AGENTS_STOP_DIRECTIVE}\\n<!-- code-review:findings-json;base64 ${payload} -->`;\n};\n\n// null when the marker is absent or holds the all-zeros placeholder (no head SHA was stamped),\n// so callers treat an unknown prior commit as a new-commit re-review rather than asserting a match.\nconst ZERO_SHA = \"0000000000000000000000000000000000000000\";\nexport const parseReviewedSha = (body: string): string | null => {\n const sha = /<!-- reviewed-sha: ([0-9a-fA-F]{40}) -->/.exec(body)?.[1]?.toLowerCase();\n return sha && sha !== ZERO_SHA ? sha : null;\n};\n\n// The route of the COMPLETED review that stamped the sticky (\"full review\" | \"mechanic\"; absent on\n// notices and on pre-route-marker stickies). The seed chain is route-aware on it: a CI-fix mechanic\n// pass must not seed a later full review as if it were the previous full review (issue #127).\nconst ROUTE_RE = /<!-- reviewed-route: ([^>]*) -->/;\nexport const parseReviewedRoute = (body: string): string | null => ROUTE_RE.exec(body)?.[1] || null;\n\n// Post's empty-mechanic guard predicate: \"does this sticky record a completed FULL review as its\n// last completed review?\" The route marker wins — a mechanic sticky carries a prior full review's\n// round history forward, so round history alone can't distinguish it — and round history is the\n// fallback for pre-route-marker stickies (only a completed full review ever APPENDS a round; a\n// mechanic can only carry one). With no signal at all the review is not classified as full here;\n// post adds its own completed-review fallbacks (review-complete, or the placeholder's\n// completed-ancestor marker) for the pre-rounds era. seed-draft deliberately does NOT use this\n// predicate: for seeding, a no-route prior is unknown (a pre-route mechanic that carried rounds\n// looks identical to a pre-route full review), and the false-prior direction is worse than one cold\n// review, so it requires the route marker outright.\nexport const isFullReviewSticky = (body: string): boolean => {\n const route = parseReviewedRoute(body);\n if (route === \"full review\") return true;\n if (route === \"mechanic\" || parseMechanicAncestor(body)) return false;\n // Round history means a completed full review — whether it rides the new convergence field/marker or a\n // legacy rounds marker (issue #185 review). A post-#174 notice carries its trajectory in the\n // document's convergence or the compact marker, and this predicate gates the empty-mechanic guard\n // that must not bury that completed review.\n return priorTrajectory(parseFindingsMarker(body), body).length > 0;\n};\n\n// Carried by a body that replaces a MECHANIC sticky: a notice over a mechanic-origin prior must\n// not stamp the reviewed-route marker (its contract is the COMPLETED review's route, and a\n// stamped route would make the next round read the notice as a completed full review) — the\n// mechanic provenance rides this dedicated ancestry marker instead.\nexport const MECHANIC_ANCESTOR_MARKER = \"<!-- review-mechanic-ancestor -->\";\n// Anchored to a standalone comment LINE: the sticky body embeds reviewer prose and patch fences,\n// and a finding quoting this literal must not gate the next round as mechanic ancestry.\nexport const parseMechanicAncestor = (body: string): boolean =>\n new RegExp(`(^|\\n)${MECHANIC_ANCESTOR_MARKER}(\\n|$)`).test(body);\n\n// Carried by the announce placeholder when the sticky it replaced was a COMPLETED review: the\n// placeholder strips review-complete (it must not read as a finished review of the new head), yet\n// the empty-mechanic guard needs to know the placeholder descends from a completed review to\n// protect a pre-route/pre-rounds full review that would otherwise lose every signal (issue #127\n// round-2). Only ever carried — never emitted by a completed render, which has review-complete.\nexport const COMPLETED_ANCESTOR_MARKER = \"<!-- review-complete-ancestor -->\";\n// Anchored to a standalone comment LINE like its mechanic sibling: the sticky embeds reviewer\n// prose, and a finding quoting this literal must not gate as full-review ancestry.\nexport const parseCompletedAncestor = (body: string): boolean =>\n new RegExp(`(^|\\n)${COMPLETED_ANCESTOR_MARKER}(\\n|$)`).test(body);\n\n// A POSITIVE marker: present only in a sticky the commenter wrote for a COMPLETED review. It is\n// absent from an incomplete notice AND from an in-progress placeholder (which carries forward a prior\n// review's reviewed-sha yet is not itself a completed review) — so a precedence check can tell those\n// apart, which reviewed-sha alone (stamped on notices too) cannot. Re-emitted by the template each\n// write from the render's `incomplete` flag, never carried forward.\nexport const REVIEW_COMPLETE_MARKER = \"<!-- review-complete -->\";\nexport const parseReviewComplete = (body: string): boolean => body.includes(REVIEW_COMPLETE_MARKER);\n\n// null when the body carries no base64 marker — the link form is what every post writes now; the\n// embedded form is read-only legacy that only a carried pre-#217 marker can re-emit verbatim.\n// Every sticky written before the link form holds one, and each PR only rewrites its own on its\n// next round. Also null when the payload isn't valid JSON. Callers validate the result — a prior\n// run may predate the shape.\nexport const parseFindingsMarker = (body: string): unknown => {\n const b64 = /<!-- code-review:findings-json;base64 ([A-Za-z0-9+/=]+) -->/.exec(body)?.[1];\n if (b64 === undefined) return null;\n return decodeBase64Json(b64) ?? null;\n};\n\n// Per-full-review-round records (severity counts + mechanism-frequency map), carried in a base64\n// marker so each completed full review appends its own and the sticky renders the convergence\n// trajectory and the advisory scope-metastasis note. A CI-fix mechanic pass carries it forward\n// unchanged (it is not a review round). Best-effort like the findings marker: any non-conforming\n// shape decodes to no history rather than throwing on this render path.\nconst ROUNDS_RE = /<!-- code-review:rounds;base64 ([A-Za-z0-9+/=]+) -->/;\n\n// The severity keys in descending weight/emphasis order, so every surface (counts validation, chips)\n// iterates them the same way from one source.\nconst SEVERITIES = [\"critical\", \"major\", \"minor\", \"nit\"] as const;\n\n// Non-negative integers only: a crafted/corrupted marker with a negative count would render as a\n// false \"clean\" chip (filtered by `> 0`), and a fractional/huge one as a garbage chip. Rejecting them\n// here drops the bad round instead of carrying it forward on every re-serialize.\nconst isSeverityCounts = (u: unknown): u is SeverityCounts =>\n typeof u === \"object\" &&\n u !== null &&\n SEVERITIES.every((k) => {\n const v = (u as Record<string, unknown>)[k];\n // isSafeInteger (not isInteger): a huge integer-valued float like 1e308 is an integer per\n // Number.isInteger, and would render a garbage `🔴1e+308` chip and re-serialize forward.\n return typeof v === \"number\" && Number.isSafeInteger(v) && v >= 0;\n });\n\n// How many distinct mechanisms (codes) a round's marker may record — a per-round top-N by count, so a\n// finding-heavy round can't grow the carried marker without bound. Recurring mechanisms are typically\n// among a round's most-counted codes, so the streak signal survives the cap.\nexport const MAX_IDS_PER_ROUND = 8;\n\n// Own-property presence of a code in a frequency map. Reviewer-supplied codes are used as plain-object\n// keys, so a code like \"constructor\" or \"__proto__\" must never read an inherited Object.prototype\n// member (which would count a function as a recurrence). Maps are built via Object.fromEntries\n// (CreateDataProperty), so the own property is what every consumer should read.\nconst hasId = (ids: IdCounts | undefined, code: string): boolean =>\n ids !== undefined && Object.prototype.hasOwnProperty.call(ids, code);\n\n// Codes render inside backticks in the advisory notes; a backtick inside a (reviewer-supplied) code\n// would break the span, and a newline would break out of the note's blockquote, so both are escaped\n// (newlines collapse to a space). Shared with render.ts (which escapes paths into backtick spans) so\n// the escaping rule lives in one place.\nexport const escapeCodeBackticks = (code: string): string =>\n code.replace(/`/g, \"-\").replace(/\\r?\\n/g, \" \");\n\n// The codes field of a round record, validated and capped: string → positive safe-integer counts only\n// (a count-0 entry means \"no findings this round\" and is not recorded — every consumer agrees that 0\n// is absence), kept sorted by preferredKeys first (a dual-spelling round's current ids keys, so a\n// stale legacy count can never evict them from the cap), then count descending with ties preferring\n// codes that recurred in the previous round (so the per-round top-N cap can't silently drop the\n// exact mechanism the streak detector is watching), then alphabetically for a stable order.\n// Malformed (or absent) codes decode to undefined so the round's severity counts still stand — a\n// crafted marker can't smuggle a bad codes shape into the streak/note renderers.\n// The bounded form for the ROUNDS marker (the carrier with the top-N cap): the shared\n// usableCountsMap validation (schema.ts — the one definition every round reader shares), then the\n// cap + prior-preference.\nconst normalizeIdCounts = (\n ids: unknown,\n priorCodes?: IdCounts,\n preferredKeys?: ReadonlySet<string>,\n preValidated = false,\n): IdCounts | undefined => {\n const entries = Object.entries((preValidated ? (ids as IdCounts) : usableCountsMap(ids)) ?? {});\n if (entries.length === 0) return undefined;\n const sorted = entries.sort((a, b) => {\n const aPreferred = preferredKeys?.has(a[0]) === true ? 1 : 0;\n const bPreferred = preferredKeys?.has(b[0]) === true ? 1 : 0;\n if (aPreferred !== bPreferred) return bPreferred - aPreferred;\n if (b[1] !== a[1]) return b[1] - a[1];\n const aPrior = hasId(priorCodes, a[0]) ? 1 : 0;\n const bPrior = hasId(priorCodes, b[0]) ? 1 : 0;\n if (aPrior !== bPrior) return bPrior - aPrior;\n return a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0;\n });\n // The base cap is the top-N by (count, prior-preference). A mechanism the streak detector is\n // watching (it recurred in the previous round) is never dropped by a finding-heavy round even when\n // its count is low — any such code cut by the cap is appended after the base (bounded by a second\n // cap), so a recurrence can't silently end.\n const base = sorted.slice(0, MAX_IDS_PER_ROUND);\n const priorKept = sorted\n .slice(MAX_IDS_PER_ROUND)\n .filter(([code]) => hasId(priorCodes, code))\n .slice(0, MAX_IDS_PER_ROUND);\n return Object.fromEntries([...base, ...priorKept]);\n};\n\nexport const parseRounds = (body: string): readonly RoundRecord[] => {\n const b64 = ROUNDS_RE.exec(body)?.[1];\n if (b64 === undefined) return [];\n const decoded = decodeBase64Json(b64);\n // Filter, not all-or-nothing: one future-shaped or corrupted round drops only itself rather than\n // erasing the whole trajectory (post re-serializes the parsed array on every write). The ids\n // field is normalized independently — a bad ids shape strips just that field, never the round.\n // A legacy marker's `codes` field reads identically (0.10 renamed it to `ids`).\n if (!Array.isArray(decoded)) return [];\n // SEQUENTIAL normalization: each round's ids are re-normalized with the PRECEDING round's\n // normalized ids as priorCodes, so the up-to-8 prior-kept ids of a finding-heavy round survive\n // the marker round-trip (without it, the re-parse collapses every round to its top-8 base and the\n // re-attached scope_metastasis under-reports mechanisms post() would have flagged, issue #150 review r2).\n const kept: RoundRecord[] = [];\n let priorCodes: IdCounts | undefined;\n for (const u of (decoded as readonly unknown[]).filter(isSeverityCounts)) {\n const rec = u as Record<string, unknown>;\n // mergedCountsMaps first (the ONE dual-spelling resolution, shared with the convergence\n // migration and the legacy upcast): a round carrying BOTH spellings merges their entries with\n // the current `ids` spelling winning every shared key, and a malformed/empty `ids` must not\n // lose its mechanism map while a valid legacy `codes` sits beside it. normalizeIdCounts then\n // applies the top-N cap.\n // The cap prefers the current ids keys (preferredKeys) so a high-count legacy codes-only key\n // can never evict a current mechanism from the capped trajectory — the merge's stated rationale.\n const codes = normalizeIdCounts(\n mergedCountsMaps(rec[\"ids\"], rec[\"codes\"]),\n priorCodes,\n new Set(Object.keys(usableCountsMap(rec[\"ids\"]) ?? {})),\n true,\n );\n priorCodes = codes;\n const sha = rec[\"sha\"];\n const shaStr = typeof sha === \"string\" && sha !== \"\" ? sha : undefined;\n const round = rec[\"round\"];\n const roundNum =\n typeof round === \"number\" && Number.isSafeInteger(round) && round >= 1 ? round : undefined;\n const base =\n codes === undefined\n ? { critical: u.critical, major: u.major, minor: u.minor, nit: u.nit }\n : { critical: u.critical, major: u.major, minor: u.minor, nit: u.nit, ids: codes };\n const record = shaStr === undefined ? base : { ...base, sha: shaStr };\n kept.push(roundNum === undefined ? record : { ...record, round: roundNum });\n }\n return kept;\n};\n\n// A convergence score for display: the same fixed-2-decimal formatting as formatConfidence (a descent\n// reads cleanly — 2.40 → 1.10 → 0.42 — and the badge and the trajectory's last entry print identically).\n// Delegates so a future change to the 2-decimal rule lands in one place.\nexport const formatScore = (score: number): string => formatConfidence(score);\n\n// The convergence trajectory (issue #174): \"**Round 3** · 2.40 → 1.10 → 0.42\"; \"\" when there is no\n// round history. Each entry is a round's stored convergence score; a round with no stored score (a\n// legacy rounds marker predating this feature) renders \"—\" rather than a severity chip, so the line\n// never mixes units. The round number is always the true count; only the most recent entries show\n// (with a leading \"…\" when older ones are elided) so a long-running PR's line stays bounded.\nconst TRAJECTORY_SCORES = 8;\nexport const roundsSummary = (\n rounds: readonly { readonly round?: number; readonly score?: number }[],\n count: number = rounds.length,\n): string => {\n if (count === 0) return \"\";\n const cells = rounds\n .slice(-TRAJECTORY_SCORES)\n .map((r) => (typeof r.score === \"number\" ? formatScore(r.score) : \"—\"));\n const trajectory =\n cells.length === 0\n ? \"\"\n : rounds.length > TRAJECTORY_SCORES\n ? `… → ${cells.join(\" → \")}`\n : cells.join(\" → \");\n return trajectory === \"\"\n ? `**Round ${String(count)}**`\n : `**Round ${String(count)}** · ${trajectory}`;\n};\n\n// The per-round mechanism-frequency map: each finding carrying a `code` counts once toward that\n// mechanism, as does each code a systemic problem ties together via `finding_ids` — so a structural\n// mechanism surfaced as a systemic problem is visible to the same-root note and the streak detector,\n// not just one surfaced on a finding. Findings without a `code` are mechanism-unknown and uncounted.\n// Built via Object.fromEntries so reviewer-supplied keys like \"__proto__\" or \"constructor\" become own\n// data properties rather than mutating the map's prototype or reading inherited members.\nexport const computeIdCounts = (\n findings: readonly Finding[],\n systemic: readonly SystemicProblem[] = [],\n): IdCounts => {\n // A single Map pass — one increment per code — then Object.fromEntries so a reviewer-supplied\n // key like \"__proto__\" becomes an own property, never the map's prototype.\n const counts = new Map<string, number>();\n for (const code of [\n // resolveFindingId: an EMPTY id counts under the same synthesized key the answered match uses —\n // one finding can never be simultaneously tracked (dropped-by-synthesis) and uncounted.\n ...findings.map((f) => resolveFindingId(f)),\n ...systemic.flatMap((s) => [s.id, ...(s.finding_ids ?? [])]),\n ]) {\n if (code === undefined || code === \"\") continue;\n counts.set(code, (counts.get(code) ?? 0) + 1);\n }\n return Object.fromEntries(counts);\n};\n\n// Per code, how many consecutive rounds (ending at the last recorded round) carried a finding with\n// that code, and the 1-indexed round where the streak began. A round with no codes record (pre-feature\n// or a round with no coded findings) ENDS every streak — absence of data cannot evidence recurrence.\nexport const consecutiveIdStreaks = (\n rounds: readonly RecurrenceRound[],\n): Readonly<Record<string, IdStreak>> => {\n const entries: [string, IdStreak][] = [];\n if (rounds.length === 0) return {};\n const lastCodes = rounds[rounds.length - 1]?.ids;\n if (lastCodes === undefined) return {};\n for (const code of Object.keys(lastCodes)) {\n let streak = 0;\n let startIndex = rounds.length;\n for (let i = rounds.length - 1; i >= 0; i--) {\n const codes = rounds[i]?.ids;\n if (codes === undefined || !hasId(codes, code)) break;\n // A same-head CI retry appends a round with the same sha as the round before it — the same\n // review iteration re-examined, not new evidence of recurrence — so it neither advances nor\n // breaks the streak. Only when the code ALSO appeared in the previous (same-sha) round is the\n // evidence genuinely repeated; a code NEW in the retry round is fresh and counts.\n if (\n i > 0 &&\n rounds[i]?.sha !== undefined &&\n rounds[i]?.sha === rounds[i - 1]?.sha &&\n hasId(rounds[i - 1]?.ids, code)\n ) {\n continue;\n }\n streak += 1;\n startIndex = i;\n }\n if (streak > 0) {\n entries.push([code, { streak, startRound: rounds[startIndex]?.round ?? startIndex + 1 }]);\n }\n }\n // Object.fromEntries so a reviewer-supplied code like \"__proto__\" becomes an own key, never the\n // map's prototype (which would corrupt the result and render [object Object] in the note).\n return Object.fromEntries(entries);\n};\n\n// The minimum consecutive-round recurrence that triggers the advisory scope-metastasis note.\nexport const DEFAULT_METASTASIS_STREAK = 3;\n\n// The decision prompt the structured scope-metastasis entry carries (issue #150): a DECISION, not a\n// directive — the issue's author-agent found \"narrow the scope\" would have been the wrong instruction\n// on salix#100 (the metastasis converged to the correct end state), so the prompt must force an\n// explicit choice, not steer one. Shared by the structured entry; the prose note paraphrases it\n// (advisory-only wording, no imperative).\nexport const SCOPE_METASTASIS_DECISION_PROMPT =\n \"Findings keep recurring in the same mechanism across consecutive rounds — each fix keeps enabling the next finding in that machinery. This is a decision, not a directive: state in your summary whether you are committing to the expanding scope (plan the remaining facets of the recurring mechanism(s) above as one unit) or narrowing the scope so the recurrence stops.\";\n\n// The codes whose consecutive-round streak meets the threshold, sorted by streak descending — the\n// single computation both the advisory prose note and the structured scope-metastasis entry derive\n// from, so the two surfaces can never disagree on what is flagged.\nconst flaggedIdStreaks = (\n rounds: readonly RecurrenceRound[],\n minStreak: number,\n): ReadonlyArray<{ readonly id: string; readonly streak: IdStreak }> =>\n Object.entries(consecutiveIdStreaks(rounds))\n .filter(([, s]) => s.streak >= minStreak)\n .sort((a, b) => b[1].streak - a[1].streak)\n .map(([id, streak]) => ({ id, streak }));\n\n// The advisory scope-metastasis note for the sticky's convergence area: \"\" when no code has recurred\n// in `minStreak` or more consecutive rounds. Names the mechanism by its code (the pipeline cannot\n// paraphrase it — that needs the finding text) and the round range it streaked over. ADVISORY ONLY —\n// mirrors the convergence badge's posture: derives from the reviewer's own codes and never alters any\n// finding's severity or the verdict.\nexport const metastasisNote = (\n rounds: readonly RecurrenceRound[],\n minStreak: number = DEFAULT_METASTASIS_STREAK,\n): string => {\n const flagged = flaggedIdStreaks(rounds, minStreak);\n if (flagged.length === 0) return \"\";\n // The note only fires at minStreak ≥ 3 (the default), so \"consecutive rounds\" is always plural.\n // The round range is deliberately omitted: the history may contain same-sha retries that the\n // streak detector de-duplicates, so any X–Y range would contradict the streak count.\n const lines = flagged.map(\n ({ id, streak }) =>\n `> **\\`${escapeCodeBackticks(id)}\\`** — findings in ${String(streak.streak)} consecutive rounds.`,\n );\n return [\n \"> [!WARNING]\",\n \"> **Scope metastasis** — findings keep recurring in the same mechanism across consecutive rounds; each fix keeps enabling the next finding in that machinery. Consider whether a structural fix (change the shape, not the edge case) or a scope narrowing would converge this faster.\",\n ...lines,\n ].join(\"\\n\");\n};\n\n// The structured counterpart of the prose note (issue #150): the per-code consecutive-round counts\n// plus the decision prompt. The re-review seed re-derives this from the carried rounds history and\n// delivers it to the next-round agent (it is NOT embedded in the findings blob), so the machine\n// channel and the sticky's prose carry the same recurrence signal. null when nothing is flagged, so a\n// clean history carries no signal (the same omission semantics as the prose note's \"\"). The\n// structured entry carries the RAW reviewer-supplied code (the identifier consumers match on); the\n// prose note renders the SANITIZED form (escapeCodeBackticks) — the flagged SET is identical, only\n// the representation differs (a backtick/newline code is escaped for the markdown surface, raw in\n// the JSON).\nexport const computeScopeMetastasis = (\n rounds: readonly RecurrenceRound[],\n minStreak: number = DEFAULT_METASTASIS_STREAK,\n): ScopeMetastasis | null => {\n const flagged = flaggedIdStreaks(rounds, minStreak);\n if (flagged.length === 0) return null;\n return {\n decision_prompt: SCOPE_METASTASIS_DECISION_PROMPT,\n recurring: flagged.map(({ id, streak }) => ({\n id,\n consecutive_rounds: streak.streak,\n start_round: streak.startRound,\n })),\n };\n};\n\n// Code → \"same mechanism as round N\" for findings whose mechanism recurred in a PRIOR round: the most\n// recent prior round that carried a finding with the same code. The deterministic backstop to the\n// reviewer's own prose — the pipeline can't name the mechanism (that needs the finding text), but it\n// can name the round the code last appeared in. Empty when nothing recurs.\nexport const computeSameRootNotes = (\n priorRounds: readonly RecurrenceRound[],\n findings: readonly Finding[],\n currentSha?: string,\n): Readonly<Record<string, string>> => {\n const codes = findings.map((f) => resolveFindingId(f));\n const entries: [string, string][] = [];\n for (const code of codes) {\n let lastRound = 0;\n for (let i = priorRounds.length - 1; i >= 0; i--) {\n // A same-sha prior round is the same commit re-reviewed (a CI retry) — its findings are the\n // same evidence, not a prior fix that re-opened the mechanism, so it must not be named. A\n // retry deeper in the history (a round that merely re-examines the commit before it) is\n // collapsed the same way consecutiveIdStreaks collapses it, so both advisory signals agree.\n if (currentSha !== undefined && priorRounds[i]?.sha === currentSha) continue;\n // Collapse a same-sha retry exactly like consecutiveIdStreaks does: only when the code ALSO\n // appeared in the retried round is the evidence genuinely repeated — a code NEW in the retry\n // round is fresh and is named here (the two advisory signals agree).\n if (\n i > 0 &&\n priorRounds[i]?.sha !== undefined &&\n priorRounds[i]?.sha === priorRounds[i - 1]?.sha &&\n hasId(priorRounds[i - 1]?.ids, code)\n )\n continue;\n const count = priorRounds[i]?.ids?.[code];\n if (count !== undefined && count > 0) {\n lastRound = priorRounds[i]?.round ?? i + 1;\n break;\n }\n }\n if (lastRound > 0) {\n entries.push([\n code,\n `Same mechanism as round ${String(lastRound)} (\\`${escapeCodeBackticks(code)}\\`) — the prior fix in this area re-opened it; consider a structural fix or a scope narrowing.`,\n ]);\n }\n }\n // Object.fromEntries so a reviewer-supplied code like \"__proto__\" becomes an own key.\n return Object.fromEntries(entries);\n};\n\n// The convergence score and its advisory badge (score ≤ threshold), per finding/systemic problem:\n// floor(severity) + max(0, ceiling − floor) × confidence × likelihood. The floor is the weight the\n// modulation cannot erode; critical's is threshold-relative (CRITICAL_FLOOR_MARGIN) so an open critical\n// is never converged at any practical threshold (the margin degrades only where FP precision drops\n// 0.01, i.e. thresholds ≳ 1e14). ADVISORY ONLY: never alters the verdict.\nconst CONVERGENCE_CEILINGS: SeverityCounts = { critical: 4, major: 2, minor: 1, nit: 0 };\n// > 0 so a lone critical fails `score ≤ threshold`; 0.01 survives round2 (a coarser round would erase it).\nconst CRITICAL_FLOOR_MARGIN = 0.01;\n// A minor's floor (issue #178): the weight the modulation cannot erode, so a PILE of low-likelihood\n// minors resists convergence even when each is individually unlikely — count matters, not only\n// per-finding likelihood. A single solid minor still converges (0.1 + 0.9 × conf × like ≤ 1).\nconst MINOR_FLOOR = 0.1;\nexport const DEFAULT_CONVERGENCE_THRESHOLD = 1;\n\nconst convergenceFloor = (severity: Severity, threshold: number): number =>\n severity === \"critical\"\n ? threshold + CRITICAL_FLOOR_MARGIN\n : severity === \"major\"\n ? 0.5\n : severity === \"minor\"\n ? MINOR_FLOOR\n : 0;\n\n// A mechanic (CI-fix) pass stamps a never-converged convergence over the prior trajectory: CI\n// failed, so whatever the prior round said, this run's stamp must not read \"converged\". The score is\n// the THRESHOLD-RELATIVE critical floor (threshold + CRITICAL_FLOOR_MARGIN) — the same guarantee\n// convergenceFloor gives an open critical — so the score ≤ threshold triple buildConvergence\n// documents stays consistent at every threshold the CLI accepts. null when no prior round exists: a\n// stamp without a trajectory is one the reader gate (validStampedConvergence) rejects, and no marker\n// is the honest form of \"nothing to carry\" (issue #224).\nexport const mechanicConvergence = (\n prior: Convergence | null,\n threshold: number,\n): Convergence | null =>\n prior === null\n ? null\n : {\n score: convergenceFloor(\"critical\", threshold),\n threshold,\n converged: false,\n rounds: prior.rounds,\n };\n\nconst round2 = (n: number): number => Math.round((n + Number.EPSILON) * 100) / 100;\n\n// One finding/systemic-problem's contribution: floor(severity) + confidence-and-likelihood-weighted\n// headroom. The interlocks live HERE so both reducers below share them: max(0, …) can't invert when\n// threshold ≥ ceiling, and the critical margin + round2 preserve an open critical's `> threshold`\n// guarantee.\nconst contribution = (\n severity: Severity,\n confidence: number,\n likelihood: number,\n threshold: number,\n): number => {\n const floor = convergenceFloor(severity, threshold);\n return floor + Math.max(0, CONVERGENCE_CEILINGS[severity] - floor) * confidence * likelihood;\n};\n\n// Findings AND systemic problems (issue #134 scope), rounded to 2 decimals. A systemic problem is\n// scored with likelihood 1, NEVER its written value (issue #178): `likelihood` measures how routinely a\n// triggering input/state occurs, but a structural/cross-cutting observation has no single triggering\n// input — it is definitionally always present — so discounting it by likelihood is a category error\n// that under-weights exactly the findings that tie a review together. The field stays on the schema\n// (removing it would invalidate blobs already posted) but the score does not read it for systemic.\nexport const convergenceScore = (doc: Findings, threshold: number): number =>\n round2(\n doc.findings.reduce(\n (sum, { severity, confidence, likelihood }) =>\n sum + contribution(severity, confidence, likelihood, threshold),\n 0,\n ) +\n (doc.systemic_problems ?? []).reduce(\n (sum, { severity, confidence }) => sum + contribution(severity, confidence, 1, threshold),\n 0,\n ),\n );\n\n// The pipeline-stamped convergence field (issue #174): this round's score/threshold/converged plus the\n// per-round trajectory. Prior rounds are carried VERBATIM — their scores are historical snapshots, and\n// recomputing at a changed threshold would rewrite the past — while THIS round is appended with its\n// score and the mechanism map + head SHA the recurrence signals read. The trajectory keeps only the\n// most recent CONVERGENCE_TRAJECTORY_LIMIT rounds — a COUNT bound (not a byte cap), which keeps the blob\n// growth bounded in the common case (a round record is compact) and caps the same-root memory at that\n// many rounds; the recurrence detectors read only the recent tail, so bounding never ends a live streak.\nexport const CONVERGENCE_TRAJECTORY_LIMIT = 64;\nexport const buildConvergence = (\n doc: Findings,\n threshold: number = DEFAULT_CONVERGENCE_THRESHOLD,\n priorRounds: readonly ConvergenceRound[] = [],\n round: number = 1,\n ids: IdCounts = {},\n sha?: string,\n): Convergence => {\n const score = convergenceScore(doc, threshold);\n const normalized = normalizeIdCounts(ids, priorRounds[priorRounds.length - 1]?.ids);\n const current: ConvergenceRound = {\n round,\n score,\n ...(normalized !== undefined ? { ids: { ...normalized } } : {}),\n ...(sha !== undefined ? { sha } : {}),\n };\n const rounds = [...priorRounds, current].slice(-CONVERGENCE_TRAJECTORY_LIMIT);\n return { score, threshold, converged: score <= threshold, rounds };\n};\n\n// ── Nit visibility floor (issue #164) ───────────────────────────────────────────────────────────\n// A nit whose confidence × likelihood falls below this is below the noise floor: KEPT in the machine\n// blob (so the next-round seed reads it as already adjudicated and never re-raises it as fresh) but\n// hidden from the HUMAN surfaces (no inline comment; a collapsed aside in the sticky). Nit-only, and\n// orthogonal to the convergence score — a nit's ceiling is 0, so it contributes 0 whether shown or\n// hidden. Scoped to findings only; a nit-severity systemic problem is never floored here (hiding a\n// cross-cutting observation is a heavier call than hiding a per-line nit).\nexport const DEFAULT_NIT_VISIBILITY_FLOOR = 0.25;\n\n// True when a finding is a nit below the visibility floor. Accepts a loose shape so it serves both a\n// validated current Finding (confidence/likelihood are always numbers) and a hand-parsed prior-blob\n// finding: a non-numeric confidence or likelihood — a pre-0.9 blob predates likelihood — makes this\n// FALSE, so a finding is never hidden on missing data; suppression fails OPEN to visible.\nexport const isBelowVisibilityFloor = (\n f: { readonly severity?: unknown; readonly confidence?: unknown; readonly likelihood?: unknown },\n floor: number = DEFAULT_NIT_VISIBILITY_FLOOR,\n): boolean =>\n f.severity === \"nit\" &&\n typeof f.confidence === \"number\" &&\n typeof f.likelihood === \"number\" &&\n f.confidence * f.likelihood < floor;\n\n// The identifying bits of a prior round's below-floor nit, hand-parsed from a decoded prior findings\n// blob (parseFindingsMarker output) — the one-round suppression memory. post derives its stickiness\n// key from these (a still-nit matching one stays hidden even if its score wobbled up); the seed\n// delivers them as adjudicated context. Defensive/best-effort like parseRounds: a non-object, an old\n// blob without likelihood, or a malformed entry contributes nothing.\nexport interface PriorSuppressedNit {\n readonly title: string;\n readonly id?: string;\n readonly path?: string;\n}\nexport const priorBelowFloorNits = (\n priorDoc: unknown,\n floor: number = DEFAULT_NIT_VISIBILITY_FLOOR,\n): readonly PriorSuppressedNit[] => {\n if (typeof priorDoc !== \"object\" || priorDoc === null) return [];\n const arr = (priorDoc as Record<string, unknown>)[\"findings\"];\n if (!Array.isArray(arr)) return [];\n const nits: PriorSuppressedNit[] = [];\n for (const f of arr) {\n if (typeof f !== \"object\" || f === null) continue;\n const rec = f as Record<string, unknown>;\n if (!isBelowVisibilityFloor(rec, floor)) continue;\n const title = rec[\"title\"];\n if (typeof title !== \"string\") continue;\n const path = typeof rec[\"path\"] === \"string\" ? rec[\"path\"] : undefined;\n // resolveRuleId: the raw marker doc may predate id (a legacy `code`), and a CODELESS pre-id nit\n // resolves to the same synthesized id the upcast derives — so post's stickiness key matches the\n // 0.10 re-raise of the same claim instead of resetting on the migration round.\n const id = resolveRuleId({\n id: typeof rec[\"id\"] === \"string\" ? rec[\"id\"] : undefined,\n code: typeof rec[\"code\"] === \"string\" ? rec[\"code\"] : undefined,\n path,\n title,\n });\n nits.push({\n title,\n ...(id !== undefined ? { id } : {}),\n ...(path !== undefined ? { path } : {}),\n });\n }\n return nits;\n};\n\n// The convergence badge from a stored or freshly-computed signal: \"**Convergence** 🏁 0.42 ≤ 1 —\n// converged\" / \"**Convergence** 🔄 2.40 > 1 — iterating\". The score prints 2-decimal (formatScore) so it\n// matches the trajectory's last entry; the converged glyph is a checkered flag, NOT the verdict badge's\n// ✅, so a reader (or the author-agent this steers) can't skim the line as an approval. `converged` is\n// read from the signal, never recomputed here, so the shown inequality can't contradict the stored\n// decision.\nexport const convergenceBadge = (c: ConvergenceCore): string =>\n c.converged\n ? `**Convergence** 🏁 ${formatScore(c.score)} ≤ ${String(c.threshold)} — converged`\n : `**Convergence** 🔄 ${formatScore(c.score)} > ${String(c.threshold)} — iterating`;\n\n// The badge computed fresh from a document — the standalone `render` command and any legacy sticky with\n// no stored convergence. The post path reads the stamped signal via convergenceBadge, so its shown\n// score is the verbatim historical value.\nexport const convergenceSummary = (\n doc: Findings,\n threshold: number = DEFAULT_CONVERGENCE_THRESHOLD,\n): string => convergenceBadge(convergenceSignal(doc, threshold));\n\n// The change-size breakdown line (issue #182): \"+240 / −80 code · +120 / −10 tests · +30 / −0 docs\",\n// dropping a role the agent left absent. \"\" when the field or every role is absent. The agent's\n// best-effort role split (chrome); the per-language cloc table rides its own collapsible beside it.\nexport const changeSizeSummary = (changeSize: ChangeSize | undefined): string => {\n if (changeSize === undefined) return \"\";\n const cell = (\n label: string,\n d: { readonly added: number; readonly removed: number } | undefined,\n ): string | null =>\n d === undefined ? null : `+${String(d.added)} / −${String(d.removed)} ${label}`;\n return [\n cell(\"code\", changeSize.code),\n cell(\"tests\", changeSize.tests),\n cell(\"docs\", changeSize.docs),\n ]\n .filter((c): c is string => c !== null)\n .join(\" · \");\n};\n\n// The round number the NEXT completed full review will stamp, from a prior sticky's parsed state: the\n// max of the trajectory and the carried convergence's last round (never regresses across a legacy\n// signal/marker split), + 1. post numbers its appended round with it and announce labels the in-progress\n// trajectory with it, so the placeholder's round and post's stamp are ONE derivation, not copy-paste.\nexport const nextRoundNumber = (\n priorTraj: readonly ConvergenceRound[],\n priorConvRounds: readonly ConvergenceRound[],\n): number => {\n const last = (rounds: readonly ConvergenceRound[]): number =>\n rounds.length > 0 ? (rounds[rounds.length - 1]?.round ?? rounds.length) : 0;\n return Math.max(last(priorTraj), last(priorConvRounds)) + 1;\n};\n\n// The in-progress trajectory line for the announce placeholder (issue #180): the completed rounds'\n// scores plus a pending \"⏳\" cell for the round now running. The caller passes the running round from\n// nextRoundNumber, so the label and the pending cell agree with what post will stamp — by construction,\n// not by re-derivation here. NO badge: a carried \"converged\" above a running round would read as \"done,\n// ignore this.\" \"\" when the prior carries no completed round.\nexport const inProgressConvergence = (prior: Convergence, runningRound: number): string => {\n const rounds = prior.rounds ?? [];\n return rounds.length === 0 ? \"\" : `${roundsSummary(rounds, runningRound)} → ⏳`;\n};\n\n// The version a LEGACY compact stop-signal marker declared, and the version a LEGACY surfaced blob\n// declared before issue #156 deleted the surfacing transform. Its writer is retired (issue #186); the\n// version survives so the migration readers recognize a pre-#185 marker. DISTINCT from the draft axis\n// (DEFAULT_SCHEMA_VERSION is 0.9.0 after issue #163) so the surface channel can never be mistaken for\n// the agent's own document: parseSurfaceSignal accepts a signal marker only at a surface version, and\n// stripSurfaceFields recognizes a legacy surfaced blob by it to peel that blob back to a draft.\nexport const SURFACE_SCHEMA_VERSION = \"0.8.0\";\n\n// The stop signal's convergence core is the schema's ConvergenceCore — one definition shared by the\n// JSON convergence field and the legacy compact signal marker's reader.\nexport type ConvergenceSignal = ConvergenceCore;\n\n// The shape parseSignalMarker / parseSurfaceSignal return from a LEGACY compact signal marker or\n// surfaced blob: the round number + that round's score/threshold/converged. Its writer is retired\n// (issue #186); post now carries convergence forward via the stamped field (carriedConvergence), and a\n// stored `converged` is never re-derived — re-deriving at a changed convergence_threshold would flip a\n// prior round's decision.\nexport interface SurfaceSignal {\n readonly round: number;\n readonly convergence: ConvergenceSignal;\n}\n\n// The pure findings→signal computation, shared by post (a completing round) and render's fallback.\nexport const convergenceSignal = (\n doc: Findings,\n threshold: number = DEFAULT_CONVERGENCE_THRESHOLD,\n): ConvergenceSignal => {\n const score = convergenceScore(doc, threshold);\n return { score, threshold, converged: score <= threshold };\n};\n\nconst SIGNAL_RE = /<!-- code-review:signal;base64 ([A-Za-z0-9+/=]+) -->/;\n\n// Decodes a LEGACY compact signal marker (writer retired, issue #186) — a read-only fallback in the\n// carry chain: carriedConvergence reads the stamped convergence field, then the code-review:convergence\n// marker, and only then this. parseSurfaceSignal below is the older fallback for pre-#156 stickies whose\n// signal rode inside the blob.\nexport const parseSignalMarker = (body: string): SurfaceSignal | null => {\n const b64 = SIGNAL_RE.exec(body)?.[1];\n if (b64 === undefined) return null;\n return parseSurfaceSignal(decodeBase64Json(b64));\n};\n\n// Best-effort like parseRounds: the carried stop signal read back from a LEGACY (pre-#156) surfaced\n// blob whose signal rode inside the findings JSON — null on any malformed shape, a pre-surface blob,\n// or a doc that does not declare a surfaced version, so a draft or foreign document carrying\n// round/convergence keys can never be treated as the commenter's stop signal (the same version gate\n// stripSurfaceFields applies to the seed channel). Nothing writes this anymore (issue #186); it is the\n// last fallback in carriedConvergence's carry chain, reached only for an older sticky.\nexport const parseSurfaceSignal = (doc: unknown): SurfaceSignal | null => {\n if (typeof doc !== \"object\" || doc === null || Array.isArray(doc)) return null;\n const o = doc as Record<string, unknown>;\n if (!isSurfaceVersion(o[\"schema_version\"])) return null;\n const round = o[\"round\"];\n const convergence = o[\"convergence\"];\n if (typeof round !== \"number\" || !Number.isSafeInteger(round) || round < 1) return null;\n if (typeof convergence !== \"object\" || convergence === null) return null;\n const c = convergence as Record<string, unknown>;\n // isFinite (not just typeof): JSON.parse(\"1e400\") yields Infinity, which typeof says is a number\n // but JSON.stringify coerces to null — a non-finite score would survive one hop and then silently\n // drop the whole carried signal on the next.\n if (\n typeof c[\"score\"] !== \"number\" ||\n !Number.isFinite(c[\"score\"]) ||\n typeof c[\"threshold\"] !== \"number\" ||\n !Number.isFinite(c[\"threshold\"]) ||\n typeof c[\"converged\"] !== \"boolean\"\n ) {\n return null;\n }\n return {\n round,\n convergence: { score: c[\"score\"], threshold: c[\"threshold\"], converged: c[\"converged\"] },\n };\n};\n\n// Decode-tolerant read of the pipeline-stamped convergence field from a prior findings blob (the raw\n// parseFindingsMarker output): the convergence when the blob carries a valid one, else null.\n// Best-effort like parseRounds — a malformed or absent field yields null, never a throw.\n// A #174 pipeline stamp always carries a NON-EMPTY trajectory. A convergence that decodes but has no\n// `rounds` (or an empty one) is either a legacy pre-#156 surface blob's embedded stop signal or a\n// crafted/reset value — treat it as absent so the marker/legacy fallbacks reconstruct the whole thing,\n// and an empty trajectory can never silently reset the round count to 0 (issue #185 review).\n// A pre-0.10 sticky's compact convergence marker carries rounds whose mechanism maps use the legacy\n// `codes` spelling (0.10 renamed it to `ids`). Map the legacy rounds before the strict codec gate\n// with the SAME resolution parseRounds applies (mergedCountsMaps: usable maps merge, the current\n// `ids` spelling winning shared keys) — a round carrying both with a malformed `ids` must not\n// lose its mechanism map. The winner maps to `ids` verbatim minus the entries usableCounts itself\n// rejects (this carrier was never capped, unlike the rounds marker).\nconst withLegacyConvergenceIds = (raw: unknown): unknown => {\n if (typeof raw !== \"object\" || raw === null || Array.isArray(raw)) return raw;\n const rec = raw as Record<string, unknown>;\n const rounds = rec[\"rounds\"];\n if (!Array.isArray(rounds)) return raw;\n const needsMigration = (r: unknown): boolean => {\n if (typeof r !== \"object\" || r === null) return false;\n const round = r as Record<string, unknown>;\n return round[\"codes\"] !== undefined || usableCountsMap(round[\"ids\"]) === undefined;\n };\n // Fast path: a current 0.10 doc whose rounds all carry usable ids maps needs no migration — the\n // mapper runs on EVERY convergence decode, so the common case must not pay per-round rebuilds.\n if (!rounds.some(needsMigration)) return raw;\n const mapped: unknown[] = rounds.map((r) => {\n if (typeof r !== \"object\" || r === null) return r as unknown;\n const round = r as Record<string, unknown>;\n const ids = mergedCountsMaps(round[\"ids\"], round[\"codes\"]);\n if (ids === undefined) {\n // Neither spelling usable: strip BOTH map fields (like parseRounds strips a bad map) rather\n // than leaving the legacy `codes` key for the strict round gate to reject — a corrupted map\n // must cost the round its mechanism data, never the whole trajectory.\n return round[\"ids\"] !== undefined || round[\"codes\"] !== undefined\n ? Object.fromEntries(Object.entries(round).filter(([k]) => k !== \"ids\" && k !== \"codes\"))\n : round;\n }\n const rest = Object.fromEntries(\n Object.entries(round).filter(([k]) => k !== \"ids\" && k !== \"codes\"),\n );\n return { ...rest, ids };\n });\n return { ...rec, rounds: mapped };\n};\n\nconst validStampedConvergence = (raw: unknown): Convergence | null => {\n const decoded = ConvergenceCodec.decode(withLegacyConvergenceIds(raw));\n return decoded._tag === \"Right\" &&\n decoded.right.rounds !== undefined &&\n decoded.right.rounds.length > 0\n ? decoded.right\n : null;\n};\n\nexport const parseConvergence = (priorDoc: unknown): Convergence | null => {\n if (typeof priorDoc !== \"object\" || priorDoc === null) return null;\n const raw = (priorDoc as Record<string, unknown>)[\"convergence\"];\n return raw === undefined ? null : validStampedConvergence(raw);\n};\n\nconst CONVERGENCE_RE = /<!-- code-review:convergence;base64 ([A-Za-z0-9+/=]+) -->/;\n\n// The compact convergence marker (issue #185): the document left the comment (issue #217), so\n// convergence no longer rides inside it — the marker carries the SAME stamped convergence object\n// compactly beside the link, on EVERY post that has a convergence to carry (a completed round, or one\n// carried forward by a notice or a CI-fix pass). Its size-fallback role is over: it is how a reader of\n// the comment reaches the trajectory and the stop signal without a fetch.\nexport const convergenceMarker = (convergence: Convergence): string =>\n `<!-- code-review:convergence;base64 ${Buffer.from(JSON.stringify(convergence), \"utf-8\").toString(\n \"base64\",\n )} -->`;\n\n// The marker pair every surface writes: the artifact link, and the compact convergence beside it. They\n// travel together because the document left the comment (issue #217) — a link alone would put a\n// trajectory and a stop signal behind a fetch. Built here rather than at each caller: post and render\n// each had their own copy, and a test had to catch one of them emitting a link with the convergence\n// missing.\nexport const findingsMarkerPair = (\n jsonUrl: string | undefined,\n convergence: Convergence | undefined,\n): string => {\n const marker = jsonUrl !== undefined ? findingsPointer(jsonUrl) : \"\";\n if (convergence === undefined) return marker;\n const conv = convergenceMarker(convergence);\n return marker === \"\" ? conv : `${marker}\\n${conv}`;\n};\n\nexport const parseConvergenceMarker = (body: string): Convergence | null => {\n const b64 = CONVERGENCE_RE.exec(body)?.[1];\n return b64 === undefined ? null : validStampedConvergence(decodeBase64Json(b64));\n};\n\n// A legacy parsed rounds marker mapped into the trajectory shape: codes/sha/round survive (the\n// recurrence detectors read them), score is absent (a legacy round stored no score, so the trajectory\n// renders \"—\" for it). The one-time bridge across the upgrade to the JSON convergence field.\nexport const roundRecordsToConvergenceRounds = (\n records: readonly RoundRecord[],\n): ConvergenceRound[] =>\n records.map((r, i) => ({\n round: r.round ?? i + 1,\n ...(r.ids !== undefined ? { ids: { ...r.ids } } : {}),\n ...(r.sha !== undefined ? { sha: r.sha } : {}),\n }));\n\n// The prior round trajectory for post + seed: the JSON convergence field's rounds when the prior blob\n// carries it, else the legacy rounds marker mapped forward. Empty on a first review.\nexport const priorTrajectory = (\n priorDoc: unknown,\n priorBody: string,\n): readonly ConvergenceRound[] =>\n parseConvergence(priorDoc)?.rounds ??\n parseConvergenceMarker(priorBody)?.rounds ??\n roundRecordsToConvergenceRounds(parseRounds(priorBody));\n\n// The prior completed round's convergence, carried VERBATIM into a notice or CI-fix pass so the JSON\n// keeps the trajectory + last score across a non-round post: the stamped convergence field if present,\n// else reconstructed from a legacy sticky's compact signal marker (the core) + rounds marker (the\n// trajectory, scoreless). null when no round has completed — a first-run notice stamps no convergence.\nexport const carriedConvergence = (priorDoc: unknown, priorBody: string): Convergence | null => {\n const stamped = parseConvergence(priorDoc) ?? parseConvergenceMarker(priorBody);\n if (stamped !== null) return stamped;\n const signal = parseSignalMarker(priorBody) ?? parseSurfaceSignal(priorDoc);\n if (signal === null) return null;\n const legacy = roundRecordsToConvergenceRounds(parseRounds(priorBody));\n // The legacy signal's round is the authoritative completed-round count; if a corrupt round was\n // filtered from the rounds marker, keep that count on the trajectory's last entry so the next round\n // never regresses (issue #141). An empty marker beside a signal becomes a single scoreless round.\n const last = legacy[legacy.length - 1];\n const rounds =\n last === undefined\n ? [{ round: signal.round }]\n : last.round < signal.round\n ? [...legacy.slice(0, -1), { ...last, round: signal.round }]\n : legacy;\n return { ...signal.convergence, rounds };\n};\n\n// Every surface-channel version this CLI recognizes: the versions a LEGACY surfaced blob declared\n// (which stripSurfaceFields peels back to the agent document, so a sticky written before issue #156\n// still seeds) plus the version a legacy compact signal marker declared. Both are read-only now (the\n// writers are retired, issue #186). A dedicated list, deliberately distinct from the draft-version\n// registry axis: only these versions declare the surface channel, so a draft bump can never be\n// mistaken for one. A future surface bump appends the superseded version(s) here alongside the new one.\nexport const SURFACE_SCHEMA_VERSIONS: readonly string[] = [\"0.7.0\", SURFACE_SCHEMA_VERSION];\n\n// Does a value declare one of the surface-channel versions? The single gate the surface channel\n// applies wherever it must tell a commenter-side surface artifact from the agent's own draft — the\n// stop-signal read-back (parseSurfaceSignal), the legacy-blob peel-back (stripSurfaceFields), and the\n// seed's authoritative-vs-echoed scope_metastasis decision all share it.\nexport const isSurfaceVersion = (version: unknown): boolean =>\n typeof version === \"string\" && SURFACE_SCHEMA_VERSIONS.includes(version);\n\n// Peels a LEGACY surfaced blob (pre-#156) back to the agent's own document for the re-review seed —\n// post-#156 a fresh blob is already the agent's draft and passes through untouched. Version-gated,\n// not key-gated: a doc declaring a known SURFACE version has its pipeline-stamped convergence/round\n// dropped and its version restored to the current draft default, so the seeded draft still validates;\n// anything else (a draft version, an unknown future version, a malformed version) passes through\n// untouched and fails or passes schema validation downstream on its own merits — never silently\n// rewritten. A non-object stays as-is. A legacy blob's `scope_metastasis` (issue #150) is NOT dropped\n// here: on a 0.8.0 surfaced blob it was pipeline-stamped and authoritative, so it must reach the\n// next-round agent (a 0.7.0 blob predates the field; the draft schema tolerates it so the seeded doc\n// validates); a draft blob's echoed entry is dropped upstream in the seed, before this runs.\nexport const stripSurfaceFields = (doc: unknown): unknown => {\n if (typeof doc !== \"object\" || doc === null || Array.isArray(doc)) return doc;\n const o = doc as Record<string, unknown>;\n if (!isSurfaceVersion(o[\"schema_version\"])) return doc;\n const rest = Object.fromEntries(\n Object.entries(o).filter(([key]) => key !== \"convergence\" && key !== \"round\"),\n );\n return { ...rest, schema_version: DEFAULT_SCHEMA_VERSION };\n};\n\n// The machine-readable markers to carry forward when a comment's PROSE is replaced but its data must\n// survive — the \"review in progress\" placeholder swaps the visible summary yet must not clobber the\n// re-review seed the review job reads back from the sticky (the embedded findings + reviewed-sha),\n// the route that made the seed chain route-aware, nor the round-history trajectory. The findings\n// marker is extracted verbatim so both its base64 and jsonUrl-link forms survive; base64 (A–Z a–z\n// 0–9 + / =) and URLs never contain '>', so `[^>]*` stops at its closing `-->`. The STOP directive\n// that always precedes it is re-emitted from AGENTS_STOP_DIRECTIVE (its SSOT above) rather than\n// re-matched, so a future edit to that constant can't silently desync a parallel regex. Returns \"\"\n// when the body carries none of them.\n// The prior sticky's findings marker, whatever form it rides (the artifact link OR the pre-#217\n// embedded base64). Shared by carryForwardMarkers and the notice paths, so both preserves of the\n// prior pointer can never diverge on which form survives.\nexport const carriedFindingsMarker = (body: string): string | null =>\n /<!-- code-review:findings-json[^>]*-->/.exec(body)?.[0] ?? null;\n\n// The pointer a body emits when it carries a PRIOR sticky's findings marker forward instead of\n// naming its own: the carried marker verbatim (link OR embedded base64 form) with this body's own\n// convergence stamp beside it. Shared by the notice paths and the no-json-url main path, so the\n// two carries can never diverge on form or layout.\nexport const carriedMarkerPointer = (\n carried: string,\n convergence: Convergence | undefined,\n): string =>\n [\n `${AGENTS_STOP_DIRECTIVE}\\n${carried}`,\n ...(convergence !== undefined ? [convergenceMarker(convergence)] : []),\n ].join(\"\\n\");\n\n// The provenance markers a replacing sticky must preserve. The reviewed-sha is deliberately NOT\n// here — a new write stamps its own head.\nconst completedAncestryMarker = (body: string): string | undefined =>\n parseReviewComplete(body) || parseCompletedAncestor(body) ? COMPLETED_ANCESTOR_MARKER : undefined;\n\nexport const carriedProvenanceMarkers = (body: string): string =>\n [\n // The placeholder keeps the REAL route marker: the seed chain requires it outright to stay\n // route-aware across the prose swap.\n ROUTE_RE.exec(body)?.[0],\n parseMechanicAncestor(body) ? MECHANIC_ANCESTOR_MARKER : undefined,\n completedAncestryMarker(body),\n ]\n .filter((m): m is string => m !== undefined)\n .join(\"\\n\\n\");\n\n// Full-review ancestry for the SEED-side readers (gather + seed-draft): the route marker wins;\n// a route-less body counts only through the carried completed-ancestor marker and never through\n// mechanic ancestry. A mechanic-route body (a mechanic sticky or a placeholder over one) fails\n// both clauses — its carried ancestor marker must not read as a full review's.\nexport const isFullReviewAncestry = (body: string): boolean =>\n parseReviewedRoute(body) === \"full review\" ||\n (parseReviewedRoute(body) === null &&\n parseCompletedAncestor(body) &&\n !parseMechanicAncestor(body));\n\n// The ancestry markers a NOTICE carries: the route marker itself is NEVER re-emitted onto an\n// incomplete body — a notice carrying `reviewed-route: full review` would read as a completed full\n// review to every downstream route check — so a mechanic prior's provenance rides the dedicated\n// mechanic-ancestor marker, and the completed-ancestor marker keeps the empty-mechanic guard's\n// pre-route protection alive.\nexport const carriedAncestryMarkers = (body: string): string =>\n [\n // A notice body carries no route marker, so the second hop reads the ancestor marker itself:\n // mechanic ancestry survives notice-over-notice, not just notice-over-sticky.\n parseReviewedRoute(body) === \"mechanic\" || parseMechanicAncestor(body)\n ? MECHANIC_ANCESTOR_MARKER\n : undefined,\n completedAncestryMarker(body),\n ]\n .filter((m): m is string => m !== undefined)\n .join(\"\\n\\n\");\n\nexport const carryForwardMarkers = (body: string): string => {\n const findings = carriedFindingsMarker(body);\n const reviewedSha = /<!-- reviewed-sha: [0-9a-fA-F]{40} -->/.exec(body)?.[0];\n // The compact convergence marker (issue #185 review) rides beside the findings link, so the\n // in-progress placeholder must carry it forward too or the trajectory is lost across the swap.\n const convergence = CONVERGENCE_RE.exec(body)?.[0];\n const rounds = ROUNDS_RE.exec(body)?.[0];\n const signal = SIGNAL_RE.exec(body)?.[0];\n const findingsBlock = findings ? `${AGENTS_STOP_DIRECTIVE}\\n${findings}` : undefined;\n return [findingsBlock, reviewedSha, carriedProvenanceMarkers(body), convergence, rounds, signal]\n .filter((m): m is string => m !== undefined && m !== \"\")\n .join(\"\\n\\n\");\n};\n\n// Escape triple-backticks so fenced content can't break out of its block.\nexport const escapeFence = (text: string): string => text.replace(/```/g, \"`` ` ``\");\n\n// A GitHub ```suggestion when the patch lowers to replacement text, a non-lossy ```patch fallback\n// when it can't, or nothing when the finding carries no patch.\nexport type PatchProjection =\n | { readonly kind: \"suggestion\"; readonly text: string }\n | { readonly kind: \"patch\"; readonly raw: string }\n | { readonly kind: \"none\" };\n\n// GitHub renders a ```suggestion as an Apply button ONLY in a review comment anchored to diff lines.\n// In an issue comment — which is what the sticky is — the same block is inert, and worse than inert:\n// it shows the replacement text stripped of the lines it replaces, so the reader sees the fix with no\n// indication of what it displaces. The raw patch is a hunk and reads as one, so a comment-body\n// surface keeps it rather than lowering it to a suggestion that surface cannot honour. Both forms\n// still go through escapeFence: a hunk that itself contains a triple backtick would otherwise close\n// the block it is rendered in, so the escape is what keeps the rest of the comment intact — the\n// displayed hunk is faithful except for that sequence.\nexport type PatchSurface = \"diff-anchored\" | \"comment-body\";\n\nexport const projectPatch = (patch: string | undefined, surface: PatchSurface): PatchProjection => {\n if (patch === undefined) return { kind: \"none\" };\n const lowered = surface === \"diff-anchored\" ? patchToSuggestion(patch) : undefined;\n return typeof lowered === \"string\"\n ? { kind: \"suggestion\", text: escapeFence(lowered) }\n : { kind: \"patch\", raw: escapeFence(patch) };\n};\n\nexport const formatConfidence = (n: number): string => n.toFixed(2);\n\n// The review-object body: a bare one-line pointer to the sticky, where the findings document lives —\n// the sole documented decode surface (issue #161) — and to the run that produced the review (issue\n// #204), so a reader who lands here has a path back to the evidence. It never embeds the document: the\n// review body is written only after upsertSticky returns — a genuinely failed sticky write throws and\n// aborts post() first, and a response it cannot parse leaves these words unlinked rather than\n// embedding the blob here. SSOT shared by the commenter (post.ts) and the `preview` command.\n// The two links degrade differently: no sticky URL leaves the words unlinked, no run URL omits the run\n// sentence entirely. The run sentence names what the link is FOR rather than what the run still holds —\n// retention prunes logs and artifacts while the review object persists. The run's SUMMARY is the\n// review rendered whole (issue #205) — the sticky shows the latest round, the summaries show each\n// round as it stood — so the sentence names it, but only when there is one: `post` run outside\n// Actions writes no summary, and a pointer promising a document that was never written is worse than\n// one that promises less.\nexport const reviewBodyPointer = (\n headSha: string,\n stickyUrl: string | undefined,\n runUrl: string | undefined,\n runHasSummary: boolean,\n): string => {\n const sha7 = headSha.slice(0, 7);\n const summary = stickyUrl ? `the [summary comment](${stickyUrl})` : \"the summary comment\";\n const run = runUrl\n ? ` See the [workflow run](${runUrl}) for ${runHasSummary ? \"this round's review in full, its job log,\" : \"the job log\"} and the findings artifact.`\n : \"\";\n return `🤖 Automated code review for \\`${sha7}\\` — see ${summary} for the verdict, walkthrough, and cost.${run}`;\n};\n","// The cycle-safe in_reply_to climb, shared by the answered-registry walk and the discussion-aside\n// walk so the cycle-guard semantics live in one place. The climb terminates at a gap: a dangling\n// parent id (a deleted comment whose replies keep pointing at it) ends the chain where the map\n// stopped — both consumers accept that a severed subtree stays out of their grouping.\nexport function* ancestors<T>(start: T, parentOf: (node: T) => T | null): Generator<T> {\n const seen = new Set<T>();\n let current: T | null = start;\n while (current !== null && !seen.has(current)) {\n yield current;\n seen.add(current);\n current = parentOf(current);\n }\n}\n","// The transcript is the only surviving spend record when a wall-clock kill leaves no clean result\n// envelope, and the live in-flight signal the budget hook steers on. Reading is total: a truncated\n// final line (a `timeout` kill mid-flush) or any malformed entry is skipped, never thrown.\n\nimport { readdirSync } from \"node:fs\";\nimport { basename, dirname, join } from \"node:path\";\nimport type { ModelUsageEntry } from \"./schema.js\";\nimport { asRecord, modelIdentity, readFileOrNull } from \"./util.js\";\n\nexport interface TranscriptUsage {\n readonly models: readonly ModelUsageEntry[];\n readonly turns: number;\n readonly durationMs: number;\n readonly firstTsMs: number | null;\n readonly lastTsMs: number | null;\n}\n\n// `missing` distinguishes an unreadable main transcript (no signal at all) from an empty-but-present one.\nexport interface TranscriptTree {\n readonly entries: readonly unknown[];\n readonly files: readonly string[];\n readonly missing: boolean;\n}\n\n// Non-negative finite, else 0 — a NaN/absent field must not poison the sum.\nconst numField = (rec: Record<string, unknown>, key: string): number => {\n const v = rec[key];\n return typeof v === \"number\" && Number.isFinite(v) && v >= 0 ? v : 0;\n};\n\ninterface MessageUsage {\n readonly id: string | null;\n readonly model: string;\n readonly input: number;\n readonly output: number;\n readonly cacheRead: number;\n readonly cacheWrite: number;\n}\n\n// Claude Code names cache fields cache_read_input_tokens/cache_creation_input_tokens; the abstract\n// envelope names them cache_read_tokens/cache_write_tokens — the rename happens here. `id` is carried\n// so a message logged across several lines (one per content block of a parallel tool-use turn, each\n// repeating the message-level usage) is summed once.\nconst messageUsage = (entry: unknown): MessageUsage | null => {\n const rec = asRecord(entry);\n if (rec === null || rec[\"type\"] !== \"assistant\") return null;\n const msg = asRecord(rec[\"message\"]);\n if (msg === null) return null;\n const model = msg[\"model\"];\n const usage = asRecord(msg[\"usage\"]);\n if (typeof model !== \"string\" || usage === null) return null;\n const id = msg[\"id\"];\n return {\n id: typeof id === \"string\" ? id : null,\n model: modelIdentity(model),\n input: numField(usage, \"input_tokens\"),\n output: numField(usage, \"output_tokens\"),\n cacheRead: numField(usage, \"cache_read_input_tokens\"),\n cacheWrite: numField(usage, \"cache_creation_input_tokens\"),\n };\n};\n\nconst tsMsOf = (entry: unknown): number | null => {\n const rec = asRecord(entry);\n const ts = rec?.[\"timestamp\"];\n if (typeof ts !== \"string\") return null;\n const ms = Date.parse(ts);\n return Number.isNaN(ms) ? null : ms;\n};\n\ninterface Totals {\n readonly input: number;\n readonly output: number;\n readonly cacheRead: number;\n readonly cacheWrite: number;\n}\nconst EMPTY_TOTALS: Totals = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };\n\n// One object per non-blank line, dropping any that fails to parse — this makes a timeout-truncated\n// final line a no-op rather than a crash.\nexport const parseJsonl = (text: string): readonly unknown[] =>\n text\n .split(\"\\n\")\n .filter((line) => line.trim() !== \"\")\n .flatMap((line) => {\n try {\n return [JSON.parse(line) as unknown];\n } catch {\n return [];\n }\n });\n\n// A message logged over multiple lines (repeated message.id) is counted once — otherwise a parallel\n// tool-use turn's usage, stamped on every content-block line, is summed several times and inflates\n// spend. Entries with no id are counted as-is. `models` order follows first-appearance.\nexport const sumTranscriptUsage = (entries: readonly unknown[]): TranscriptUsage => {\n const summed = entries.reduce<{ totals: Map<string, Totals>; turns: number; seen: Set<string> }>(\n (acc, entry) => {\n const u = messageUsage(entry);\n if (u === null) return acc;\n if (u.id !== null && acc.seen.has(u.id)) return acc;\n if (u.id !== null) acc.seen.add(u.id);\n const prev = acc.totals.get(u.model) ?? EMPTY_TOTALS;\n acc.totals.set(u.model, {\n input: prev.input + u.input,\n output: prev.output + u.output,\n cacheRead: prev.cacheRead + u.cacheRead,\n cacheWrite: prev.cacheWrite + u.cacheWrite,\n });\n return { totals: acc.totals, turns: acc.turns + 1, seen: acc.seen };\n },\n { totals: new Map(), turns: 0, seen: new Set() },\n );\n\n const models: readonly ModelUsageEntry[] = [...summed.totals].map(([model, t]) => ({\n model,\n input_tokens: t.input,\n output_tokens: t.output,\n cache_read_tokens: t.cacheRead,\n cache_write_tokens: t.cacheWrite,\n }));\n\n const bounds = entries.reduce<{ min: number | null; max: number | null }>(\n (acc, entry) => {\n const ms = tsMsOf(entry);\n if (ms === null) return acc;\n return {\n min: acc.min === null || ms < acc.min ? ms : acc.min,\n max: acc.max === null || ms > acc.max ? ms : acc.max,\n };\n },\n { min: null, max: null },\n );\n\n return {\n models,\n turns: summed.turns,\n durationMs: bounds.min !== null && bounds.max !== null ? bounds.max - bounds.min : 0,\n firstTsMs: bounds.min,\n lastTsMs: bounds.max,\n };\n};\n\n// Claude Code writes each subagent to <dir>/<session-id>/subagents/agent-*.jsonl, beside\n// <dir>/<session-id>.jsonl. An empty result covers a missing directory or an older/other layout.\nconst subagentFiles = (mainPath: string): readonly string[] => {\n const dir = join(dirname(mainPath), basename(mainPath, \".jsonl\"), \"subagents\");\n try {\n return readdirSync(dir)\n .filter((name) => name.endsWith(\".jsonl\"))\n .map((name) => join(dir, name));\n } catch {\n return [];\n }\n};\n\n// Two layouts: subagents in their own files, OR inlined into the main marked isSidechain:true. Read\n// the sibling files ONLY when the main carries no inline sidechain, so either layout is summed once.\nexport const readTranscriptTree = (mainPath: string): TranscriptTree => {\n const mainText = readFileOrNull(mainPath);\n const mainEntries = mainText === null ? [] : parseJsonl(mainText);\n const inlineSidechains = mainEntries.some((e) => asRecord(e)?.[\"isSidechain\"] === true);\n const siblings = inlineSidechains ? [] : subagentFiles(mainPath);\n const siblingReads = siblings.flatMap((path) => {\n const text = readFileOrNull(path);\n return text === null ? [] : [{ path, entries: parseJsonl(text) }];\n });\n return {\n entries: [...mainEntries, ...siblingReads.flatMap((r) => r.entries)],\n files: [...(mainText === null ? [] : [mainPath]), ...siblingReads.map((r) => r.path)],\n missing: mainText === null,\n };\n};\n","// The \"already answered\" state (issue #151): the deterministic registry of prior inline findings\n// whose threads a human reply answered, plus the two rules built on it — the re-review seed surfaces\n// the registry so the next-round agent does not re-raise, and post() treats a VERBATIM re-raise as\n// closed: identical match (id), identical claim TEXT (title + description + reasoning),\n// identical severity, and identical location/fix (path + patch — the line is deliberately excluded,\n// positional drift is not evidence), i.e. no new evidence by definition. The drop is removed from\n// the surfaced review and NAMED in the sticky; a re-raise with any changed component is kept and\n// annotated with the prior answer's link.\n\nimport * as t from \"io-ts\";\nimport { ancestors } from \"./comment-chain.js\";\nimport { escapeCodeBackticks, parseFindingsMarker } from \"./surface.js\";\nimport { parseJsonl } from \"./transcript.js\";\nimport type { GhApi } from \"./gh.js\";\nimport {\n isSynthesizedFindingId,\n resolveFindingId,\n resolveRuleId,\n synthesizedFindingId,\n} from \"./schema.js\";\nimport type { Finding, Severity } from \"./schema.js\";\nimport { clipText, errMsg } from \"./util.js\";\n\n// One flat review comment as REST `pulls/{n}/comments` returns it — enough to rebuild reply threads\n// from `in_reply_to_id` chains (a reply to a reply included) and to decode the bot comment's embedded\n// per-finding marker.\nexport interface ThreadComment {\n readonly id: number;\n readonly in_reply_to_id: number | null;\n readonly user_login: string;\n // \"User\" | \"Bot\" — lets the registry exclude replies from OTHER bots (a CI/dependabot comment\n // is not a human answer), not just this pipeline's own bot login.\n readonly user_type: string | null;\n readonly body: string | null;\n readonly html_url: string;\n readonly path: string | null;\n readonly line: number | null;\n readonly created_at: string | null;\n}\n\n// The jq projection gather and post share. It emits BOTH the flat `user_login`/`user_type` the\n// answered-registry codec reads AND the nested `user: {login}` (+ author_association) the\n// conversation codec reads — one fetch feeds two consumers, and neither may be silently starved by\n// a field rename (issue #151 review r1: the original single-shape projection emptied the\n// conversation's review_comments in production while the mocks, which bypass jq, kept the tests\n// green).\nexport const THREAD_COMMENT_JQ =\n \".[] | {id, in_reply_to_id, user: {login: .user.login}, user_login: .user.login, user_type: .user.type, body, html_url, path, line, created_at, author_association}\";\n\nexport const ThreadCommentCodec = t.type({\n id: t.number,\n in_reply_to_id: t.union([t.number, t.null]),\n user_login: t.string,\n user_type: t.union([t.string, t.null]),\n body: t.union([t.string, t.null]),\n html_url: t.string,\n path: t.union([t.string, t.null]),\n line: t.union([t.number, t.null]),\n created_at: t.union([t.string, t.null]),\n});\n\n// The registry entry for one answered finding: the finding's identifying fields (the verbatim-match\n// targets), the thread link, and the last human reply's link + a clipped excerpt for the seed.\nexport interface AnsweredEntry {\n // The answered finding's id; a pre-id marker resolves it the same way the registry's legacy\n // upcast does (code → id, else synthesized), so the entry keys to the identical claim next round.\n readonly code: string;\n readonly title: string;\n readonly description: string;\n readonly reasoning: string;\n // The answered finding's severity — a re-raise ESCALATED in severity is not verbatim (the claim\n // weight changed), so it is kept and annotated rather than dropped (issue #151 review r1).\n readonly severity: Severity;\n // The answered finding's path and proposed patch — a re-raise RELOCATED to another file, or one\n // whose proposed fix changed, carries something new and is kept, not dropped (issue #151 review\n // r3). patch is null when the answered finding carried none. The LINE is deliberately NOT part of\n // the predicate: positional drift (a rebase moving the same claim) is not evidence, while a\n // genuinely new instance changes the claim text.\n readonly path: string;\n readonly patch: string | null;\n // The LAST human reply's timestamp and id — both READ for the dedup: \"most recent answer wins\"\n // keys on the ANSWER time, never the root (review-posting) order, and an equal-timestamp tie\n // breaks by the reply id (monotonic with creation), not by thread order (issues #151 review r4 +\n // r7).\n readonly repliedAt: string | null;\n readonly replyId: number;\n readonly threadUrl: string;\n readonly replyUrl: string;\n readonly replyAuthor: string;\n readonly replyExcerpt: string;\n}\n\n// The staged-registry codec (what gather writes to answered.json and seed-draft reads back) — the\n// SNAKE_CASE wire shape, distinct from the camelCase in-process AnsweredEntry; rows that fail decode\n// are dropped like every other untrusted artifact, never fatal.\nexport const AnsweredEntryCodec = t.type({\n code: t.string,\n title: t.string,\n description: t.string,\n reasoning: t.string,\n severity: t.union([\n t.literal(\"critical\"),\n t.literal(\"major\"),\n t.literal(\"minor\"),\n t.literal(\"nit\"),\n ]),\n path: t.string,\n patch: t.union([t.string, t.null]),\n replied_at: t.union([t.string, t.null]),\n reply_id: t.number,\n thread_url: t.string,\n reply_url: t.string,\n reply_author: t.string,\n reply_excerpt: t.string,\n});\n\nexport type StagedAnsweredEntry = t.TypeOf<typeof AnsweredEntryCodec>;\n\nexport const encodeAnsweredEntry = (e: AnsweredEntry): StagedAnsweredEntry => ({\n code: e.code,\n title: e.title,\n description: e.description,\n reasoning: e.reasoning,\n severity: e.severity,\n path: e.path,\n patch: e.patch,\n replied_at: e.repliedAt,\n reply_id: e.replyId,\n thread_url: e.threadUrl,\n reply_url: e.replyUrl,\n reply_author: e.replyAuthor,\n reply_excerpt: e.replyExcerpt,\n});\n\nexport const decodeAnsweredEntry = (raw: unknown): StagedAnsweredEntry | null => {\n const decoded = AnsweredEntryCodec.decode(raw);\n return decoded._tag === \"Right\" ? decoded.right : null;\n};\n\n// A reply is \"answered\" when a HUMAN commented on the thread: neither this pipeline's bot (matched\n// by login) nor any other bot account (matched by the REST user.type, so a CI/dependabot comment\n// can't masquerade as an answer — issue #151 review r1). A MISSING type (null — an unexpected API\n// shape) fails closed to \"not human\": an uncertain answer must not cause a finding to be dropped\n// (issue #151 review r2).\nconst isHuman = (login: string, type: string | null, botLogin: string): boolean =>\n login !== botLogin && type === \"User\";\n\nconst EXCERPT_LIMIT = 400;\n\n// OUTDATED/minimized threads are deliberately NOT excluded: the pipeline minimizes superseded\n// bot comments at the end of every post, so excluding them would erase the very persistence the\n// feature exists for — an answer from round 1 must still close a verbatim re-raise in round 8\n// (issue #151 review r1 considered and rejected the stale-thread scope).\n\n// The pure thread→registry construction. A thread is anchored on the bot's comment (by login); the\n// root's embedded per-finding marker names the finding. Replies are every non-bot comment whose\n// in_reply_to chain reaches that root. The LAST human reply per thread is recorded (the operative\n// dismissal — issue #151 review r5); when the same\n// code was answered in several threads, the most recent thread wins. Tolerant: an undecodable bot\n// comment (no marker, or a marker that fell to the link form) contributes nothing.\nexport const answeredRegistryFrom = (\n comments: readonly ThreadComment[],\n botLogin: string,\n): readonly AnsweredEntry[] => {\n // Order-independent: the REST order (ascending creation) is not a contract, so the reply\n // selections sort explicitly by (created_at, id) before processing (issue #151 review r2). A\n // MISSING created_at sorts FIRST (\"\"), so an unknown-time reply is never picked as the\n // operative LAST answer (issue #151 review r7).\n const ordered = [...comments].sort(\n (a, b) =>\n (a.created_at ?? \"\").localeCompare(b.created_at ?? \"\") ||\n (a.id > b.id ? 1 : a.id < b.id ? -1 : 0),\n );\n const byId = new Map<number, ThreadComment>();\n for (const c of ordered) byId.set(c.id, c);\n\n // The root of a comment's chain (walk in_reply_to_id up, cycle-safe); null when the chain never\n // reaches a top-level comment within the fetched set.\n const rootOf = (c: ThreadComment): ThreadComment | null => {\n const chain = [\n ...ancestors(c, (n) =>\n n.in_reply_to_id === null ? null : (byId.get(n.in_reply_to_id) ?? null),\n ),\n ];\n const root = chain[chain.length - 1];\n return root !== undefined && root.in_reply_to_id === null ? root : null;\n };\n\n // The answered finding of a bot-rooted thread, from the root comment's embedded per-finding marker.\n const findingOf = (\n root: ThreadComment,\n ): {\n code: string;\n title: string;\n description: string;\n reasoning: string;\n severity: Severity;\n path: string;\n patch: string | null;\n } | null => {\n const decoded = parseFindingsMarker(root.body ?? \"\");\n const doc =\n typeof decoded === \"object\" && decoded !== null\n ? (decoded as { findings?: unknown }).findings\n : undefined;\n const first = Array.isArray(doc) ? (doc[0] as Record<string, unknown> | undefined) : undefined;\n if (first === undefined) return null;\n const title = first[\"title\"];\n const description = first[\"description\"];\n const reasoning = first[\"reasoning\"];\n const id = first[\"id\"];\n const legacyCode = first[\"code\"];\n const severity = first[\"severity\"];\n const path = first[\"path\"];\n const patch = first[\"patch\"];\n return typeof title === \"string\" &&\n typeof description === \"string\" &&\n typeof reasoning === \"string\" &&\n typeof path === \"string\" &&\n (severity === \"critical\" ||\n severity === \"major\" ||\n severity === \"minor\" ||\n severity === \"nit\")\n ? {\n // resolveRuleId: the ONE legacy-spelling precedence the upcast, this reader, and the\n // below-floor nit reader share — a pre-id marker (or one written before the migration)\n // carries `code`; a codeless one resolves to the same synthesized id the registry's\n // legacy upcast derives, so the entry keys to the identical claim on the next round.\n code:\n resolveRuleId({\n id: typeof id === \"string\" ? id : undefined,\n code: typeof legacyCode === \"string\" ? legacyCode : undefined,\n path,\n title,\n }) ?? synthesizedFindingId(path, title),\n title,\n description,\n reasoning,\n severity,\n path,\n patch: typeof patch === \"string\" ? patch : null,\n }\n : null;\n };\n\n // Group every comment under its root id; the root's own id keys the group. Iterating the SORTED\n // array feeds both selections below — the first-human-reply find() and the last-wins dedup both\n // read group/map insertion order, so the sort must drive that order (issue #151 review r3: the\n // original fix sorted into `byId` only, leaving the selection loops on the raw API order).\n const threads = new Map<number, ThreadComment[]>();\n for (const c of ordered) {\n const root = rootOf(c);\n if (root === null) continue;\n const group = threads.get(root.id);\n if (group === undefined) threads.set(root.id, [c]);\n else group.push(c);\n }\n\n // One entry per answered bot-rooted thread: the thread must be anchored on the BOT's comment;\n // the answer recorded is the LAST HUMAN reply in it — the operative dismissal is the most recent\n // answer, and a thread answered twice must not have its earlier reply win the dedup below (issue\n // #151 review r5).\n const entries: AnsweredEntry[] = [];\n for (const [rootId, group] of threads) {\n const root = byId.get(rootId);\n if (root === undefined || root.user_login !== botLogin) continue;\n const finding = findingOf(root);\n if (finding === null) continue;\n const humanReplies = group.filter(\n (c) => c.id !== root.id && isHuman(c.user_login, c.user_type, botLogin),\n );\n const reply = humanReplies[humanReplies.length - 1];\n if (reply === undefined) continue;\n entries.push({\n ...finding,\n repliedAt: reply.created_at,\n replyId: reply.id,\n threadUrl: root.html_url,\n replyUrl: reply.html_url,\n replyAuthor: reply.user_login,\n replyExcerpt: clipText(reply.body ?? \"\", EXCERPT_LIMIT),\n });\n }\n // Dedup by the shared note key, keeping the entry with the MOST RECENT ANSWER — keyed on the\n // REPLY time, never the root (review-posting) order: an older thread answered later must win over\n // a newer thread answered earlier (issue #151 review r4). Sort DESCENDING by (repliedAt, replyId)\n // and keep the first per key — an equal-timestamp tie breaks toward the LATER reply id\n // (monotonic with creation), not toward any thread order (issue #151 review r7).\n const byKey = new Map<string, AnsweredEntry>();\n for (const entry of [...entries].sort(\n (a, b) => (b.repliedAt ?? \"\").localeCompare(a.repliedAt ?? \"\") || b.replyId - a.replyId,\n )) {\n const key = answeredNoteKey({ id: entry.code, title: entry.title });\n if (!byKey.has(key)) byKey.set(key, entry);\n }\n return [...byKey.values()];\n};\n\n// The id match: 0.10 requires every finding to carry an id, and the legacy upcast gives every pre-id\n// finding one (code → id, or synthesized), so two rounds of the same claim always key to equal ids.\n// An EMPTY id resolves exactly the way the registry builder resolves a marker finding — the two sides\n// share resolveFindingId, so a verbatim re-raise of an empty-id finding still matches the entry its\n// marker synthesized. A TITLE match is the second chance the pre-0.10 \"code (or title)\" rule gave,\n// RESTRICTED to entries whose code was synthesized (isSynthesizedFindingId): a codeless claim whose\n// answer pre-dates ids can only recover its annotation when the re-raise is RELOCATED (the\n// synthesized key is path-derived) or carries a fresh agent id — while an unrelated same-title entry\n// with a real code can never mis-bind. The full-claim verbatim check still gates the drop.\nconst isSynthesizedTitleMatch = (f: Finding, e: Pick<AnsweredEntry, \"code\" | \"title\">): boolean =>\n isSynthesizedFindingId(e.code) && e.title === f.title;\n\nconst matches = (\n resolvedId: string,\n f: Finding,\n e: Pick<AnsweredEntry, \"code\" | \"title\">,\n): boolean => e.code === resolvedId || isSynthesizedTitleMatch(f, e);\n\n// The full-claim verbatim predicate, extracted from applyAnswered below so the seed's pre-filter\n// (issue #233 r2) can ask the SAME question of the staged registry — one definition, two consumers.\n// The ONE verbatim claim-field list: the six per-field comparisons consumed by both the full-claim\n// predicate and the title-second-chance scorer. The VerbatimPick type DERIVES from the array, so\n// adding a claim field is a single edit the compiler verifies — the type and the runtime list can\n// never diverge (the same one-definition discipline as answeredNoteKey below).\nconst VERBATIM_FIELDS = [\"title\", \"description\", \"reasoning\", \"severity\", \"path\", \"patch\"] as const;\ntype VerbatimPick = Pick<AnsweredEntry, (typeof VERBATIM_FIELDS)[number]>;\n\nconst verbatimFieldEqual = (\n f: Finding,\n e: VerbatimPick,\n field: (typeof VERBATIM_FIELDS)[number],\n): boolean => (field === \"patch\" ? (f.patch ?? null) === e.patch : f[field] === e[field]);\n\nexport const isVerbatimReRaise = (f: Finding, e: VerbatimPick): boolean =>\n VERBATIM_FIELDS.every((field) => verbatimFieldEqual(f, e, field));\n\n// Would post's answered-filter DROP this finding? applyAnswered below and the seed's pre-filter\n// both ask this (issue #233 r2), so \"answered\" can never mean two things across the pipeline. e is\n// the staged wire shape too: every field the predicate reads shares its name across both types.\n// The one known corner where the two consumers disagree: a finding that id-matches a NON-verbatim\n// entry while a verbatim (6/6) synthesized same-title entry sits beside it — post keeps it (only\n// the chosen entry feeds the drop), the seed's existential scan drops it (see applyAnswered).\nexport const isAnsweredDrop = (\n resolvedId: string,\n f: Finding,\n e: Pick<\n AnsweredEntry,\n \"code\" | \"title\" | \"description\" | \"reasoning\" | \"severity\" | \"path\" | \"patch\"\n >,\n): boolean => matches(resolvedId, f, e) && isVerbatimReRaise(f, e) && f.severity !== \"critical\";\n\n// How many of the verbatim claim fields a finding shares with an entry — the title-second-chance\n// scorer: among several synthesized same-title entries (same title, different paths — their\n// synthesized ids differ), the entry sharing the MOST fields is the thread the claim came from, so\n// a kept re-raise's annotation link binds it rather than the first same-title entry in registry\n// order.\nconst verbatimMatchCount = (f: Finding, e: VerbatimPick): number =>\n VERBATIM_FIELDS.reduce((count, field) => count + (verbatimFieldEqual(f, e, field) ? 1 : 0), 0);\n\n// The ONE note-key contract: a finding's annotation key is its id; an empty id (a pre-id staged row,\n// or a reviewer-supplied empty id) falls back to \"title:<title>\" so the note still keys to something\n// — written once here, consumed by the registry builder, applyAnswered, and both renderers, so the\n// key can never drift between the writer and the lookups (issue #151 review r2).\nexport const answeredNoteKey = (f: { id: string; title: string }): string =>\n f.id !== \"\" ? f.id : `title:${f.title}`;\n\n// The title second chance, run ONLY on an id miss (the common case pays nothing): the synthesized\n// same-title entry sharing the most verbatim claim fields, ties keeping registry order. Scored in\n// one pass — each candidate once, strict > preserves the first on ties.\nconst NO_TITLE_MATCH = { entry: undefined, score: -1 } as const;\n\nconst bestTitleMatch = (\n f: Finding,\n registry: readonly AnsweredEntry[],\n): { entry: AnsweredEntry | undefined; score: number } => {\n let best: AnsweredEntry | undefined;\n let bestScore = -1;\n for (const e of registry) {\n if (!isSynthesizedTitleMatch(f, e)) continue;\n const score = verbatimMatchCount(f, e);\n if (score > bestScore) {\n best = e;\n bestScore = score;\n if (score === VERBATIM_FIELDS.length) break;\n }\n }\n return { entry: best, score: bestScore };\n};\n\n// The per-finding \"re-raised; prior answer at <link>\" annotation for a kept (changed-evidence)\n// re-raise; the pipeline cannot judge whether the reply dismissed or acknowledged the finding, so the\n// annotation links it and demands the new evidence be named.\nexport const answeredNote = (e: AnsweredEntry): string =>\n `Re-raised; prior answer at ${e.replyUrl} by ${e.replyAuthor} — cite the new evidence that invalidates it.`;\n\nexport interface AnsweredFilter {\n readonly findings: readonly Finding[];\n // code → note for KEPT re-raises with changed evidence; rendered under each such finding.\n readonly reRaisedNotes: Readonly<Record<string, string>>;\n // The entries whose findings were dropped: verbatim re-raises of an answered finding, named in the\n // sticky rather than silently vanishing. DEDUPED by ENTRY — several findings dropped against one\n // answer (an id repeated within a round, or same-title fresh-id re-raises of a synthesized entry)\n // list the answer once, never double-counted (issue #151 review r2).\n readonly verbatimReRaised: readonly AnsweredEntry[];\n // The dropped FINDINGS' ids (resolved): post strips these from systemic finding_ids — a title-\n // matched drop keys the entry's synthesized code, but the systemic list names the finding's own id,\n // so stripping by entry code alone would dangle a dropped finding (the two sides must agree on what\n // a drop removes).\n readonly droppedFindingIds: readonly string[];\n // The TRUE count of dropped findings (pre-dedup): the sticky's count must not understate the\n // suppression just because several findings shared one code (issue #151 review r5).\n readonly droppedCount: number;\n}\n\n// The deterministic backstop beneath the seed guidance: an answered finding re-raised VERBATIM\n// (identical title, description, and reasoning — no new evidence by definition) is treated as closed\n// and dropped from this review, so the round's counts and stop signal reflect the dismissal. The\n// claim TEXT is the evidence: a change to any of title/description/reasoning, or to the severity,\n// means the re-raise carries something new and MUST be kept + annotated (issue #151 review r2 — the\n// SPEC's \"no new evidence\" criterion, not just a title+reasoning byte-match). A critical is never\n// dropped — the pipeline must not suppress a critical from the surfaced review.\nexport const applyAnswered = (\n findings: readonly Finding[],\n registry: readonly AnsweredEntry[],\n): AnsweredFilter => {\n const kept: Finding[] = [];\n // Built via Object.fromEntries (CreateDataProperty): a reviewer-supplied code like \"__proto__\"\n // must become an OWN data key, never a prototype write that silently no-ops the annotation (the\n // same invariant the codebase's other code-keyed maps hold — issue #151 review r1).\n const noteEntries: [string, string][] = [];\n const droppedByEntry = new Map<number, AnsweredEntry>();\n const droppedFindingIds: string[] = [];\n let droppedCount = 0;\n for (const f of findings) {\n // ID match first across the WHOLE registry, title second chance only against synthesized\n // entries: a finding title-matching an unrelated entry ahead of its true id-matched entry must\n // not mis-bind its annotation (the id match wins wherever it exists). The second chance picks\n // the synthesized same-title entry sharing the MOST verbatim claim fields (ties keep registry\n // order), so two codeless same-title answers under different paths cannot mis-bind a kept\n // re-raise. The chosen entry alone feeds the drop decision: a title-matched entry drops the\n // finding exactly when its score is a full verbatim match (6/6), while the seed pre-filter is\n // existential over the whole registry — so the two sides disagree in one corner (a non-verbatim\n // id match beside a verbatim same-title entry; documented on isAnsweredDrop). The scorer\n // changes suppression, not just annotation.\n const resolvedId = resolveFindingId(f);\n const idMatch = registry.find((e) => e.code === resolvedId);\n const { entry: titleMatch, score: titleScore } =\n idMatch === undefined ? bestTitleMatch(f, registry) : NO_TITLE_MATCH;\n const entry = idMatch ?? titleMatch;\n if (entry === undefined) {\n kept.push(f);\n continue;\n }\n // The full claim: text (title/description/reasoning), weight (severity), AND location/fix\n // (path, patch) — a re-raise relocated to another file or proposing a different fix carries\n // something new. The line is deliberately excluded: positional drift (a rebase moving the same\n // claim) is not evidence (issue #151 review r3). patch is normalized (undefined → null) so an\n // absent patch on both sides compares equal. isAnsweredDrop's conjunction holds by\n // construction here (the entry was selected BY a match), so the drop reuses the scorer's\n // already-computed verbatim count on the title path — score === VERBATIM_FIELDS.length is\n // exactly isVerbatimReRaise, and the id path re-runs the predicate the seed shares.\n const dropped =\n (idMatch !== undefined\n ? isVerbatimReRaise(f, entry)\n : titleScore === VERBATIM_FIELDS.length) && f.severity !== \"critical\";\n if (dropped) {\n droppedByEntry.set(entry.replyId, entry);\n droppedFindingIds.push(resolvedId);\n droppedCount += 1;\n } else {\n kept.push(f);\n noteEntries.push([answeredNoteKey(f), answeredNote(entry)]);\n }\n }\n return {\n findings: kept,\n reRaisedNotes: Object.fromEntries(noteEntries),\n verbatimReRaised: [...droppedByEntry.values()],\n droppedFindingIds,\n droppedCount,\n };\n};\n\n// The sticky note naming what was dropped — the suppression is never silent (SPEC §3.3 truthful).\n// The COUNT is the true pre-dedup finding count (several findings sharing one code count as several\n// suppressions); the LINES stay deduped by key (issue #151 review r5). count is REQUIRED — a\n// default would silently reintroduce the understated count for a caller that forgets it (issue\n// #151 review r7).\nexport const answeredReRaiseNote = (entries: readonly AnsweredEntry[], count: number): string => {\n if (entries.length === 0) return \"\";\n const label = (e: AnsweredEntry): string =>\n e.code !== \"\" ? `\\`${escapeCodeBackticks(e.code)}\\`` : `“${escapeCodeBackticks(e.title)}”`;\n const lines = entries.map(\n (e) => `> - ${label(e)} — [prior answer](${e.replyUrl}) by ${e.replyAuthor}`,\n );\n return [\n `> ↩️ **${String(count)} finding(s) re-raised without new evidence — treated as answered** (each has a human reply on its prior inline thread):`,\n ...lines,\n ].join(\"\\n\");\n};\n\n// Best-effort fetch of the full review-comment set (bot + human, paginated at the API's max page\n// size so a long-lived PR's history costs the fewest requests — the FULL history is intentional,\n// persistence is the feature: an answer from round 1 must still close a round-8 verbatim re-raise);\n// null on any transport error so a degraded channel degrades to an empty registry — never a failed\n// post.\nexport const fetchThreadComments = async (\n ghApi: GhApi,\n repo: string,\n prNumber: number,\n): Promise<readonly ThreadComment[] | null> => {\n try {\n const rows = parseJsonl(\n await ghApi([\n // per_page rides the QUERY string — a `-f` field would flip `gh api` from GET to POST\n // and 422 every answered-thread fetch.\n `repos/${repo}/pulls/${String(prNumber)}/comments?per_page=100`,\n \"--paginate\",\n \"--jq\",\n THREAD_COMMENT_JQ,\n ]),\n );\n return rows.flatMap((row) => {\n const decoded = ThreadCommentCodec.decode(row);\n return decoded._tag === \"Right\" ? [decoded.right] : [];\n });\n } catch (err) {\n process.stderr.write(\n `Warning: could not fetch review threads to detect answered findings (${errMsg(err)}) — no answered-finding state for this post\\n`,\n );\n return null;\n }\n};\n","// Pure data-in, string-out Eta rendering — no side effects, no model invocation.\n\nimport { Eta } from \"eta\";\nimport { BODY_CLIP_CHARS, clipText } from \"./util.js\";\nimport type { Finding, Severity, SystemicProblem, Verdict } from \"./schema.js\";\nimport { isIncompleteFindings, resolveFindingId } from \"./schema.js\";\nimport type { DiscussionLink, RenderInput, SeverityCounts } from \"./types.js\";\nimport { computeCost, parseInstant, parseIsoDate } from \"./cost.js\";\nimport {\n severityEmoji,\n projectPatch,\n formatConfidence,\n roundsSummary,\n convergenceSummary,\n convergenceBadge,\n changeSizeSummary,\n computeSameRootNotes,\n metastasisNote,\n findingsMarkerPair,\n escapeCodeBackticks,\n escapeFence,\n lineRange,\n DEFAULT_NIT_VISIBILITY_FLOOR,\n} from \"./surface.js\";\nimport { answeredNoteKey } from \"./answered.js\";\nimport type { PatchProjection } from \"./surface.js\";\n\n// pipes break markdown table columns.\nconst escapePipes = (text: string): string => text.replace(/\\|/g, \"\\\\|\");\n\n// A code renders inside backticks and a code_url inside a markdown link: a backtick in the code\n// breaks the span, and a paren/newline in the URL breaks the link (or the blockquote the nit's\n// aside sits in) — issue #233 r2. The newline/backtick handling is escapeCodeBackticks' own.\n// The paren policy has ONE owner: an unbalanced paren truncates GitHub's autolink, so every\n// URL-building surface on the sticky shares this encoding (issue #231 r2).\nconst encodeAutolinkParens = (url: string): string =>\n url.replace(/\\(/g, \"%28\").replace(/\\)/g, \"%29\");\n\nconst linkSafeUrl = (url: string): string => encodeAutolinkParens(escapeCodeBackticks(url));\n\n// A stray finding the sticky lists links back to its code at the reviewed SHA: a BARE URL — GitHub\n// autolinks it and sizes the rendering sensibly, where the nested-aside `<details>` permalink JP\n// prototyped renders dead in issue comments (issue #231). Each segment is percent-encoded: lone\n// surrogates are replaced with U+FFFD first (encodeURIComponent THROWS on them — a junk path must\n// degrade, never crash the post), then parens after it (an unbalanced paren truncates GitHub's\n// autolink; linkSafeUrl's policy — issue #231 r1). Returns null for the findings a link would lie\n// about: a LEFT-side finding (its line numbers index the BASE tree, so a head-blob anchor names\n// the wrong code) and an empty path. `anchor` false links the path only — a stray GitHub rejected\n// inline must not re-assert its known-bad coordinates as an exact anchor.\nconst permalinkFor = (base: string, f: Finding, anchor: boolean): string | undefined => {\n if (f.path === \"\" || f.side === \"LEFT\") return undefined;\n const path = f.path\n .split(\"/\")\n .map((segment) =>\n encodeAutolinkParens(\n encodeURIComponent(\n segment.replace(\n /[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?<![\\uD800-\\uDBFF])[\\uDC00-\\uDFFF]/g,\n \"�\",\n ),\n ),\n // Markdown emphasis/syntax characters: `__` runs split the bare URL across CommonMark\n // nodes and truncate the autolink, and a path-only link ending in one of these loses its\n // tail to the autolinker's trailing-punctuation trim (issue #231 r4).\n )\n .replace(/_/g, \"%5F\")\n .replace(/\\*/g, \"%2A\")\n .replace(/'/g, \"%27\")\n .replace(/!/g, \"%21\"),\n )\n .join(\"/\");\n return anchor ? `${base}${path}#L${lineRange(f.start_line, f.end_line, \"-L\")}` : `${base}${path}`;\n};\n\n// The machine-channel budget for suppressed-nit blocks: each field is clipped individually\n// (BODY_CLIP_CHARS), but the SUM across a nit-heavy round is unbounded, and the sticky is the one\n// comment post deliberately does not shed — an unbounded machine block can still 422 it, which the\n// old embed-limit valve structurally prevented (issue #233 r1). The budget counts each nit's\n// WHOLE block — the carried lines plus the fixed summary/severity/location/`-->` lines and their\n// blockquote prefixes — and drops a nit's entire block once exhausted. The cut is marked in the\n// machine channel, never silent (issue #233 r5).\nconst CARRIED_TOTAL_CHARS = 40_000;\nconst SUPPRESSED_NIT_BLOCK_OVERHEAD = 280;\n\n// The discussion surface's budget: the per-finding asides AND the orphaned \"earlier rounds\"\n// section are additive to the one body post never sheds, so a discussion-heavy round drops whole\n// asides past this total — the cut is named in the template, never silent (the same discipline\n// the suppressed-nit budget applies). The orphaned section draws FIRST: its cut is permanent (a\n// departed id never re-enters a prior round's findings, so a dropped orphan is never re-listed),\n// while an aside cut recovers next round when the finding is still current.\nconst DISCUSSION_TOTAL_CHARS = 8_000;\nconst DISCUSSION_BLOCK_OVERHEAD = 120;\n// The orphaned entry renders as ONE composed line — the template interpolates this exact string,\n// so the budget charges the rendered length and no markup model can drift from it.\nconst orphanedEntryHtml = (\n token: string,\n links: readonly DiscussionLink[],\n truncated?: number,\n): string =>\n `- **\\`${token}\\`**: ${links\n .map((d) => `[${escapeHtml(d.author)} · ${d.when}](${linkSafeUrl(d.url)})`)\n .join(\" \")}${\n truncated !== undefined\n ? ` _(showing the ${String(PER_FINDING_LINKS)} newest of ${String(truncated)})_`\n : \"\"\n }`;\n// The newest-first cap every discussion list keeps (per-finding, per-orphan-token, and the\n// suppressed aside's slots). LIVES HERE so the template's \"showing the N newest of M\" notes\n// interpolate it — a cap change cannot leave a rendered note lying.\nexport const PER_FINDING_LINKS = 6;\n// How many dropped-thread ids the disclosure names per class; the rest ride the \"+N more\" suffix.\nconst DROPPED_IDS_SHOWN = 6;\n\n// The shared \"budget by rendered size\" walk both collateral asides use: items are added in order\n// while the ACCUMULATED size fits the cap; past it, onDrop decides each dropped item's fate\n// (null drops it entirely, a transformed item stays rendered emptied). The two budgets were\n// near-twins that drifted into a dead-budget bug — one walk, one cap comparison.\nconst budgetBySize = <T>(\n items: readonly T[],\n cap: number,\n sizeOf: (item: T) => number,\n onDrop: (item: T) => T | null,\n): { readonly kept: readonly T[]; readonly droppedItems: readonly T[]; readonly used: number } => {\n const kept: T[] = [];\n const droppedItems: T[] = [];\n let used = 0;\n for (const item of items) {\n const size = sizeOf(item);\n if (used + size > cap) {\n droppedItems.push(item);\n const replaced = onDrop(item);\n if (replaced !== null) kept.push(replaced);\n continue;\n }\n kept.push(item);\n used += size;\n }\n return { kept, droppedItems, used };\n};\n\nconst escapeHtml = (text: string): string =>\n text.replace(\n /[&<>\"']/g,\n (c) => ({ \"&\": \"&amp;\", \"<\": \"&lt;\", \">\": \"&gt;\", '\"': \"&quot;\", \"'\": \"&#39;\" })[c] ?? c,\n );\n\n// The aside's list + truncation note, composed ONCE here — the stray, systemic, and suppressed\n// surfaces all render this exact snippet (with the suppressed variant's blockquote prefix), so the\n// list markup and the \"showing the N newest of M\" wording have one owner. The template wraps it in\n// the <details> shell.\nconst discussionAsideHtml = (\n links: readonly DiscussionLink[],\n truncated: number | undefined,\n prefix: string,\n): string =>\n [\n ...links.map((d) => `${prefix}- [${escapeHtml(d.author)} · ${d.when}](${linkSafeUrl(d.url)})`),\n ...(truncated !== undefined\n ? [\n // A blank line closes the list: the note stands apart as its own paragraph instead of\n // reading as a continuation of the newest bullet.\n prefix,\n `${prefix}_(showing the ${String(PER_FINDING_LINKS)} newest of ${String(\n truncated,\n )} replies — the rest live on the comment thread.)_`,\n ]\n : []),\n ].join(\"\\n\");\n\ntype StrayView = Finding & {\n readonly patchProjection: PatchProjection;\n readonly answeredNote: string;\n // The RAW id, carried beside the escaped display form: the same-root note lookup in the\n // template is keyed on raw ids, so a backtick/newline id must not lose its note through\n // the escaping (issue #233 r3).\n readonly idKey: string;\n // The heading's collapsed line range (`start–end` via the shared lineRange collapse, so the\n // heading and the permalink anchor can never disagree — issue #231 r1).\n readonly rangeLabel: string;\n // Pre-encoded bare permalink to the finding's code at the reviewed SHA (issue #231); absent when\n // the caller supplies no repo (the standalone render command), for a LEFT-side finding (its\n // coordinates index the base tree), or for an empty path.\n readonly permalink?: string;\n // False for a stray GitHub rejected inline: its permalink links the path only, so the template\n // can tell an anchored link (which carries the agent-reported qualifier) from a bare one.\n readonly permalinkAnchored?: boolean;\n // Replies to the sticky comment that mention this finding's id (issue #246): the discussion\n // aside's linked list — pointers only, never reply prose.\n readonly discussion: readonly DiscussionLink[];\n // The pre-cap reply count when the 6-newest cap trimmed this finding's list — the aside names\n // its cut instead of rendering indistinguishably from a short thread.\n readonly discussionTruncated?: number;\n // The aside's composed list + truncation note (discussionAsideHtml) — empty when there is no\n // aside to render.\n readonly discussionHtml?: string;\n};\n\n// The per-stray \"re-raised; prior answer\" note, resolved HERE from the RAW finding's key — the\n// title is sanitized for rendering (escapePipes) but the note key was built from the raw title, so\n// a template-side lookup against the sanitized title would miss on a pipe/backtick title (issue\n// #151 review r2). The template renders the precomputed note.\nconst sanitizeFinding = (\n f: Finding,\n answeredNotes: Readonly<Record<string, string>> | undefined,\n discussionByFinding: Readonly<Record<string, readonly DiscussionLink[]>> | undefined,\n permalinkBase?: string,\n unanchored?: ReadonlySet<Finding>,\n discussionTruncated?: Readonly<Record<string, number>>,\n): StrayView => {\n const key = answeredNoteKey(f);\n // Reference identity, not a location key: post spreads the SAME finding objects into both\n // arrays, so the rejected set un-anchors exactly the findings GitHub rejected — a string key\n // would also demote a distinct twin finding at the same coordinates (issue #231 r2).\n const anchored = permalinkBase !== undefined && !(unanchored?.has(f) ?? false);\n const permalink =\n permalinkBase === undefined ? undefined : permalinkFor(permalinkBase, f, anchored);\n // permalinkBase undefined AND a LEFT/empty-path omission both land on `undefined`, so the spread\n // below is truly absent for every no-permalink case — the StrayView contract (issue #231 r4).\n return {\n ...f,\n title: escapePipes(f.title),\n path: escapeCodeBackticks(f.path),\n id: escapeCodeBackticks(f.id),\n // The RESOLVED id: the same-root notes are keyed on resolveFindingId (an empty id resolves to\n // its synthesized key), so the lookup must not miss the note on the raw id.\n idKey: resolveFindingId(f),\n ...(f.code_url !== undefined ? { code_url: linkSafeUrl(f.code_url) } : {}),\n rangeLabel: lineRange(f.start_line, f.end_line, \"–\"),\n ...(permalink !== undefined ? { permalink, permalinkAnchored: anchored } : {}),\n patchProjection: projectPatch(f.patch, \"comment-body\"),\n answeredNote:\n answeredNotes !== undefined && Object.prototype.hasOwnProperty.call(answeredNotes, key)\n ? (answeredNotes[key] ?? \"\")\n : \"\",\n discussion:\n discussionByFinding !== undefined &&\n Object.prototype.hasOwnProperty.call(discussionByFinding, f.id)\n ? (discussionByFinding[f.id] ?? [])\n : [],\n ...(discussionTruncated !== undefined &&\n Object.prototype.hasOwnProperty.call(discussionTruncated, f.id)\n ? { discussionTruncated: discussionTruncated[f.id] }\n : {}),\n };\n};\n\n// The suppressed-nit aside sits inside a `> [!NOTE]` blockquote, so a reviewer-supplied newline in a\n// title or path would break out of it (the hazard escapeCodeBackticks documents — it collapses\n// newlines AND neutralizes backticks). `m` is the confidence × likelihood the floor compared against,\n// shown so a maintainer who expands the aside sees WHY each nit was shelved (issue #164).\n// A below-floor nit is HIDDEN from the human list by policy (issue #164) — that is a visibility\n// decision, and it must not become a content filter. The projection used to keep 5 of a finding's 14\n// fields, which meant description, recommendation, reasoning and patch existed nowhere in the comment;\n// harmless while the document rode along as base64, a real hole once the document moved to the\n// artifact (issue #217). Everything now travels: the summary line stays exactly as it was, and the\n// rest rides the machine channel beside it, where a hidden nit's detail belongs.\ntype SuppressedNitView = {\n readonly title: string;\n readonly id: string;\n readonly codeUrl?: string;\n readonly path: string;\n // The machine location line renders start-end ALWAYS FULL (plain hyphen, no collapse) — a\n // machine-parseable form, deliberately distinct from the heading's collapsed rangeLabel; do not\n // migrate it onto lineRange (issue #231 r4).\n readonly startLine: number;\n readonly endLine: number;\n readonly side?: string;\n readonly severity: string;\n readonly confidence: string;\n readonly likelihood: string;\n readonly m: string;\n // Pre-split into blockquote-safe lines: the aside is a `>` blockquote, so an unprefixed line would\n // break out of it and spill a hidden nit's detail into the visible prose.\n readonly carried: readonly string[];\n // Replies naming this hidden nit's id (the aside's discussion slot — the suppressed aside is a\n // discussion surface like the strays').\n readonly discussion: readonly DiscussionLink[];\n readonly discussionTruncated?: number;\n // The aside's composed list + truncation note, blockquote-prefixed (discussionAsideHtml).\n readonly discussionHtml: string;\n};\n\n// HTML comments cannot nest, so a `-->` inside a carried field would close the block early and spill\n// the rest into the visible prose. A zero-width space between the dashes and the `>` breaks the\n// sequence while rendering invisibly, so a human reading the carried text sees it VERBATIM — the\n// previous replacement mutated the author's own text to a visible hyphen (issue #217 review r7).\nconst commentSafe = (text: string): string =>\n text.replace(/--+(?=>)/g, (dashes) => `${dashes}\\u200b`);\n\nconst sanitizeSuppressedNit = (\n f: Finding,\n discussion: readonly DiscussionLink[],\n discussionTruncated?: number,\n): SuppressedNitView => ({\n title: escapeCodeBackticks(f.title),\n id: escapeCodeBackticks(f.id),\n ...(f.code_url !== undefined ? { codeUrl: linkSafeUrl(f.code_url) } : {}),\n path: commentSafe(escapeCodeBackticks(f.path)),\n startLine: f.start_line,\n endLine: f.end_line,\n ...(f.side !== undefined ? { side: f.side } : {}),\n severity: f.severity,\n confidence: formatConfidence(f.confidence),\n likelihood: formatConfidence(f.likelihood),\n m: formatConfidence(f.confidence * f.likelihood),\n carried: carriedLines(f),\n discussion,\n ...(discussionTruncated !== undefined ? { discussionTruncated } : {}),\n discussionHtml:\n discussion.length > 0 ? discussionAsideHtml(discussion, discussionTruncated, \"> \") : \"\",\n});\n\n// Each carried field is clipped. Every below-floor nit's full finding rides in the sticky body, and\n// that body is the one GitHub rejects over 65536 chars — which post deliberately does not shed, so an\n// oversized body 422s the round with the announce placeholder still up. Removing the ~32KB document\n// bought far more room than this spends, but \"far more room\" is not a bound. The cap IS the\n// conversation clip's (BODY_CLIP_CHARS, util.ts) — one constant so the two can't drift — and clipText\n// marks what it cut so a reader is never silently shown a fragment.\n\nconst carriedLines = (f: Finding): readonly string[] =>\n [\n `description: ${clipText(f.description, BODY_CLIP_CHARS)}`,\n ...(f.recommendation !== undefined\n ? [`recommendation: ${clipText(f.recommendation, BODY_CLIP_CHARS)}`]\n : []),\n `reasoning: ${clipText(f.reasoning, BODY_CLIP_CHARS)}`,\n ...(f.patch !== undefined ? [\"patch:\", clipText(f.patch, BODY_CLIP_CHARS)] : []),\n ]\n .flatMap((block) => commentSafe(block).split(\"\\n\"))\n .map((line) => line.trimEnd());\n\n// The same render-safety escaping as strays: pipes break tables, backticks break inline code spans.\n// finding_ids render inside backticks too, so they get the same backtick escaping as paths.\nconst sanitizeSystemic = (\n s: SystemicProblem,\n discussion: readonly DiscussionLink[],\n discussionTruncated?: number,\n): SystemicProblem & {\n readonly discussion: readonly DiscussionLink[];\n readonly discussionTruncated?: number;\n readonly discussionHtml: string;\n} => ({\n ...s,\n title: escapePipes(s.title),\n discussion,\n ...(discussionTruncated !== undefined ? { discussionTruncated } : {}),\n discussionHtml:\n discussion.length > 0 ? discussionAsideHtml(discussion, discussionTruncated, \"\") : \"\",\n ...(s.id !== undefined ? { id: escapeCodeBackticks(s.id) } : {}),\n ...(s.code_url !== undefined ? { code_url: linkSafeUrl(s.code_url) } : {}),\n ...(s.paths !== undefined ? { paths: s.paths.map(escapeCodeBackticks) } : {}),\n ...(s.finding_ids !== undefined ? { finding_ids: s.finding_ids.map(escapeCodeBackticks) } : {}),\n});\n\nconst emptySeverityCounts = (): Record<Severity, number> => ({\n critical: 0,\n major: 0,\n minor: 0,\n nit: 0,\n});\n\nexport const computeSeverityCounts = (findings: readonly Finding[]): SeverityCounts =>\n findings.reduce<Record<Severity, number>>(\n (acc, f) => (f.severity in acc ? { ...acc, [f.severity]: acc[f.severity] + 1 } : acc),\n emptySeverityCounts(),\n );\n\n// The other half of the round decision, shared by post (round append) and render (badge): \"error\"\n// is the pipeline-reserved no-verdict value, so a doc that carries it — even one that somehow also\n// carries findings — never counts as a completed review and must never read as converged (#141).\nexport const isReviewVerdict = (verdict: Verdict): boolean => verdict !== \"error\";\n\n// The single decision \"is THIS run a convergence-defining full-review round?\" — a completed full\n// review (not a CI-fix mechanic pass, not an incomplete notice). post() calls it to decide the round\n// append AND passes the result to render() for the badge gate, so the two can never disagree; render()\n// falls back to it only for the standalone `render` command, which has no post to compute it.\nexport const isConvergenceRound = (\n route: string | null | undefined,\n incomplete: boolean,\n): boolean => route === \"full review\" && !incomplete;\n\nexport const render = (input: RenderInput): string => {\n const eta = new Eta({ autoTrim: false });\n const usageAvailable = input.envelope !== null;\n // The meta line prints turns/cost only when there is real usage to print — a present-but-zeroed\n // envelope (the synthesized notice wrap: no models) would otherwise show a false \"$0.00 · turns 0\".\n const hasUsage = input.envelope !== null && input.envelope.models.length > 0;\n // Enforce the invariant here, not just at the producers: a no-verdict notice (isIncompleteFindings)\n // is ALWAYS incomplete however it reached render (an envelope-less notice, a recovered draft), so it\n // never renders \"clean review\" or the review-complete marker.\n const incomplete =\n (input.incomplete ?? input.envelope?.incomplete ?? false) ||\n isIncompleteFindings(input.findings);\n // Price a time-slotted model at the RUN's completion instant (issue #170) — stamped in the envelope\n // by adapt, so re-rendering the same envelope always picks the same slot; input.pricedAt is only the\n // fallback for a pre-#170 envelope that carries no generated_at.\n const pricedAt = parseInstant(input.envelope?.generated_at) ?? input.pricedAt;\n const costReport = input.envelope\n ? computeCost(input.envelope.models, input.prices, pricedAt)\n : null;\n // The aggregate's provenance, one value for the header meta and the Total row (issue #221):\n // complete renders the plain figure, partial renders the real subtotal with a ≥ marker (the\n // unpriced rows are excluded and shown as N/A beside it), unknown renders N/A — a run whose\n // every model missed the map never presents a confident $0.00 anywhere.\n const costProvenance: \"complete\" | \"partial\" | \"unknown\" =\n costReport === null || costReport.lines.length === 0\n ? \"unknown\"\n : costReport.allKnown\n ? \"complete\"\n : costReport.lines.some((line) => line.known)\n ? \"partial\"\n : \"unknown\";\n const pricesProvided = input.pricesProvided ?? true;\n const route = input.route ?? input.envelope?.route ?? null;\n const effort = input.effort ?? input.envelope?.effort ?? null;\n const modelNames = input.envelope ? input.envelope.models.map((m) => m.model).join(\", \") : \"\";\n const severityCounts = input.severityCounts ?? computeSeverityCounts(input.findings.findings);\n // The pipeline-stamped convergence field (issue #174) is the source for the trajectory and the badge.\n // `input.rounds` is a fallback only for callers that supply a legacy trajectory directly (tests, or a\n // standalone render of a doc without convergence); its entries carry no score and render \"—\". Every\n // production sticky carries convergence — in the compact marker beside the link (issue #217) — so\n // the fallback never fires there.\n const convergence = input.findings.convergence;\n const trajectory = convergence?.rounds ?? input.rounds ?? [];\n // The same-root annotation: post passes the explicit map computed from the PRIOR-round history it\n // parsed before appending this run's record; the standalone render command derives it from the\n // supplied history minus its last (current) round. Keyed by code, rendered under each finding that\n // carries it; empty when nothing recurs — no annotation.\n const sameRootNotes =\n input.sameRootNotes ?? computeSameRootNotes(trajectory.slice(0, -1), input.findings.findings);\n // The convergence badge is a property of a completed FULL-REVIEW round: render it only then, from\n // the completed round's counts. A CI-fix mechanic pass, a lost-envelope pass, and a notice each\n // append no round and declare no convergence verdict — a badge from the current findings would sit\n // \"converged\" above a mechanic's fresh critical, and one from a carried-forward prior round would\n // contradict the findings beside it. Neither is a truthful stop signal, so no badge shows; the\n // carried-forward trajectory alone gives context. Prefer post's explicit signal (which also gates\n // the round append, so badge ⇔ append); fall back to the shared predicate for the standalone\n // `render` command — which additionally requires a rounds history, since without one no round has\n // completed and neither the badge nor the stop signal may appear (the README's omission\n // semantics, issue #141 review r4). The verdict guard (isReviewVerdict, shared with post's round\n // append) closes an edge isIncompleteFindings misses (it flags an \"error\" verdict only when\n // findings are also empty): an error doc that carries findings must still show no badge, never\n // \"converged\" beside the \"no review verdict\" badge.\n const isFullReviewRound =\n (input.convergenceRound ?? (isConvergenceRound(route, incomplete) && trajectory.length > 0)) &&\n isReviewVerdict(input.findings.verdict);\n\n // The badge and the trajectory both read the ONE pipeline-stamped `convergence` field (issue #174),\n // whose score is per-finding — reading confidence × likelihood off the findings themselves, not a\n // round's aggregate counts (issue #162) — so by construction they can never disagree (issue #141\n // review r2). In the post path this run is the last stored round, so the stamped score matches the\n // trajectory's last chip; the score already weighs a systemic critical like a finding critical (issue #134 scope).\n // The advisory notes (same-root + scope-metastasis) are a property of a real review, gated by the\n // same decision as the badge (a completed FULL-REVIEW round): a mechanic pass or a lost-envelope\n // completed review must not render a \"still recurring\" claim from carried-forward rounds beside a\n // suppressed convergence badge.\n const advisoryAllowed = isFullReviewRound;\n\n // The discussion links a below-floor nit's aside slot renders — keyed by the RAW id like every\n // other discussion lookup.\n const discussionLinksFor = (id: string): readonly DiscussionLink[] =>\n input.discussionByFinding !== undefined &&\n Object.prototype.hasOwnProperty.call(input.discussionByFinding, id)\n ? (input.discussionByFinding[id] ?? [])\n : [];\n const discussionTruncatedFor = (id: string): number | undefined =>\n input.discussionTruncated !== undefined &&\n Object.prototype.hasOwnProperty.call(input.discussionTruncated, id)\n ? input.discussionTruncated[id]\n : undefined;\n\n const suppressedBudget = budgetBySize(\n (input.suppressedNits ?? []).map((f) =>\n sanitizeSuppressedNit(f, discussionLinksFor(f.id), discussionTruncatedFor(f.id)),\n ),\n CARRIED_TOTAL_CHARS,\n (n) =>\n // The fixed overhead covers the summary line's structure; the reviewer-controlled variable\n // parts are budgeted at their true RENDERED size — the title, the path TWICE (summary +\n // location line), the code/code_url the summary line renders, each carried line's `> `\n // blockquote prefix (length + 3: prefix + newline), the location line's line numbers and\n // side label, and the discussion slot's link list.\n n.carried.reduce((sum, line) => sum + line.length + 3, 0) +\n SUPPRESSED_NIT_BLOCK_OVERHEAD +\n n.title.length +\n n.path.length * 2 +\n // The id renders with its two wrapper backticks; the code_url adds the [](...) link form.\n // The id renders ONCE: a backtick span inside parens, or the []() link form.\n n.id.length +\n (n.codeUrl !== undefined ? n.codeUrl.length + 8 : 4) +\n String(n.startLine).length * 2 +\n String(n.endLine).length +\n (n.side !== undefined ? n.side.length + 2 : 0) +\n // The composed slot's EXACT rendered size — its `> ` blockquote prefixes included.\n n.discussionHtml.length,\n () => null,\n );\n\n // The permalink identity is ONE optional: repo + reviewedSha only mean something together, and a\n // half-supplied OR EMPTY pair must not render malformed `//blob/` links — precomputed once per\n // render rather than rebuilt per stray (issue #231 r1 + r3).\n const permalinkBase =\n input.repo !== undefined &&\n input.repo !== \"\" &&\n input.reviewedSha !== undefined &&\n input.reviewedSha !== \"\"\n ? `https://github.com/${input.repo}/blob/${input.reviewedSha}/`\n : undefined;\n const unanchored = new Set(input.unanchoredStrays ?? []);\n\n const strayViews = (input.strays ?? []).map((f) => {\n const view = sanitizeFinding(\n f,\n input.answeredNotes,\n input.discussionByFinding,\n permalinkBase,\n unanchored,\n input.discussionTruncated,\n );\n return {\n ...view,\n discussionHtml:\n view.discussion.length > 0\n ? discussionAsideHtml(view.discussion, view.discussionTruncated, \"\")\n : \"\",\n };\n });\n // The discussion aside is additive to the one body post deliberately never sheds: the orphaned\n // section and the per-finding asides draw from ONE budget, whole asides dropped past it, the cut\n // named in the template, never silent. An aside whose finding has no replies costs nothing and\n // is never counted as dropped — only a thread that existed can be \"not listed\".\n // Escape-twin raw entries fold into ONE display-keyed item BEFORE the budget walk, so the\n // budget decides whole display entries: a dropped name is a spelling the render truly lacks,\n // never a twin whose sibling is still listed under the same spelling.\n const orphanedPreBudget = new Map<\n string,\n {\n readonly links: readonly DiscussionLink[];\n readonly truncated?: number;\n readonly html: string;\n }\n >();\n for (const [token, links] of Object.entries(input.orphanedDiscussion ?? {})) {\n const key = escapeCodeBackticks(token);\n const truncatedFor =\n input.orphanedTruncated !== undefined &&\n Object.prototype.hasOwnProperty.call(input.orphanedTruncated, token)\n ? input.orphanedTruncated[token]\n : undefined;\n const existing = orphanedPreBudget.get(key);\n const htmlFor = (entryLinks: readonly DiscussionLink[], entryTruncated?: number): string =>\n orphanedEntryHtml(key, entryLinks, entryTruncated);\n if (existing === undefined) {\n orphanedPreBudget.set(key, {\n links,\n ...(truncatedFor !== undefined ? { truncated: truncatedFor } : {}),\n html: htmlFor(links, truncatedFor),\n });\n } else {\n const mergedTotal =\n (existing.truncated ?? existing.links.length) + (truncatedFor ?? links.length);\n const merged = [...existing.links, ...links].sort((a, b) =>\n (b.at ?? b.when).localeCompare(a.at ?? a.when),\n );\n const mergedLinks = merged.slice(0, PER_FINDING_LINKS);\n const mergedTruncated = mergedTotal > PER_FINDING_LINKS ? mergedTotal : undefined;\n orphanedPreBudget.set(key, {\n links: mergedLinks,\n ...(mergedTruncated !== undefined ? { truncated: mergedTruncated } : {}),\n html: htmlFor(mergedLinks, mergedTruncated),\n });\n }\n }\n const orphanedBudget = budgetBySize(\n [...orphanedPreBudget.entries()],\n DISCUSSION_TOTAL_CHARS,\n ([, entry]) => entry.html.length,\n () => null,\n );\n const discussionBudget = budgetBySize(\n strayViews,\n DISCUSSION_TOTAL_CHARS - orphanedBudget.used,\n (view) =>\n view.discussion.length > 0 ? DISCUSSION_BLOCK_OVERHEAD + view.discussionHtml.length : 0,\n (view) => ({ ...view, discussion: [], discussionHtml: \"\" }),\n );\n // The systemic asides draw from the SAME pool, third in line: orphaned (permanent cut) first,\n // then the strays' asides, then the systemics'.\n const systemicBudget = budgetBySize(\n (input.findings.systemic_problems ?? []).map((s) =>\n sanitizeSystemic(\n s,\n s.id !== undefined ? discussionLinksFor(s.id) : [],\n s.id !== undefined ? discussionTruncatedFor(s.id) : undefined,\n ),\n ),\n DISCUSSION_TOTAL_CHARS - orphanedBudget.used - discussionBudget.used,\n (s) => (s.discussion.length > 0 ? DISCUSSION_BLOCK_OVERHEAD + s.discussionHtml.length : 0),\n (s) => ({ ...s, discussion: [], discussionHtml: \"\" }),\n );\n // The \"(showing N of M)\" total counts DISTINCT DISPLAYED entries — the pre-budget fold above\n // already merged twins, and the budget's own drops are named in the dropped-threads marker.\n const orphanedRender = {\n lines: orphanedBudget.kept.map(([, entry]) => entry.html),\n // The \"(showing N of M)\" total counts DISTINCT DISPLAYED entries — the pre-budget fold above\n // already merged twins, and the budget's own drops are named in the dropped-threads marker.\n total:\n input.orphanedTotal !== undefined\n ? input.orphanedTotal -\n (Object.keys(input.orphanedDiscussion ?? {}).length - orphanedPreBudget.size)\n : orphanedPreBudget.size - orphanedBudget.droppedItems.length,\n };\n\n return eta.renderString(input.template, {\n findings: input.findings,\n envelope: input.envelope,\n usageAvailable,\n hasUsage,\n incomplete,\n costReport,\n pricesProvided,\n costProvenance,\n // The house sanitizer for untrusted template fields — collapses line breaks AND escapes\n // backticks, so a hand-edited stamp cannot break the code span or the blockquote.\n // A nonconforming stamp must not be presented as validated: the template shows a note\n // instead of the smoothed value when the staleness axis cannot parse it.\n stampValid: parseIsoDate(input.prices._updated) !== undefined,\n pricesUpdatedAt: escapeCodeBackticks(input.prices._updated.replace(/\\r/g, \" \")).trim(),\n route,\n effort,\n modelNames,\n testReport: input.testReport ?? null,\n // The agent's best-effort role split (issue #182) and the pipeline's deterministic cloc table; both\n // chrome, gated to a completed review by the template's !incomplete block.\n changeSummary: changeSizeSummary(input.findings.change_size),\n clocDiff: input.clocDiff !== undefined ? escapeFence(input.clocDiff) : null,\n reviewedSha: input.reviewedSha ?? \"0000000000000000000000000000000000000000\",\n postedAt: input.postedAt ?? \"\",\n severityCounts,\n convergenceSummary: !isFullReviewRound\n ? \"\"\n : convergence\n ? convergenceBadge(convergence)\n : convergenceSummary(input.findings, input.convergenceThreshold),\n strays: discussionBudget.kept,\n orphanedLines: orphanedRender.lines,\n orphanedUnresolvable: input.orphanedUnresolvable === true,\n discussionDropped:\n discussionBudget.droppedItems.length +\n systemicBudget.droppedItems.length +\n orphanedBudget.droppedItems.length,\n discussionDroppedIds: discussionBudget.droppedItems\n .map((v) => clipText(escapeCodeBackticks(v.idKey), 64))\n .slice(0, DROPPED_IDS_SHOWN),\n discussionDroppedSystemicIds: systemicBudget.droppedItems\n .flatMap((s) => (s.id !== undefined ? [clipText(s.id, 64)] : []))\n .slice(0, DROPPED_IDS_SHOWN),\n discussionDroppedOrphanedIds: orphanedBudget.droppedItems\n .map(([token]) => clipText(token, 64))\n .slice(0, DROPPED_IDS_SHOWN),\n discussionDroppedExtra:\n Math.max(0, discussionBudget.droppedItems.length - DROPPED_IDS_SHOWN) +\n Math.max(0, systemicBudget.droppedItems.length - DROPPED_IDS_SHOWN) +\n Math.max(0, orphanedBudget.droppedItems.length - DROPPED_IDS_SHOWN),\n discussionCap: PER_FINDING_LINKS,\n orphanedTotal: orphanedRender.total,\n suppressedNits: suppressedBudget.kept,\n carriedDroppedNits: suppressedBudget.droppedItems.length,\n nitVisibilityFloor: input.nitVisibilityFloor ?? DEFAULT_NIT_VISIBILITY_FLOOR,\n systemic: systemicBudget.kept,\n unanchoredCount: input.unanchoredCount ?? 0,\n inlineDisposition: input.inlineDisposition ?? null,\n unverifiedNoLogs: input.unverifiedNoLogs === true,\n runUrl: input.runUrl ?? null,\n jsonUrl: input.jsonUrl ?? null,\n // The marker names the findings artifact, so the convergence no longer rides inside the comment —\n // it needs its own compact marker beside the link or a trajectory would require a fetch to read\n // (issue #217). post precomputes both together in findingsBlob; the standalone `render` command\n // builds the same pair here, so neither path can emit a link with the convergence missing.\n findingsPointer:\n input.findingsPointer ?? findingsMarkerPair(input.jsonUrl, input.findings.convergence),\n roundsSummary: roundsSummary(trajectory, input.roundCount),\n metastasisNote: advisoryAllowed ? metastasisNote(trajectory) : \"\",\n sameRootNotes: advisoryAllowed ? sameRootNotes : {},\n answeredNotes: input.answeredNotes ?? {},\n answeredReRaiseNote: input.answeredReRaiseNote ?? \"\",\n reviewUrl: input.reviewUrl ?? null,\n formatTokens: (n: number): string =>\n Number.isFinite(n) && n >= 0 ? n.toLocaleString(\"en-US\") : \"—\",\n // N/A (never a false $0.00) when no real price map was provided — real tokens, no rates to\n // price them — and N/A for a model that missed the map entirely (issue #221): a misconfigured\n // row must not look like a free review. Provenance is REQUIRED (no permissive default): a\n // user-swapped template that drops the argument fails loudly, not silently fail-open.\n formatCost: (n: number, provenance: \"complete\" | \"partial\" | \"unknown\"): string => {\n // Fail CLOSED: Eta is runtime JS with no arity enforcement, so a swapped template that\n // drops the argument binds provenance to undefined — anything but the two explicit states\n // renders N/A, never a confident figure.\n if (!pricesProvided || (provenance !== \"complete\" && provenance !== \"partial\")) return \"N/A\";\n // A sub-cent partial figure is a lower bound on nothing — the ≤ marker must not wrap it.\n if (provenance === \"partial\" && !(n >= 0.005)) return \"N/A\";\n const figure = Number.isFinite(n)\n ? n > 0 && n.toFixed(2) === \"0.00\"\n ? \"<$0.01\"\n : `$${n.toFixed(2)}`\n : \"—\";\n return provenance === \"partial\" ? `≥ ${figure}` : figure;\n },\n formatDuration: (ms: number): string => {\n if (!Number.isFinite(ms) || ms < 0) return \"—\";\n const s = Math.round(ms / 1000);\n return s >= 60 ? `${String(Math.floor(s / 60))}m ${String(s % 60)}s` : `${String(s)}s`;\n },\n verdictBadge: (v: string): string => {\n switch (v) {\n case \"approve\":\n return \"✅ approved\";\n case \"comment\":\n return \"💬 comment\";\n case \"changes\":\n return \"🔧 changes requested\";\n case \"error\":\n return \"🛠️ no review verdict\";\n default:\n return `❓ ${v}`;\n }\n },\n severityEmoji,\n formatConfidence,\n });\n};\n","import parseDiff from \"parse-diff\";\nimport type { Finding, Side } from \"./schema.js\";\n\nexport type DiffLineIndex = ReadonlySet<string>;\n\nconst key = (path: string, line: number): string => `${path}:${String(line)}`;\n\nconst indexChanges = (\n keys: Set<string>,\n fpath: string,\n changes: ReadonlyArray<{\n readonly type: \"normal\" | \"add\" | \"del\";\n readonly ln1?: number;\n readonly ln2?: number;\n readonly ln?: number;\n }>,\n): void => {\n for (const change of changes) {\n if (change.type === \"normal\") {\n if (change.ln1 !== undefined) keys.add(key(fpath, change.ln1));\n if (change.ln2 !== undefined) keys.add(key(fpath, change.ln2));\n } else if (change.ln !== undefined) {\n keys.add(key(fpath, change.ln));\n }\n }\n};\n\n// For renamed files, both old and new paths are indexed so a finding on either matches.\nexport const indexDiff = (diff: string): DiffLineIndex => {\n const files = parseDiff(diff);\n if (!Array.isArray(files)) return new Set();\n\n const keys = new Set<string>();\n for (const file of files) {\n // from ?? to covers deleted (to=/dev/null), new (from undefined), and modified; a rename differs\n // and is indexed under both paths.\n const primary = file.from ?? file.to;\n if (!primary) continue;\n\n indexChanges(\n keys,\n primary,\n file.chunks.flatMap((c) => c.changes),\n );\n\n if (file.to && file.to !== \"/dev/null\" && file.to !== primary) {\n indexChanges(\n keys,\n file.to,\n file.chunks.flatMap((c) => c.changes),\n );\n }\n }\n return keys;\n};\n\nexport const isInDiff = (index: DiffLineIndex, path: string, line: number): boolean =>\n index.has(key(path, line));\n\nexport const isEmptyDiff = (diff: string): boolean => {\n if (diff.trim().length === 0) return true;\n const files = parseDiff(diff);\n return !Array.isArray(files) || files.length === 0 || files.every((f) => f.chunks.length === 0);\n};\n\nexport const defaultSide = (side: string | undefined): Side => (side === \"LEFT\" ? \"LEFT\" : \"RIGHT\");\n\nexport const partitionFindings = (\n findings: readonly Finding[],\n index: DiffLineIndex,\n): {\n readonly inDiff: readonly Finding[];\n readonly strays: readonly Finding[];\n} => {\n const inDiff: Finding[] = [];\n const strays: Finding[] = [];\n for (const f of findings) {\n if (isInDiff(index, f.path, f.start_line) && isInDiff(index, f.path, f.end_line)) {\n inDiff.push(f);\n } else {\n strays.push(f);\n }\n }\n return { inDiff, strays };\n};\n","import { Eta } from \"eta\";\nimport { partitionFindings, indexDiff, defaultSide } from \"./diff.js\";\nimport {\n severityEmoji,\n findingPointer,\n findingPayload,\n INLINE_PROSE_CLIP_THRESHOLD_CHARS,\n projectPatch,\n formatConfidence,\n} from \"./surface.js\";\nimport { BODY_CLIP_CHARS, clipText } from \"./util.js\";\nimport { answeredNoteKey } from \"./answered.js\";\nimport { resolveFindingId } from \"./schema.js\";\nimport type { Finding, Findings } from \"./schema.js\";\nimport type { InlineComment, InlineResult } from \"./types.js\";\n\nconst formatModels = (models: readonly string[]): string =>\n models.length > 0 ? models.map((m) => `\\`${m}\\``).join(\"/\") : \"an AI model\";\n\n// The template is the SSOT for all body text; TS supplies only data. The patch is projected here\n// (never a `suggestion` field — that field is gone as of schema 0.4).\nconst renderCommentBody = (\n f: Finding,\n eta: Eta,\n template: string,\n modelsText: string,\n jsonUrl: string | undefined,\n pointer: string,\n sameRootNote: string,\n answeredNote: string,\n): string =>\n // Eta.renderString returns string | Promise<string>; with autoTrim:false it's always sync.\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n eta.renderString(template, {\n ...f,\n patchProjection: projectPatch(f.patch, \"diff-anchored\"),\n severityEmoji,\n formatConfidence,\n modelsText,\n jsonUrl: jsonUrl ?? null,\n findingsPointer: pointer,\n sameRootNote,\n answeredNote,\n }) as string;\n\nexport interface InlineContext {\n readonly inlineTemplate: string;\n readonly models?: readonly string[];\n readonly jsonUrl?: string;\n // Each in-diff comment embeds only its OWN finding, but needs the document's schema_version to do\n // so; omitted when the caller has no document (each comment's marker is then omitted too).\n readonly findings?: Findings;\n // Code → \"same mechanism as round N\" note, rendered under a finding whose code recurred in a prior\n // round; omitted/empty ⇒ no per-comment annotation.\n readonly sameRootNotes?: Readonly<Record<string, string>>;\n // Code → \"Re-raised; prior answer at <link>\" note for a kept finding whose code an answered prior\n // thread named (issue #151); omitted/empty ⇒ no per-comment annotation.\n readonly answeredNotes?: Readonly<Record<string, string>>;\n // A precomputed in-diff partition — the caller that needs the split for other reasons (the\n // discussion known set) computes it once and shares it; omitted ⇒ built here.\n readonly partition?: {\n readonly inDiff: readonly Finding[];\n readonly strays: readonly Finding[];\n };\n}\n\nexport const buildInlineComments = (\n findings: readonly Finding[],\n diff: string,\n context: InlineContext,\n): InlineResult => {\n const { inlineTemplate, models = [], jsonUrl, findings: fullFindings } = context;\n const { inDiff, strays } = context.partition ?? partitionFindings(findings, indexDiff(diff));\n const eta = new Eta({ autoTrim: false });\n const modelsText = formatModels(models);\n\n const noteFor = (notes: Readonly<Record<string, string>> | undefined, key: string): string =>\n notes !== undefined && Object.prototype.hasOwnProperty.call(notes, key)\n ? (notes[key] ?? \"\")\n : \"\";\n\n const comments: InlineComment[] = inDiff.map((f) => {\n const pointer = fullFindings ? findingPointer(f, fullFindings.schema_version, jsonUrl) : \"\";\n // In the clip band the prose sheds so the comment fits — the marker still embeds the WHOLE\n // finding, which is what keeps the answered registry decoding the thread (issue #233 r2). The\n // clip is clipText's marked truncation, never silent.\n const clipProse =\n fullFindings !== undefined &&\n findingPayload(f, fullFindings.schema_version).length > INLINE_PROSE_CLIP_THRESHOLD_CHARS;\n const view = clipProse\n ? {\n ...f,\n title: clipText(f.title, BODY_CLIP_CHARS),\n description: clipText(f.description, BODY_CLIP_CHARS),\n ...(f.recommendation != null\n ? { recommendation: clipText(f.recommendation, BODY_CLIP_CHARS) }\n : {}),\n reasoning: clipText(f.reasoning, BODY_CLIP_CHARS),\n ...(f.patch != null ? { patch: clipText(f.patch, BODY_CLIP_CHARS) } : {}),\n }\n : f;\n // Each map keys differently, per its writer: the same-root notes key on the RESOLVED id\n // (computeSameRootNotes), the answered notes on answeredNoteKey (applyAnswered) — the lookup\n // must match the writer, not one shared key.\n const sameRootNote = noteFor(context.sameRootNotes, resolveFindingId(f));\n const answeredNote = noteFor(context.answeredNotes, answeredNoteKey(f));\n const comment: InlineComment = {\n path: f.path,\n line: f.end_line,\n side: defaultSide(f.side),\n body: renderCommentBody(\n view,\n eta,\n inlineTemplate,\n modelsText,\n jsonUrl,\n pointer,\n sameRootNote,\n answeredNote,\n ),\n };\n if (f.start_line < f.end_line) {\n return {\n ...comment,\n start_line: f.start_line,\n start_side: defaultSide(f.side),\n };\n }\n return comment;\n });\n\n return { comments, strays, inDiff };\n};\n\nexport const renderStraysSection = (strays: readonly Finding[]): string => {\n if (strays.length === 0) return \"\";\n\n const items = strays.map(\n (f) => `- **${f.severity}** · \\`${f.path}:${String(f.start_line)}\\` — ${f.title}`,\n );\n\n return [\n \"\",\n \"---\",\n \"\",\n \"#### ⚠️ Findings on lines not in the diff (demoted to summary)\",\n \"\",\n ...items,\n ].join(\"\\n\");\n};\n","// Defense-in-depth: the CLI already enforces the schema on the agent side.\n\nimport { Ajv2020 } from \"ajv/dist/2020.js\";\nimport type { ValidateFunction as AjvValidateFunction } from \"ajv/dist/2020.js\";\nimport _addFormats from \"ajv-formats\";\nimport { readFileSync } from \"node:fs\";\nimport type { Either } from \"fp-ts/Either\";\nimport { FindingsCodec } from \"./schema.js\";\nimport type { Findings } from \"./schema.js\";\n\nconst addFormats = _addFormats as unknown as (ajv: Ajv2020) => void;\n\nconst validatorCache = new Map<string, AjvValidateFunction>();\n\nconst compileSchema = (schemaPath: string): AjvValidateFunction => {\n const cached = validatorCache.get(schemaPath);\n if (cached) return cached;\n\n let schemaJson: string;\n try {\n schemaJson = readFileSync(schemaPath, \"utf-8\");\n } catch {\n throw new Error(`Cannot read schema file: ${schemaPath}`);\n }\n let schema: unknown;\n try {\n schema = JSON.parse(schemaJson);\n } catch {\n throw new Error(`Invalid JSON in schema file: ${schemaPath}`);\n }\n const ajv = new Ajv2020({ allErrors: true, strict: true });\n addFormats(ajv);\n const validator = ajv.compile(schema as Record<string, unknown>);\n validatorCache.set(schemaPath, validator);\n return validator;\n};\n\nexport interface ValidateResult {\n readonly valid: boolean;\n readonly errors: readonly string[];\n}\n\nexport const validateAgainstSchema = (findings: unknown, schemaPath: string): ValidateResult => {\n const validator = compileSchema(schemaPath);\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion -- ajv returns boolean | Promise<unknown>\n const valid = validator(findings) as boolean;\n const errors: readonly string[] =\n valid || !validator.errors\n ? []\n : validator.errors.map((e) => `${e.instancePath} ${e.message ?? \"unknown error\"}`);\n return { valid, errors };\n};\n\nexport const unsafeUnwrap = <A>(decoded: Either<unknown, A>): A => {\n if (decoded._tag === \"Right\") return decoded.right;\n throw new Error(\"io-ts decode failed — data does not match expected shape\");\n};\n\nexport const decodeFindings = (data: unknown): Findings => unsafeUnwrap(FindingsCodec.decode(data));\n","// A Claude Code Stop hook that refuses to let the review agent end its turn until it has written a\n// findings document that validates against the schema — turning \"validate before stopping\" from a\n// hope into an invariant. Same validation as `code-review validate`.\n\nimport { readFileSync, writeFileSync } from \"node:fs\";\nimport { validateAgainstSchema } from \"./validate.js\";\nimport { errMsg } from \"./util.js\";\n\n// Distinguishes an UNREADABLE file (EACCES/EISDIR) from an INVALID one — \"does not validate\" is a\n// lie when the file could not even be read.\nexport type DraftState =\n | { readonly kind: \"missing\" }\n | { readonly kind: \"unreadable\"; readonly error: string }\n | { readonly kind: \"invalid\"; readonly errors: readonly string[] }\n | { readonly kind: \"valid\" };\n\nexport type GateDecision =\n { readonly kind: \"allow\" } | { readonly kind: \"block\"; readonly reason: string };\n\nconst whatsWrong = (\n state: Exclude<DraftState, { kind: \"valid\" }>,\n draftPath: string,\n kind: string,\n): string => {\n switch (state.kind) {\n case \"missing\":\n return `${draftPath} does not exist yet`;\n case \"unreadable\":\n return `${draftPath} could not be read: ${state.error}`;\n case \"invalid\":\n return `${draftPath} does not validate against the ${kind} schema:\\n${state.errors\n .map((e) => ` - ${e}`)\n .join(\"\\n\")}`;\n }\n};\n\nexport interface StopHookSettings {\n readonly hooks: {\n readonly Stop: readonly {\n readonly hooks: readonly { readonly type: \"command\"; readonly command: string }[];\n }[];\n };\n}\n\nexport const decideGate = (\n state: DraftState,\n nudges: number,\n maxNudges: number,\n draftPath: string,\n kind: string,\n): GateDecision => {\n if (state.kind === \"valid\") return { kind: \"allow\" };\n if (nudges >= maxNudges) return { kind: \"allow\" };\n return {\n kind: \"block\",\n reason: [\n `This review is not complete — ${whatsWrong(state, draftPath, kind)}`,\n `The only deliverable is a ${kind} document that validates against the ${kind} schema — run \"code-review print-schema ${kind}\" to see the exact shape.`,\n `Write it to ${draftPath}, then run \"code-review validate ${draftPath} --kind ${kind} --explain\" until it exits 0 before ending your turn (--explain prints the schema when the shape is wrong).`,\n ].join(\"\\n\"),\n };\n};\n\n// Never throws — every failure mode degrades to a DraftState the gate can act on, rather than\n// crashing the hook and letting the agent stop by default.\nexport const draftState = (\n draftPath: string,\n resolveSchema: (parsed: unknown) => string,\n): DraftState => {\n let raw: string;\n try {\n raw = readFileSync(draftPath, \"utf-8\");\n } catch (err) {\n if (err instanceof Error && (err as NodeJS.ErrnoException).code === \"ENOENT\") {\n return { kind: \"missing\" };\n }\n return { kind: \"unreadable\", error: errMsg(err) };\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (err) {\n return {\n kind: \"invalid\",\n errors: [`not valid JSON: ${errMsg(err)}`],\n };\n }\n let schemaPath: string;\n try {\n schemaPath = resolveSchema(parsed);\n } catch (err) {\n return { kind: \"invalid\", errors: [errMsg(err)] };\n }\n try {\n const { valid, errors } = validateAgainstSchema(parsed, schemaPath);\n return valid ? { kind: \"valid\" } : { kind: \"invalid\", errors };\n } catch (err) {\n return { kind: \"invalid\", errors: [errMsg(err)] };\n }\n};\n\n// Absent or unparseable reads as 0, so a fresh review starts with a full nudge budget.\nexport const readNudges = (counterPath: string): number => {\n try {\n const n = Number.parseInt(readFileSync(counterPath, \"utf-8\").trim(), 10);\n return Number.isInteger(n) && n >= 0 ? n : 0;\n } catch {\n return 0;\n }\n};\n\n// The caller passes the `current` it just read (no stale second read). May throw on a write failure —\n// the caller decides how to handle that.\nexport const bumpNudges = (counterPath: string, current: number): void => {\n writeFileSync(counterPath, `${String(current + 1)}\\n`);\n};\n\nexport const shellQuote = (s: string): string => `'${s.replace(/'/g, `'\\\\''`)}'`;\n\nexport const defaultHookCommand = (\n draftPath: string,\n opts: {\n readonly kind?: string;\n readonly schema?: string;\n readonly schemaVersion?: string;\n readonly maxNudges?: string;\n readonly counter?: string;\n },\n): string =>\n [\n \"code-review stop-gate --draft\",\n shellQuote(draftPath),\n ...(opts.kind ? [\"--kind\", shellQuote(opts.kind)] : []),\n ...(opts.schema ? [\"--schema\", shellQuote(opts.schema)] : []),\n ...(opts.schemaVersion ? [\"--schema-version\", shellQuote(opts.schemaVersion)] : []),\n ...(opts.maxNudges ? [\"--max-nudges\", shellQuote(opts.maxNudges)] : []),\n ...(opts.counter ? [\"--counter\", shellQuote(opts.counter)] : []),\n ].join(\" \");\n\nexport const stopHookSettings = (command: string): StopHookSettings => ({\n hooks: { Stop: [{ hooks: [{ type: \"command\", command }] }] },\n});\n","// Pure — the CLI (index.ts) owns IO and degrades any error to an allow-everything no-op.\n\nimport { basename, dirname, extname, join } from \"node:path\";\n\nimport { shellQuote } from \"./stop-gate.js\";\nimport { asRecord } from \"./util.js\";\n\nexport const DEADLINE_ENV = \"CODE_REVIEW_DEADLINE_EPOCH\";\n\nexport interface BudgetInputs {\n // Unmeasurable spend is null, never 0 — never tell the agent \"$0.00 spent\".\n readonly spentUsd: number | null;\n readonly budgetUsd: number | null;\n readonly elapsedMs: number | null;\n readonly wallMs: number | null;\n readonly reserve: ReserveParams;\n}\n\nexport interface ReserveParams {\n readonly frac: number;\n readonly growth: number;\n readonly flatUsd: number;\n readonly flatMs: number;\n}\n\nexport const DEFAULT_RESERVE: ReserveParams = {\n frac: 0.15,\n growth: 0.25,\n flatUsd: 0.02,\n flatMs: 120_000,\n};\n\nconst SOFT_MULTIPLE = 2;\n\nexport type BudgetPhase =\n { readonly kind: \"ok\" } | { readonly kind: \"soft\" } | { readonly kind: \"hard\" };\n\n// Each axis carries its own absolute hardReserve, grown with usage so convergence lands earlier the\n// longer the run has gone. axisSeverity then only compares remaining headroom to that reserve.\ninterface Axis {\n readonly used: number;\n readonly limit: number;\n readonly hardReserve: number;\n}\n\nconst growingReserve = (used: number, limit: number, flat: number, r: ReserveParams): number => {\n const usedFrac = Math.min(1, Math.max(0, used / limit));\n return Math.max(flat, (r.frac + r.growth * usedFrac) * limit);\n};\n\nconst costAxis = (i: BudgetInputs): Axis | null =>\n i.spentUsd !== null && i.budgetUsd !== null && i.budgetUsd > 0\n ? {\n used: i.spentUsd,\n limit: i.budgetUsd,\n hardReserve: growingReserve(i.spentUsd, i.budgetUsd, i.reserve.flatUsd, i.reserve),\n }\n : null;\n\nconst timeAxis = (i: BudgetInputs): Axis | null =>\n i.elapsedMs !== null && i.wallMs !== null && i.wallMs > 0\n ? {\n used: i.elapsedMs,\n limit: i.wallMs,\n hardReserve: growingReserve(i.elapsedMs, i.wallMs, i.reserve.flatMs, i.reserve),\n }\n : null;\n\nconst axisSeverity = (a: Axis): 0 | 1 | 2 => {\n const remaining = a.limit - a.used;\n if (remaining <= a.hardReserve) return 2;\n if (remaining <= SOFT_MULTIPLE * a.hardReserve) return 1;\n return 0;\n};\n\nexport const decideBudget = (i: BudgetInputs): BudgetPhase => {\n const worst = [costAxis(i), timeAxis(i)]\n .filter((a): a is Axis => a !== null)\n .reduce<0 | 1 | 2>((max, a) => Math.max(max, axisSeverity(a)) as 0 | 1 | 2, 0);\n return worst === 2 ? { kind: \"hard\" } : worst === 1 ? { kind: \"soft\" } : { kind: \"ok\" };\n};\n\nconst pct = (n: number): string => `${String(Math.round(n * 100))}%`;\nconst money = (n: number): string => `$${n.toFixed(2)}`;\nconst mins = (ms: number): string => `${(ms / 60_000).toFixed(1)}m`;\n\nconst spendClause = (i: BudgetInputs): string | null =>\n i.spentUsd === null\n ? null\n : i.budgetUsd !== null && i.budgetUsd > 0\n ? `spent ${money(i.spentUsd)}/${money(i.budgetUsd)} (${pct(i.spentUsd / i.budgetUsd)})`\n : `spent ${money(i.spentUsd)}`;\n\nconst timeClause = (i: BudgetInputs): string | null =>\n i.elapsedMs === null\n ? null\n : i.wallMs !== null && i.wallMs > 0\n ? `${mins(i.elapsedMs)}/${mins(i.wallMs)} elapsed (${pct(i.elapsedMs / i.wallMs)})`\n : `${mins(i.elapsedMs)} elapsed`;\n\n// A subagent can't write the draft (single-writer deny below), so it is told to report back, not write.\nconst directive = (\n phase: Exclude<BudgetPhase, { kind: \"ok\" }>,\n draftPath: string,\n isSubagent: boolean,\n): string => {\n if (isSubagent)\n return phase.kind === \"hard\"\n ? `Budget nearly exhausted — STOP all new investigation now and report the findings you have back to the main agent in your reply. Do not write ${draftPath} yourself; only the main agent writes it.`\n : `Wind down investigation and report the findings you have back to the main agent in your reply — do not write ${draftPath} yourself; the main agent writes it, and you may run out of budget otherwise.`;\n return phase.kind === \"hard\"\n ? `Budget nearly exhausted — STOP all new investigation now. Do not wait for subagents still running in the background. Write your COMPLETE findings from what you already have to ${draftPath} and run \\`code-review validate ${draftPath} --explain\\` until it passes (--explain prints the exact schema when the shape is wrong). Other tools are blocked until that draft is written.`\n : `Wind down investigation and write your COMPLETE findings to ${draftPath} now, then run \\`code-review validate ${draftPath} --explain\\` (it prints the exact schema if the shape is wrong) — fold in the subagent reports you already have rather than waiting on stragglers; you may run out of budget before you finish otherwise.`;\n};\n\nexport const budgetMessage = (\n i: BudgetInputs,\n phase: Exclude<BudgetPhase, { kind: \"ok\" }>,\n draftPath: string,\n isSubagent: boolean,\n): string => {\n const status = [spendClause(i), timeClause(i)].filter((c): c is string => c !== null).join(\" · \");\n return `Budget check — ${status}. ${directive(phase, draftPath, isSubagent)}`;\n};\n\nconst invokesCodeReviewValidate = (toolInput: unknown): boolean => {\n const cmd = asRecord(toolInput)?.[\"command\"];\n // (?![\\w-]) excludes validate-patches — a findings-mutating command that must not pass this gate.\n return typeof cmd === \"string\" && /\\bcode-review\\s+validate(?![\\w-])/.test(cmd);\n};\n\nconst SPAWN_TOOLS: ReadonlySet<string> = new Set([\"Agent\", \"Task\"]);\nconst WEB_TOOLS: ReadonlySet<string> = new Set([\"WebFetch\", \"WebSearch\"]);\n\nexport const blockedDuringConvergence = (toolName: string, toolInput: unknown): boolean => {\n if (SPAWN_TOOLS.has(toolName) || WEB_TOOLS.has(toolName)) return true;\n if (toolName === \"Bash\") return !invokesCodeReviewValidate(toolInput);\n return false;\n};\n\nconst escapeRegExp = (s: string): string => s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\nconst WRITE_TOOLS: ReadonlySet<string> = new Set([\"Write\", \"Edit\", \"MultiEdit\", \"NotebookEdit\"]);\n\n// Scoped to the accidental fan-out race, not adversarial evasion (cp/mv/dd are out of scope).\nexport const writesToDraft = (toolName: string, toolInput: unknown, draftPath: string): boolean => {\n const rec = asRecord(toolInput);\n const targets = [draftPath, basename(draftPath), \"$DRAFT\", \"${DRAFT}\"];\n if (WRITE_TOOLS.has(toolName)) {\n const fp = rec?.[\"file_path\"] ?? rec?.[\"notebook_path\"];\n if (typeof fp === \"string\" && targets.some((t) => fp === t || basename(fp) === basename(t)))\n return true;\n }\n if (toolName === \"Bash\") {\n const cmd = rec?.[\"command\"];\n if (typeof cmd !== \"string\") return false;\n const alt = targets.map(escapeRegExp).join(\"|\");\n const end = \"(?=$|[\\\\s|&;)])\";\n const redirect = new RegExp(`>>?\\\\|?\\\\s*(['\"]?)(?:${alt})\\\\1${end}`);\n const teeArg = new RegExp(`\\\\btee\\\\b(?:\\\\s+-{1,2}\\\\S+)*\\\\s+(['\"]?)(?:${alt})\\\\1${end}`);\n return redirect.test(cmd) || teeArg.test(cmd);\n }\n return false;\n};\n\n// Agent-facing (ships to every user's review): no internal refs.\nexport const singleWriterMessage = (draftPath: string): string =>\n `Only the main agent may write ${draftPath}. When a subagent writes it too, the concurrent writers clobber each other and the review comes out empty. Do NOT write, edit, or redirect into ${draftPath} — instead, return the findings you discovered in your reply (the field names are in the schema); the main agent collects every subagent's reported findings and writes the draft itself.`;\n\n// The pre-seed is a SENTINEL, never a valid findings document (issue #127): no recovery path — the\n// extraction ladder's agent-file/last-valid rungs, the budget hook's fan-out floor — can mistake it\n// for a review, so \"agent produced nothing\" is always an honest incomplete notice. Content, not\n// mtime: a coarse-timestamp filesystem can't misclassify a fresh draft written in the same clock\n// tick, and a missing draft is simply inert (there is no seed to recover).\nexport const SEED_SENTINEL =\n \"code-review seed sentinel — not a review; replace this file with your findings review.\";\n\n// A normalized compare: a trailing newline, CRLF, or leading BOM added by any tool that touches the\n// file must not silently flip the \"untouched seed\" signal. Anything beyond that is a different\n// content — the agent's own writing. One normalization, shared by both predicates.\nconst normalizedDraft = (draftText: string | null): string =>\n typeof draftText === \"string\" ? draftText.replace(/^\\uFEFF/, \"\").trim() : \"\";\n\nexport const isSeedSentinel = (draftText: string | null): boolean =>\n normalizedDraft(draftText) === SEED_SENTINEL;\n\n// The fan-out floor: the main agent has replaced the sentinel with real first-pass content — an\n// empty or missing draft is not a first pass.\nexport const mainHasWrittenDraft = (draftText: string | null): boolean => {\n const normalized = normalizedDraft(draftText);\n return normalized !== \"\" && normalized !== SEED_SENTINEL;\n};\n\n// One sidecar-name derivation for every postfix-before-extension convention, so last-valid and\n// prior-context can never drift apart.\nexport const sidecarPath = (draftPath: string, postfix: string): string => {\n const ext = extname(draftPath);\n return join(dirname(draftPath), `${basename(draftPath, ext)}${postfix}${ext}`);\n};\n\n// The prior review's decoded findings, delivered OUT-OF-BAND beside the sentinel draft: the agent\n// may read this as re-review context, but no recovery path ever validates it as the run's\n// deliverable (only $DRAFT, its last-valid snapshot, and the native envelope are read back).\nexport const priorContextPath = (draftPath: string): string => sidecarPath(draftPath, \".prior\");\n\n// The prior review's \"already answered\" registry (issue #151) — the prior inline findings whose\n// threads a human reply answered — delivered beside the prior context so the next-round agent sees\n// what it must not re-raise verbatim. Like $PRIOR_CONTEXT, it is read-only context, never a\n// deliverable.\nexport const priorAnswersPath = (draftPath: string): string =>\n sidecarPath(draftPath, \".prior-answers\");\n\n// The prior review's below-visibility-floor nits (issue #164) — the nits the last round shelved\n// below the noise floor — delivered beside the prior context so the next-round agent knows not to\n// re-raise them as fresh nits. Like $PRIOR_CONTEXT/$PRIOR_ANSWERS, read-only context, never a\n// deliverable.\nexport const priorSuppressedPath = (draftPath: string): string =>\n sidecarPath(draftPath, \".prior-suppressed\");\n\n// Holds only ever a document that passed the extraction ladder: the budget hook snapshots the draft\n// here whenever it validates, so a wall-kill that leaves the live draft truncated still recovers the\n// last valid state instead of posting \"did not complete\". The postfix goes before the extension so\n// the snapshot keeps the draft's real type (findings-draft.last-valid.json). The sentinel never\n// validates, so it can never be checkpointed here.\nexport const lastValidPath = (draftPath: string): string => sidecarPath(draftPath, \".last-valid\");\nexport const costAxisDisengagedPath = (draftPath: string): string =>\n sidecarPath(draftPath, \".cost-axis-disengaged\");\n\n// Agent-facing: no internal refs.\nexport const spawnFloorMessage = (draftPath: string): string =>\n `Write your own first-pass findings to ${draftPath} before spawning subagents — a review must never depend on subagents alone, and the pre-seeded $DRAFT is a non-review sentinel: it does not count until you have replaced it with your own review. Write ${draftPath} from what you have read so far (preliminary findings are fine), run \\`code-review validate ${draftPath} --explain\\` until it passes, then fan out; your subagents run in the background, so keep refining the draft as their reports arrive.`;\n\n// Background so the spawner never blocks on a batch join, where no hook can reach it to steer.\nexport const forceBackgroundSpawn = (toolInput: unknown): Record<string, unknown> => ({\n hookSpecificOutput: {\n hookEventName: \"PreToolUse\",\n permissionDecision: \"allow\",\n updatedInput: { ...(asRecord(toolInput) ?? {}), run_in_background: true },\n },\n});\n\nexport interface BudgetParams {\n readonly spentUsd: number | null;\n readonly budgetUsd: number | null;\n readonly elapsedMs: number | null;\n readonly wallMs: number | null;\n readonly reserve: ReserveParams;\n readonly draftPath: string;\n // A THUNK: the draft read is only needed on the main agent's PreToolUse spawn gate, the single\n // consumer of this check — evaluating it on every hook event would read the whole draft file on\n // every tool call (the hook fires with no matcher).\n readonly mainDraftWritten: () => boolean;\n}\n\nconst denyPreTool = (reason: string): Record<string, unknown> => ({\n hookSpecificOutput: {\n hookEventName: \"PreToolUse\",\n permissionDecision: \"deny\",\n permissionDecisionReason: reason,\n },\n});\n\n// A non-empty agent_id marks a fan-out subagent; the main agent has none (or \"\"). The one predicate\n// every consumer shares, so the snapshot gate and the single-writer deny never disagree on \"\".\nexport const isSubagentHookInput = (input: unknown): boolean => {\n const agentId = asRecord(input)?.[\"agent_id\"];\n return typeof agentId === \"string\" && agentId.length > 0;\n};\n\nexport const evaluateBudgetHook = (\n input: unknown,\n params: BudgetParams,\n): Record<string, unknown> => {\n const rec = asRecord(input);\n const inputs: BudgetInputs = {\n spentUsd: params.spentUsd,\n budgetUsd: params.budgetUsd,\n elapsedMs: params.elapsedMs,\n wallMs: params.wallMs,\n reserve: params.reserve,\n };\n const phase = decideBudget(inputs);\n const isSubagent = isSubagentHookInput(input);\n\n switch (rec?.[\"hook_event_name\"]) {\n case \"PostToolBatch\":\n return phase.kind === \"ok\"\n ? {}\n : {\n hookSpecificOutput: {\n hookEventName: \"PostToolBatch\",\n additionalContext: budgetMessage(inputs, phase, params.draftPath, isSubagent),\n },\n };\n case \"PreToolUse\": {\n const toolName = rec[\"tool_name\"];\n if (typeof toolName !== \"string\") return {};\n // Single-writer enforcement is independent of budget phase.\n if (isSubagent && writesToDraft(toolName, rec[\"tool_input\"], params.draftPath))\n return denyPreTool(singleWriterMessage(params.draftPath));\n if (phase.kind === \"hard\" && blockedDuringConvergence(toolName, rec[\"tool_input\"]))\n return denyPreTool(budgetMessage(inputs, phase, params.draftPath, isSubagent));\n // Gate the main agent's first fan-out on its own draft existing; then background every spawn.\n if (SPAWN_TOOLS.has(toolName)) {\n if (!isSubagent && !params.mainDraftWritten())\n return denyPreTool(spawnFloorMessage(params.draftPath));\n return forceBackgroundSpawn(rec[\"tool_input\"]);\n }\n return {};\n }\n default:\n return {};\n }\n};\n\nexport const parseWallMs = (raw: string): number | null => {\n const m = /^(\\d+(?:\\.\\d+)?)(ms|s|m|h)?$/.exec(raw.trim());\n if (m === null) return null;\n const [, num = \"\", unit = \"s\"] = m;\n const n = Number.parseFloat(num);\n if (!Number.isFinite(n)) return null;\n switch (unit) {\n case \"ms\":\n return n;\n case \"s\":\n return n * 1000;\n case \"m\":\n return n * 60_000;\n default:\n return n * 3_600_000;\n }\n};\n\nexport const parseEpochSecMs = (raw: string | undefined): number | null => {\n if (raw === undefined) return null;\n const t = raw.trim();\n if (!/^\\d+$/.test(t)) return null;\n const n = Number.parseInt(t, 10);\n return Number.isFinite(n) && n > 0 ? n * 1000 : null;\n};\n\n// Prefer the shared deadline anchor: a fresh subagent's transcript-start reads ≈0, so per-transcript\n// elapsed would leave the fan-out unsteered. Falls back to transcript start, then null (axis off).\nexport const anchoredElapsedMs = (src: {\n readonly deadlineMs: number | null;\n readonly wallMs: number | null;\n readonly firstTsMs: number | null;\n readonly nowMs: number;\n}): number | null => {\n if (src.deadlineMs !== null && src.wallMs !== null)\n return Math.max(0, src.wallMs - (src.deadlineMs - src.nowMs));\n if (src.firstTsMs !== null) return Math.max(0, src.nowMs - src.firstTsMs);\n return null;\n};\n\n// Round the wall UP to whole seconds so the anchor never expires before the matching timeout kill.\nexport const deadlineEpochSec = (wallMs: number, nowMs: number): number =>\n Math.floor(nowMs / 1000) + Math.ceil(wallMs / 1000);\n\n// 0 is valid: it disables the fraction term, leaving only the flat floor.\nexport const parseFraction = (raw: string | undefined, fallback: number): number => {\n if (raw === undefined) return fallback;\n const n = Number.parseFloat(raw);\n return Number.isFinite(n) && n >= 0 && n <= 1 ? n : fallback;\n};\n\n// One string wired to both hooks; it self-dispatches on the event it reads from stdin.\nexport const budgetHookCommand = (\n draftPath: string,\n opts: {\n readonly budgetUsd?: string;\n readonly wall?: string;\n readonly prices?: string;\n readonly reserveFrac?: string;\n readonly reserveGrowth?: string;\n readonly reserveUsd?: string;\n readonly reserveWall?: string;\n },\n): string =>\n [\n \"code-review budget-hook --draft\",\n shellQuote(draftPath),\n ...(opts.budgetUsd ? [\"--budget-usd\", shellQuote(opts.budgetUsd)] : []),\n ...(opts.wall ? [\"--wall\", shellQuote(opts.wall)] : []),\n ...(opts.prices ? [\"--prices\", shellQuote(opts.prices)] : []),\n ...(opts.reserveFrac ? [\"--reserve-frac\", shellQuote(opts.reserveFrac)] : []),\n ...(opts.reserveGrowth ? [\"--reserve-growth\", shellQuote(opts.reserveGrowth)] : []),\n ...(opts.reserveUsd ? [\"--reserve-usd\", shellQuote(opts.reserveUsd)] : []),\n ...(opts.reserveWall ? [\"--reserve-wall\", shellQuote(opts.reserveWall)] : []),\n ].join(\" \");\n","// Fenced code blocks pass through verbatim — a `suggestion` block's blank lines and trailing\n// whitespace are significant.\n\ninterface ScanState {\n readonly lines: readonly string[];\n readonly inFence: boolean;\n readonly blankRun: number;\n}\n\nconst FENCE_RE = /^\\s*```/;\n\nconst scanLine = (state: ScanState, line: string): ScanState => {\n if (FENCE_RE.test(line)) {\n return { lines: [...state.lines, line], inFence: !state.inFence, blankRun: 0 };\n }\n if (state.inFence) {\n return { lines: [...state.lines, line], inFence: true, blankRun: 0 };\n }\n const trimmed = line.replace(/[ \\t]+$/, \"\");\n if (trimmed !== \"\") {\n return { lines: [...state.lines, trimmed], inFence: false, blankRun: 0 };\n }\n const blankRun = state.blankRun + 1;\n return blankRun === 1\n ? { lines: [...state.lines, \"\"], inFence: false, blankRun }\n : { ...state, blankRun };\n};\n\nexport const formatMarkdown = (md: string): string => {\n const { lines } = md\n .split(\"\\n\")\n .reduce<ScanState>(scanLine, { lines: [], inFence: false, blankRun: 0 });\n return `${lines.join(\"\\n\").replace(/\\n+$/, \"\")}\\n`;\n};\n\nconst pad2 = (n: number): string => String(n).padStart(2, \"0\");\n\n// Computed at the IO boundary so render() stays pure/clockless.\nexport const formatUtc = (d: Date): string =>\n `${String(d.getUTCFullYear())}-${pad2(d.getUTCMonth() + 1)}-${pad2(d.getUTCDate())} ${pad2(d.getUTCHours())}:${pad2(d.getUTCMinutes())} UTC`;\n","// The notices the review workflow synthesizes when there is no completed review to post: a security\n// block (triage returned a genuine unsafe verdict), a triage that could not evaluate (an operational\n// failure, not a verdict about the diff), a setup failure before triage could run, a PR head that\n// would not check out, or a run that passed triage but emitted nothing. Their messages and the\n// \"incomplete\" envelope shape live here — one typed SSOT — rather than as jq object literals spread\n// across the workflow YAML, so the commenter renders every one honestly (no false \"clean\n// review\"/\"$0.00\", and an operational failure never reads as a security verdict about the diff) and\n// the sticky precedence guard treats them as non-completing.\n\nimport { DEFAULT_SCHEMA_VERSION, incompleteFindings } from \"./schema.js\";\nimport type { ResultEnvelope } from \"./schema.js\";\n\n// One list is the source of truth for the kind union, its runtime guard, and the CLI's kind listing,\n// so adding a kind is a single edit rather than five that can drift out of sync.\nexport const NOTICE_KINDS = [\n \"security-blocked\",\n \"triage-error\",\n \"setup-failed\",\n \"checkout-failed\",\n \"no-output\",\n] as const;\n\nexport type NoticeKind = (typeof NOTICE_KINDS)[number];\n\nexport const isNoticeKind = (s: string): s is NoticeKind => NOTICE_KINDS.some((k) => k === s);\n\n// A host is safe to name in the raw-rendered, grep-scanned summary only if it can neither break out of\n// its backtick code span (`) nor forge a comment marker (<, >) nor start a new line (\\n, \\r) or table\n// cell (|). This is a render-safety denylist, NOT a hostname grammar: it keeps legitimate but unusual\n// hosts (bracketed IPv6, IDN) a strict pattern would wrongly drop, while still neutralizing a tampered\n// sandbox.json (the agent can rewrite it — the jail confines egress, not the filesystem). Shared with\n// scope.ts, whose scope values are spliced into the review prompt and must reject exactly these\n// prompt-structure breakers (issue #139).\nexport const UNSAFE_IN_SUMMARY = /[\\n\\r`<>|]/;\n\n// Cap how many hosts are named: a tampered config could pad allowedDomains until the rendered summary\n// blows past GitHub's 65536-char comment limit and the comment fails to post at all. A real allowlist\n// is a handful; the count is the diagnostic signal, not every entry.\nconst MAX_NAMED_HOSTS = 20;\n\n// The review agent's egress jail (sandbox-runtime) confines ONLY the agent — setup, install, and\n// gather run unfiltered. So when a jailed run produced no review, naming the jail's allowlist turns\n// \"the agent could not reach a host it needed\" into a one-line diagnosis. Pure: pulls\n// network.allowedDomains out of a parsed sandbox config, keeping only render-safe, sanely-sized host\n// strings (capped) and yielding none for any other shape (a missing config, or one before jail setup).\nexport const parseAgentAllowlist = (sandboxConfig: unknown): readonly string[] => {\n const domains = (sandboxConfig as { network?: { allowedDomains?: unknown } } | null | undefined)\n ?.network?.allowedDomains;\n return Array.isArray(domains)\n ? domains\n .filter(\n (d): d is string =>\n typeof d === \"string\" && d.length <= 256 && !UNSAFE_IN_SUMMARY.test(d),\n )\n .slice(0, MAX_NAMED_HOSTS)\n : [];\n};\n\n// Appended only to the notices where a jailed `claude -p` actually ran (no-output, triage-error), so\n// an egress-blocked host it needed is nameable against the allowlist. Framed conditionally — these\n// notices also fire for non-egress causes (a missing key, a wall-clock kill) — so it informs without\n// asserting egress was the cause. Empty allowlist ⇒ empty note.\nconst egressNote = (agentAllowlist: readonly string[]): string =>\n agentAllowlist.length === 0\n ? \"\"\n : `\\n\\nIf the review failed because the agent could not reach a host it needed, note that its network egress is jailed to only ${agentAllowlist\n .map((host) => `\\`${host}\\``)\n .join(\n \", \",\n )}. Add any missing host to the agent's egress allowlist — the reusable workflow's \\`extra_endpoints\\` input, or a single-file workflow's \\`--extra\\` flag on \\`sandbox-config\\`.`;\n\n// Blockquote every line so a multi-line reason stays quoted, not just its first line.\nconst blockquote = (text: string): string => text.replaceAll(\"\\n\", \"\\n> \");\n\n// A reason-bearing notice: when the triage supplied a detail string — a genuine unsafe verdict, or\n// the operational failure it hit — quote it under the lead; otherwise fall back to the no-reason\n// wording. The `typeof` guard fails closed on a null reason too (a JSON round-trip can yield null\n// where the type says undefined), never crashing this render path on `.trim()`.\nconst reasoned = (lead: string, noReason: string, reasons: string | undefined): string =>\n typeof reasons === \"string\" && reasons.trim() !== \"\"\n ? `${lead}\\n\\n> ${blockquote(reasons)}`\n : noReason;\n\nconst noticeSummary = (\n kind: NoticeKind,\n reasons: string | undefined,\n agentAllowlist: readonly string[],\n): string => {\n switch (kind) {\n case \"security-blocked\":\n return reasoned(\n \"### 🛑 Code review skipped by the security gate\\n\\nThe diff was flagged as unsafe to apply and execute:\",\n \"### 🛑 Code review skipped by the security gate\\n\\nThe security triage returned an unsafe verdict without a reason. See workflow logs.\",\n reasons,\n );\n case \"triage-error\":\n return (\n reasoned(\n \"### 🛠️ Security gate could not evaluate\\n\\nThe security triage could not produce a verdict (operational error), so the review failed closed — this is an infrastructure failure, not a finding about this diff. Re-run to retry a transient fault; a persistent one is a configuration issue (see the workflow logs). The triage step reported:\",\n \"### 🛠️ Security gate could not evaluate\\n\\nThe security triage could not produce a verdict (operational error), so the review failed closed — this is an infrastructure failure, not a finding about this diff. Re-run to retry a transient fault; a persistent one is a configuration issue (see the workflow logs).\",\n reasons,\n ) + egressNote(agentAllowlist)\n );\n case \"setup-failed\":\n return \"### 🛠️ Review did not run\\n\\nThe review job failed before the security triage could run (e.g. dependency install or environment setup). See the workflow logs — this is an infrastructure failure, not a security verdict.\";\n case \"checkout-failed\":\n return \"### ⚠️ Could not check out the PR head\\n\\nThe PR head commit could not be fetched or checked out (it may have been force-pushed away, or is otherwise unavailable), so the review was skipped rather than run against the wrong tree. See workflow logs.\";\n case \"no-output\":\n return (\n \"### ⚠️ Review did not complete\\n\\nThe diff passed triage but the review produced no output. See workflow logs.\" +\n egressNote(agentAllowlist)\n );\n }\n};\n\nconst noticeEnvelope = (summary: string): ResultEnvelope => ({\n schema_version: DEFAULT_SCHEMA_VERSION,\n findings: incompleteFindings(summary),\n models: [],\n turns: 0,\n duration_ms: 0,\n vendor_cost_usd: null,\n incomplete: true,\n});\n\nexport const buildNoticeEnvelope = (\n kind: NoticeKind,\n reasons?: string,\n agentAllowlist: readonly string[] = [],\n): ResultEnvelope => noticeEnvelope(noticeSummary(kind, reasons, agentAllowlist));\n\n// A workflow that asks for a kind this CLI does not know is almost always version skew — the pinned\n// CLI is older than the workflow calling it. Degrade to an honest incomplete envelope that names the\n// cause rather than exiting non-zero and crashing the assemble step into posting nothing at all.\nexport const buildUnknownNoticeEnvelope = (kind: string): ResultEnvelope =>\n noticeEnvelope(\n `### ⚠️ Review could not be rendered\\n\\nThe workflow asked for an unrecognized notice kind (\\`${kind}\\`) — the pinned code-review CLI is older than the workflow calling it (check that its version matches). Failing closed. See the workflow logs.`,\n );\n","// Findings 0.4 REQUIRES reasoning/confidence, which can't be honestly upcast from a 0.2/0.3 document\n// (confidence can't be fabricated) — so older minors are dropped from the table and degrade to the\n// unsupported-version notice. Imports schema.ts one-way (schema.ts stays a leaf; no import cycle).\n// Bundled schema paths resolve via tsup into the same dist as index.ts, so import.meta.dirname\n// matches at runtime, in dev, and from the published package.\n\nimport { resolve as resolvePath } from \"node:path\";\nimport type * as t from \"io-ts\";\nimport type { Decoder, Encoder, Errors, ValidationError } from \"io-ts\";\nimport {\n FindingsCodec,\n FindingsCodecV09,\n normalizeV09,\n TriageCodec,\n PriceMapCodec,\n DEFAULT_SCHEMA_VERSION,\n} from \"./schema.js\";\nimport type { Findings, Triage, PriceMap } from \"./schema.js\";\n\nexport type SchemaKind = \"findings\" | \"triage\" | \"prices\";\n\nexport interface DecodedFor {\n readonly findings: Findings;\n readonly triage: Triage;\n readonly prices: PriceMap;\n}\n\ninterface VersionEntry<K extends SchemaKind, A, D = A> {\n /** major.minor of `schema_version` this entry dispatches on; patch is ignored. */\n readonly minor: string;\n /** full semver stamped when a document omits `schema_version` (findings) or reported as the\n * resolved version for kinds with no in-data signal (triage, prices). */\n readonly defaultVersion: string;\n readonly schemaFile: string;\n readonly codec: Decoder<unknown, D> & Encoder<D, unknown>;\n /** upcast to the latest shape for this kind; identity when the codec already accepts both\n * shapes (e.g. an additive minor whose new field is optional). */\n readonly normalize: (decoded: D) => DecodedFor[K];\n readonly latest: boolean;\n}\n\nexport type Resolution<K extends SchemaKind> =\n | { readonly kind: \"ok\"; readonly version: string; readonly value: DecodedFor[K] }\n | {\n readonly kind: \"unsupported-version\";\n readonly version: string;\n readonly supported: readonly string[];\n }\n | { readonly kind: \"invalid-shape\"; readonly errors: readonly string[] }\n | { readonly kind: \"missing-version\" }; // findings only; triage/prices never return this\n\nconst identity = <A>(decoded: A): A => decoded;\n\n// 0.5 widened the verdict enum with the pipeline-only \"error\" value, 0.6 added the optional\n// systemic_problems array, and 0.9 added REQUIRED `likelihood` (the draft axis skips 0.7/0.8, which\n// belong to the surface-signal axis — issue #156 — so the two version spaces stay distinct). 0.10\n// made `id` REQUIRED (code → id), so every pre-0.10 minor now decodes through the one tolerant legacy\n// codec and upcasts to the 0.10 shape (code → id, or the synthesized content-derived id when a\n// finding carried none) — a pre-0.10 doc without an id still resolves, and the dropped 0.2/0.3 minors\n// still can't (they lack the required reasoning/confidence). Keeping the older minors live matches\n// their declared version to a supported entry rather than reporting an unknown version.\nconst legacyFindingsCodec = FindingsCodecV09 as unknown as Decoder<unknown, Findings> &\n Encoder<Findings, unknown>;\nconst legacyFindingsNormalize = (doc: t.TypeOf<typeof FindingsCodecV09>): Findings =>\n normalizeV09(doc);\n\nconst findingsTable: readonly VersionEntry<\"findings\", Findings>[] = [\n {\n minor: \"0.4\",\n defaultVersion: \"0.4.0\",\n // The frozen tolerant-in legacy schema, NOT the live 0.10 file: every ajv-gated channel\n // (validate --schema-version, the extraction ladder) dispatches the RAW doc's declared minor\n // through schemaPathFor, so the ajv gate must accept exactly what the tolerant legacy codec\n // accepts — the live file (id required) would reject the legacy docs the upcast promises to read.\n schemaFile: \"v0.9/findings.schema.json\",\n codec: legacyFindingsCodec,\n normalize: legacyFindingsNormalize,\n latest: false,\n },\n {\n minor: \"0.5\",\n defaultVersion: \"0.5.0\",\n schemaFile: \"v0.9/findings.schema.json\",\n codec: legacyFindingsCodec,\n normalize: legacyFindingsNormalize,\n latest: false,\n },\n {\n minor: \"0.6\",\n defaultVersion: \"0.6.0\",\n schemaFile: \"v0.9/findings.schema.json\",\n codec: legacyFindingsCodec,\n normalize: legacyFindingsNormalize,\n latest: false,\n },\n {\n minor: \"0.9\",\n defaultVersion: \"0.9.0\",\n schemaFile: \"v0.9/findings.schema.json\",\n codec: legacyFindingsCodec,\n normalize: legacyFindingsNormalize,\n latest: false,\n },\n {\n minor: \"0.10\",\n defaultVersion: DEFAULT_SCHEMA_VERSION,\n schemaFile: \"findings.schema.json\",\n codec: FindingsCodec,\n normalize: identity,\n latest: true,\n },\n];\n\nconst triageTable: readonly VersionEntry<\"triage\", Triage>[] = [\n {\n minor: \"0.1\",\n defaultVersion: \"0.1.0\",\n schemaFile: \"triage.schema.json\",\n codec: TriageCodec,\n normalize: identity,\n latest: true,\n },\n];\n\nconst pricesTable: readonly VersionEntry<\"prices\", PriceMap>[] = [\n {\n // Retained non-latest so `validate`/`print-schema --schema-version 0.1` still resolves (the\n // keep-old-minors convention the findings table follows). The price map carries no version signal,\n // and the schema is a single unversioned file, so both entries point at it; the codec's oneOf\n // accepts a flat 0.1-era map unchanged.\n minor: \"0.1\",\n defaultVersion: \"0.1.0\",\n schemaFile: \"prices.schema.json\",\n codec: PriceMapCodec,\n normalize: identity,\n latest: false,\n },\n {\n // v0.2.0 (issue #170): a model's value gained the time-slotted alternative (flat | { slots }).\n minor: \"0.2\",\n defaultVersion: \"0.2.0\",\n schemaFile: \"prices.schema.json\",\n codec: PriceMapCodec,\n normalize: identity,\n latest: true,\n },\n];\n\ntype Table<K extends SchemaKind> = readonly VersionEntry<K, DecodedFor[K]>[];\n\nconst tables: { readonly [K in SchemaKind]: Table<K> } = {\n findings: findingsTable,\n triage: triageTable,\n prices: pricesTable,\n};\n\nconst tableFor = <K extends SchemaKind>(kind: K): Table<K> => tables[kind];\n\n/** major.minor of a semver-ish string; dispatch ignores patch and any prerelease/build suffix. */\nconst majorMinor = (version: string): string => version.split(\".\").slice(0, 2).join(\".\");\n\nconst describeValidationError = (e: ValidationError): string => {\n const path = e.context\n .map((entry) => entry.key)\n .filter((key) => key.length > 0)\n .join(\".\");\n return e.message ?? `${path || \"(root)\"}: invalid value ${JSON.stringify(e.value)}`;\n};\n\nconst formatErrors = (errors: Errors): readonly string[] => errors.map(describeValidationError);\n\nexport const declaredVersion = (raw: unknown): string | undefined =>\n typeof raw === \"object\" && raw !== null && \"schema_version\" in raw\n ? typeof raw.schema_version === \"string\"\n ? raw.schema_version\n : undefined\n : undefined;\n\nexport const supportedVersions = (kind: SchemaKind): readonly string[] =>\n tableFor(kind).map((entry) => entry.minor);\n\nexport const defaultVersion = (kind: SchemaKind): string => {\n const latest = tableFor(kind).find((entry) => entry.latest);\n if (!latest) throw new Error(`Registry invariant violated — no latest entry for \"${kind}\"`);\n return latest.defaultVersion;\n};\n\nconst bundledSchemaPath = (relativePath: string): string =>\n resolvePath(import.meta.dirname, \"..\", \"schema\", relativePath);\n\nexport const schemaPathFor = (kind: SchemaKind, version?: string): string => {\n const table = tableFor(kind);\n const entry =\n version === undefined\n ? table.find((v) => v.latest)\n : table.find((v) => v.minor === majorMinor(version));\n if (!entry) {\n throw new Error(\n `Unsupported ${kind} schema version \"${version ?? \"\"}\" — supported: ${supportedVersions(kind).join(\", \")}`,\n );\n }\n return bundledSchemaPath(entry.schemaFile);\n};\n\nconst resolveFindings = (raw: unknown): Resolution<\"findings\"> => {\n const version = declaredVersion(raw);\n if (version === undefined) return { kind: \"missing-version\" };\n const entry = findingsTable.find((v) => v.minor === majorMinor(version));\n if (!entry) {\n return { kind: \"unsupported-version\", version, supported: supportedVersions(\"findings\") };\n }\n const decoded = entry.codec.decode(raw);\n return decoded._tag === \"Left\"\n ? { kind: \"invalid-shape\", errors: formatErrors(decoded.left) }\n : { kind: \"ok\", version, value: entry.normalize(decoded.right) };\n};\n\n/** Resolve a kind with no in-data version signal, never \"missing-version\". A versionless document is\n * the CURRENT contract, so it resolves against the latest entry (matching defaultVersion/schemaPathFor);\n * older entries exist only so an explicit `--schema-version` still resolves. */\nconst resolveSingleVersion = <K extends \"triage\" | \"prices\">(\n kind: K,\n raw: unknown,\n): Resolution<K> => {\n const table = tableFor(kind);\n const entry = table.find((e) => e.latest) ?? table[0];\n if (!entry) throw new Error(`Registry invariant violated — no entry for \"${kind}\"`);\n const decoded = entry.codec.decode(raw);\n return decoded._tag === \"Left\"\n ? { kind: \"invalid-shape\", errors: formatErrors(decoded.left) }\n : { kind: \"ok\", version: entry.defaultVersion, value: entry.normalize(decoded.right) };\n};\n\nconst resolvers: { readonly [K in SchemaKind]: (raw: unknown) => Resolution<K> } = {\n findings: resolveFindings,\n triage: (raw) => resolveSingleVersion(\"triage\", raw),\n prices: (raw) => resolveSingleVersion(\"prices\", raw),\n};\n\n/** Decode + version-dispatch a raw document for a schema kind. Pure — no IO. */\nexport const resolve = <K extends SchemaKind>(kind: K, raw: unknown): Resolution<K> =>\n resolvers[kind](raw);\n\n// The seed chain's tolerant findings resolution: the value when the document resolves, and — when the\n// STRICT entry rejects a body the migration's tolerant-in contract admits (a peeled legacy surfaced\n// blob re-stamped with the CURRENT draft version, or a hybrid doc whose findings carry the pre-0.10\n// `code` spelling) — the legacy codec's upcast value. null for an unsupported-version stamp: the\n// fallback must never revive a version the allowlist refuses (a dropped 0.2/0.3 minor, a future\n// 0.11+/1.x) and re-stamp it 0.10.0. The ONE place this upcast policy lives, shared by every raw-\n// document channel (the seed gate; the marker readers apply the same precedence on their fragments).\nexport const resolveTolerantFindings = (doc: unknown): Findings | null => {\n const r = resolveFindings(doc);\n if (r.kind === \"ok\") return r.value;\n if (r.kind === \"unsupported-version\") return null;\n const legacy = FindingsCodecV09.decode(doc);\n return legacy._tag === \"Right\" ? normalizeV09(legacy.right) : null;\n};\n","// The single child-process boundary for the external CLIs (`gh`, `git`); pure callers inject fakes.\n\nimport { execFile } from \"node:child_process\";\nimport { errMsg } from \"./util.js\";\n\nconst MAX_BUFFER = 100 * 1024 * 1024;\n\n// Node's child_process `timeout` is a `setTimeout` under the hood, which clamps any delay above the\n// signed-32-bit maximum to 1ms — an over-large override would paradoxically kill every call almost\n// instantly. Honor a large-but-valid ceiling; treat an out-of-range value as invalid (fall back).\nconst MAX_TIMEOUT_MS = 2_147_483_647;\n\n// `/^\\d+$/` matches the codebase's other numeric-env parsers (requireMaxNudges, requirePositiveInt):\n// it rejects the surprising forms `Number` would coerce (`\"0.5\"` → 0.5ms, `\"0x10\"`, `\"3e5\"`).\nexport const parseTimeoutMs = (raw: string | undefined, fallback: number): number => {\n if (raw === undefined || !/^\\d+$/.test(raw)) return fallback;\n const parsed = Number(raw);\n return parsed > 0 && parsed <= MAX_TIMEOUT_MS ? parsed : fallback;\n};\n\nconst SUBPROCESS_TIMEOUT_ENV = \"CODE_REVIEW_SUBPROCESS_TIMEOUT_MS\";\nconst DEFAULT_SUBPROCESS_TIMEOUT_MS = 120_000;\n\nexport const subprocessTimeoutMs = (): number =>\n parseTimeoutMs(process.env[SUBPROCESS_TIMEOUT_ENV], DEFAULT_SUBPROCESS_TIMEOUT_MS);\n\n// A child that outlives the timeout is killed via SIGKILL, and `maxBuffer` overflow kills it too;\n// both surface as `killed`, so name which one fired (and fall back to the child's own stderr/error)\n// rather than blame a timeout for an overflow.\nexport const classifyExecError = (err: unknown, stderr: string, timeoutMs: number): string => {\n const e = err as { killed?: boolean; code?: unknown };\n const stderrStr = stderr.trim();\n if (e.code === \"ERR_CHILD_PROCESS_STDIO_MAXBUFFER\")\n return `output exceeded ${String(MAX_BUFFER)} bytes (killed)`;\n // `killed` is set for any signal (the timeout SIGKILL, or an external one), so keep the child's own\n // stderr when it left some — an externally-killed child is still diagnosable from its output.\n if (e.killed === true)\n return `no response within ${String(timeoutMs)}ms (killed a hung child)${stderrStr ? `: ${stderrStr}` : \"\"}`;\n return stderrStr || errMsg(err);\n};\n\nexport type ExecSpec = {\n readonly command: string;\n readonly args: readonly string[];\n readonly label: string;\n readonly timeoutMs: number;\n readonly env?: Readonly<Record<string, string>>;\n readonly stdin?: string;\n};\n\n// A wedged external CLI (a stalled network read, an interactive auth/pager prompt that never\n// returns) would otherwise hang the whole job until the workflow's own wall clock fires. `env` is\n// spread over the inherited environment only when overrides are supplied; untrusted values reach the\n// child via `env.NAME`, never interpolated into a command.\nexport const execFileWithTimeout = (spec: ExecSpec): Promise<string> =>\n new Promise<string>((resolve, reject) => {\n const child = execFile(\n spec.command,\n [...spec.args],\n {\n ...(spec.env ? { env: { ...process.env, ...spec.env } } : {}),\n encoding: \"utf-8\",\n maxBuffer: MAX_BUFFER,\n timeout: spec.timeoutMs,\n killSignal: \"SIGKILL\",\n },\n (err, stdout, stderr) => {\n if (err)\n reject(\n new Error(`${spec.label} failed: ${classifyExecError(err, stderr, spec.timeoutMs)}`),\n );\n else resolve(stdout);\n },\n );\n if (spec.stdin !== undefined) {\n // A SIGKILLed child (timeout/maxBuffer) can tear down its stdin mid-write; without this handler\n // the resulting EPIPE would crash the process instead of letting the promise reject.\n child.stdin?.on(\"error\", () => undefined);\n child.stdin?.end(spec.stdin);\n }\n });\n","// The single GitHub-API shell boundary; pure callers inject a fake GhApi.\n\nimport { execFileWithTimeout, subprocessTimeoutMs } from \"./exec.js\";\nimport { errMsg } from \"./util.js\";\n\nexport type GhApi = (\n args: readonly string[],\n stdin?: string,\n env?: Readonly<Record<string, string>>,\n) => Promise<string>;\n\n// The endpoint for the error message: `graphql`, or the first path-shaped arg (a REST endpoint always\n// contains a `/`), so a swallowed 403 names WHICH call failed even for `--method POST <path>` forms\n// where the path is not args[0]. Falls back to args[0] for the pathological no-path case.\nexport const describeEndpoint = (args: readonly string[]): string =>\n args.find((a) => a === \"graphql\" || (a.includes(\"/\") && !a.startsWith(\"-\"))) ??\n args[0] ??\n \"(no endpoint)\";\n\n// Newer gh REFUSES raw responses containing terminal escapes unless told to allow them, and GitHub's\n// endpoints now embed ANSI color in responses built from untrusted PR content (job logs, and any\n// diff/conversation an author happens to carry raw escapes in). Every response here is CAPTURED —\n// written to a file or parsed, never echoed to a terminal — so the escapes are always safe to allow.\n// The refusal names its own remedy, so each call retries against the error it actually got: plain\n// first (an old gh accepts it, a new gh accepts it for escape-free content), and a refusal retries\n// with --allow-escape-sequences. A successful retry memoizes flag-first for the process — an old gh\n// never sees the flag, so no capability probe is needed and no probe failure can silently degrade\n// the boundary. The retry re-executes the command, so only IDEMPOTENT calls may retry — a write\n// that already landed server-side before the refusal must surface loudly, never replay. The retry's\n// cost is bounded by design: it re-fetches ONE already-buffered response (for a --paginate call,\n// gh has buffered every page before it refuses, so the retry re-downloads the whole sequence once),\n// and concurrent first calls can each refuse-and-retry once before the memoization lands — a\n// one-time per-process per-endpoint doubling, paid again in each fresh workflow step.\nlet flagFirst: boolean | undefined;\n\nexport const withEscapeRetry = async <T>(\n run: (withFlag: boolean) => Promise<T>,\n idempotent: boolean,\n): Promise<T> => {\n if (flagFirst) return run(true);\n try {\n return await run(false);\n } catch (err) {\n if (errMsg(err).includes(\"--allow-escape-sequences\")) {\n if (!idempotent) throw err;\n flagFirst = true;\n return run(true);\n }\n throw err;\n }\n};\n\n// A write call is one carrying --input, an explicit --method, or a graphql invocation — a\n// conservative reading: a `--method GET` is idempotent too, but nothing here issues one, and the one\n// graphql read query loses nothing by opting out (JSON responses bypass gh's guard anyway), while\n// the graphql minimize MUTATION carries neither REST write flag and must never replay.\nconst isIdempotentCall = (args: readonly string[]): boolean =>\n !args.includes(\"--input\") && !args.includes(\"--method\") && !args.includes(\"graphql\");\n\nexport const runGhApi: GhApi = (args, stdin, env) =>\n withEscapeRetry(\n (withFlag) =>\n execFileWithTimeout({\n command: \"gh\",\n args: [\"api\", ...(withFlag ? [\"--allow-escape-sequences\"] : []), ...args],\n label: `gh api ${describeEndpoint(args)}`,\n timeoutMs: subprocessTimeoutMs(),\n env,\n stdin,\n }),\n isIdempotentCall(args),\n );\n","import { execFile } from \"node:child_process\";\nimport { mkdtemp, readFile, rm, writeFile } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { join, resolve, sep } from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { parseConvergenceMarker, parseFindingsMarker } from \"./surface.js\";\nimport { annotationSafe, errMsg } from \"./util.js\";\nimport { withEscapeRetry } from \"./gh.js\";\n\nconst run = promisify(execFile);\n\n// A hung `gh api` or a stalled `unzip` would wait forever, in a gather step the workflow deliberately\n// leaves without a job-level cap. The seed degrades to \"no prior findings\" on timeout, which is the\n// same state as a first round — strictly better than a stuck job.\nconst STEP_TIMEOUT_MS = 60_000;\n\n// The sticky's marker names the findings artifact rather than carrying it (issue #217). Anything that\n// needs a PRIOR round's findings — the re-review seed, the nit-visibility-floor stickiness — resolves\n// it through here.\n//\n// This runs OUTSIDE the reviewing agent's jail, in gather/seed-draft/post, which hold the token. The\n// jailed agent is netns-confined to the model host and cannot reach GitHub at all; it receives prior\n// findings the same way it always has, through the out-of-band context file seed-draft writes.\nconst MARKER_URL = /<!-- code-review:findings-json (https?:\\/\\/[^\\s>]+) -->/;\n\nexport const findingsArtifactUrl = (body: string): string | null =>\n MARKER_URL.exec(body)?.[1] ?? null;\n\n// The located member name comes from the archive's own listing; before reading it, verify the\n// resolved path stays inside the extraction directory — a stored name like `../../findings.json`\n// must resolve to null, never to a file outside the temp dir (issue #233 r4).\nexport const containedPath = (dir: string, member: string): string | null => {\n const target = resolve(dir, member);\n return target.startsWith(`${dir}${sep}`) || target === dir ? target : null;\n};\n\n// Does the sticky carry a findings marker the next round could seed from — the embedded blob or the\n// artifact link? The single probe post's no-json-url guard and the resolver's callers share, so the\n// two can never disagree on what \"has a prior document\" means (issue #233 r5).\nexport const hasFindingsMarker = (body: string): boolean =>\n parseFindingsMarker(body) !== null || findingsArtifactUrl(body) !== null;\n\n// The exact stored name of the findings member in `unzip -Z1` output, matched CASE-INSENSITIVELY — a\n// case-sensitive filter misses a `Findings.json` member and the seed goes cold with nothing logged\n// (issue #217 review r7). Shortest match wins, so a root-level member is preferred over a nested one\n// if an archive ever holds both — the pipeline uploads a single directory, so today there is exactly\n// one.\nexport const locateFindingsMember = (listing: string): string | null =>\n listing\n .split(\"\\n\")\n .map((l) => l.trim())\n .filter(\n (l) => l.toLowerCase() === \"findings.json\" || l.toLowerCase().endsWith(\"/findings.json\"),\n )\n .sort((a, b) => a.length - b.length)[0] ?? null;\n\n// Reads `findings.json` out of the zip an artifact URL serves. Injected at the call sites so the\n// resolver is testable without a network or an unzip binary.\nexport type ArtifactReader = (zipUrl: string) => Promise<string | null>;\n\nexport const readArtifactFindings = (\n ghApiPath: (url: string, outPath: string) => Promise<void>,\n): ArtifactReader => {\n return async (zipUrl: string): Promise<string | null> => {\n try {\n const dir = await mkdtemp(join(tmpdir(), \"code-review-artifact-\"));\n const zip = join(dir, \"findings.zip\");\n try {\n await ghApiPath(zipUrl, zip);\n // The member is located by NAME, not assumed at the root (locateFindingsMember below) — a\n // findings document can nest as `findings/findings.json`, and today's upload-artifact strips the\n // directory prefix (verified against a real archive), but that is its behaviour, not ours.\n const { stdout: listing } = await run(\"unzip\", [\"-Z1\", zip], {\n encoding: \"utf-8\",\n maxBuffer: 4 * 1024 * 1024,\n timeout: STEP_TIMEOUT_MS,\n });\n const member = locateFindingsMember(listing);\n if (member === null) return null;\n // Extract ALL members and read the located one by exact filesystem path. `unzip -p <zip>\n // <member>` treats the name as a WILDCARD pattern, so a stored path containing `[`/`]`/`*`/`?`\n // matches nothing, exits 11, and the catch returns null — the exact silent cold-seed the\n // located-name fix exists to prevent (issue #217 review r7, verified empirically on Info-ZIP\n // 6.00). A path read has no pattern semantics at all.\n await run(\"unzip\", [zip, \"-d\", dir], {\n maxBuffer: 64 * 1024 * 1024,\n timeout: STEP_TIMEOUT_MS,\n });\n const target = containedPath(dir, member);\n if (target === null) {\n process.stderr.write(\n `::warning::the findings artifact names a member outside the archive directory (${member}) — the re-review seeds without the prior document`,\n );\n return null;\n }\n return await readFile(target, \"utf-8\");\n } finally {\n // Best-effort: a failed cleanup must not override the document/null this promise resolved\n // to — both callers await with no try/catch, so a rejection here would fail the gather\n // step or abort the post (issue #233 r1).\n await rm(dir, { recursive: true, force: true }).catch(() => undefined);\n }\n } catch (err) {\n // Every other best-effort channel in gather/post logs its failures; a mute one made an\n // expired-artifact cold seed undiagnosable. ::warning:: so the Actions UI surfaces it as an\n // annotation, not just a log line (issue #233 r1 + r2).\n process.stderr.write(\n annotationSafe(\n `::warning::could not resolve the prior findings artifact ${zipUrl} (${errMsg(err)}) — the re-review seeds without the prior document`,\n ),\n );\n return null;\n }\n };\n};\n\n// The default reader: `gh api <url> > <path>` — gh follows the artifact redirect and writes the zip.\n// gh's guard classifies binary responses by their first bytes and refuses them only when writing to\n// a TTY, which this piped child stdout never is — so the zip streams verbatim today. The shared\n// escape-retry still wraps the call as defense against a future gh that inspects binary bodies, and\n// to keep every gh api site on one boundary (this one reads its own run call because it needs buffer\n// output rather than runGhApi's string).\nexport const ghArtifactReader = readArtifactFindings(async (url, outPath) => {\n const { stdout } = await withEscapeRetry(\n (withFlag) =>\n run(\"gh\", [\"api\", ...(withFlag ? [\"--allow-escape-sequences\"] : []), url], {\n encoding: \"buffer\",\n maxBuffer: 256 * 1024 * 1024,\n timeout: STEP_TIMEOUT_MS,\n }),\n true,\n );\n await writeFile(outPath, stdout);\n});\n\n// convergence is pipeline-owned, and the artifact holds the agent's draft — uploaded before post stamps\n// it — so a fetched document's convergence is the agent ECHOING what the prior seed showed it. The\n// sticky's compact marker beside the link is the stamped copy, and replaces the echo here so every\n// consumer downstream reads one corrected document. A link with no marker predates the marker and drops\n// the echo; priorTrajectory's legacy rounds-marker fallback covers it.\nconst withoutKey = (doc: Record<string, unknown>, key: string): Record<string, unknown> =>\n Object.fromEntries(Object.entries(doc).filter(([k]) => k !== key));\n\nconst withStampedConvergence = (doc: unknown, body: string): unknown => {\n if (typeof doc !== \"object\" || doc === null || Array.isArray(doc)) return doc;\n const stripped = withoutKey(doc as Record<string, unknown>, \"convergence\");\n const stamped = parseConvergenceMarker(body);\n return stamped === null ? stripped : { ...stripped, convergence: stamped };\n};\n\n// A prior sticky's findings document, or null when the body names none and carries none.\n//\n// The embedded branch is read-only legacy: nothing writes a base64 marker any more, but every sticky\n// posted before #217 holds one, and each PR only rewrites its own on its next round — so this branch\n// is what keeps those PRs' seeds alive rather than a form we still produce.\nexport const resolvePriorFindings = async (\n body: string,\n read: ArtifactReader,\n): Promise<unknown> => {\n const embedded = parseFindingsMarker(body);\n if (embedded !== null) return embedded;\n\n const url = findingsArtifactUrl(body);\n if (url === null) return null;\n\n const text = await read(url);\n if (text === null) return null;\n try {\n return withStampedConvergence(JSON.parse(text), body);\n } catch (err) {\n process.stderr.write(\n annotationSafe(\n `::warning::could not parse the findings document fetched from ${url} (${errMsg(err)}) — the re-review seeds without the prior document`,\n ),\n );\n return null;\n }\n};\n","// post (comment job) and gather (review job) resolve the PR on separate runners but from this SAME\n// pure logic, so they never disagree on which PR (no split-brain).\n\nimport type { GhApi } from \"./gh.js\";\nimport { parseJsonl } from \"./transcript.js\";\n\ninterface PrCandidate {\n readonly number: number;\n readonly state: string;\n readonly headRef: string;\n readonly headSha: string;\n}\n\nconst CANDIDATE_JQ =\n \".[] | {number: .number, state: .state, headRef: .head.ref, headSha: .head.sha}\";\n\nconst parseCandidates = (stdout: string): readonly PrCandidate[] =>\n parseJsonl(stdout) as readonly PrCandidate[];\n\n// A fork PR's head commit lives on the fork, unreachable from the base repo, so\n// `commits/{sha}/pulls` returns nothing for it. Fall back to matching head.sha across open PRs,\n// which does reach forks. The commit endpoint stays the primary path: it is a targeted O(1)\n// lookup and resolves same-repo PRs even when head.sha has since advanced past the CI commit.\n//\n// The primary is treated as advisory: a fork head SHA absent from the base repo can 403 (not just\n// return empty) on a read-scoped token, which is exactly when the fork listing is needed — so a\n// throwing primary falls through the same way an empty one does. A genuine permission gap then\n// surfaces on the listing call (named by ghApi), never swallowed silently here.\nconst fetchDirectCandidates = async (\n repo: string,\n headSha: string,\n ghApi: GhApi,\n): Promise<readonly PrCandidate[]> => {\n try {\n return parseCandidates(\n await ghApi([`repos/${repo}/commits/${headSha}/pulls`, \"--jq\", CANDIDATE_JQ]),\n );\n } catch {\n return [];\n }\n};\n\nexport const fetchPrCandidates = async (\n repo: string,\n headSha: string,\n ghApi: GhApi,\n): Promise<readonly PrCandidate[]> => {\n const direct = await fetchDirectCandidates(repo, headSha, ghApi);\n if (direct.length > 0) return direct;\n const open = parseCandidates(\n await ghApi([\n `repos/${repo}/pulls?state=open&per_page=100`,\n \"--paginate\",\n \"--jq\",\n CANDIDATE_JQ,\n ]),\n );\n return open.filter((c) => c.headSha === headSha);\n};\n\nexport type PrResolution =\n | { readonly kind: \"none\" }\n | { readonly kind: \"not-open\"; readonly prNumber: number; readonly state: string }\n | { readonly kind: \"open\"; readonly prNumber: number };\n\nexport const resolvePr = (\n candidates: readonly PrCandidate[],\n headBranch: string | undefined,\n): PrResolution => {\n if (candidates.length === 0) return { kind: \"none\" };\n const scoped =\n candidates.length > 1 && headBranch\n ? candidates.filter((c) => c.headRef === headBranch)\n : candidates;\n const chosen = scoped.find((c) => c.state === \"open\") ?? scoped[0] ?? candidates[0];\n if (chosen === undefined) return { kind: \"none\" };\n return chosen.state === \"open\"\n ? { kind: \"open\", prNumber: chosen.number }\n : { kind: \"not-open\", prNumber: chosen.number, state: chosen.state };\n};\n\nexport const fetchDiff = async (repo: string, prNumber: number, ghApi: GhApi): Promise<string> =>\n ghApi([\n `repos/${repo}/pulls/${String(prNumber)}`,\n \"-H\",\n \"Accept: application/vnd.github.v3.diff\",\n ]);\n","// A native check-run on the PR head SHA is the attribution surface #115 asks for: it shows in the\n// PR's own checks list, correlates by construction (it IS on the SHA), and — because the review runs\n// from the base repo's default branch with a write token — works for fork PRs too, whose head commit\n// is reachable in the base repo via the PR ref. The in-progress check is created at review start (the\n// announce job, in its own concurrency group) so it survives a superseding run's cancellation. A\n// completed review finalizes it `neutral` (non-gating); a hard-failed review finalizes it `failure`;\n// a cancelled review finalizes its OWN check `cancelled` (issue #139). Every settlement is\n// OWNERSHIP-AWARE: it targets the check whose details_url carries this run's id (the announce stamps\n// `${server_url}/${repo}/actions/runs/<run_id>`), so a same-SHA supersede — where a newer run's\n// announce has already opened its own in-progress check — never settles the wrong run's check.\n\nimport type { GhApi } from \"./gh.js\";\nimport { runGhApi } from \"./gh.js\";\nimport { parseJsonl } from \"./transcript.js\";\n\nexport const CHECK_RUN_NAME = \"Code review\";\n\nexport type CheckIntent = \"in_progress\" | \"neutral\" | \"failure\" | \"cancelled\";\n\nexport interface ExistingCheck {\n readonly id: number;\n readonly status: string;\n readonly conclusion: string | null;\n readonly detailsUrl: string | null;\n}\n\n// Forward-only across the writers (comment finalizes `neutral`, attribute_failure finalizes\n// `failure`, the cancelled run settles `cancelled`) that can race on a same-SHA re-run: a completed\n// review is the truth, so `failure`/`cancelled` never overwrite a completed `neutral`/`success`, and\n// `in_progress` never re-opens a finished check.\nexport type CheckAction =\n | { readonly kind: \"noop\"; readonly reason: string }\n | {\n readonly kind: \"create\";\n readonly status: \"in_progress\" | \"completed\";\n readonly conclusion?: string;\n }\n | {\n readonly kind: \"patch\";\n readonly id: number;\n readonly status: \"completed\";\n readonly conclusion: string;\n };\n\nconst settled = new Set([\"success\", \"neutral\", \"skipped\"]);\n\n// The run id the announce job stamps into the check's details_url (`.../actions/runs/<run_id>`), used\n// to attribute a check to the run that created it. null when the URL doesn't carry one.\nexport const runIdFromUrl = (runUrl: string): string | null => {\n const m = /\\/actions\\/runs\\/(\\d+)\\/?$/.exec(runUrl);\n return m?.[1] ?? null;\n};\n\n// The check THIS run's announce created — the one whose details_url ends with `/runs/<this run id>`.\n// Matching the numeric run id (not a substring of the whole URL) keeps a successor whose run id has\n// this one as a numeric prefix from being matched.\nconst ownedCheck = (checks: readonly ExistingCheck[], runUrl: string): ExistingCheck | null => {\n const runId = runIdFromUrl(runUrl);\n if (runId === null) return null;\n return (\n checks.find((c) => c.detailsUrl !== null && c.detailsUrl.endsWith(`/runs/${runId}`)) ?? null\n );\n};\n\nexport const decideCheckAction = (\n checks: readonly ExistingCheck[],\n intent: CheckIntent,\n runUrl: string,\n): CheckAction => {\n const owned = ownedCheck(checks, runUrl);\n switch (intent) {\n case \"in_progress\":\n // Per-run idempotent: each run opens exactly ONE check (announce retries no-op once its own\n // exists), so a same-SHA supersede never shares a check with the superseded run.\n return owned !== null\n ? { kind: \"noop\", reason: \"this run's check is already in progress\" }\n : { kind: \"create\", status: \"in_progress\" };\n case \"neutral\":\n if (owned === null) return { kind: \"create\", status: \"completed\", conclusion: \"neutral\" };\n return owned.status === \"completed\" && owned.conclusion === \"neutral\"\n ? { kind: \"noop\", reason: \"the check already records this completed review\" }\n : { kind: \"patch\", id: owned.id, status: \"completed\", conclusion: \"neutral\" };\n case \"failure\":\n if (owned === null) return { kind: \"create\", status: \"completed\", conclusion: \"failure\" };\n if (\n owned.status === \"completed\" &&\n owned.conclusion !== null &&\n settled.has(owned.conclusion)\n )\n return { kind: \"noop\", reason: \"a completed review already recorded this head\" };\n return owned.status === \"completed\" && owned.conclusion === \"failure\"\n ? { kind: \"noop\", reason: \"the check already records this failure\" }\n : { kind: \"patch\", id: owned.id, status: \"completed\", conclusion: \"failure\" };\n case \"cancelled\":\n // Never reached via decideCheckAction — `cancelled` needs the runUrl and is dispatched to\n // decideCancelledAction by checkRun.\n return { kind: \"noop\", reason: \"cancelled is handled via decideCancelledAction\" };\n }\n};\n\n// Settle ONLY the check this run's announce created — matched by its details_url carrying this run's\n// id. Ownership-aware: on a concurrency-cancelled review the superseding run's announce has already\n// opened a NEWER in-progress check on the same head, and settling that one would falsely mark a live\n// review cancelled. Matching the numeric run id (not a substring of the whole URL) also keeps a\n// successor whose run id has this one as a numeric prefix from being matched.\nexport const decideCancelledAction = (\n checks: readonly ExistingCheck[],\n runUrl: string,\n): CheckAction => {\n const owned = ownedCheck(checks, runUrl);\n if (owned === null) return { kind: \"noop\", reason: \"no check was created by this run to settle\" };\n if (owned.status === \"completed\" && owned.conclusion === \"cancelled\")\n return { kind: \"noop\", reason: \"the check already records this cancelled run\" };\n // Forward-only like `failure`: never overwrite a completed review's settled check with cancelled.\n if (owned.status === \"completed\" && owned.conclusion !== null && settled.has(owned.conclusion))\n return { kind: \"noop\", reason: \"a completed review already recorded this head\" };\n return { kind: \"patch\", id: owned.id, status: \"completed\", conclusion: \"cancelled\" };\n};\n\nconst CHECK_JQ =\n \".check_runs[] | {id: .id, status: .status, conclusion: .conclusion, detailsUrl: .details_url}\";\n\nconst fetchChecks = async (\n repo: string,\n headSha: string,\n ghApi: GhApi,\n): Promise<readonly ExistingCheck[]> =>\n parseJsonl(\n await ghApi([\n `repos/${repo}/commits/${headSha}/check-runs?check_name=${encodeURIComponent(CHECK_RUN_NAME)}&per_page=100`,\n \"--paginate\",\n \"--jq\",\n CHECK_JQ,\n ]),\n ) as readonly ExistingCheck[];\n\nconst output = (intent: CheckIntent, runUrl: string): { title: string; summary: string } => {\n switch (intent) {\n case \"in_progress\":\n return {\n title: \"Code review in progress\",\n summary: `The review is running — [see the run](${runUrl}).`,\n };\n case \"neutral\":\n return {\n title: \"Code review complete\",\n summary: `The review was posted — [see the run](${runUrl}).`,\n };\n case \"failure\":\n return {\n title: \"Code review did not complete\",\n summary: `The review job failed — [see the run](${runUrl}). Re-request the review; do not treat this round as spent.`,\n };\n case \"cancelled\":\n return {\n title: \"Code review superseded\",\n summary: `This review run was cancelled — [see the run](${runUrl}). No action needed.`,\n };\n }\n};\n\nexport interface CheckRunInput {\n readonly repo: string;\n readonly headSha: string;\n readonly intent: CheckIntent;\n readonly runUrl: string;\n}\n\n// Resolve the current check, decide the forward-only ownership-aware action, then apply it. Head SHA\n// (not the PR) is the whole key — no PR resolution needed, which is why this also works for fork PRs.\nexport const checkRun = async (input: CheckRunInput, ghApi: GhApi = runGhApi): Promise<void> => {\n const checks = await fetchChecks(input.repo, input.headSha, ghApi);\n const action =\n input.intent === \"cancelled\"\n ? decideCancelledAction(checks, input.runUrl)\n : decideCheckAction(checks, input.intent, input.runUrl);\n if (action.kind === \"noop\") {\n process.stderr.write(`code-review check-run: ${action.reason} — leaving it\\n`);\n return;\n }\n const body =\n action.kind === \"create\"\n ? {\n name: CHECK_RUN_NAME,\n head_sha: input.headSha,\n status: action.status,\n details_url: input.runUrl,\n ...(action.conclusion ? { conclusion: action.conclusion } : {}),\n output: output(input.intent, input.runUrl),\n }\n : {\n status: action.status,\n conclusion: action.conclusion,\n details_url: input.runUrl,\n output: output(input.intent, input.runUrl),\n };\n const endpoint =\n action.kind === \"create\"\n ? [`--method`, `POST`, `repos/${input.repo}/check-runs`, `--input`, `-`]\n : [\n `--method`,\n `PATCH`,\n `repos/${input.repo}/check-runs/${String(action.id)}`,\n `--input`,\n `-`,\n ];\n await ghApi(endpoint, JSON.stringify(body));\n};\n","// Ordering invariant: all reads, decodes, and rendering complete before the first API write; then\n// the sticky, then the inline review. A posting failure propagates and exits non-zero (never partial).\n\nimport { readFileSync, appendFileSync } from \"node:fs\";\nimport type { DiscussionLink, InlineComment, InlineDisposition, RenderInput } from \"./types.js\";\nimport { buildInlineComments } from \"./inline.js\";\nimport { isEmptyDiff, indexDiff, partitionFindings } from \"./diff.js\";\nimport {\n render,\n computeSeverityCounts,\n isConvergenceRound,\n isReviewVerdict,\n PER_FINDING_LINKS,\n} from \"./render.js\";\nimport { formatMarkdown } from \"./format.js\";\nimport { warnStalePrices } from \"./cost.js\";\nimport {\n buildConvergence,\n carriedAncestryMarkers,\n carriedConvergence,\n carriedFindingsMarker,\n carriedMarkerPointer,\n carryForwardMarkers,\n isFullReviewAncestry,\n computeIdCounts,\n computeSameRootNotes,\n findingsMarkerPair,\n inProgressConvergence,\n nextRoundNumber,\n isBelowVisibilityFloor,\n isFullReviewSticky,\n priorBelowFloorNits,\n parseCompletedAncestor,\n parseFindingsMarker,\n parseReviewComplete,\n parseMechanicAncestor,\n parseReviewedRoute,\n parseReviewedSha,\n priorTrajectory,\n reviewBodyPointer,\n mechanicConvergence,\n escapeCodeBackticks,\n DEFAULT_CONVERGENCE_THRESHOLD,\n} from \"./surface.js\";\nimport {\n ResultEnvelopeCodec,\n PriceMapCodec,\n TestSummaryCodec,\n incompleteFindings,\n isIncompleteFindings,\n RECOVERABLE_OPTIONAL_FIELDS,\n} from \"./schema.js\";\nimport { resolveFindingId, resolveRuleId, synthesizedSystemicId } from \"./schema.js\";\nimport type { Convergence, Finding, Findings, ResultEnvelope, TestSummary } from \"./schema.js\";\nimport { resolve, supportedVersions } from \"./registry.js\";\nimport type { GhApi } from \"./gh.js\";\nimport { runGhApi } from \"./gh.js\";\nimport {\n findingsArtifactUrl,\n ghArtifactReader,\n hasFindingsMarker,\n resolvePriorFindings,\n type ArtifactReader,\n} from \"./artifact.js\";\nexport type { GhApi } from \"./gh.js\";\nimport { fetchDiff, fetchPrCandidates, resolvePr } from \"./pr.js\";\nimport { runIdFromUrl } from \"./checkrun.js\";\nimport {\n applyAnswered,\n answeredNoteKey,\n answeredReRaiseNote,\n answeredRegistryFrom,\n fetchThreadComments,\n} from \"./answered.js\";\nimport { asRecord, errMsg, tryParseJson } from \"./util.js\";\n\nexport interface PostInput {\n readonly repo: string;\n // The head repo (owner/name of the fork) threaded by the workflow via HEAD_REPO — a finding\n // permalink targets the reviewed SHA, which the base repo stops resolving for a fork once the\n // pull ref is force-pushed away. The workflow derives it from the caller's event\n // (workflow_run.head_repository.full_name / pull_request.head.repo.full_name); this base-repo\n // fallback serves the event types it cannot derive from.\n readonly headRepo?: string;\n readonly headSha: string;\n readonly botLogin: string;\n readonly findingsPath: string;\n readonly envelopePath: string;\n readonly pricesPath: string;\n // false ⇒ the bundled all-zero example; the render layer shows cost as N/A, never a false $0.00.\n readonly pricesProvided: boolean;\n readonly templatePath: string;\n readonly inlineTemplatePath: string;\n readonly route?: string;\n readonly headBranch?: string;\n readonly testReportPath?: string;\n // Raw `cloc --git --diff` table (issue #182), rendered verbatim in the sticky's cloc collapsible.\n readonly clocDiffPath?: string;\n readonly effort?: string;\n readonly runUrl?: string;\n // Render findings as inline review comments on the diff. Omitted/false ⇒ the review object is\n // posted body-only and the findings are listed in the sticky instead, which is the default because\n // an inline thread is a human-only surface that cannot be revised: a later round can neither update\n // nor resolve it, so stale threads accumulate on the diff (issue #179).\n readonly inline?: boolean;\n // The fast-fix route ran with no failing-job logs staged (issue #154). Passed as a flag because\n // this runs in the comment job, where the staged logs are not: the review job counted them. It\n // could equally ride the envelope, which `adapt` stamps with route and effort after the agent —\n // the flag is the same channel `--route` already uses, and works when the envelope is lost.\n readonly unverifiedNoLogs?: boolean;\n // Findings-json marker's fallback across surfaces when the embedded form is too large.\n readonly jsonUrl?: string;\n // Advisory convergence tolerance passed through to render(); omitted ⇒ the render default.\n readonly convergenceThreshold?: number;\n // The nit visibility floor (issue #164): nits below confidence × likelihood are hidden from humans.\n // Omitted ⇒ the surface default.\n readonly nitVisibilityFloor?: number;\n // Computed by the caller via formatUtc so post() stays a clockless pass-through into render().\n readonly postedAt?: string;\n // The run's UTC instant (same instant as postedAt), threaded to render for time-slotted pricing\n // (issue #170); post() stays clockless. Ignored for a flat price map.\n readonly pricedAt?: Date;\n}\n\nconst DEFAULT_MARKER = \"<!-- code-review -->\";\n\nconst EMPTY_MECHANIC_LEAVE_MESSAGE =\n \"The CI-fix pass found no issues and the sticky already reflects a completed full review — leaving it in place\\n\";\nconst MAX_SUGGESTION_LINES = 10;\n\nconst countSuggestionLines = (text: string): number => text.split(\"\\n\").length;\n\nconst checkLongSuggestions = (\n comments: readonly InlineComment[],\n): { readonly comments: readonly InlineComment[]; readonly longFiles: readonly string[] } => {\n const longFiles: string[] = [];\n const adjusted = comments.map((c) => {\n const match = /```suggestion\\n([\\s\\S]*?)\\n```/.exec(c.body);\n if (match?.[1] && countSuggestionLines(match[1]) > MAX_SUGGESTION_LINES) {\n longFiles.push(`${c.path}:${String(c.line)}`);\n return {\n ...c,\n body: c.body.replace(\n /```suggestion\\n[\\s\\S]*?\\n```/,\n \"*(suggestion omitted — exceeds GitHub's ~10-line suggestion limit; see summary)*\",\n ),\n };\n }\n return c;\n });\n return { comments: adjusted, longFiles };\n};\n\n// Loaders never throw on untrusted artifacts — malformed input degrades to a tagged result the\n// caller renders as a notice, never crashing the post.\ntype FindingsLoadResult =\n | { readonly kind: \"ok\"; readonly findings: Findings }\n | { readonly kind: \"corrupt\" }\n | { readonly kind: \"invalid-shape\" }\n | { readonly kind: \"unsupported-schema-version\"; readonly version: string };\n\nconst decodeFindings = (doc: unknown): FindingsLoadResult => {\n const resolution = resolve(\"findings\", doc);\n switch (resolution.kind) {\n case \"ok\":\n return { kind: \"ok\", findings: resolution.value };\n case \"unsupported-version\":\n return { kind: \"unsupported-schema-version\", version: resolution.version };\n case \"invalid-shape\":\n case \"missing-version\":\n return { kind: \"invalid-shape\" };\n }\n};\n\nconst loadFindings = (path: string): FindingsLoadResult => {\n let raw: unknown;\n try {\n raw = JSON.parse(readFileSync(path, \"utf-8\")) as unknown;\n } catch {\n return { kind: \"corrupt\" };\n }\n const first = decodeFindings(raw);\n // The seed hands the agent a prior doc that carries `convergence`, and the agent is told not to write\n // it — but an echoed or mangled stamp must not fail the WHOLE review into a \"did not complete\" notice,\n // since the pipeline overwrites both stamped fields after load. Strip them and retry before degrading\n // (mirrors seed-draft's strip-and-retry, issue #185 review).\n if (\n first.kind === \"invalid-shape\" &&\n typeof raw === \"object\" &&\n raw !== null &&\n !Array.isArray(raw) &&\n Object.keys(raw).some((k) => RECOVERABLE_OPTIONAL_FIELDS.has(k))\n ) {\n const stripped = Object.fromEntries(\n Object.entries(raw).filter(([key]) => !RECOVERABLE_OPTIONAL_FIELDS.has(key)),\n );\n const retry = decodeFindings(stripped);\n if (retry.kind === \"ok\") {\n process.stderr.write(\n \"Warning: the review draft carried an invalid best-effort field (convergence/scope_metastasis/change_size) — stripped it and used the rest; the pipeline re-stamps convergence\\n\",\n );\n return retry;\n }\n }\n return first;\n};\n\nconst noticeMessageFor = (result: Exclude<FindingsLoadResult, { kind: \"ok\" }>): string => {\n switch (result.kind) {\n case \"corrupt\":\n return \"Review output was missing or malformed — the review did not complete. See the workflow run for logs.\";\n case \"invalid-shape\":\n return \"Review output was malformed — it did not conform to the findings schema. See the workflow run for logs.\";\n case \"unsupported-schema-version\": {\n const supported = supportedVersions(\"findings\")\n .map((minor) => `${minor}.x`)\n .join(\", \");\n return `Review output declares schema_version \"${result.version}\", which this commenter does not support (supported: ${supported}). See the workflow run for logs.`;\n }\n }\n};\n\nconst loadEnvelope = (path: string): ResultEnvelope | null => {\n let raw: unknown;\n try {\n raw = JSON.parse(readFileSync(path, \"utf-8\")) as unknown;\n } catch {\n return null;\n }\n const decoded = ResultEnvelopeCodec.decode(raw);\n return decoded._tag === \"Right\" ? decoded.right : null;\n};\n\n// Optional enrichment: any failure warns and returns undefined, never aborts the post.\nconst loadTestReport = (path: string): TestSummary | undefined => {\n let raw: unknown;\n try {\n raw = JSON.parse(readFileSync(path, \"utf-8\")) as unknown;\n } catch (err) {\n process.stderr.write(\n `Warning: could not read test report at ${path}: ${errMsg(err)} — omitting test panel\\n`,\n );\n return undefined;\n }\n const decoded = TestSummaryCodec.decode(raw);\n if (decoded._tag === \"Left\") {\n process.stderr.write(\n `Warning: test report at ${path} does not match the expected shape — omitting test panel\\n`,\n );\n return undefined;\n }\n return decoded.right;\n};\n\n// The raw cloc --diff table (issue #182), best-effort like loadTestReport: an unreadable path warns\n// and omits the collapsible, and an empty/whitespace-only file (cloc ran but produced nothing, or a\n// placeholder left by a failed run) is treated as absent so no empty collapsible renders.\nexport const loadClocDiff = (path: string): string | undefined => {\n let raw: string;\n try {\n raw = readFileSync(path, \"utf-8\");\n } catch (err) {\n process.stderr.write(\n `Warning: could not read cloc diff at ${path}: ${errMsg(err)} — omitting the cloc collapsible\\n`,\n );\n return undefined;\n }\n return raw.trim() === \"\" ? undefined : raw;\n};\n\nconst parseHtmlUrl = (raw: string): string | undefined => {\n const parsed = tryParseJson(raw);\n const htmlUrl = parsed.ok ? asRecord(parsed.value)?.[\"html_url\"] : undefined;\n return typeof htmlUrl === \"string\" ? htmlUrl : undefined;\n};\n\nconst commentPayload = (c: InlineComment): Record<string, unknown> => ({\n path: c.path,\n line: c.line,\n side: c.side,\n ...(c.start_line !== undefined && c.start_side !== undefined\n ? { start_line: c.start_line, start_side: c.start_side }\n : {}),\n body: formatMarkdown(c.body),\n});\n\n// comments[i] is the rendered comment for inDiff[i] (1:1, same order). Returns the review url\n// (undefined when no breadcrumb review object posted — the caller gates the dismiss/minimize on\n// `posted`, the POST's success, not the parsed url), the count that actually posted, and the\n// findings GitHub rejected (for the caller to surface in the sticky).\nconst postInlineReview = async (\n pr: {\n readonly repo: string;\n readonly prNumber: number;\n readonly headSha: string;\n readonly stickyUrl: string | undefined;\n readonly runUrl: string | undefined;\n },\n comments: readonly InlineComment[],\n inDiff: readonly Finding[],\n ghApi: GhApi,\n): Promise<{\n readonly url: string | undefined;\n readonly posted: boolean;\n readonly inlinePosted: number;\n readonly unposted: readonly Finding[];\n}> => {\n const pointer = reviewBodyPointer(\n pr.headSha,\n pr.stickyUrl,\n pr.runUrl,\n (process.env[\"GITHUB_STEP_SUMMARY\"] ?? \"\") !== \"\",\n );\n const reviewBody = (withComments: boolean): string =>\n JSON.stringify({\n body: pointer,\n commit_id: pr.headSha,\n event: \"COMMENT\",\n comments: withComments ? comments.map(commentPayload) : [],\n });\n const reviewsEndpoint = [`repos/${pr.repo}/pulls/${String(pr.prNumber)}/reviews`, \"--input\", \"-\"];\n try {\n const stdout = await ghApi(reviewsEndpoint, reviewBody(true));\n return { url: parseHtmlUrl(stdout), posted: true, inlinePosted: comments.length, unposted: [] };\n } catch (err) {\n // The reviews endpoint is atomic — one rejected position fails the whole batch — so on rejection\n // post the body only, then re-post each comment individually, collecting the ones GitHub rejects.\n if (comments.length === 0) {\n // No inline comments to salvage: the breadcrumb review-object POST itself failed. The sticky\n // already carries the full review, so this is a DEGRADED-but-complete round — report it and\n // return posted false; the caller gates the dismiss/minimize on `posted` (the POST's success —\n // an unparseable response still means the object exists), so a permanent failure never leaves\n // the PR review-less (issue #223).\n // An Actions annotation (::warning:: in the step output), not a GITHUB_OUTPUT key: the CLI\n // owns the loudness so every workflow copy and every pinned CLI version sees the degradation.\n process.stderr.write(\n `::warning:: the review-object POST on PR #${String(pr.prNumber)} failed (${errMsg(err)}) — the sticky carries the review, but no diff-anchored review object exists this round\\n`,\n );\n return { url: undefined, posted: false, inlinePosted: 0, unposted: [] };\n }\n process.stderr.write(\n `Warning: the batched inline review on PR #${String(pr.prNumber)} was rejected (${errMsg(err)}) — posting the review body-only, then each comment individually to keep the ones GitHub accepts (issue #57)\\n`,\n );\n let url: string | undefined;\n let posted = false;\n try {\n url = parseHtmlUrl(await ghApi(reviewsEndpoint, reviewBody(false)));\n posted = true;\n } catch (bodyErr) {\n // The body-only retry failed too — the individual comments still re-post, but no breadcrumb\n // review object exists this round; the caller gates the dismiss/minimize on `posted` (the\n // POST's success — an unparseable response still means the object exists) (issue #223).\n process.stderr.write(\n `::warning:: the body-only review retry on PR #${String(pr.prNumber)} failed (${errMsg(bodyErr)}) — individual comments still re-post, but no breadcrumb review object exists this round\\n`,\n );\n }\n const commentsEndpoint = [\n `repos/${pr.repo}/pulls/${String(pr.prNumber)}/comments`,\n \"--input\",\n \"-\",\n ];\n const unposted: Finding[] = [];\n let inlinePosted = 0;\n for (const [i, c] of comments.entries()) {\n try {\n await ghApi(\n commentsEndpoint,\n JSON.stringify({ commit_id: pr.headSha, ...commentPayload(c) }),\n );\n inlinePosted += 1;\n } catch (e) {\n const finding = inDiff[i];\n if (finding) unposted.push(finding);\n process.stderr.write(\n `Warning: inline comment on ${c.path}:${String(c.line)} rejected (${errMsg(e)}) — surfacing that finding in the sticky instead (issue #57)\\n`,\n );\n }\n }\n return { url, posted, inlinePosted, unposted };\n }\n};\n\n// ONE projection + ONE fetch for every issue-comment consumer: the sticky lookup (findBotComment)\n// and the discussion aside read the same rows. post() fetches the history once per round and passes\n// the rows to both; announce routes through findBotComment, which fetches on its own. Transport\n// errors PROPAGATE — the callers that must not mistake a failed fetch for an absent sticky let the\n// rejection through.\n// The issue-comments endpoint returns NO in_reply_to_id — the field exists only on pull-request\n// REVIEW comments (the answered registry's endpoint), and GitHub's API exposes no issue-comment\n// reply chain at all. The projection therefore carries only the fields the endpoint actually has.\nconst ISSUE_COMMENTS_JQ =\n '.[] | {id, user: (.user.login // \"(deleted)\"), created_at, html_url, body: (.body // \"\")}';\n\ninterface IssueCommentRow {\n readonly id: number;\n readonly author: string;\n readonly created: string;\n readonly url: string;\n readonly body: string;\n}\n\nconst parseIssueCommentRows = (\n raw: string,\n): { readonly rows: readonly IssueCommentRow[]; readonly malformed: number } => {\n let malformed = 0;\n const rows: IssueCommentRow[] = [];\n for (const line of raw.split(\"\\n\")) {\n const trimmed = line.trim();\n if (trimmed === \"\") continue;\n const parsed = tryParseJson(trimmed);\n if (!parsed.ok) {\n malformed += 1;\n continue;\n }\n const rec = asRecord(parsed.value);\n const id = rec?.[\"id\"];\n const author = rec?.[\"user\"];\n const created = rec?.[\"created_at\"];\n const url = rec?.[\"html_url\"];\n const body = rec?.[\"body\"];\n if (\n typeof id === \"number\" &&\n typeof author === \"string\" &&\n typeof created === \"string\" &&\n typeof url === \"string\" &&\n typeof body === \"string\"\n ) {\n rows.push({ id, author, created, url, body });\n } else {\n // A shape failure IS corruption: the ghost-account case this branch once served is now\n // coalesced to \"(deleted)\" in the projection, so every remaining drop is a field the\n // endpoint guarantees — and a dropped sticky row would read as \"no sticky\" and mint a\n // duplicate, the exact failure the fail-loud invariant exists to prevent.\n malformed += 1;\n }\n }\n // The REST order is not a contract — the caps and the walk derive recency from it, so the rows\n // sort explicitly by (created, id), the sibling registry's discipline.\n rows.sort(\n (a, b) => a.created.localeCompare(b.created) || (a.id > b.id ? 1 : a.id < b.id ? -1 : 0),\n );\n return { rows, malformed };\n};\n\nconst fetchIssueCommentRows = async (\n repo: string,\n prNumber: number,\n ghApi: GhApi,\n): Promise<readonly IssueCommentRow[]> => {\n const raw = await ghApi([\n // per_page rides the QUERY string — a `-f` field would flip `gh api` from GET to POST\n // (create-comment) and 422 every sticky lookup.\n `repos/${repo}/issues/${String(prNumber)}/comments?per_page=100`,\n \"--paginate\",\n \"--jq\",\n ISSUE_COMMENTS_JQ,\n ]);\n const { rows, malformed } = parseIssueCommentRows(raw);\n // A sticky lookup is a WRITE-GATING decision: a corrupted fetch that silently read as \"no sticky\"\n // would mint a duplicate sticky while the real one is still live. Fail loudly instead (the\n // pre-parseJsonl code threw on garbage for exactly this reason).\n if (malformed > 0) {\n throw new Error(\n `${String(malformed)} issue-comment row(s) failed to decode — refusing to treat a corrupted history as an absent sticky`,\n );\n }\n return rows;\n};\n\nconst selectBotComment = (\n rows: readonly IssueCommentRow[],\n botLogin: string,\n marker: string,\n): { readonly id: number; readonly body: string } | null => {\n const bot = rows.filter((r) => r.author === botLogin && r.body.startsWith(marker));\n const last = bot[bot.length - 1];\n return last === undefined ? null : { id: last.id, body: last.body };\n};\n\nexport const findBotComment = async (\n repo: string,\n prNumber: number,\n botLogin: string,\n marker: string,\n ghApi: GhApi,\n): Promise<{ readonly id: number; readonly body: string } | null> =>\n selectBotComment(await fetchIssueCommentRows(repo, prNumber, ghApi), botLogin, marker);\n\nconst parseCommentRef = (\n raw: string,\n): { readonly id: number; readonly html_url: string } | null => {\n const parsed = tryParseJson(raw);\n const rec = parsed.ok ? asRecord(parsed.value) : null;\n const id = rec?.[\"id\"];\n const html_url = rec?.[\"html_url\"];\n return typeof id === \"number\" && typeof html_url === \"string\" ? { id, html_url } : null;\n};\n\nconst patchComment = async (\n repo: string,\n commentId: number,\n body: string,\n ghApi: GhApi,\n): Promise<{ readonly html_url: string } | null> => {\n const stdout = await ghApi(\n [`repos/${repo}/issues/comments/${String(commentId)}`, \"--input\", \"-\"],\n JSON.stringify({ body }),\n );\n // Only html_url is needed — the id is already known — unlike parseCommentRef for a new comment.\n const htmlUrl = parseHtmlUrl(stdout);\n return htmlUrl !== undefined ? { html_url: htmlUrl } : null;\n};\n\nconst postComment = async (\n repo: string,\n prNumber: number,\n body: string,\n ghApi: GhApi,\n): Promise<{ readonly id: number; readonly html_url: string } | null> => {\n const stdout = await ghApi(\n [`repos/${repo}/issues/${String(prNumber)}/comments`, \"--input\", \"-\"],\n JSON.stringify({ body }),\n );\n return parseCommentRef(stdout);\n};\n\n// The discussion aside's reply chain (issue #246): every issue comment whose reply chain reaches the\n// sticky comment, grouped by the backtick-quoted finding ids its body mentions (the same form the\n// sticky renders). Pointers only — the implementer reads the replies at the links.\nexport interface StickyDiscussion {\n readonly byFinding: Readonly<Record<string, readonly DiscussionLink[]>>;\n // Replies naming an id THIS round's report no longer carries but the PRIOR sticky's findings did:\n // a finding that was fixed or re-id'd between rounds. The sticky is overwritten every round\n // (issue #205), so without this bucket the conversation's pointers vanish from the review surface\n // exactly when the finding left the report.\n readonly orphaned: Readonly<Record<string, readonly DiscussionLink[]>>;\n // How many distinct departed ids were mentioned in total — the rendered section shows\n // \"(showing N of M)\" when the cap trimmed some, so the cut is named, never silent.\n readonly orphanedTotal: number;\n // Finding id → the pre-cap link total, present only when the 6-newest cap trimmed that finding's\n // list — the aside names its cut instead of rendering indistinguishably from a short thread.\n readonly truncated: Readonly<Record<string, number>>;\n // The same per-token pre-cap totals for the orphaned bucket's entries.\n readonly orphanedTruncated: Readonly<Record<string, number>>;\n}\n\nconst ID_TOKEN_RE = /`([^`\\n]+)`/g;\nconst ORPHAN_TOKEN_CAP = 8;\n\n// The raw id → escaped DISPLAY spelling index: the sticky renders ids through escapeCodeBackticks\n// (backticks → '-', newlines → ' '), so a reply quoting the DISPLAYED spelling of an id must land\n// in the same bucket as a reply quoting the raw one. The escaping is not injective (escape-twin ids\n// display identically), and an ambiguous spelling must NOT be silently assigned a winner — the\n// token stays unmatched and the raw spellings remain the only keys.\nconst escapedIdIndex = (ids: readonly string[]): ReadonlyMap<string, string> => {\n const owners = new Map<string, string[]>();\n for (const id of ids) {\n const escaped = escapeCodeBackticks(id);\n if (escaped === id) continue;\n const list = owners.get(escaped);\n if (list === undefined) owners.set(escaped, [id]);\n // Deduped: ONE distinct raw id owns its spelling regardless of how many times it appears in\n // the input (a current id also carried by the prior doc); only DISTINCT escape-twins drop it.\n else if (!list.includes(id)) list.push(id);\n }\n return new Map(\n [...owners.entries()].flatMap(([escaped, raws]) =>\n raws.length === 1 && raws[0] !== undefined ? ([[escaped, raws[0]]] as const) : [],\n ),\n );\n};\n\n// The discussion rows: EVERY comment on the PR, the sticky's own excluded. GitHub's API exposes\n// no reply-chain for issue comments (in_reply_to_id exists only on pull-request REVIEW comments —\n// the answered registry's endpoint), so \"replies to the sticky\" cannot be derived from any\n// channel; the aside groups the whole comment conversation instead, which serves the same\n// discoverability. Rows are deduped by id, first occurrence wins — gh --paginate fetches pages\n// sequentially, and a comment edited mid-pagination can legitimately appear on two pages; two\n// rows for one comment must not push two links into one aside. Computed ONCE per round and shared\n// by the gate and the grouping.\nexport const discussionRows = (\n rows: readonly IssueCommentRow[],\n stickyId: number,\n botLogin: string,\n): readonly IssueCommentRow[] => {\n const seen = new Set<number>();\n return rows.filter((c) => {\n if (seen.has(c.id)) return false;\n seen.add(c.id);\n // Bot-authored comments are the pipeline's own surfaces — a stale or duplicate sticky\n // quotes every finding id and must never scrape into the asides as human discussion.\n return c.id !== stickyId && c.author !== botLogin;\n });\n};\n\n// Whether any non-sticky comment names a backtick token this round does NOT report —\n// the only case the orphan bucket can be non-empty, and therefore the only case the prior sticky's\n// findings document is worth resolving for it. A necessary-not-sufficient condition: a reply\n// quoting a code snippet or path in backticks fires it too, and the round pays the artifact\n// download for a token that was never a finding id — the local alternative (the sticky's carried\n// rounds marker) records ids top-N-capped, so pre-filtering on it would skip real departed ids.\n// On the notice path (an empty known set) the same false positive can escalate into the rendered\n// unresolvable note when the resolve then fails — an accepted noise cost, since the note names\n// the artifact failure itself, never the token as a departed id.\n// The id-shape pre-filter: the gate pays the artifact resolve only for an unknown token that\n// could plausibly BE a finding id (the pipeline's ids are kebab-case identifiers and the\n// synthesized f-/s- base64url forms). A backticked shell command, path, or URL never fires it.\n// An id-shaped junk word still fires — the documented necessary-not-sufficient trade-off.\nconst ID_SHAPE_RE = /^[A-Za-z0-9][A-Za-z0-9_-]*$/;\n\nexport const mentionsOutsideKnown = (\n reachable: readonly IssueCommentRow[],\n currentIds: readonly string[],\n): boolean => {\n const known = new Set(currentIds);\n const escapedToRaw = escapedIdIndex(currentIds);\n for (const c of reachable) {\n for (const m of c.body.matchAll(ID_TOKEN_RE)) {\n const token = m[1];\n if (token === undefined) continue;\n const raw = known.has(token) ? token : escapedToRaw.get(token);\n if ((raw === undefined || !known.has(raw)) && ID_SHAPE_RE.test(token)) return true;\n }\n }\n return false;\n};\n\n// The pure comment→discussion grouping: every non-sticky comment on the PR, grouped by the\n// backtick-quoted ids it mentions — capped 6 newest-first per id. The orphan bucket holds ONLY\n// tokens the PRIOR sticky's findings actually carried (priorIds), never shape-guessed prose: a\n// backtick token that was never a finding id is not published as one. Extracted pure so the caps\n// and the dedupe are unit-testable without an API mock.\nexport const buildStickyDiscussion = (\n reachable: readonly IssueCommentRow[],\n currentIds: readonly string[],\n priorIds: readonly string[],\n): StickyDiscussion => {\n const known = new Set(currentIds);\n const departed = new Set(priorIds);\n const escapedToRaw = escapedIdIndex([...currentIds, ...priorIds]);\n const byFinding = Object.fromEntries(\n currentIds.map((id): [string, DiscussionLink[]] => [id, []]),\n );\n const orphaned = new Map<string, DiscussionLink[]>();\n const latestAt = new Map<string, string>();\n for (const c of reachable) {\n const link = { author: c.author, when: c.created.slice(0, 10), url: c.url, at: c.created };\n // One link per (comment, token): a reply quoting the same id twice must not crowd the cap.\n const pushed = new Set<string>();\n for (const m of c.body.matchAll(ID_TOKEN_RE)) {\n const token = m[1];\n if (token === undefined || pushed.has(token)) continue;\n pushed.add(token);\n const rawKnown = known.has(token);\n const alias = rawKnown ? undefined : escapedToRaw.get(token);\n const aliasIsKnown = alias !== undefined && known.has(alias);\n const rawDeparted = departed.has(token);\n if (rawKnown) {\n byFinding[token]?.push(link);\n } else if (aliasIsKnown) {\n // A token that is BOTH a current id's display alias and a departed raw id is ambiguous —\n // it stays unmatched rather than silently winning for either side.\n if (!rawDeparted) byFinding[alias]?.push(link);\n } else if (rawDeparted) {\n const key = token;\n const links = orphaned.get(key);\n if (links === undefined) orphaned.set(key, [link]);\n else links.push(link);\n const latest = latestAt.get(key);\n if (latest === undefined || c.created.localeCompare(latest) > 0)\n latestAt.set(key, c.created);\n } else if (alias !== undefined && departed.has(alias)) {\n // The token is a DEPARTED id's display spelling — filed under the departed raw id, the\n // same attribution the orphan bucket's contract promises.\n const key = alias;\n const links = orphaned.get(key);\n if (links === undefined) orphaned.set(key, [link]);\n else links.push(link);\n const latest = latestAt.get(key);\n if (latest === undefined || c.created.localeCompare(latest) > 0)\n latestAt.set(key, c.created);\n }\n }\n }\n // Map-built then Object.fromEntries: a `__proto__`-named id must record its cut like any other\n // key, which a bare {}-literal assignment silently swallows.\n const truncated = new Map<string, number>();\n for (const [id, links] of Object.entries(byFinding)) {\n links.reverse();\n if (links.length > PER_FINDING_LINKS) {\n truncated.set(id, links.length);\n links.splice(PER_FINDING_LINKS);\n }\n }\n const orphanedTruncated = new Map<string, number>();\n for (const [token, links] of orphaned) {\n links.reverse();\n if (links.length > PER_FINDING_LINKS) {\n orphanedTruncated.set(token, links.length);\n links.splice(PER_FINDING_LINKS);\n }\n }\n // Bound the orphan bucket at the 8 NEWEST departed ids (by their latest reply's FULL timestamp —\n // the date-only display string would tie same-day replies and let the stable sort cut the newer\n // one), matching the newest-first discipline the per-finding lists keep.\n const orphanedTotal = orphaned.size;\n const byLatestReply = [...orphaned.entries()].sort((a, b) =>\n (latestAt.get(b[0]) ?? \"\").localeCompare(latestAt.get(a[0]) ?? \"\"),\n );\n return {\n byFinding,\n orphaned: Object.fromEntries(byLatestReply.slice(0, ORPHAN_TOKEN_CAP)),\n orphanedTotal,\n truncated: Object.fromEntries(truncated),\n orphanedTruncated: Object.fromEntries(orphanedTruncated),\n };\n};\n\n// The prior findings document's finding + systemic ids — the full departed set the orphan bucket may\n// hold (a departed systemic id orphans exactly like a departed finding id). Tolerant over the\n// resolved shape: a non-document yields no ids, so the bucket fails open to empty.\nexport const priorIdsFrom = (doc: unknown): readonly string[] => {\n if (typeof doc !== \"object\" || doc === null || Array.isArray(doc)) return [];\n const rec = doc as Record<string, unknown>;\n // The id spelling with the LEGACY code fallback — a pre-0.10 prior document (findings with a\n // code and no id) must still feed the departed set, or its replies pay the resolve and then\n // render nowhere.\n const idsOf = (field: string, systemic: boolean): readonly string[] =>\n (Array.isArray(rec[field]) ? rec[field] : []).flatMap((raw) => {\n const item = typeof raw === \"object\" && raw !== null ? asRecord(raw) : null;\n if (item === null) return [];\n const title = typeof item[\"title\"] === \"string\" ? item[\"title\"] : \"\";\n const resolved = resolveRuleId({\n ...(typeof item[\"id\"] === \"string\" ? { id: item[\"id\"] } : {}),\n ...(typeof item[\"code\"] === \"string\" ? { code: item[\"code\"] } : {}),\n ...(typeof item[\"path\"] === \"string\" ? { path: item[\"path\"] } : {}),\n title,\n });\n // The upcast's own fallback for a code-less systemic (no path to synthesize from).\n const id = resolved ?? (systemic && title !== \"\" ? synthesizedSystemicId(title) : undefined);\n return id !== undefined ? [id] : [];\n });\n return [...idsOf(\"findings\", false), ...idsOf(\"systemic_problems\", true)];\n};\n\n// Best-effort append to a runner file: a write failure warns with the given label and never fails\n// the round. The path is a parameter, so the effect is the only thing here that is not pure.\nconst appendBestEffort = (path: string | undefined, label: string, body: string): void => {\n if (path === undefined || path === \"\") return;\n try {\n appendFileSync(path, body);\n } catch (err) {\n process.stderr.write(`Warning: could not write ${label}: ${errMsg(err)}\\n`);\n }\n};\n\n// The posted signal travels through the step's GITHUB_OUTPUT file — the runner publishes it as the\n// step's output when the step completes. Written INSIDE upsertSticky so every sticky landing (the\n// main path and the notice paths alike) signals itself, and written as posted=false on the\n// deliberate no-write exits so a never-landed run never reads as landed.\nconst writePostedSignal = (value: boolean): void => {\n appendBestEffort(\n process.env[\"GITHUB_OUTPUT\"],\n \"the posted signal to GITHUB_OUTPUT\",\n `posted=${value ? \"true\" : \"false\"}\\n`,\n );\n};\n\n// The job's run summary is the review's long-lived twin: a sticky is overwritten as rounds iterate,\n// while each run's summary keeps the review as it stood for that run (issue #205). The template\n// renders OUTSIDE the best-effort write: a failing template is a defect that should surface, and the\n// sticky rendered from the same input a moment earlier, so this throwing means something is\n// genuinely wrong. Only the write is best-effort.\nconst appendRunSummary = (summaryPath: string | undefined, body: () => string): void => {\n if (summaryPath === undefined || summaryPath === \"\") return;\n const rendered = body();\n appendBestEffort(summaryPath, \"the run summary\", `\\n${rendered}\\n`);\n};\n\n// Trust by author identity (bot login), not the marker alone. Returns null only when a NEW comment's\n// response couldn't be parsed — there is then no id to re-patch with the review link.\nconst upsertSticky = async (\n repo: string,\n prNumber: number,\n existing: { readonly id: number; readonly body: string } | null,\n body: string,\n ghApi: GhApi,\n signal = false,\n): Promise<{ readonly id: number; readonly url: string | undefined } | null> => {\n if (existing !== null) {\n const patched = await patchComment(repo, existing.id, body, ghApi);\n process.stderr.write(\n `Updated sticky comment #${String(existing.id)} on PR #${String(prNumber)}\\n`,\n );\n if (signal) writePostedSignal(true);\n return { id: existing.id, url: patched?.html_url };\n }\n const posted = await postComment(repo, prNumber, body, ghApi);\n process.stderr.write(`Posted new sticky comment on PR #${String(prNumber)}\\n`);\n if (signal && posted !== null) writePostedSignal(true);\n return posted ? { id: posted.id, url: posted.html_url } : null;\n};\n\n// Only the id is needed — every prior bot review is superseded regardless of the commit it reviewed.\ninterface BotReviewRef {\n readonly id: number;\n}\n\nconst isBotReview = (r: unknown): r is { id: number; user: { login: string }; state: string } =>\n typeof r === \"object\" &&\n r !== null &&\n typeof (r as { id?: unknown }).id === \"number\" &&\n typeof (r as { state?: unknown }).state === \"string\" &&\n typeof (r as { user?: { login?: unknown } }).user?.login === \"string\";\n\nconst fetchBotReviews = async (\n repo: string,\n prNumber: number,\n botLogin: string,\n ghApi: GhApi,\n): Promise<readonly BotReviewRef[]> => {\n const stdout = await ghApi([`repos/${repo}/pulls/${String(prNumber)}/reviews`, \"--paginate\"]);\n let reviews: unknown;\n try {\n reviews = JSON.parse(stdout || \"[]\");\n } catch {\n return [];\n }\n if (!Array.isArray(reviews)) return [];\n return reviews\n .filter(isBotReview)\n .filter((r) => r.user.login === botLogin && r.state !== \"DISMISSED\")\n .map((r) => ({ id: r.id }));\n};\n\n// Best-effort: a dismissal failure is logged, never fails the job.\nconst dismissReviews = async (\n repo: string,\n prNumber: number,\n ids: readonly number[],\n ghApi: GhApi,\n): Promise<void> => {\n for (const id of ids) {\n try {\n await ghApi(\n [\n `repos/${repo}/pulls/${String(prNumber)}/reviews/${String(id)}/dismissals`,\n \"-X\",\n \"PUT\",\n \"--input\",\n \"-\",\n ],\n // GitHub caps a dismissal message at 140 chars.\n JSON.stringify({ message: \"Superseded by a new review for an updated commit.\" }),\n );\n } catch (err) {\n process.stderr.write(\n `Warning: failed to dismiss prior review #${String(id)} on PR #${String(prNumber)}: ${errMsg(err)}\\n`,\n );\n }\n }\n};\n\n// Capped at the first 100 threads (×100 comments each); hasNextPage flags a PR that exceeds it.\nconst REVIEW_THREAD_COMMENTS_QUERY =\n \"query($owner:String!,$name:String!,$pr:Int!){repository(owner:$owner,name:$name){pullRequest(number:$pr){reviewThreads(first:100){pageInfo{hasNextPage}nodes{comments(first:100){nodes{id isMinimized author{login}}}}}}}}\";\n\n// Reversible — minimized as OUTDATED, not deleted.\nconst MINIMIZE_COMMENT_MUTATION =\n \"mutation($id:ID!){minimizeComment(input:{subjectId:$id,classifier:OUTDATED}){minimizedComment{isMinimized}}}\";\n\n// GraphQL reports the bare login (github-actions), so match with and without the REST [bot] suffix.\nconst priorBotCommentId = (c: unknown, logins: readonly string[]): string | null => {\n if (typeof c !== \"object\" || c === null) return null;\n const o = c as { id?: unknown; isMinimized?: unknown; author?: { login?: unknown } | null };\n const login = o.author?.login;\n return typeof o.id === \"string\" &&\n o.isMinimized !== true &&\n typeof login === \"string\" &&\n logins.includes(login)\n ? o.id\n : null;\n};\n\nconst priorBotCommentIds = (\n raw: string,\n botLogin: string,\n): { readonly ids: readonly string[]; readonly truncated: boolean } => {\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return { ids: [], truncated: false };\n }\n const conn = (\n parsed as {\n data?: {\n repository?: {\n pullRequest?: {\n reviewThreads?: { nodes?: unknown; pageInfo?: { hasNextPage?: unknown } };\n };\n };\n };\n }\n ).data?.repository?.pullRequest?.reviewThreads;\n const truncated = conn?.pageInfo?.hasNextPage === true;\n const nodes = conn?.nodes;\n if (!Array.isArray(nodes)) return { ids: [], truncated };\n const logins = [botLogin.replace(/\\[bot\\]$/, \"\"), botLogin];\n const ids = nodes.flatMap((t) => {\n const cnodes = (t as { comments?: { nodes?: unknown } }).comments?.nodes;\n return Array.isArray(cnodes)\n ? cnodes.map((c) => priorBotCommentId(c, logins)).filter((id): id is string => id !== null)\n : [];\n });\n return { ids, truncated };\n};\n\n// Snapshot BEFORE posting the fresh review, so the set is exactly the prior (stale) comments.\n// Best-effort: a listing failure logs and returns [].\nconst listPriorBotCommentIds = async (\n repo: string,\n prNumber: number,\n botLogin: string,\n ghApi: GhApi,\n): Promise<readonly string[]> => {\n const slash = repo.indexOf(\"/\");\n if (slash <= 0) return [];\n const owner = repo.slice(0, slash);\n const name = repo.slice(slash + 1);\n let raw: string;\n try {\n raw = await ghApi([\n \"graphql\",\n \"-f\",\n `query=${REVIEW_THREAD_COMMENTS_QUERY}`,\n \"-f\",\n `owner=${owner}`,\n \"-f\",\n `name=${name}`,\n \"-F\",\n `pr=${String(prNumber)}`,\n ]);\n } catch (err) {\n process.stderr.write(\n `Warning: could not list review threads to minimize stale comments on PR #${String(prNumber)}: ${errMsg(err)}\\n`,\n );\n return [];\n }\n const { ids, truncated } = priorBotCommentIds(raw, botLogin);\n if (truncated) {\n process.stderr.write(\n `Note: PR #${String(prNumber)} has more than 100 review threads — only the first 100 were scanned for stale bot comments\\n`,\n );\n }\n return ids;\n};\n\n// Best-effort: a minimize failure is logged, never fails the post.\nconst minimizeComments = async (\n prNumber: number,\n ids: readonly string[],\n ghApi: GhApi,\n): Promise<void> => {\n let minimized = 0;\n for (const id of ids) {\n try {\n await ghApi([\"graphql\", \"-f\", `query=${MINIMIZE_COMMENT_MUTATION}`, \"-f\", `id=${id}`]);\n minimized += 1;\n } catch (err) {\n process.stderr.write(\n `Warning: failed to minimize a stale review comment on PR #${String(prNumber)}: ${errMsg(err)}\\n`,\n );\n }\n }\n if (minimized > 0) {\n process.stderr.write(\n `Minimized ${String(minimized)} stale inline comment(s) from superseded reviews on PR #${String(prNumber)}\\n`,\n );\n }\n};\n\nexport const post = async (\n input: PostInput,\n ghApi: GhApi = runGhApi,\n readArtifact: ArtifactReader = ghArtifactReader,\n): Promise<void> => {\n // Phase 1: reads + rendering, no writes yet.\n const candidates = await fetchPrCandidates(input.repo, input.headSha, ghApi);\n const resolution = resolvePr(candidates, input.headBranch);\n if (resolution.kind === \"none\") {\n process.stderr.write(`No open PR for ${input.headSha} — nothing to post\\n`);\n writePostedSignal(false);\n process.exit(0);\n }\n if (resolution.kind === \"not-open\") {\n process.stderr.write(\n `PR #${String(resolution.prNumber)} for ${input.headSha} is not open (state: ${resolution.state}) — nothing to post\\n`,\n );\n writePostedSignal(false);\n process.exit(0);\n }\n const prNumber = resolution.prNumber;\n\n const [diff, commentRows] = await Promise.all([\n fetchDiff(input.repo, prNumber, ghApi),\n fetchIssueCommentRows(input.repo, prNumber, ghApi),\n ]);\n const existingSticky = selectBotComment(commentRows, input.botLogin, DEFAULT_MARKER);\n\n // An incomplete result (a notice, not a completed review) must never overwrite a sticky that\n // already shows a completed review — else a superseded/killed/late run buries a real review under a\n // \"did not complete\" that reads as a clean pass. A completed result always writes; an in-progress\n // placeholder is not \"complete\" (it lacks the marker), so its own commenter may still write.\n const existingComplete = existingSticky !== null && parseReviewComplete(existingSticky.body);\n const wouldBuryCompleted = (incomplete: boolean): boolean => incomplete && existingComplete;\n\n // \"The sticky reflects a completed FULL review\": the isFullReviewSticky predicate (route marker\n // wins, round history as the pre-marker fallback), plus, for a sticky with no route or round\n // signal at all, the two completed-review signals of the pre-marker era — review-complete on the\n // sticky itself, or the carried completed-ancestor marker (a notice carries that ANCESTRY marker,\n // never review-complete itself). This deliberately does NOT require review-complete: the announce\n // placeholder strips it while preserving the route and round markers, and an empty mechanic must\n // not bury the full review the placeholder still records.\n const priorIsFullReview = (body: string): boolean =>\n isFullReviewSticky(body) ||\n (parseReviewedRoute(body) === null &&\n (parseReviewComplete(body) ||\n (parseCompletedAncestor(body) && !parseMechanicAncestor(body))));\n\n // An EMPTY CI-fix mechanic pass must not bury a completed FULL review either: it completes with\n // genuinely empty findings ({verdict: \"comment\", findings: []}), so it is not \"incomplete\" and\n // wouldBuryCompleted can't see it — yet replacing a full review's sticky with \"No findings — clean\n // review.\" is the same false clean pass class (issue #127). A mechanic WITH findings still\n // supersedes (its fixes are the actionable output on a red CI). The route comes from the review\n // job (passed through as --route; the envelope is the fallback for standalone callers), so the\n // guard also fires when the result envelope was lost in transit.\n const emptyMechanicWouldBury = (route: string | null | undefined, incomplete: boolean): boolean =>\n route === \"mechanic\" &&\n !incomplete &&\n findings.findings.length === 0 &&\n existingSticky !== null &&\n priorIsFullReview(existingSticky.body);\n\n // The full-review convergence history carried in the sticky's marker (it survives the announce\n // placeholder via carryForwardMarkers). A completed FULL review appends this round below; a CI-fix\n // mechanic pass and every notice carry it forward unchanged so the trajectory is never lost.\n // The prior round trajectory + the convergence to carry forward, read from the JSON convergence field\n // the pipeline stamps into the blob (issue #174), with a one-time fallback to a pre-feature sticky's\n // legacy rounds + compact signal markers. Carried VERBATIM into a non-round post — recomputing at the\n // current threshold would flip a prior round's `converged` when the operator changes\n // convergence_threshold mid-PR.\n const priorDoc = existingSticky !== null ? parseFindingsMarker(existingSticky.body) : null;\n const priorBody = existingSticky?.body ?? \"\";\n // The trajectory to append to + the recurrence detectors read (priorTrajectory reads the JSON\n // convergence, else the legacy rounds marker — so a legacy prior with only a rounds marker still\n // carries its codes); and the convergence to carry forward on a non-round post (carriedConvergence).\n const priorTraj = priorTrajectory(priorDoc, priorBody);\n const priorConv = carriedConvergence(priorDoc, priorBody);\n // The completed-round count never regresses: nextRoundNumber takes the max round across the trajectory\n // and the carried convergence (a legacy sticky whose compact signal ran ahead of a filtered rounds\n // marker still advances, issue #141), and announce labels its in-progress line with the SAME derivation\n // so the placeholder's round and this round's stamp can't disagree (issue #188 review).\n const priorRoundCount = nextRoundNumber(priorTraj, priorConv?.rounds ?? []) - 1;\n\n // The agent's document carries no convergence of its own (issue #217 review r7): the pipeline stamps\n // it, and the compact marker beside the findings link carries the SAME stamped object, so a reader of\n // the comment never needs the artifact for the stop signal. A notice / CI-fix pass carries the prior\n // convergence forward, so the trajectory + last score survive a non-round post; a first-run notice\n // with no completed round carries none. convergence is pipeline-owned and ALWAYS overwritten: any\n // value the agent echoed is replaced by the pipeline's (or by undefined, which serializes to an\n // omitted key), so a draft can never smuggle a self-declared score/converged into the document.\n const stampConvergence = (doc: Findings, conv: Convergence | null): Findings => ({\n ...doc,\n convergence: conv ?? undefined,\n });\n // The error rides HERE rather than at the main path's call site, so the notice and lost-envelope\n // paths — which also post a body built from this — say it too. Once per post, not once per surface.\n // When no --json-url can name an artifact and the existing sticky carries a findings marker, the\n // rendered body carries the PRIOR review's findings LINK forward — through findingsBlob, so EVERY\n // rendered body (main, final patch, the empty-diff/corrupt/lost-envelope paths) carries it, and\n // the template places it after the sticky's leading markers so findBotComment still identifies\n // the comment. The freeze guard above still wins for a completed full-review sticky\n // (leaveInPlace); every OTHER marker-carrying sticky — placeholder, mechanic, pre-route — gets\n // the carry instead of a markerless overwrite (issue #235 + #236 r1-r3). Only the LINK form is\n // carried here — re-embedding the base64 form would put an unbounded blob back into the body\n // that is posted unshed against GitHub's 65536 limit, the 422 class the link form exists to\n // prevent. (The notice paths DO re-emit a carried embedded marker verbatim: their bodies are\n // short, and the pre-#217 blob was size-gated when written.)\n let warnedNoJsonUrl = false;\n const findingsBlob = (doc: Findings): string => {\n if (input.jsonUrl) return findingsMarkerPair(input.jsonUrl, doc.convergence);\n const carriedLink = existingSticky !== null ? findingsArtifactUrl(existingSticky.body) : null;\n if (carriedLink !== null) {\n // The prior link is carried: the machine channel survives, though this run names no NEW\n // artifact — the sticky's findings remain the prior round's.\n return findingsMarkerPair(carriedLink, doc.convergence);\n }\n if (!warnedNoJsonUrl) {\n warnedNoJsonUrl = true;\n process.stderr.write(\n \"::error::no --json-url was supplied and the existing sticky carries no findings marker to carry forward, so this comment names no findings artifact — the review's prose is intact but its machine channel is gone, and the next round cannot seed from it\\n\",\n );\n }\n return findingsMarkerPair(undefined, doc.convergence);\n };\n // NOTE: leaveInPlace must NEVER read `verbatimReRaised` — it is also called from the empty-diff\n // and corrupt-findings guards, which run BEFORE the const initializes; a read there throws a\n // TDZ ReferenceError and crashes the post (issue #151 review r4 — a real regression in r3). The\n // post-filter call sites log the drops themselves.\n const leaveInPlace = (message?: string): never => {\n process.stderr.write(\n message ??\n \"Review did not complete and the sticky already reflects a completed review — leaving it in place\\n\",\n );\n // The preserved sticky IS the landed review — signal it, so a deliberate leave never reads as\n // never-posted and never rides the exit-0 fallback.\n writePostedSignal(true);\n process.exit(0);\n };\n\n // The leave paths cannot write a note — the preserved sticky still surfaces each dropped finding\n // and its reply thread — so the one place that names the drops in the run log, shared by every\n // post-filter leave site (issue #151 review r5). The count is the TRUE pre-dedup dropped-finding\n // count, never the deduped entry list (issue #151 review r7).\n const logAnsweredDrops = (): void => {\n if (verbatimReRaised.length > 0) {\n process.stderr.write(\n `${String(droppedCount)} verbatim re-raise(s) of answered findings were treated as answered — the preserved sticky shows each finding and its prior reply\\n`,\n );\n }\n };\n\n // When the guard fires on a real completed review, leaving it in place is right — it IS the\n // terminal content. When it fires on the announce PLACEHOLDER (which strips review-complete), a\n // bare leave would strand a stale \"Code review in progress\" as the terminal state, so post a\n // compact honest notice instead, carrying the preserved full review's markers forward so the seed\n // chain and trajectory survive the swap. Callers pass the sticky the guard already established\n // exists (TS can't see the closure's narrowing).\n const emptyMechanicLeaveOrNote = async (sticky: {\n readonly id: number;\n readonly body: string;\n }): Promise<void> => {\n if (existingComplete) {\n logAnsweredDrops();\n leaveInPlace(EMPTY_MECHANIC_LEAVE_MESSAGE);\n }\n const priorSha = parseReviewedSha(sticky.body);\n const dropNote = answeredDropNote;\n const body = formatMarkdown(\n noticeBody(\n `${DEFAULT_MARKER}\\n\\n⚠️ **CI-fix pass completed with no findings** for \\`${input.headSha.slice(0, 7)}\\`${\n input.unverifiedNoLogs === true\n ? ' — **but no failing-job logs were available**, so it worked from the diff and any local reproduction of the checks, and \"no findings\" is not evidence of none'\n : \"\"\n } — the completed full review of \\`${priorSha ? priorSha.slice(0, 7) : \"an earlier commit\"}\\` is preserved below.${dropNote ? `\\n\\n${dropNote}` : \"\"}`,\n sticky.body,\n ),\n );\n await upsertSticky(input.repo, prNumber, sticky, body, ghApi, true);\n process.exit(0);\n };\n\n const prices = JSON.parse(readFileSync(input.pricesPath, \"utf-8\")) as unknown;\n const decodedPrices = PriceMapCodec.decode(prices);\n if (decodedPrices._tag === \"Left\") {\n throw new Error(`Price map at ${input.pricesPath} does not match the expected shape`);\n }\n // Once per round, before any render — the sticky's cost collapsible carries the snapshot date,\n // and a map predating this CLI's release warns as a step annotation (issue #220). Null when the\n // consumer configured no pricing: a bundled example map they never supplied is never stale.\n warnStalePrices(input.pricesProvided ? decodedPrices.right : null);\n const template = readFileSync(input.templatePath, \"utf-8\");\n const inlineRequested = input.inline === true;\n // Loaded before the notice paths: their convergence stamps read the route, exactly like the main\n // path (issue #224's mechanic pin must hold on EVERY write path).\n const envelope = loadEnvelope(input.envelopePath);\n\n const reachable =\n existingSticky !== null ? discussionRows(commentRows, existingSticky.id, input.botLogin) : [];\n // The discussion orphan gate excludes ONLY a mechanic prior: its own findings are not this\n // review's departed findings. Every other prior feeds the bucket — a full review, a pre-rounds\n // sticky (no route marker, but its embedded blob still resolves), and a placeholder (whose\n // carried link resolves the last full review's document).\n const priorIsMechanic =\n existingSticky !== null &&\n (parseReviewedRoute(existingSticky.body) === \"mechanic\" ||\n parseMechanicAncestor(existingSticky.body));\n\n // The notice overwrites the sticky with no findings of its own — the pointer trail a replied-to\n // prior sticky carries must survive the overwrite. Resolved and grouped ONLY when a notice\n // actually exits (the rare path); a normal round never pays this. The prior document's ids are\n // the whole departed set for a notice (the notice reports nothing), and only a full-review prior\n // may feed it — a mechanic pass's own findings are not this review's departed findings.\n const noticeDiscussion = async (): Promise<{\n readonly orphanedDiscussion: Readonly<Record<string, readonly DiscussionLink[]>>;\n readonly orphanedTotal: number;\n readonly orphanedTruncated: Readonly<Record<string, number>>;\n readonly orphanedUnresolvable: boolean;\n }> => {\n if (existingSticky === null) {\n return {\n orphanedDiscussion: {},\n orphanedTotal: 0,\n orphanedTruncated: {},\n orphanedUnresolvable: false,\n };\n }\n const wantsPrior = !priorIsMechanic && mentionsOutsideKnown(reachable, []);\n const resolved = wantsPrior\n ? await resolvePriorFindings(existingSticky.body, readArtifact)\n : null;\n const built = buildStickyDiscussion(reachable, [], priorIdsFrom(resolved));\n // \"Unresolvable\" claims an artifact failed — it must never fire for a marker-less prior\n // (a first-run placeholder), where there is no artifact to fail.\n const hadMarker = carriedFindingsMarker(existingSticky.body) !== null;\n return {\n orphanedDiscussion: built.orphaned,\n orphanedTotal: built.orphanedTotal,\n orphanedTruncated: built.orphanedTruncated,\n orphanedUnresolvable: wantsPrior && hadMarker && resolved === null,\n };\n };\n\n const renderNotice = (\n message: string,\n discussion: Awaited<ReturnType<typeof noticeDiscussion>>,\n ): string => {\n // The notice carries the prior convergence forward IN its blob so the trajectory + last score\n // survive; render's incomplete gate keeps the badge/trajectory off the human surface, so a carried\n // \"converged\" is never shown beside a run that produced no verdict (issue #141 review r2). A\n // MECHANIC notice stamps the never-converged pin instead — CI failed, whatever the prior said\n // (issue #224: the pin holds on every write path, not just the main one).\n const noticeConvergence =\n (input.route ?? envelope?.route) === \"mechanic\"\n ? mechanicConvergence(\n priorConv,\n input.convergenceThreshold ?? DEFAULT_CONVERGENCE_THRESHOLD,\n )\n : priorConv;\n const findings = stampConvergence(incompleteFindings(`### ⚠️ ${message}`), noticeConvergence);\n // The notice's own blob holds no findings — stamping its link would point the NEXT round's\n // resolve at an empty document and sever the departed set the trail needs. The prior sticky's\n // findings marker is carried verbatim instead — BOTH forms via the shared extractor, never a\n // hand-rolled link-only carry — with the notice's own convergence stamp beside it.\n const noticeFindingsPointer = (doc: Findings): string => {\n const carried = existingSticky !== null ? carriedFindingsMarker(existingSticky.body) : null;\n if (carried === null) return findingsBlob(doc);\n // The prior's provenance rides beside its findings marker: a mechanic-origin prior must stay\n // mechanic through the notice, or the next round's orphan gate reads its findings as a\n // departed full review's.\n const provenance = existingSticky !== null ? carriedAncestryMarkers(existingSticky.body) : \"\";\n return [carriedMarkerPointer(carried, doc.convergence), provenance]\n .filter((p) => p !== \"\")\n .join(\"\\n\\n\");\n };\n return formatMarkdown(\n render({\n findings,\n envelope: null,\n incomplete: true,\n prices: decodedPrices.right,\n pricesProvided: input.pricesProvided,\n template,\n route: input.route,\n reviewedSha: input.headSha,\n effort: input.effort,\n sameRootNotes: {},\n roundCount: priorRoundCount,\n convergenceRound: false,\n runUrl: input.runUrl,\n jsonUrl: input.jsonUrl,\n findingsPointer: noticeFindingsPointer(findings),\n postedAt: input.postedAt,\n orphanedDiscussion: discussion.orphanedDiscussion,\n orphanedTotal: discussion.orphanedTotal,\n orphanedTruncated: discussion.orphanedTruncated,\n orphanedUnresolvable: discussion.orphanedUnresolvable,\n }),\n );\n };\n\n if (isEmptyDiff(diff)) {\n if (wouldBuryCompleted(true)) leaveInPlace();\n const discussion = await noticeDiscussion();\n await upsertSticky(\n input.repo,\n prNumber,\n existingSticky,\n renderNotice(\"The diff for this PR is empty — nothing to review.\", discussion),\n ghApi,\n true,\n );\n process.exit(0);\n }\n\n const findingsResult = loadFindings(input.findingsPath);\n if (findingsResult.kind !== \"ok\") {\n if (wouldBuryCompleted(true)) leaveInPlace();\n const discussion = await noticeDiscussion();\n await upsertSticky(\n input.repo,\n prNumber,\n existingSticky,\n renderNotice(noticeMessageFor(findingsResult), discussion),\n ghApi,\n true,\n );\n process.exit(0);\n }\n // The \"already answered\" state (issue #151): the prior inline findings whose threads a human reply\n // answered, fetched live (the threads persist on GitHub; no carried marker needed). A verbatim\n // re-raise of an answered finding — identical title and reasoning, no new evidence by definition —\n // is treated as closed: dropped from this review's findings, counts, inline comments, and round\n // signal, and NAMED in the sticky (never silently). A re-raise with changed evidence is kept and\n // annotated with the prior answer's link. A failed fetch degrades to an empty registry (the review\n // posts unfiltered); the seed already told the agent what not to re-raise.\n const loadedFindings = findingsResult.findings;\n // The answered-thread fetch runs only when a review will actually be filtered — an empty-diff or\n // corrupt-findings post exits above without paying for the paginated history (issue #151 review\n // r3), and a FIRST-EVER review (no bot sticky at all, so no bot threads can exist) provably has\n // an empty registry (issue #151 review r4).\n // ALWAYS fetch on a filterable post: a missing sticky does not prove an empty thread history (a\n // maintainer can delete the sticky while the threads remain; pre-sticky reviews leave threads\n // with no sticky at all), so the round-4 sticky-absence skip — which could silently starve the\n // registry — is inverted and removed (issue #151 review r7). The empty-diff/corrupt-findings\n // early exits above still avoid the fetch entirely.\n const threadComments = await fetchThreadComments(ghApi, input.repo, prNumber);\n const answeredRegistry =\n threadComments === null ? [] : answeredRegistryFrom(threadComments, input.botLogin);\n const answeredFilter = applyAnswered(loadedFindings.findings, answeredRegistry);\n const reRaisedNotes = answeredFilter.reRaisedNotes;\n const verbatimReRaised = answeredFilter.verbatimReRaised;\n const droppedCount = answeredFilter.droppedCount;\n // Everything downstream (counts, rounds, signal, inline, the embedded blob) reads the FILTERED\n // document — a closed verbatim re-raise is gone from the review, not just from the prose.\n // [...spread] restores the codec's mutable array type. A DROPPED re-raise's code is also\n // stripped from any systemic problem's finding_ids — a \"ties together\" list must not dangle a\n // finding that is no longer in the document. Scoped to the actual drops: a systemic whose codes\n // were never dropped passes through untouched (issue #151 review r1).\n // Both the dropped entries' codes AND the dropped FINDINGS' resolved ids: a title-matched drop of\n // a fresh-id finding keys the entry's synthesized code, but the systemic list names the finding's\n // own id — stripping by entry code alone would dangle it.\n const droppedIds = new Set([\n ...verbatimReRaised.flatMap((e) => (e.code !== \"\" ? [e.code] : [])),\n ...answeredFilter.droppedFindingIds.filter((id) => id !== \"\"),\n ]);\n // A dropped code is stripped only when NO KEPT finding still carries it — the drop removed one\n // instance of a mechanism, not the mechanism itself (issue #151 review r2).\n const keptCodes = new Set(answeredFilter.findings.map((f) => f.id));\n const trulyDropped = new Set([...droppedIds].filter((c) => !keptCodes.has(c)));\n const systemic =\n trulyDropped.size === 0\n ? (loadedFindings.systemic_problems ?? [])\n : (loadedFindings.systemic_problems ?? []).map((s) => {\n if (s.finding_ids === undefined) return s;\n const codes = s.finding_ids.filter((c) => !trulyDropped.has(c));\n return codes.length === s.finding_ids.length ? s : { ...s, finding_ids: codes };\n });\n const findings: Findings = {\n ...loadedFindings,\n findings: [...answeredFilter.findings],\n ...(systemic.length > 0 ? { systemic_problems: systemic } : {}),\n };\n // Nit visibility floor (issue #164): split the human-visible findings from the below-floor nits.\n // The blob (`findings`) stays COMPLETE — the machine channel and the next-round seed keep every nit,\n // so a hidden nit reads as already adjudicated and is never re-raised as fresh (a policy-suppressed\n // nit has no external anchor the way an answered-drop's live GitHub thread does, so it MUST remain in\n // the blob). Only the HUMAN surfaces filter: no inline comment, no visible stray, a collapsed aside;\n // the severity histogram and the rounds trajectory stay FULL (a nit contributes 0 to the score, and\n // an all-suppressed round must not read as \"clean\"). Stickiness, one round deep, re-derived from the\n // prior sticky's blob: a nit matching a prior round's below-floor nit (by code, else title) stays\n // hidden even if its score wobbled up — only a promotion to >= minor un-hides it — so a hidden nit\n // never flickers into view. The prior blob is read ONLY from a completed FULL-REVIEW sticky\n // (isFullReviewSticky) — route-aware like the seed chain, since a mechanic pass writes its OWN\n // findings blob and its nits are not this review's prior round; a notice/placeholder carries an empty\n // or prior blob and is handled the same way. Best-effort: an old/missing/oversized/non-review prior\n // yields no keys, so stickiness fails open to visible.\n // Resolved rather than decoded: the prior sticky's marker names the findings artifact (issue #217),\n // so this fetches it — and still reads an embedded blob on a sticky written before that change.\n // One resolve serves BOTH consumers — the nit stickiness keys and the discussion orphan gate —\n // and the resolve is a download plus an unzip subprocess on the critical path before the sticky\n // write, so it is paid only when one of them can use it. The nit keys only ever match a nit; the\n // orphan bucket is non-empty only when a reply names an id-shaped token this round does not\n // report (with no prior ids the bucket is empty either way, so that gate skips a fetch it could\n // not use, never an output it could change).\n // The PROVISIONAL known set (every finding id + the systemics) gates the fetch BEFORE the nit\n // split: the split's stickiness reads the prior document, so the exact set cannot be computed\n // until the resolve has happened. The provisional set is a superset of the exact one, so a round\n // pays the fetch a second time below ONLY for the tokens the split narrows out — the ids of\n // inline-posted findings.\n const broadCurrentIds = [\n ...findings.findings.map((f) => f.id).filter((id) => id !== \"\"),\n ...(findings.systemic_problems ?? [])\n .map((s) => s.id)\n .filter((id): id is string => id !== undefined && id !== \"\"),\n ];\n const roundHasNit = findings.findings.some((f) => f.severity === \"nit\");\n const nitWantsPrior =\n roundHasNit &&\n existingSticky !== null &&\n (isFullReviewSticky(existingSticky.body) || isFullReviewAncestry(existingSticky.body));\n const broadWantsPrior =\n existingSticky !== null && !priorIsMechanic && mentionsOutsideKnown(reachable, broadCurrentIds);\n const resolvedPrior =\n existingSticky !== null && (nitWantsPrior || broadWantsPrior)\n ? await resolvePriorFindings(existingSticky.body, readArtifact)\n : null;\n const priorDocForNits = nitWantsPrior ? resolvedPrior : null;\n const priorSuppressedKeys = new Set(\n priorBelowFloorNits(priorDocForNits, input.nitVisibilityFloor).map((n) =>\n answeredNoteKey({ id: n.id ?? \"\", title: n.title }),\n ),\n );\n const isSuppressedNit = (f: Finding): boolean =>\n f.severity === \"nit\" &&\n (isBelowVisibilityFloor(f, input.nitVisibilityFloor) ||\n // ALL THREE key forms the prior side can emit: the resolved id (a coded or same-path\n // synthesized prior), the answeredNoteKey form (an empty-id prior), and the bare title: key\n // (a pathless codeless prior).\n priorSuppressedKeys.has(resolveFindingId(f)) ||\n priorSuppressedKeys.has(answeredNoteKey(f)) ||\n priorSuppressedKeys.has(`title:${f.title}`));\n const suppressedNits = findings.findings.filter(isSuppressedNit);\n const visibleFindings = findings.findings.filter((f) => !isSuppressedNit(f));\n // The drop note, shared by every surface that renders the filtered findings: the TRUE pre-dedup\n // count (issue #151 review r5), plus — when the drops emptied the round — a line reconciling the\n // draft's verdict with the empty kept counts, so the sticky never reads \"changes requested\"\n // beside a converged signal without the explanation (issue #151 review r5).\n const answeredDropNote =\n answeredReRaiseNote(verbatimReRaised, droppedCount) +\n (verbatimReRaised.length > 0 && findings.findings.length === 0\n ? \"\\n> _The stop signal reflects the kept findings — this round carries none._\"\n : \"\");\n\n // The EXACT known set — the ids this sticky's discussion surfaces actually render: the visible\n // strays, the below-floor nits (the suppressed aside has a discussion slot), and the systemics.\n // An inline-posted finding's id is deliberately absent: the sticky renders no surface for it,\n // and its conversation lives on the inline thread itself.\n // One partition per round: the inline split below and buildInlineComments share it.\n const inlinePartition =\n input.inline === true && envelope !== null\n ? partitionFindings(visibleFindings, indexDiff(diff))\n : null;\n const straysForDiscussion = inlinePartition?.strays ?? visibleFindings;\n const currentIds = [\n ...straysForDiscussion.map((f) => f.id).filter((id) => id !== \"\"),\n ...suppressedNits.map((f) => f.id).filter((id) => id !== \"\"),\n ...(findings.systemic_problems ?? [])\n .map((s) => s.id)\n .filter((id): id is string => id !== undefined && id !== \"\"),\n ];\n // When a reply named an unknown token but the prior document could not be resolved (an expired\n // artifact, a transport failure), the trail loss is named on the surface, never silent. Only\n // ever claimed when the prior actually carries a findings marker — a marker-less prior has no\n // artifact to fail.\n const orphanResolveFailed =\n existingSticky !== null &&\n broadWantsPrior &&\n carriedFindingsMarker(existingSticky.body) !== null &&\n resolvedPrior === null;\n // The departed set is the prior document's ids MINUS every id still live this round — an\n // inline-posted finding's id persists in the prior doc while the finding is still current, so it\n // must never be published under the \"no longer reports\" header.\n const broadLive = new Set(broadCurrentIds);\n const departedIds = priorIdsFrom(resolvedPrior).filter((id) => !broadLive.has(id));\n\n // The discussion aside's reply chain (issue #246): built from the rows ALREADY fetched for the\n // sticky lookup — pure, so a round pays one history fetch total. Built whenever a sticky exists,\n // including zero-stray rounds: the orphaned bucket is exactly the case where the last stray left\n // the report, and the overwrite (issue #205) would otherwise drop the pointer trail. Hoisted above\n // the lost-envelope branch so that surface carries the same trail as the main path.\n const stickyDiscussion =\n existingSticky !== null\n ? buildStickyDiscussion(reachable, currentIds, departedIds)\n : { byFinding: {}, orphaned: {}, orphanedTotal: 0, truncated: {}, orphanedTruncated: {} };\n const discussionByFinding = stickyDiscussion.byFinding;\n const orphanedDiscussion = stickyDiscussion.orphaned;\n const orphanedTotal = stickyDiscussion.orphanedTotal;\n const discussionTruncated = stickyDiscussion.truncated;\n const orphanedTruncated = stickyDiscussion.orphanedTruncated;\n\n const testReport = input.testReportPath ? loadTestReport(input.testReportPath) : undefined;\n const clocDiff = input.clocDiffPath ? loadClocDiff(input.clocDiffPath) : undefined;\n\n // The route the review job stamped, read the same way render does — `input.route` first, then the\n // envelope — so the workflow's --route passthrough and standalone callers both work, and the\n // sticky's route marker, the guard, and the rounds logic can never disagree.\n const effectiveRoute = input.route ?? envelope?.route;\n\n if (envelope === null) {\n // The envelope carried the incomplete flag; with it lost, derive incompleteness from the verdict\n // (render does the same) so an error-verdict findings doc here still reads as a notice and — via\n // the guard below — can't bury a completed review, which this branch previously skipped.\n const envelopelessIncomplete = isIncompleteFindings(findings);\n if (wouldBuryCompleted(envelopelessIncomplete)) {\n logAnsweredDrops();\n leaveInPlace();\n }\n // The route is passed through as --route, so an empty mechanic with a lost envelope still\n // cannot bury a completed full review (issue #127).\n if (emptyMechanicWouldBury(effectiveRoute, envelopelessIncomplete) && existingSticky !== null)\n await emptyMechanicLeaveOrNote(existingSticky);\n // A lost envelope is not a completed round, so the prior convergence is carried forward in the\n // blob unchanged rather than a new round being built (issue #174) — except on the mechanic\n // route, whose pin applies here exactly as on the main path (issue #224).\n const stampedFindings = stampConvergence(\n findings,\n effectiveRoute === \"mechanic\"\n ? mechanicConvergence(\n priorConv,\n input.convergenceThreshold ?? DEFAULT_CONVERGENCE_THRESHOLD,\n )\n : priorConv,\n );\n // This branch lists every visible finding, exactly like the inline-off default, so it can exceed\n // GitHub's comment limit the same way — and here a 422 is the difference between a notice and\n // nothing at all.\n const body = formatMarkdown(\n render({\n findings: stampedFindings,\n envelope: null,\n incomplete: envelopelessIncomplete,\n prices: decodedPrices.right,\n pricesProvided: input.pricesProvided,\n template,\n route: effectiveRoute,\n reviewedSha: input.headSha,\n repo: input.headRepo || input.repo,\n effort: input.effort,\n sameRootNotes: {},\n // The answered-state honesty rules apply on EVERY surface that renders the filtered\n // findings — the lost-envelope branch lists every VISIBLE finding (no inline review exists to\n // carry them) so the kept re-raises' annotations actually render, and names the drops\n // exactly like the main path (issues #151 review r1 + r2). The nit visibility floor applies\n // here too (issue #164): below-floor nits are hidden from the human list and shown only in the\n // collapsed aside — the floor is a human-visibility policy, not an inline-comment policy, so it\n // must hold on the surface that lists findings without an inline review.\n strays: visibleFindings,\n suppressedNits,\n nitVisibilityFloor: input.nitVisibilityFloor,\n answeredNotes: reRaisedNotes,\n answeredReRaiseNote: answeredDropNote,\n roundCount: priorRoundCount,\n convergenceRound: false,\n testReport,\n clocDiff,\n inlineDisposition: inlineRequested ? { kind: \"no-envelope\" } : { kind: \"disabled\" },\n runUrl: input.runUrl,\n unverifiedNoLogs: input.unverifiedNoLogs,\n jsonUrl: input.jsonUrl,\n findingsPointer: findingsBlob(stampedFindings),\n postedAt: input.postedAt,\n discussionByFinding,\n orphanedDiscussion,\n orphanedTotal,\n discussionTruncated,\n orphanedTruncated,\n orphanedUnresolvable: orphanResolveFailed,\n }),\n );\n await upsertSticky(input.repo, prNumber, existingSticky, body, ghApi, true);\n // The body this branch posts, whatever shape it took, also goes to the run summary.\n appendRunSummary(process.env[\"GITHUB_STEP_SUMMARY\"], () => body);\n if (inlineRequested) {\n process.stderr.write(\n \"Warning: inline: true was requested, but the result envelope is missing — inline comments cannot be built; the findings are in the sticky and the run summary instead\\n\",\n );\n }\n process.stderr.write(\n \"Result envelope missing or malformed — posted sticky summary without usage/cost data\\n\",\n );\n process.exit(0);\n }\n\n // Read once the lost-envelope branch has passed — that branch posts and exits, and an ENOENT here\n // would have taken its notice with it — but still before anything on THIS path is written, so a\n // misconfigured template fails loudly rather than half-way through posting.\n const inlineTemplate = inlineRequested ? readFileSync(input.inlineTemplatePath, \"utf-8\") : \"\";\n\n // A completed review carries real telemetry; adapt (and the workflow's notice wrap) flag a run that\n // produced only a notice. Don't let such a notice bury an existing completed review or post a stray\n // empty inline review over it — leave the real review in place.\n const thisIncomplete = envelope.incomplete === true || isIncompleteFindings(findings);\n if (wouldBuryCompleted(thisIncomplete)) {\n logAnsweredDrops();\n leaveInPlace();\n }\n\n if (emptyMechanicWouldBury(effectiveRoute, thisIncomplete) && existingSticky !== null)\n await emptyMechanicLeaveOrNote(existingSticky);\n\n // A convergence round is a COMPLETED FULL review (effectiveRoute read above — `input.route` first,\n // then the envelope — the same way render does). A mechanic pass or any incomplete/failed run\n // carries the trajectory forward unchanged (it is a CI fix or a non-review, not a round). The\n // verdict guard (isReviewVerdict, render's badge uses the same predicate) also gates the append\n // here, so an out-of-contract \"error\" verdict that somehow carries findings never counts as a\n // round: the trajectory, the badge, and the blob's convergence stay one decision. A same-head CI\n // retry simply appends again — an identical chip reads as \"no change\", which is accurate; a\n // reviewed-sha-keyed replace is unsafe because a mechanic stamps a new head without adding a\n // round, so the last round need not be its head. The same-root annotation is a property of a\n // REVIEW round — a mechanic pass is a CI-fix pass, not a round, so it carries no notes — and names\n // the most recent prior round (excluding a same-head retry) each of this round's recurring codes\n // appeared in.\n const isRound =\n isConvergenceRound(effectiveRoute, thisIncomplete) && isReviewVerdict(findings.verdict);\n const sameRootNotes = isRound\n ? computeSameRootNotes(priorTraj, findings.findings, input.headSha.slice(0, 12))\n : {};\n\n // With inline off there is no diff-anchored surface, so the split does not apply: every visible\n // finding is a stray and the sticky carries them all, exactly as it does when the envelope is lost.\n const {\n comments: rawComments,\n strays,\n inDiff,\n } = inlineRequested\n ? buildInlineComments(visibleFindings, diff, {\n ...(inlinePartition !== null ? { partition: inlinePartition } : {}),\n inlineTemplate,\n models: envelope.models.map((m) => m.model),\n findings,\n jsonUrl: input.jsonUrl,\n sameRootNotes,\n answeredNotes: reRaisedNotes,\n })\n : { comments: [], strays: visibleFindings, inDiff: [] };\n const { comments, longFiles } = checkLongSuggestions(rawComments);\n for (const wf of longFiles) {\n process.stderr.write(\n `Warning: suggestion in ${wf} exceeds ${String(MAX_SUGGESTION_LINES)} lines — omitted from inline to avoid 422\\n`,\n );\n }\n\n // All prior bot reviews, fetched to supersede below — a re-run on the same commit still posts a\n // fresh review rather than being skipped.\n const botReviews = await fetchBotReviews(input.repo, prNumber, input.botLogin, ghApi);\n\n // The \"posted\" disposition is only ever built from the actual post result below, never optimistically.\n const initialDisposition: InlineDisposition | undefined = !inlineRequested\n ? { kind: \"disabled\" }\n : comments.length === 0 && strays.length > 0\n ? { kind: \"none-in-diff\" }\n : undefined;\n\n const currentCounts = computeSeverityCounts(findings.findings);\n\n // This round's mechanism-frequency map (findings + the codes systemic problems tie together) and the\n // true completed-round number, which numbers itself after the carried count. buildConvergence appends\n // this round's score + codes + head SHA to the carried trajectory (prior rounds verbatim) when the run\n // completes a full-review round. A mechanic pass, a notice, or an incomplete run is NOT a round: it\n // carries the prior convergence (the last completed round's, verbatim) forward, so the trajectory + last\n // score survive; render's incomplete gate keeps that off the human surface, so a carried \"converged\" is\n // never shown beside a run that produced no verdict (issue #141 reviews r2 + r4).\n const currentCodes = computeIdCounts(findings.findings, findings.systemic_problems ?? []);\n const roundNumber = priorRoundCount + 1;\n const convergence = isRound\n ? buildConvergence(\n findings,\n input.convergenceThreshold,\n priorTraj,\n roundNumber,\n currentCodes,\n input.headSha.slice(0, 12),\n )\n : effectiveRoute === \"mechanic\"\n ? // A mechanic pass means CI failed — whatever the carried prior says, its own stamp must\n // never read \"converged\". The threshold-relative critical floor keeps the carried triple\n // consistent at every threshold; null (no marker) when no prior round exists (issue #224).\n mechanicConvergence(priorConv, input.convergenceThreshold ?? DEFAULT_CONVERGENCE_THRESHOLD)\n : priorConv;\n const stampedFindings = stampConvergence(findings, convergence);\n const currentRoundCount = isRound ? roundNumber : priorRoundCount;\n\n const findingsMarker = findingsBlob(stampedFindings);\n\n const commonRenderInput: Omit<RenderInput, \"inlineDisposition\" | \"reviewUrl\"> = {\n findings: stampedFindings,\n envelope,\n incomplete: thisIncomplete,\n prices: decodedPrices.right,\n pricesProvided: input.pricesProvided,\n template,\n route: effectiveRoute,\n reviewedSha: input.headSha,\n repo: input.headRepo || input.repo,\n effort: input.effort,\n testReport,\n clocDiff,\n severityCounts: currentCounts,\n sameRootNotes,\n answeredNotes: reRaisedNotes,\n answeredReRaiseNote: answeredDropNote,\n discussionByFinding,\n orphanedDiscussion,\n orphanedTotal,\n discussionTruncated,\n orphanedTruncated,\n orphanedUnresolvable: orphanResolveFailed,\n roundCount: currentRoundCount,\n convergenceThreshold: input.convergenceThreshold,\n nitVisibilityFloor: input.nitVisibilityFloor,\n convergenceRound: isRound,\n strays,\n suppressedNits,\n runUrl: input.runUrl,\n unverifiedNoLogs: input.unverifiedNoLogs,\n jsonUrl: input.jsonUrl,\n findingsPointer: findingsMarker,\n postedAt: input.postedAt,\n pricedAt: input.pricedAt,\n };\n const longFilesNote =\n longFiles.length > 0\n ? `\\n\\n---\\n\\n> **Note:** ${String(longFiles.length)} suggestion(s) exceeded GitHub's ~10-line inline suggestion limit and were omitted from the inline comments; the affected findings remain in the review.\\n`\n : \"\";\n // Called twice: before the review exists (no disposition claim) and after (with reviewUrl + truth).\n const renderBody = (\n inlineDisposition: InlineDisposition | undefined,\n reviewUrl?: string,\n straysOverride?: readonly Finding[],\n unanchoredCount?: number,\n unanchoredStrays?: readonly Finding[],\n discussionOverride?: Pick<\n RenderInput,\n | \"discussionByFinding\"\n | \"orphanedDiscussion\"\n | \"orphanedTotal\"\n | \"discussionTruncated\"\n | \"orphanedTruncated\"\n >,\n ): string =>\n formatMarkdown(\n render({\n ...commonRenderInput,\n ...(straysOverride ? { strays: straysOverride } : {}),\n ...(unanchoredCount !== undefined ? { unanchoredCount } : {}),\n ...(unanchoredStrays !== undefined && unanchoredStrays.length > 0\n ? { unanchoredStrays }\n : {}),\n ...(discussionOverride ?? {}),\n inlineDisposition,\n reviewUrl,\n }) + longFilesNote,\n );\n\n // The body is posted unshed: GitHub rejects one over 65536 chars, and postComment/patchComment let\n // that 422 propagate, so an oversized body fails the job with the announce placeholder still up.\n // Inline off makes that reachable — every finding's prose now renders into this one comment, where\n // the in-diff ones used to be separate posts. Shedding is issue #214; tolerating a failed write\n // after the sticky is up is issue #223. The embedded document is gone from this body (issue #217),\n // which removed the largest fixed cost it had — an oversized round is now a matter of finding prose,\n // not of a ~32KB blob. Each sticky-listed stray's permalink adds a URL line (~55–130 chars) to this\n // budgeted-by-nobody section, so a nit-heavy inline-off round sits closer to the limit (issue #231 r1).\n // A body with no --json-url carries no findings marker, and upserting it would overwrite the last\n // pointer to the prior findings document. The guard refuses only when the pointer is actually\n // load-bearing: a COMPLETED full-review sticky whose markers gather would seed from. The\n // review-complete requirement exempts the announce placeholder, which carries the route and the\n // markers forward but strips review-complete — it must be replaced by an honest notice, not\n // frozen (post.ts's empty-mechanic path handles it). A mechanic/notice sticky is never a seed\n // either. An expired artifact link is not resolvability-checked here — a fetch in the write path\n // is the wrong trade — so an expired link can still freeze a round; the run log's ::error:: names\n // why (issue #233 r2 + r5 + r6).\n if (\n !input.jsonUrl &&\n existingSticky !== null &&\n parseReviewComplete(existingSticky.body) &&\n parseReviewedRoute(existingSticky.body) === \"full review\" &&\n hasFindingsMarker(existingSticky.body)\n ) {\n leaveInPlace(\n \"no --json-url was supplied and the existing sticky still carries the prior findings document's marker (embedded or link) — leaving it in place rather than severing the seed chain\\n\",\n );\n }\n\n // Phase 2: writes — sticky first, inline second. The carry is a property of the rendered body\n // (findingsBlob above), so every write site gets it for free.\n const stickyRef = await upsertSticky(\n input.repo,\n prNumber,\n existingSticky,\n renderBody(initialDisposition),\n ghApi,\n true,\n );\n // Snapshot stale comments BEFORE posting the fresh ones; timing (not commit SHA) separates them.\n const priorInlineComments = await listPriorBotCommentIds(\n input.repo,\n prNumber,\n input.botLogin,\n ghApi,\n );\n\n // Post first, THEN dismiss: the PR is never left review-less if the process dies between the two.\n // The review object is posted whatever `inline` says — it is the trail from the PR to the sticky and\n // to the run. With inline off it is body-only; the dismiss and minimize below run either way, so\n // flipping a repo to inline=false also clears the threads a previous round left on the diff.\n const {\n url: reviewUrl,\n posted: reviewObjectPosted,\n inlinePosted,\n unposted,\n } = await postInlineReview(\n {\n repo: input.repo,\n prNumber,\n headSha: input.headSha,\n stickyUrl: stickyRef?.url,\n runUrl: input.runUrl,\n },\n comments,\n inDiff,\n ghApi,\n );\n process.stderr.write(\n reviewObjectPosted\n ? inlineRequested\n ? `Posted a review with ${String(inlinePosted)} inline comment(s) on PR #${String(prNumber)}\\n`\n : `Posted a body-only review on PR #${String(prNumber)}; the findings are in the sticky\\n`\n : inlinePosted > 0\n ? `No review object posted this round on PR #${String(prNumber)}, but ${String(inlinePosted)} inline comment(s) anchored — the sticky carries the review\\n`\n : `No review object posted this round on PR #${String(prNumber)} — the sticky carries the review\\n`,\n );\n\n // The dismiss and minimize are gated on a BREADCRUMB review being POSTED this round: when the\n // POST failed, the prior round's reviews and threads are the only diff-anchored review objects\n // and must stay — a permanent failure (a short-scoped token, a recurring stale SHA) must not\n // clear them every round (issue #223). (The POST's success, not the parsed url — an unparseable\n // response still means the object exists.)\n const priorReviewIds = botReviews.map((r) => r.id);\n if (reviewObjectPosted && priorReviewIds.length > 0) {\n await dismissReviews(input.repo, prNumber, priorReviewIds, ghApi);\n }\n if (reviewObjectPosted || inlinePosted > 0) {\n await minimizeComments(prNumber, priorInlineComments, ghApi);\n }\n\n // Re-render the sticky to the truth: \"posted N\" is the count that ACTUALLY anchored, any\n // GitHub-rejected in-diff findings join the strays, and none-anchored says \"inline unavailable\",\n // never a false \"posted\". Best-effort — the sticky and review are already posted.\n const unanchoredCount = unposted.length;\n const finalStrays = unanchoredCount > 0 ? [...unposted, ...strays] : strays;\n // GitHub-rejected in-diff findings render on the final sticky as strays — the discussion grouping\n // was built before their rejection was knowable, so it is rebuilt with their ids in the known set:\n // their asides render, and their replies never land in the \"no longer reports\" bucket.\n const finalDiscussion =\n unanchoredCount > 0\n ? buildStickyDiscussion(\n reachable,\n [...currentIds, ...unposted.map((f) => f.id).filter((id) => id !== \"\")],\n departedIds,\n )\n : null;\n const finalDiscussionOverride =\n finalDiscussion !== null\n ? {\n discussionByFinding: finalDiscussion.byFinding,\n orphanedDiscussion: finalDiscussion.orphaned,\n orphanedTotal: finalDiscussion.orphanedTotal,\n discussionTruncated: finalDiscussion.truncated,\n orphanedTruncated: finalDiscussion.orphanedTruncated,\n }\n : undefined;\n if (stickyRef !== null && (inlinePosted > 0 || unanchoredCount > 0)) {\n const finalDisposition: InlineDisposition =\n inlinePosted > 0\n ? { kind: \"posted\", count: inlinePosted, sha: input.headSha }\n : { kind: \"inline-unavailable\" };\n try {\n await patchComment(\n input.repo,\n stickyRef.id,\n renderBody(\n finalDisposition,\n reviewUrl,\n finalStrays,\n unanchoredCount,\n unposted,\n finalDiscussionOverride,\n ),\n ghApi,\n );\n process.stderr.write(\n `Updated sticky comment #${String(stickyRef.id)} to reflect the review\\n`,\n );\n } catch (err) {\n process.stderr.write(\n `Warning: failed to update the sticky summary after the review: ${errMsg(err)}\\n`,\n );\n }\n }\n\n // Same findings, same options, same template — the run summary differs from the sticky in one\n // thing: it carries every finding, because it has no diff to anchor any of them to. That set is\n // `visibleFindings`, which the in-diff/stray split partitions and neither half holds: taking it\n // whole keeps the document's severity order, and cannot list a rejected finding twice. The\n // disposition says which document this is, so the headings do not describe the sticky's contents\n // over the summary's.\n appendRunSummary(process.env[\"GITHUB_STEP_SUMMARY\"], () =>\n renderBody(\n { kind: \"whole-document\", inlineCount: inlinePosted, rejectedCount: unanchoredCount },\n reviewUrl,\n visibleFindings,\n undefined,\n // The rejected-anchor invariant holds on EVERY surface, the run summary included — this\n // document deliberately carries every finding, so the GitHub-rejected ones must keep their\n // path-only links here too (issue #231 r2). Unconditional: renderBody's own gate treats an\n // empty array exactly like absence, so the ternary was a duplicated decision (issue #231 r3).\n unposted,\n // The summary is the sticky's long-lived twin — a rejected finding's rebuilt discussion\n // trail renders here exactly as on the final patch.\n finalDiscussionOverride,\n ),\n );\n};\n\nexport interface AnnounceInput {\n readonly repo: string;\n readonly headSha: string;\n readonly botLogin: string;\n readonly runUrl: string;\n readonly headBranch?: string;\n}\n\n// The notice bodies (announce placeholder, did-not-complete, superseded) share one shape: the sticky\n// marker, a lead line, and — when a prior sticky exists — its machine-readable markers carried forward\n// verbatim, so replacing the summary prose never strips the re-review seed the review job reads back\n// (embedded findings + reviewed-sha). Each body builds its own lead; this helper owns the shared tail.\nconst noticeBody = (lead: string, existingBody: string | undefined): string => {\n const carried = existingBody ? carryForwardMarkers(existingBody) : \"\";\n return carried ? `${lead}\\n\\n${carried}` : lead;\n};\n\n// Whether a sticky body references THIS run's URL — matched by the run id (shared grammar with\n// checkrun's runIdFromUrl) with a non-digit boundary so a successor whose numeric run id has this one\n// as a prefix (…/runs/123 vs …/runs/1234) is not mistaken for this run. Falls back to a plain substring\n// when the run URL carries no run id.\nconst bodyRefsRun = (body: string, runUrl: string): boolean => {\n const runId = runIdFromUrl(runUrl);\n return runId === null\n ? body.includes(runUrl)\n : new RegExp(`/actions/runs/${runId}(?!\\\\d)`).test(body);\n};\n\n// The placeholder body: a \"review in progress\" line linking the run, plus — when the sticky it replaces\n// carried a completed review — the prior convergence trajectory with a pending \"⏳\" cell for the round\n// now running (issue #180), so the iterations → convergence progression stays visible while the review\n// runs. The commenter job overwrites this with the real summary when the review completes.\nconst announceBody = (\n headSha: string,\n runUrl: string,\n existingBody: string | undefined,\n): string => {\n const priorDoc = existingBody !== undefined ? parseFindingsMarker(existingBody) : null;\n const prior = existingBody !== undefined ? carriedConvergence(priorDoc, existingBody) : null;\n // The running round is the SAME derivation post uses to number its appended round (nextRoundNumber),\n // so the placeholder's label matches what post will stamp — by construction (issue #188 review).\n const progress =\n prior !== null\n ? inProgressConvergence(\n prior,\n nextRoundNumber(priorTrajectory(priorDoc, existingBody ?? \"\"), prior.rounds ?? []),\n )\n : \"\";\n return noticeBody(\n `${DEFAULT_MARKER}\\n\\n🔄 **Code review in progress** for \\`${headSha.slice(0, 7)}\\` — see the [workflow run](${runUrl}) for progress; this comment is updated with the review when it completes.${progress ? `\\n\\n${progress}` : \"\"}`,\n existingBody,\n );\n};\n\n// Post (or update) the sticky the moment a review starts, so a workflow_run review — which runs from\n// the default branch and is otherwise invisible on the PR — is visibly under way. Shares post's PR\n// resolution and sticky upsert; the review job holds no write token, so it can't do this itself.\nexport const announce = async (input: AnnounceInput, ghApi: GhApi = runGhApi): Promise<void> => {\n const candidates = await fetchPrCandidates(input.repo, input.headSha, ghApi);\n const resolution = resolvePr(candidates, input.headBranch);\n if (resolution.kind !== \"open\") {\n process.stderr.write(\n `No open PR for ${input.headSha} — nothing to announce (${resolution.kind})\\n`,\n );\n return;\n }\n const existing = await findBotComment(\n input.repo,\n resolution.prNumber,\n input.botLogin,\n DEFAULT_MARKER,\n ghApi,\n );\n // If the sticky already reflects a COMPLETED review OF THIS HEAD, leave it — overwriting it with the\n // in-progress placeholder would hide a finished review (a CI re-run of an already-reviewed commit,\n // or the review+comment pipeline racing ahead of this job). Both conditions matter: a same-head\n // INCOMPLETE notice (which also stamps reviewed-sha) must be replaced by the placeholder on a re-run,\n // and a prior head's sha still gets replaced regardless. `review-complete` is the discriminator the\n // commenter guard uses too, so both write paths agree on what \"completed\" means.\n if (\n existing !== null &&\n parseReviewComplete(existing.body) &&\n parseReviewedSha(existing.body) === input.headSha.toLowerCase()\n ) {\n process.stderr.write(\n `Sticky already reflects a completed review of ${input.headSha} — leaving it in place\\n`,\n );\n return;\n }\n await upsertSticky(\n input.repo,\n resolution.prNumber,\n existing,\n announceBody(input.headSha, input.runUrl, existing?.body),\n ghApi,\n );\n};\n\nconst incompleteBody = (\n headSha: string,\n runUrl: string,\n existingBody: string | undefined,\n): string =>\n noticeBody(\n `${DEFAULT_MARKER}\\n\\n⚠️ **Code review did not complete** for \\`${headSha.slice(0, 7)}\\` — the review job failed ([run](${runUrl})). Re-request the review; do not treat this round as spent.`,\n existingBody,\n );\n\n// A review run CANCELLED is not an operational failure — issue #139. Distinct sentence, no action\n// needed, and it must NOT read as a crash: no \"did not complete\", no \"Re-request\", and it never\n// carries the review-complete marker. The wording is deliberately soft about WHY it was cancelled —\n// `needs.review.result == 'cancelled'` also fires for a manual cancel, so the sticky must not assert\n// \"a newer review run started\" as fact, and the run it links is this (cancelled) one, not a \"latest\"\n// run it cannot name. The superseding run's own announce (or the commenter) replaces it.\nconst cancelledBody = (headSha: string, runUrl: string, existingBody: string | undefined): string =>\n noticeBody(\n `${DEFAULT_MARKER}\\n\\n↩️ **Code review superseded** for \\`${headSha.slice(0, 7)}\\` — this run was cancelled before completing, typically because a newer review run started on this branch. No action needed. [View the cancelled run](${runUrl}) for the record.`,\n existingBody,\n );\n\nexport interface ReportIncompleteInput extends AnnounceInput {\n // Issue #139: this run was CANCELLED by a superseding run on the same branch — post the\n // informational \"superseded\" sticky instead of the failure notice.\n readonly cancelled?: boolean;\n}\n\n// The human-readable half of failure attribution (the check-run is the machine half): a review that\n// died leaves NO comment, so a separate always()-job posts this. Shares announce's PR resolution and\n// sticky upsert; the guard is stronger — it never buries a completed review OF ANY head, so a failed\n// run reporting late (after a superseding run already finished) can't clobber the real review. A\n// CANCELLED run (issue #139) posts the superseded notice instead, and the same guards keep it from\n// clobbering a newer run's live placeholder.\nexport const reportIncomplete = async (\n input: ReportIncompleteInput,\n ghApi: GhApi = runGhApi,\n): Promise<void> => {\n const candidates = await fetchPrCandidates(input.repo, input.headSha, ghApi);\n const resolution = resolvePr(candidates, input.headBranch);\n if (resolution.kind !== \"open\") {\n process.stderr.write(\n `No open PR for ${input.headSha} — nothing to report (${resolution.kind})\\n`,\n );\n return;\n }\n const existing = await findBotComment(\n input.repo,\n resolution.prNumber,\n input.botLogin,\n DEFAULT_MARKER,\n ghApi,\n );\n if (existing !== null && parseReviewComplete(existing.body)) {\n process.stderr.write(`Sticky already reflects a completed review — leaving it in place\\n`);\n return;\n }\n // The sticky exists but is NOT this run's own placeholder — it belongs to a superseding run whose\n // announce already posted a live \"in progress\" for a newer head. Overwriting it with \"did not\n // complete\" would be a false alarm for a review that is actively running. This run's own placeholder\n // (or a prior failure notice this run posted) embeds this run's URL, so its presence is the signal\n // that overwriting is safe. The run id is matched with a non-digit boundary so a successor whose\n // numeric run id has this one as a prefix (123 vs 1234) is not mistaken for this run.\n if (existing !== null && !bodyRefsRun(existing.body, input.runUrl)) {\n process.stderr.write(`Sticky belongs to another run — leaving it in place\\n`);\n return;\n }\n // A CANCELLED run with NO placeholder at all (cancelled before its announce, or a manual cancel with\n // nothing ever posted) must not CREATE a lone \"superseded\" sticky — nothing superseded it. Only a\n // run that announced (or already posted its own notice) replaces its placeholder. A superseding run\n // will post its own review, so a missing sticky is not a gap.\n if (input.cancelled && existing === null) {\n process.stderr.write(`Cancelled review has no sticky to supersede — leaving it absent\\n`);\n return;\n }\n await upsertSticky(\n input.repo,\n resolution.prNumber,\n existing,\n input.cancelled\n ? cancelledBody(input.headSha, input.runUrl, existing?.body)\n : incompleteBody(input.headSha, input.runUrl, existing?.body),\n ghApi,\n );\n};\n","// Parses a ChatOps trigger comment (\"/code-review [24m] [$1.00] <instructions>\") into structured\n// review overrides, and resolves the PR head from the comment's PR NUMBER via the API (never from a\n// SHA in the comment). The untrusted comment is parsed here, in type-safe code, not in workflow bash.\n\nimport * as t from \"io-ts\";\nimport type { GhApi } from \"./gh.js\";\nimport { runGhApi } from \"./gh.js\";\n\nexport interface CommandArgs {\n // null ⇒ the commenter did not specify it; the reusable workflow keeps its configured default.\n readonly durationSec: number | null;\n readonly usd: number | null;\n readonly instructions: string;\n // Human-readable adjustments (a clamp hit, a truncation) for the CI log — the sticky footer shows\n // the values actually used, so these are diagnostics, not the user-facing signal.\n readonly notes: readonly string[];\n}\n\nexport type CommandParse =\n { readonly kind: \"not-a-command\" } | { readonly kind: \"command\"; readonly args: CommandArgs };\n\nexport interface ParseOptions {\n readonly trigger: string;\n // null ⇒ no clamp (a comment could then request an unbounded wall/budget — callers set a ceiling).\n readonly maxDurationSec: number | null;\n readonly maxUsd: number | null;\n readonly maxInstructionsLen: number;\n}\n\nconst DURATION_RE = /^(\\d+)(h|m|s)$/;\nconst USD_RE = /^\\$(\\d+(?:\\.\\d+)?)$/;\n\nconst toSeconds = (n: number, unit: string): number =>\n unit === \"h\" ? n * 3600 : unit === \"m\" ? n * 60 : n;\n\n// null when the body does not begin with the trigger as a WHOLE token (so \"/code-reviewer\" is not a\n// hit); otherwise the remainder after the trigger, leading whitespace and all.\nconst stripTrigger = (body: string, trigger: string): string | null => {\n const trimmed = body.replace(/^\\s+/, \"\");\n if (!trimmed.startsWith(trigger)) return null;\n const after = trimmed.slice(trigger.length);\n return after === \"\" || /^\\s/.test(after) ? after : null;\n};\n\n// Consume leading whitespace-delimited tokens that are a duration or a dollar amount (each at most\n// once, either order); stop at the first token that is neither (or a duplicate). The untouched\n// remainder — from that token on, its own leading whitespace included — is the instructions.\nconst scanLeading = (\n s: string,\n acc: { readonly durationSec: number | null; readonly usd: number | null },\n): { readonly durationSec: number | null; readonly usd: number | null; readonly rest: string } => {\n const m = /^(\\s*)(\\S+)([\\s\\S]*)$/.exec(s);\n if (m === null) return { ...acc, rest: \"\" };\n const [, , token = \"\", tail = \"\"] = m;\n const dm = DURATION_RE.exec(token);\n if (dm && acc.durationSec === null)\n return scanLeading(tail, {\n ...acc,\n durationSec: toSeconds(Number.parseInt(dm[1] ?? \"\", 10), dm[2] ?? \"s\"),\n });\n const um = USD_RE.exec(token);\n if (um && acc.usd === null)\n return scanLeading(tail, { ...acc, usd: Number.parseFloat(um[1] ?? \"\") });\n return { ...acc, rest: s };\n};\n\nconst clampDuration = (\n requested: number | null,\n ceiling: number | null,\n): { readonly value: number | null; readonly notes: readonly string[] } =>\n requested !== null && ceiling !== null && requested > ceiling\n ? {\n value: ceiling,\n notes: [\n `requested duration ${String(requested)}s exceeds the ${String(ceiling)}s ceiling — clamped to ${String(ceiling)}s`,\n ],\n }\n : { value: requested, notes: [] };\n\nconst clampUsd = (\n requested: number | null,\n ceiling: number | null,\n): { readonly value: number | null; readonly notes: readonly string[] } =>\n requested !== null && ceiling !== null && requested > ceiling\n ? {\n value: ceiling,\n notes: [\n `requested $${requested.toFixed(2)} exceeds the $${ceiling.toFixed(2)} ceiling — clamped to $${ceiling.toFixed(2)}`,\n ],\n }\n : { value: requested, notes: [] };\n\nconst capInstructions = (\n text: string,\n maxLen: number,\n): { readonly value: string; readonly notes: readonly string[] } =>\n text.length > maxLen\n ? {\n value: text.slice(0, maxLen),\n notes: [\n `instructions truncated from ${String(text.length)} to ${String(maxLen)} characters`,\n ],\n }\n : { value: text, notes: [] };\n\nexport const parseCommandArgs = (body: string, options: ParseOptions): CommandParse => {\n const afterTrigger = stripTrigger(body, options.trigger);\n if (afterTrigger === null) return { kind: \"not-a-command\" };\n const scan = scanLeading(afterTrigger, { durationSec: null, usd: null });\n const duration = clampDuration(scan.durationSec, options.maxDurationSec);\n const usd = clampUsd(scan.usd, options.maxUsd);\n const instructions = capInstructions(scan.rest.trim(), options.maxInstructionsLen);\n return {\n kind: \"command\",\n args: {\n durationSec: duration.value,\n usd: usd.value,\n instructions: instructions.value,\n notes: [...duration.notes, ...usd.notes, ...instructions.notes],\n },\n };\n};\n\nconst PrHeadCodec = t.type({\n head_sha: t.string,\n head_ref: t.string,\n head_repo: t.union([t.string, t.null]),\n state: t.string,\n});\n\nexport const resolvePrHead = async (\n repo: string,\n prNumber: number,\n ghApi: GhApi,\n): Promise<t.TypeOf<typeof PrHeadCodec>> => {\n const stdout = await ghApi([\n `repos/${repo}/pulls/${String(prNumber)}`,\n \"--jq\",\n \"{head_sha: .head.sha, head_ref: .head.ref, head_repo: .head.repo.full_name, state: .state}\",\n ]);\n const decoded = PrHeadCodec.decode(JSON.parse(stdout) as unknown);\n if (decoded._tag === \"Left\") {\n throw new Error(`PR head for #${String(prNumber)} did not match the expected shape`);\n }\n return decoded.right;\n};\n\nexport interface CommandInput {\n readonly repo: string;\n readonly prNumber: number;\n readonly body: string;\n readonly options: ParseOptions;\n}\n\nexport type CommandResult =\n | { readonly kind: \"skip\"; readonly reason: string }\n | {\n readonly kind: \"run\";\n readonly headSha: string;\n readonly headBranch: string;\n readonly headRepo: string;\n readonly args: CommandArgs;\n };\n\nexport const parseCommand = async (\n input: CommandInput,\n ghApi: GhApi = runGhApi,\n): Promise<CommandResult> => {\n const parse = parseCommandArgs(input.body, input.options);\n if (parse.kind === \"not-a-command\") {\n return {\n kind: \"skip\",\n reason: `comment does not begin with the trigger \"${input.options.trigger}\"`,\n };\n }\n const head = await resolvePrHead(input.repo, input.prNumber, ghApi).catch((err: unknown) =>\n err instanceof Error ? err : new Error(String(err)),\n );\n if (head instanceof Error) {\n return {\n kind: \"skip\",\n reason: `could not resolve PR #${String(input.prNumber)}: ${head.message}`,\n };\n }\n if (head.state !== \"open\") {\n return {\n kind: \"skip\",\n reason: `PR #${String(input.prNumber)} is not open (state: ${head.state})`,\n };\n }\n return {\n kind: \"run\",\n headSha: head.head_sha,\n headBranch: head.head_ref,\n headRepo: head.head_repo ?? input.repo,\n args: parse.args,\n };\n};\n\n// A heredoc delimiter guaranteed not to equal any line of the (untrusted) instructions, so the value\n// can't break out of its $GITHUB_OUTPUT block and forge later outputs (e.g. should_run=true). A\n// 128-bit random tag never collides in practice; the bounded recursion is belt-and-braces.\nexport const safeHeredocDelim = (\n instructions: string,\n randomHex: () => string,\n attemptsLeft = 8,\n): string => {\n const candidate = `GHOUT_${randomHex()}`;\n if (!instructions.split(\"\\n\").includes(candidate)) return candidate;\n if (attemptsLeft <= 0) throw new Error(\"could not derive a collision-free heredoc delimiter\");\n return safeHeredocDelim(instructions, randomHex, attemptsLeft - 1);\n};\n\nexport const renderCommandOutputs = (result: CommandResult, delim: string): string => {\n if (result.kind === \"skip\") return \"should_run=false\\n\";\n const { headSha, headBranch, headRepo, args } = result;\n return `${[\n \"should_run=true\",\n `head_sha=${headSha}`,\n `head_branch=${headBranch}`,\n `head_repo=${headRepo}`,\n `duration=${args.durationSec === null ? \"\" : `${String(args.durationSec)}s`}`,\n `usd=${args.usd === null ? \"\" : args.usd.toFixed(2)}`,\n `instructions<<${delim}`,\n args.instructions,\n delim,\n ].join(\"\\n\")}\\n`;\n};\n","// Manages the ChatOps acknowledgement reaction on a PR/issue comment: 👀 on receipt, swapped to 🚀\n// (or 😕) on completion. Reactions are cosmetic, so the CLI wrapper never fails a job over them.\n\nimport * as t from \"io-ts\";\nimport type { GhApi } from \"./gh.js\";\nimport { runGhApi } from \"./gh.js\";\nimport { errMsg, tryParseJson } from \"./util.js\";\n\n// GitHub's fixed reaction vocabulary — there is no ✅; 🚀 (rocket) reads as \"review shipped\".\nexport const REACTIONS = [\n \"+1\",\n \"-1\",\n \"laugh\",\n \"confused\",\n \"heart\",\n \"hooray\",\n \"rocket\",\n \"eyes\",\n] as const;\nexport type Reaction = (typeof REACTIONS)[number];\nexport const isReaction = (s: string): s is Reaction =>\n (REACTIONS as readonly string[]).includes(s);\n\nconst ReactionCodec = t.type({ id: t.number, content: t.string });\n\nexport interface ReactInput {\n readonly repo: string;\n readonly commentId: number;\n readonly add?: Reaction;\n readonly remove?: Reaction;\n}\n\nconst reactionsPath = (repo: string, commentId: number): string =>\n `repos/${repo}/issues/comments/${String(commentId)}/reactions`;\n\nconst removeReactions = async (\n repo: string,\n commentId: number,\n content: Reaction,\n ghApi: GhApi,\n): Promise<void> => {\n // --paginate WITHOUT --jq concatenates pages as `[..][..]` (invalid JSON) once a comment has >100\n // reactions; flatten to one record per line via --jq and decode line by line, like pr.ts. Each\n // undecodable line is logged and skipped rather than silently swallowed.\n const stdout = await ghApi([\n reactionsPath(repo, commentId),\n \"--paginate\",\n \"--jq\",\n \".[] | {id, content}\",\n ]);\n for (const line of stdout.split(\"\\n\").filter((l) => l.trim() !== \"\")) {\n const parsed = tryParseJson(line);\n const decoded = parsed.ok ? ReactionCodec.decode(parsed.value) : undefined;\n if (decoded === undefined || decoded._tag === \"Left\") {\n process.stderr.write(\"code-review react: could not decode a reaction entry — skipping\\n\");\n continue;\n }\n if (decoded.right.content !== content) continue;\n // The token may delete only its OWN reactions; a 403 on someone else's is expected, not fatal.\n await ghApi([\n \"--method\",\n \"DELETE\",\n `${reactionsPath(repo, commentId)}/${String(decoded.right.id)}`,\n ]).catch((err: unknown) =>\n process.stderr.write(\n `code-review react: could not remove reaction ${String(decoded.right.id)} (${errMsg(err)}) — skipping\\n`,\n ),\n );\n }\n};\n\n// Add first, then remove, so the comment is never momentarily unmarked during a 👀→🚀 swap.\nexport const react = async (input: ReactInput, ghApi: GhApi = runGhApi): Promise<void> => {\n if (input.add !== undefined) {\n await ghApi([\n \"--method\",\n \"POST\",\n reactionsPath(input.repo, input.commentId),\n \"-f\",\n `content=${input.add}`,\n ]);\n }\n if (input.remove !== undefined) {\n await removeReactions(input.repo, input.commentId, input.remove, ghApi);\n }\n};\n","// Resolves and waits for a PR head's CI workflow run, so the on-demand comment trigger routes on the\n// SAME real CI conclusion the workflow_run trigger would: success → full review, failure → mechanic\n// with that run's failing-job logs. Without this the comment path reviews blind to CI — throwing away\n// the differentiator. The head SHA is trusted (resolved from the PR number via the API), so it is\n// safe in the query; the workflow name is trusted caller config.\n\nimport { performance } from \"node:perf_hooks\";\nimport * as t from \"io-ts\";\nimport { PathReporter } from \"io-ts/lib/PathReporter.js\";\nimport type { GhApi } from \"./gh.js\";\nimport { runGhApi } from \"./gh.js\";\nimport { parseJsonl } from \"./transcript.js\";\nimport { errMsg } from \"./util.js\";\n\nconst RunCodec = t.type({\n id: t.number,\n name: t.union([t.string, t.null]),\n status: t.union([t.string, t.null]),\n conclusion: t.union([t.string, t.null]),\n run_number: t.number,\n});\n\nexport interface CiRun {\n readonly id: number;\n // queued | in_progress | requested | waiting | pending | completed\n readonly status: string;\n // success | failure | cancelled | timed_out | ... — null until status is completed\n readonly conclusion: string | null;\n}\n\nexport interface CiLookup {\n // The matched run, or null if the named workflow has no run for this head SHA yet.\n readonly run: CiRun | null;\n // Distinct workflow names that DID run for this head SHA — lets a caller tell a mistyped\n // workflowName (which otherwise just times out) from \"the named CI simply has not queued yet\".\n readonly seenNames: readonly string[];\n}\n\n// One projected run object per row across ALL pages: `--paginate` WITHOUT `--jq` concatenates each\n// page's `{workflow_runs: […]}` object into a stream JSON.parse rejects, so only the first page (≤100\n// runs) was ever read — a head SHA with many workflows or re-runs could push the awaited run out of\n// view and the comment path would decline with no diagnostic. `--jq` unwraps `.workflow_runs[]` and\n// streams NDJSON parseJsonl reads line by line, the shape gather/post already use.\nconst RUN_JQ =\n \".workflow_runs[] | {id: .id, name: .name, status: .status, conclusion: .conclusion, run_number: .run_number}\";\n\n// The latest run of the named CI workflow for this head SHA. NOT filtered by triggering event: CI may\n// run on `push` as well as `pull_request`, and the head SHA already pins the commit. Latest = highest\n// run_number, so a re-run supersedes. `run` is null when the named workflow has no run yet (the\n// comment may fire before CI even queues). A row that doesn't match the run shape is dropped rather\n// than aborting the lookup — an empty result then reads as \"not queued yet\" and the caller declines.\nexport const resolveCiRun = async (\n repo: string,\n headSha: string,\n workflowName: string,\n ghApi: GhApi,\n): Promise<CiLookup> => {\n const endpoint = `repos/${repo}/actions/runs?head_sha=${headSha}&per_page=100`;\n const rows = parseJsonl(await ghApi([endpoint, \"--paginate\", \"--jq\", RUN_JQ]));\n const decoded = rows.map((row) => RunCodec.decode(row));\n const runs = decoded.flatMap((d) => (d._tag === \"Right\" ? [d.right] : []));\n // A row that fails the codec is dropped rather than aborting the lookup, but a drop is never normal:\n // a partial drift can silently drop the newest run and route on a stale one, and a total drift reads\n // as an empty result that declines only after a full timeout. So name every drop, with the first\n // failure's field-level detail, so the drifted field is diagnosable without reproducing the call.\n const dropped = decoded.length - runs.length;\n if (dropped > 0) {\n const firstDrift = decoded.find((d) => d._tag === \"Left\");\n const detail =\n firstDrift === undefined ? \"\" : ` (${PathReporter.report(firstDrift).join(\"; \")})`;\n process.stderr.write(\n `Warning: ${String(dropped)} of ${String(rows.length)} workflow-run row(s) from ${endpoint} failed to decode${detail} — excluded from the lookup\\n`,\n );\n }\n const latest = runs\n .filter((r) => r.name === workflowName)\n .reduce<t.TypeOf<typeof RunCodec> | null>(\n (best, r) => (best === null || r.run_number > best.run_number ? r : best),\n null,\n );\n return {\n run:\n latest === null\n ? null\n : { id: latest.id, status: latest.status ?? \"unknown\", conclusion: latest.conclusion },\n seenNames: [...new Set(runs.flatMap((r) => (r.name === null ? [] : [r.name])))],\n };\n};\n\nexport type CiOutcome =\n | { readonly kind: \"concluded\"; readonly conclusion: string; readonly runId: number }\n // No conclusive CI result within the timeout — the run never appeared or never completed. The\n // caller declines to review rather than fabricate a conclusion. seenNames carries the workflow\n // names that DID run, so a mistyped ci_workflow can be diagnosed instead of silently timing out.\n | {\n readonly kind: \"timed-out\";\n readonly runId: number | null;\n readonly seenNames: readonly string[];\n };\n\nexport interface AwaitOptions {\n readonly workflowName: string;\n readonly pollIntervalMs: number;\n readonly timeoutMs: number;\n}\n\nexport interface AwaitDeps {\n readonly ghApi: GhApi;\n readonly sleep: (ms: number) => Promise<void>;\n readonly elapsedMs: () => number;\n}\n\nexport const awaitCiConclusion = async (\n repo: string,\n headSha: string,\n options: AwaitOptions,\n deps: AwaitDeps = { ghApi: runGhApi, sleep: defaultSleep, elapsedMs: monotonicElapsed() },\n): Promise<CiOutcome> => {\n // `--paginate` fetches one page per HTTP request, so a transient blip on any page rejects the whole\n // lookup. Contain it to a diagnostic + empty result rather than let it unwind and abort the wait:\n // the loop is meant to be resilient, so a failed poll should retry until the run settles or the\n // timeout declines, never crash mid-wait.\n const safeResolve = async (): Promise<CiLookup> => {\n try {\n return await resolveCiRun(repo, headSha, options.workflowName, deps.ghApi);\n } catch (err) {\n process.stderr.write(\n `Warning: CI-run lookup for ${headSha} failed (${errMsg(err)}) — retrying until the timeout\\n`,\n );\n return { run: null, seenNames: [] };\n }\n };\n const poll = async (\n lastSeenNames: readonly string[],\n lastRunId: number | null,\n ): Promise<CiOutcome> => {\n const { run, seenNames } = await safeResolve();\n // A run momentarily reports `completed` with a null conclusion before GitHub settles it; treating\n // that as concluded would fabricate a routing decision, so keep polling until the conclusion lands\n // (or the timeout declines) rather than collapsing it to a made-up \"unknown\" the caller can act on.\n if (run !== null && run.status === \"completed\" && run.conclusion !== null)\n return { kind: \"concluded\", conclusion: run.conclusion, runId: run.id };\n // A caught error zeroes this poll's view, so carry the last non-empty observation forward — else a\n // transient failure on the very iteration that times out would erase the run id and workflow names\n // earlier polls saw, misleading the mistyped-workflow-vs-not-queued-yet diagnostic renderCiOutputs\n // depends on.\n const runId = run === null ? lastRunId : run.id;\n const names = seenNames.length > 0 ? seenNames : lastSeenNames;\n if (deps.elapsedMs() >= options.timeoutMs)\n return { kind: \"timed-out\", runId, seenNames: names };\n await deps.sleep(options.pollIntervalMs);\n return poll(names, runId);\n };\n return poll([], null);\n};\n\nexport const defaultSleep = (ms: number): Promise<void> =>\n new Promise((resolvePromise) => setTimeout(resolvePromise, ms));\n\n// performance.now() is monotonic — unlike Date.now(), an NTP/VM wall-clock step back mid-poll can't\n// make elapsedMs() decrease and stall the timeout check the loop depends on.\nexport const monotonicElapsed = (): (() => number) => {\n const start = performance.now();\n return () => performance.now() - start;\n};\n\n// ci_settled distinguishes \"we know the CI result\" from \"we gave up waiting\" so the gate can decline\n// the review on a non-settle rather than run it on a guessed conclusion.\nexport const renderCiOutputs = (outcome: CiOutcome): string =>\n outcome.kind === \"concluded\"\n ? `ci_settled=true\\nci_conclusion=${outcome.conclusion}\\nci_run_id=${String(outcome.runId)}\\n`\n : `ci_settled=false\\nci_run_id=${outcome.runId === null ? \"\" : String(outcome.runId)}\\n`;\n","// Shares post's PR resolution so the review and comment jobs never split-brain on which PR.\n\nimport { writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport * as t from \"io-ts\";\nimport { execFileWithTimeout, subprocessTimeoutMs } from \"./exec.js\";\nimport type { GhApi } from \"./gh.js\";\nimport { runGhApi } from \"./gh.js\";\nimport { ghArtifactReader, resolvePriorFindings, type ArtifactReader } from \"./artifact.js\";\nimport { isFullReviewAncestry } from \"./surface.js\";\nimport { fetchDiff, fetchPrCandidates, resolvePr } from \"./pr.js\";\nimport { parseJsonl } from \"./transcript.js\";\nimport {\n answeredRegistryFrom,\n encodeAnsweredEntry,\n ThreadCommentCodec,\n THREAD_COMMENT_JQ,\n} from \"./answered.js\";\nimport { annotationSafe, BODY_CLIP_CHARS, clipText, errMsg } from \"./util.js\";\n\nexport interface GatherInput {\n readonly repo: string;\n readonly headSha: string;\n readonly headBranch?: string;\n // The repo's default branch — the trusted base the review checks out and the reference point for\n // the full (triage) diff. A PR whose base is a different branch is \"stacked\".\n readonly defaultBranch: string;\n readonly runId: string;\n readonly conclusion: string;\n readonly botLogin: string;\n readonly outDir: string;\n}\n\nexport type GatherResult =\n | { readonly kind: \"skip\" }\n | {\n readonly kind: \"gathered\";\n readonly pr: number;\n readonly conclusion: string;\n readonly diffSize: number;\n // The PR's base is not the default branch (a stacked PR): the review scope (base...head) is a\n // strict subset of what gets checked out + triaged (default...head), so the review prompt frames\n // the extra changes as already-reviewed context.\n readonly stacked: boolean;\n // The review-scope base commit (the pr.diff endpoint), exposed so a downstream step can run\n // `cloc --git --diff <baseSha> <head>` over exactly the PR's own change (issue #182).\n readonly baseSha: string;\n // Failing-job logs actually written for the fast-fix route to read. Zero means that route has\n // nothing but the diff, which every downstream surface has to say rather than imply (#154).\n readonly stagedJobLogs: number;\n // Failing jobs the run reported, which the cap can leave larger than stagedJobLogs. Carried so\n // the fast-fix route is TOLD it is reading a subset, rather than reporting the break fixed on\n // the strength of the logs it happened to get.\n readonly failingJobs: number;\n };\n\nexport const renderOutputs = (result: GatherResult): string => {\n switch (result.kind) {\n case \"skip\":\n return \"skip=true\\n\";\n case \"gathered\":\n return `pr=${String(result.pr)}\\nconclusion=${result.conclusion}\\ndiff_size=${String(result.diffSize)}\\nstacked=${String(result.stacked)}\\nbase_sha=${result.baseSha}\\nstaged_job_logs=${String(result.stagedJobLogs)}\\nfailing_jobs=${String(result.failingJobs)}\\n`;\n }\n};\n\nexport type GitRun = (args: readonly string[]) => Promise<string>;\n\nexport const runGit: GitRun = (args) =>\n execFileWithTimeout({\n command: \"git\",\n args,\n label: `git ${args.join(\" \")}`,\n timeoutMs: subprocessTimeoutMs(),\n });\n\nconst PrMetaCodec = t.type({\n changed_files: t.number,\n base_sha: t.string,\n base_ref: t.string,\n title: t.string,\n body: t.union([t.string, t.null]),\n});\ntype PrMeta = t.TypeOf<typeof PrMetaCodec>;\n\nconst IssueCommentCodec = t.intersection([\n t.type({\n id: t.number,\n body: t.union([t.string, t.null]),\n user: t.type({ login: t.string }),\n }),\n t.partial({\n created_at: t.union([t.string, t.null]),\n author_association: t.union([t.string, t.null]),\n }),\n]);\ntype IssueComment = t.TypeOf<typeof IssueCommentCodec>;\n\nconst JobCodec = t.type({\n id: t.number,\n // A null name (an API edge) degrades to a nameless entry rather than aborting the whole gather —\n // the identity the reproduction steer needs is best-effort, never load-bearing.\n name: t.union([t.string, t.null]),\n conclusion: t.union([t.string, t.null]),\n});\n\n// One job per row across all pages, for the same reason the conversation fetches project with --jq:\n// `--paginate` alone concatenates each page into an invalid `{..}{..}` stream. Unpaginated, a failing\n// job past the first page is invisible — and everything this route reports (the staged count, the\n// \"(N failing job(s) reported)\" line, the unverified stamp) would be computed from a truncated list.\n// `name` rides along so a zero-logs pass can still tell the agent WHICH jobs failed (failed_jobs.json),\n// not just how many.\nconst JOBS_JQ = \".jobs[] | {id: .id, name: .name, conclusion: .conclusion}\";\n\nconst fetchPrMeta = async (repo: string, prNumber: number, ghApi: GhApi): Promise<PrMeta> => {\n const stdout = await ghApi([\n `repos/${repo}/pulls/${String(prNumber)}`,\n \"--jq\",\n \"{changed_files: .changed_files, base_sha: .base.sha, base_ref: .base.ref, title: .title, body: .body}\",\n ]);\n const decoded = PrMetaCodec.decode(JSON.parse(stdout) as unknown);\n if (decoded._tag === \"Left\") {\n throw new Error(`PR metadata for #${String(prNumber)} did not match the expected shape`);\n }\n return decoded.right;\n};\n\nconst fetchApiDiff = async (\n repo: string,\n prNumber: number,\n ghApi: GhApi,\n): Promise<string | null> => {\n try {\n return await fetchDiff(repo, prNumber, ghApi);\n } catch {\n return null;\n }\n};\n\n// The review checks out the PR head; the untrusted surface a checkout exposes over the trusted\n// default branch is exactly `default...head`. So triage scans THIS diff (not the PR's base...head),\n// and it is the same diff for a normal PR (base === default). Compare API with a git-diff fallback\n// (fetch the head, diff from the checked-out default-branch tip) mirroring the pr.diff path.\nconst fetchFullDiff = async (\n repo: string,\n defaultBranch: string,\n headSha: string,\n ghApi: GhApi,\n gitRun: GitRun,\n): Promise<string> => {\n try {\n const diff = await ghApi([\n `repos/${repo}/compare/${defaultBranch}...${headSha}`,\n \"-H\",\n \"Accept: application/vnd.github.v3.diff\",\n ]);\n if (diff.length > 0) return diff;\n process.stderr.write(\n `compare diff for ${defaultBranch}...${headSha} was empty — falling back to git diff\\n`,\n );\n } catch (err) {\n process.stderr.write(`compare diff fetch failed (${errMsg(err)}) — falling back to git diff\\n`);\n }\n await gitRun([\"fetch\", \"origin\", headSha]);\n // Three-dot, matching the compare API's semantics (merge-base...head): the checked-out default\n // branch is HEAD, so this is the same untrusted surface the compare primary computes.\n const base = (await gitRun([\"rev-parse\", \"HEAD\"])).trim();\n return gitRun([\"diff\", `${base}...${headSha}`]);\n};\n\nconst CommitCodec = t.type({\n sha: t.string,\n message: t.string,\n author: t.union([t.string, t.null]),\n email: t.union([t.string, t.null]),\n});\nconst COMMIT_JQ =\n \".commits[] | {sha: .sha, message: .commit.message, author: .commit.author.name, email: .commit.author.email}\";\n\n// Commit messages + author identities of every commit in `default...head`. Once the head is checked\n// out, `git log` exposes these to the reviewing agent, so they are an untrusted surface triage must\n// scan for injection. FAIL CLOSED: a fetch failure propagates (never a silent empty scan) — the\n// caller must not expose commit messages it could not vet.\nconst fetchCompareCommits = async (\n repo: string,\n defaultBranch: string,\n headSha: string,\n ghApi: GhApi,\n): Promise<readonly t.TypeOf<typeof CommitCodec>[]> => {\n const rows = parseJsonl(\n await ghApi([\n `repos/${repo}/compare/${defaultBranch}...${headSha}`,\n \"--paginate\",\n \"--jq\",\n COMMIT_JQ,\n ]),\n );\n const decoded = rows.map((row) => CommitCodec.decode(row));\n const commits = decoded.flatMap((d) => (d._tag === \"Right\" ? [d.right] : []));\n // A dropped row is a scan gap, not a no-op: a checkout's `git log` still exposes that commit's\n // message to the agent, so name any drop rather than let an unscanned message pass silently.\n const dropped = decoded.length - commits.length;\n if (dropped > 0) {\n process.stderr.write(\n `Warning: ${String(dropped)} of ${String(rows.length)} commit row(s) failed to decode — their messages are NOT in the triage scan though a checkout's git log still exposes them\\n`,\n );\n }\n return commits;\n};\n\n// One object per row across all pages: `--paginate` WITHOUT `--jq` concatenates each page's JSON\n// array into an invalid `[..][..]` stream JSON.parse rejects, silently losing the prior review (and\n// the conversation) on any PR past the first page; the `--jq` projection streams NDJSON parseJsonl\n// reads line by line — the shape post.ts's findBotComment already uses.\nconst COMMENT_JQ =\n \".[] | {id: .id, body: .body, user: {login: .user.login}, created_at: .created_at, author_association: .author_association}\";\n// The review-comments fetch feeds TWO consumers from one projection: the conversation (human\n// replies, via ReviewCommentCodec) and the answered-findings registry (thread structure + the bot's\n// own comments, via ThreadCommentCodec) — the richer THREAD_COMMENT_JQ shape serves both, the\n// conversation codec tolerating the extra fields.\nconst REVIEW_COMMENT_JQ = THREAD_COMMENT_JQ;\nconst REVIEW_JQ =\n \".[] | {body: .body, user: {login: .user.login}, submitted_at: .submitted_at, author_association: .author_association, state: .state}\";\n\nconst ReviewCommentCodec = t.intersection([\n t.type({ body: t.union([t.string, t.null]), user: t.type({ login: t.string }) }),\n t.partial({\n created_at: t.union([t.string, t.null]),\n author_association: t.union([t.string, t.null]),\n path: t.union([t.string, t.null]),\n line: t.union([t.number, t.null]),\n }),\n]);\ntype ReviewComment = t.TypeOf<typeof ReviewCommentCodec>;\n\nconst ReviewCodec = t.intersection([\n t.type({ body: t.union([t.string, t.null]), user: t.type({ login: t.string }) }),\n t.partial({\n submitted_at: t.union([t.string, t.null]),\n author_association: t.union([t.string, t.null]),\n state: t.union([t.string, t.null]),\n }),\n]);\ntype Review = t.TypeOf<typeof ReviewCodec>;\n\n// Fetch + stream-parse a paginated endpoint; null on any transport error (named on stderr so a\n// degraded channel is diagnosable), so a failed fetch never aborts the review — the conversation is\n// best-effort context.\nconst fetchJsonlRows = async (\n ghApi: GhApi,\n endpoint: string,\n jq: string,\n): Promise<readonly unknown[] | null> => {\n try {\n return parseJsonl(await ghApi([endpoint, \"--paginate\", \"--jq\", jq]));\n } catch (err) {\n process.stderr.write(\n `Warning: could not fetch ${endpoint} (${errMsg(err)}) — omitting it from the review context\\n`,\n );\n return null;\n }\n};\n\n// Decode row by row, dropping only the rows that don't validate (e.g. a deleted account's null login)\n// rather than letting one malformed row fail the whole channel the way an atomic `t.array` decode\n// would. null still propagates a failed fetch (rows === null); a bad row is silently skipped.\nconst decodeArrayOrNull = <A>(\n codec: t.Type<A>,\n rows: readonly unknown[] | null,\n): readonly A[] | null => {\n if (rows === null) return null;\n return rows.flatMap((row) => {\n const decoded = codec.decode(row);\n return decoded._tag === \"Right\" ? [decoded.right] : [];\n });\n};\n\n// The bot's own last comment — its embedded findings marker seeds the re-review draft (seed-draft).\nconst priorReviewFrom = (\n comments: readonly IssueComment[],\n botLogin: string,\n): { readonly id: number; readonly body: string | null } | null => {\n const byBot = comments.filter((c) => c.user.login === botLogin);\n const last = byBot[byBot.length - 1];\n return last ? { id: last.id, body: last.body } : null;\n};\n\n// The untrusted PR discussion staged for the review agent to TRIAGE as claims — so a re-review can\n// recognize a finding the author already answered without OBEYING the comment. Everyone but the\n// review bot (its own output is seeded back via prior_review), bounded to the most recent items per\n// channel with each body clipped so a long thread can't blow the agent's context; the workflow frames\n// these files as claims-to-verify, never as instructions.\nconst MAX_CONVERSATION_COMMENTS = 50;\n\n// The shared surrogate-safe clip (util.ts) at the shared body cap — one constant with render's\n// carried-field clip so the two caps cannot drift (issue #217 review r7).\nconst clip = (body: string): string => clipText(body, BODY_CLIP_CHARS);\n\n// Drop the review bot and empty bodies, keep the most recent MAX (logging when it caps), then project.\nconst boundedHuman = <\n A extends { readonly user: { readonly login: string }; readonly body: string | null },\n B,\n>(\n items: readonly A[],\n botLogin: string,\n label: string,\n project: (item: A & { readonly body: string }) => B,\n): readonly B[] => {\n const human = items.filter(\n (a): a is A & { readonly body: string } =>\n a.user.login !== botLogin && typeof a.body === \"string\" && a.body.trim() !== \"\",\n );\n const kept = human.slice(-MAX_CONVERSATION_COMMENTS);\n if (kept.length < human.length) {\n process.stderr.write(\n `Note: PR has ${String(human.length)} ${label} — feeding the review the most recent ${String(MAX_CONVERSATION_COMMENTS)}\\n`,\n );\n }\n return kept.map(project);\n};\n\nconst issueCommentsFrom = (comments: readonly IssueComment[], botLogin: string) =>\n boundedHuman(comments, botLogin, \"discussion comments\", (c) => ({\n author: c.user.login,\n author_association: c.author_association ?? null,\n created_at: c.created_at ?? null,\n body: clip(c.body),\n }));\n\nconst reviewCommentsFrom = (comments: readonly ReviewComment[], botLogin: string) =>\n boundedHuman(comments, botLogin, \"inline review comments\", (c) => ({\n author: c.user.login,\n author_association: c.author_association ?? null,\n created_at: c.created_at ?? null,\n path: c.path ?? null,\n line: c.line ?? null,\n body: clip(c.body),\n }));\n\nconst reviewsFrom = (reviews: readonly Review[], botLogin: string) =>\n boundedHuman(reviews, botLogin, \"review submissions\", (r) => ({\n author: r.user.login,\n author_association: r.author_association ?? null,\n submitted_at: r.submitted_at ?? null,\n state: r.state ?? null,\n body: clip(r.body),\n }));\n\n// Jobs-list failure is fatal; a per-log download failure degrades — logs are advisory, and partial\n// logs plus the diff beat a dead review. Returns how many landed: on the fast-fix route the logs are\n// the whole premise, so zero of them is worth saying out loud rather than leaving the agent to infer\n// it from an empty directory (issue #154).\n// A matrix build can fail in hundreds of jobs, and each log is a separate sequential API call whose\n// bytes land on disk before the review starts — uncapped, that turns a gather step with no timeout\n// into minutes of downloading for a route that exists to be fast. The first failures in run order are\n// kept because a matrix usually fails from one root, and the earliest job to hit it is the one whose\n// log still shows the original error rather than a cascade.\nconst MAX_STAGED_JOB_LOGS = 20;\n\nconst downloadFailingJobLogs = async (\n repo: string,\n runId: string,\n outDir: string,\n ghApi: GhApi,\n): Promise<{ readonly staged: number; readonly failing: number }> => {\n const rows = parseJsonl(\n await ghApi([`repos/${repo}/actions/runs/${runId}/jobs`, \"--paginate\", \"--jq\", JOBS_JQ]),\n );\n const decoded = t.array(JobCodec).decode(rows);\n if (decoded._tag === \"Left\") {\n throw new Error(`Jobs list for run ${runId} did not match the expected shape`);\n }\n const failing = decoded.right.filter((j) => j.conclusion === \"failure\");\n const selected = failing.slice(0, MAX_STAGED_JOB_LOGS);\n let staged = 0;\n for (const job of selected) {\n try {\n const log = await ghApi([`repos/${repo}/actions/jobs/${String(job.id)}/logs`]);\n // GitHub serves a \"no log available\" placeholder body when a job produced none (a killed\n // runner, no step output). A placeholder is NOT failure evidence: counting it as staged\n // would fire the all-staged steer and skip the unverified stamp on exactly the rounds that\n // must not present themselves as evidenced.\n if (log.trim() === \"no log available\" || log.trim() === \"\") {\n process.stderr.write(\n `Warning: job ${String(job.id)} has no log available (placeholder body) — not staged\n`,\n );\n continue;\n }\n writeFileSync(join(outDir, `job_${String(job.id)}.log`), log);\n staged += 1;\n } catch (err) {\n process.stderr.write(\n `Warning: failed to download logs for job ${String(job.id)}: ${errMsg(err)} — continuing with the logs retrieved so far\\n`,\n );\n }\n }\n // The failing jobs' identities ride along even when their log bodies cannot: a zero-logs mechanic\n // pass still knows WHICH jobs failed (name + conclusion), so its reproduction instruction has a\n // defined target instead of a bare count. A null name stays null — best-effort, never load-bearing.\n writeFileSync(\n join(outDir, \"failed_jobs.json\"),\n `${JSON.stringify(\n failing.map((j) => ({ name: j.name, conclusion: j.conclusion })),\n null,\n 2,\n )}\\n`,\n );\n if (failing.length > selected.length) {\n process.stderr.write(\n `::warning::${annotationSafe(`${String(failing.length)} failing job(s) in run ${runId}; staged ${String(staged)} of the first ${String(selected.length)} log(s) — the review does not see the rest`)}\\n`,\n );\n }\n if (staged === 0) {\n // stderr, like every other annotation here: this command's STDOUT is the step's $GITHUB_OUTPUT,\n // so a line written there would not render as an annotation and would corrupt the outputs.\n // ::warning:: rather than a plain line because this says the fast-fix route is about to reason\n // without its primary evidence source — the failing logs — which is the thing it exists to read.\n const reported =\n failing.length > 0\n ? `${String(failing.length)} failing job(s) reported`\n : \"no job concluded 'failure' (timeouts or cancellations)\";\n process.stderr.write(\n `::warning::${annotationSafe(\n `No failing-job logs could be staged for run ${runId} (${reported}) — the review must reproduce the failures itself${\n failing.length > 0 ? \" (the failing jobs are listed in failed_jobs.json)\" : \"\"\n }`,\n )}\\n`,\n );\n }\n return { staged, failing: failing.length };\n};\n\nexport const gather = async (\n input: GatherInput,\n ghApi: GhApi = runGhApi,\n gitRun: GitRun = runGit,\n readArtifact: ArtifactReader = ghArtifactReader,\n): Promise<GatherResult> => {\n const candidates = await fetchPrCandidates(input.repo, input.headSha, ghApi);\n const resolution = resolvePr(candidates, input.headBranch);\n if (resolution.kind === \"none\") {\n process.stderr.write(`No open PR for ${input.headSha} — nothing to review\\n`);\n return { kind: \"skip\" };\n }\n if (resolution.kind === \"not-open\") {\n process.stderr.write(\n `PR #${String(resolution.prNumber)} for ${input.headSha} is not open (state: ${resolution.state}) — nothing to review\\n`,\n );\n return { kind: \"skip\" };\n }\n const prNumber = resolution.prNumber;\n\n const meta = await fetchPrMeta(input.repo, prNumber, ghApi);\n\n const stacked = meta.base_ref !== input.defaultBranch;\n\n // pr.diff (base...head) is the review SCOPE — the PR's own change; its endpoint + git-diff fallback\n // are unchanged.\n const prDiff = await (async () => {\n const apiDiff = await fetchApiDiff(input.repo, prNumber, ghApi);\n if (apiDiff !== null && !(apiDiff.length === 0 && meta.changed_files > 0)) return apiDiff;\n process.stderr.write(\n `PR diff fetch failed or was empty for ${String(meta.changed_files)} changed files — falling back to git diff\\n`,\n );\n await gitRun([\"fetch\", \"origin\", input.headSha]);\n return gitRun([\"diff\", meta.base_sha, input.headSha]);\n })();\n\n // full.diff (default...head) is the surface a head checkout exposes over the trusted base — what\n // triage scans and what the checkout produces. Same as pr.diff for a normal PR (base === default);\n // a superset for a stacked one, so only then is a separate fetch needed. commits.json carries the\n // messages/authors a checked-out `git log` exposes, scanned by triage alongside the diff.\n const fullDiff = stacked\n ? await fetchFullDiff(input.repo, input.defaultBranch, input.headSha, ghApi, gitRun)\n : prDiff;\n const commits = await fetchCompareCommits(input.repo, input.defaultBranch, input.headSha, ghApi);\n\n writeFileSync(join(input.outDir, \"full.diff\"), fullDiff);\n writeFileSync(join(input.outDir, \"pr.diff\"), prDiff);\n writeFileSync(join(input.outDir, \"commits.json\"), JSON.stringify(commits));\n writeFileSync(\n join(input.outDir, \"pr_context.json\"),\n JSON.stringify({ title: meta.title, body: meta.body }),\n );\n\n // The three conversation fetches are independent — run them together rather than one after another.\n const [issueRows, reviewCommentRows, reviewRows] = await Promise.all([\n fetchJsonlRows(ghApi, `repos/${input.repo}/issues/${String(prNumber)}/comments`, COMMENT_JQ),\n fetchJsonlRows(\n ghApi,\n `repos/${input.repo}/pulls/${String(prNumber)}/comments`,\n REVIEW_COMMENT_JQ,\n ),\n fetchJsonlRows(ghApi, `repos/${input.repo}/pulls/${String(prNumber)}/reviews`, REVIEW_JQ),\n ]);\n const issueComments = decodeArrayOrNull(IssueCommentCodec, issueRows);\n const reviewComments = decodeArrayOrNull(ReviewCommentCodec, reviewCommentRows);\n const threadComments = decodeArrayOrNull(ThreadCommentCodec, reviewCommentRows);\n const reviews = decodeArrayOrNull(ReviewCodec, reviewRows);\n\n const prior = issueComments === null ? null : priorReviewFrom(issueComments, input.botLogin);\n writeFileSync(\n join(input.outDir, \"prior_review.json\"),\n prior === null ? \"null\" : JSON.stringify(prior),\n );\n // The prior round's findings document, RESOLVED here rather than by seed-draft. The sticky names an\n // artifact instead of carrying the document (issue #217), and fetching it needs the token — which\n // THIS step has and the agentic-review step deliberately does not: that step runs the jailed agent\n // over untrusted PR code, so handing it a repo token to read an artifact would be a bad trade. A\n // failed resolve stages null and the seed degrades to no prior context, exactly like a first round.\n // Two gates, because the seed chain is route-aware on both sides. THIS run must be a full review —\n // the workflow's mechanic branch invokes seed-draft with no --prior-findings at all, so a CI-fix\n // round following a completed review (the routine case that route exists for) would otherwise\n // download and unzip an artifact nothing is ever handed. And the PRIOR must be a full review, since\n // seed-draft discards a mechanic pass's findings: they are not the previous round's.\n const seedsFromPrior =\n input.conclusion === \"success\" &&\n prior !== null &&\n prior.body !== null &&\n isFullReviewAncestry(prior.body);\n const resolvedPrior = seedsFromPrior\n ? await resolvePriorFindings(prior.body, readArtifact)\n : null;\n // The staged file must always be valid JSON. The normalization is defensive against the\n // resolver's contract drifting — a future non-object resolve would make JSON.stringify return\n // undefined and throw in writeFileSync — but it also makes the invariant local to this write\n // rather than borrowed from resolvePriorFindings (issue #233 r4 + r5).\n const priorFindings =\n resolvedPrior !== null && typeof resolvedPrior === \"object\" ? resolvedPrior : null;\n writeFileSync(\n join(input.outDir, \"prior_findings.json\"),\n priorFindings === null ? \"null\" : JSON.stringify(priorFindings),\n );\n // The \"already answered\" registry (issue #151): the prior inline findings whose threads a human\n // reply answered — staged for seed-draft to deliver beside the prior context, so the next-round\n // agent sees what it must not re-raise verbatim. Best-effort like the conversation: a failed fetch\n // yields [] (the agent then relies on the conversation alone).\n const answered =\n threadComments === null ? [] : answeredRegistryFrom(threadComments, input.botLogin);\n writeFileSync(\n join(input.outDir, \"answered.json\"),\n JSON.stringify(answered.map(encodeAnsweredEntry)),\n );\n writeFileSync(\n join(input.outDir, \"pr_conversation.json\"),\n JSON.stringify({\n issue_comments:\n issueComments === null ? [] : issueCommentsFrom(issueComments, input.botLogin),\n review_comments:\n reviewComments === null ? [] : reviewCommentsFrom(reviewComments, input.botLogin),\n reviews: reviews === null ? [] : reviewsFrom(reviews, input.botLogin),\n }),\n );\n\n const jobLogs =\n input.conclusion === \"failure\"\n ? await downloadFailingJobLogs(input.repo, input.runId, input.outDir, ghApi)\n : { staged: 0, failing: 0 };\n\n return {\n kind: \"gathered\",\n pr: prNumber,\n conclusion: input.conclusion,\n diffSize: Buffer.byteLength(prDiff, \"utf8\"),\n stacked,\n baseSha: meta.base_sha,\n stagedJobLogs: jobLogs.staged,\n failingJobs: jobLogs.failing,\n };\n};\n","// Extraction ladder: recovers a schema-conforming candidate (findings or triage) from a native\n// agent-CLI envelope when structured-output enforcement is imperfect or absent. Security rationale:\n// a rung wins only on EXACTLY ONE distinct schema-validating candidate (fenced blocks deduped by\n// canonical value first), which defeats block-injection; disagreeing candidates are refused. Every\n// candidate must pass BOTH gates — ajv (shape + additionalProperties:false) and the registry's io-ts\n// codec (cross-field invariants ajv can't express, e.g. end_line >= start_line).\n\nimport { readFileOrNull, tryParseJson } from \"./util.js\";\nimport { resolve, schemaPathFor, defaultVersion } from \"./registry.js\";\nimport { validateAgainstSchema } from \"./validate.js\";\n\nexport type ExtractKind = \"findings\" | \"triage\";\n\nexport interface ExtractInput {\n readonly kind: ExtractKind;\n // findings only — a documented no-op for triage.\n readonly agentFilePath?: string;\n // Last valid draft snapshot, tried after agentFilePath and before the native envelope.\n readonly agentFileFallbackPath?: string;\n readonly native: unknown;\n}\n\nexport type LadderOutcome =\n | { readonly kind: \"ok\"; readonly version: string; readonly candidate: unknown }\n | { readonly kind: \"error-envelope\"; readonly detail: string }\n | { readonly kind: \"none\"; readonly detail: string }\n | { readonly kind: \"ambiguous\"; readonly detail: string };\n\ninterface NativeForExtraction {\n readonly result: unknown;\n readonly structuredOutput: unknown;\n readonly isError: unknown;\n readonly subtype: unknown;\n readonly apiErrorStatus: unknown;\n}\n\nconst fieldOf = (raw: unknown, key: string): unknown =>\n typeof raw === \"object\" && raw !== null && key in raw\n ? (raw as Record<string, unknown>)[key]\n : undefined;\n\nconst parseNativeForExtraction = (raw: unknown): NativeForExtraction => ({\n result: fieldOf(raw, \"result\"),\n structuredOutput: fieldOf(raw, \"structured_output\"),\n isError: fieldOf(raw, \"is_error\"),\n subtype: fieldOf(raw, \"subtype\"),\n apiErrorStatus: fieldOf(raw, \"api_error_status\"),\n});\n\nconst isNullish = (value: unknown): boolean => value === null || value === undefined;\n\nconst isErrorEnvelope = (native: NativeForExtraction): boolean =>\n native.isError === true ||\n (!isNullish(native.subtype) && native.subtype !== \"success\") ||\n !isNullish(native.apiErrorStatus);\n\nconst describeErrorEnvelope = (native: NativeForExtraction): string => {\n const parts: readonly string[] = [\n ...(native.isError === true ? [\"is_error=true\"] : []),\n ...(!isNullish(native.subtype) && native.subtype !== \"success\"\n ? [`subtype=${JSON.stringify(native.subtype)}`]\n : []),\n ...(!isNullish(native.apiErrorStatus)\n ? [`api_error_status=${JSON.stringify(native.apiErrorStatus)}`]\n : []),\n ];\n return `agent run did not complete successfully (${parts.join(\", \")})`;\n};\n\nexport const withDefaultSchemaVersion = (candidate: unknown): unknown =>\n typeof candidate === \"object\" &&\n candidate !== null &&\n !Array.isArray(candidate) &&\n !(\"schema_version\" in candidate)\n ? { ...candidate, schema_version: defaultVersion(\"findings\") }\n : candidate;\n\nconst normalizeCandidate = (kind: ExtractKind, candidate: unknown): unknown =>\n kind === \"findings\" ? withDefaultSchemaVersion(candidate) : candidate;\n\nconst candidateVersion = (kind: ExtractKind, candidate: unknown): string | undefined => {\n if (kind !== \"findings\") return undefined;\n const version = fieldOf(candidate, \"schema_version\");\n return typeof version === \"string\" ? version : undefined;\n};\n\nconst safeSchemaPathFor = (kind: ExtractKind, version: string | undefined): string | null => {\n try {\n return schemaPathFor(kind, version);\n } catch {\n return null;\n }\n};\n\ninterface GatedCandidate {\n readonly version: string;\n // Pre-registry-normalize (identical for alpha) — what the extract CLI prints, per the registry seam.\n readonly candidate: unknown;\n}\n\n// Sort keys recursively so two values differing only in key order canonicalize equal.\nconst canonicalize = (value: unknown): unknown =>\n Array.isArray(value)\n ? value.map(canonicalize)\n : value !== null && typeof value === \"object\"\n ? Object.fromEntries(\n Object.entries(value as Record<string, unknown>)\n .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))\n .map(([k, v]) => [k, canonicalize(v)]),\n )\n : value;\n\n// A model re-emitting its answer verbatim is benign, not a conflict; candidates differing in any\n// value stay distinct, so the injection defense (refusing a survivor among disagreeing candidates) holds.\nconst dedupCandidates = (candidates: readonly GatedCandidate[]): readonly GatedCandidate[] => {\n const seen = new Set<string>();\n return candidates.filter((c) => {\n const key = JSON.stringify(canonicalize(c.candidate));\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n};\n\n// Both gates: ajv (shape + injection defense) then the registry's io-ts codec (materialization +\n// cross-field invariants). Null when either rejects.\nconst gateCandidate = (kind: ExtractKind, rawCandidate: unknown): GatedCandidate | null => {\n const candidate = normalizeCandidate(kind, rawCandidate);\n const schemaPath = safeSchemaPathFor(kind, candidateVersion(kind, candidate));\n if (schemaPath === null) return null;\n if (!validateAgainstSchema(candidate, schemaPath).valid) return null;\n const resolution = resolve(kind, candidate);\n return resolution.kind === \"ok\" ? { version: resolution.version, candidate } : null;\n};\n\nconst candidateFromJsonText = (kind: ExtractKind, text: string | null): GatedCandidate | null => {\n if (text === null) return null;\n const parsed = tryParseJson(text);\n return parsed.ok ? gateCandidate(kind, parsed.value) : null;\n};\n\ninterface FenceScanState {\n readonly blocks: readonly string[];\n readonly openLength: number | null;\n readonly buffer: readonly string[];\n}\n\nconst FENCE_OPEN = /^\\s*(`{3,})/;\nconst FENCE_MARKER_ONLY = /^`+$/;\n\n// Line-based by design — no regex spans more than one line, so no catastrophic-backtracking surface.\nconst scanLine = (state: FenceScanState, line: string): FenceScanState => {\n if (state.openLength === null) {\n const opened = FENCE_OPEN.exec(line)?.[1]?.length;\n return opened !== undefined ? { blocks: state.blocks, openLength: opened, buffer: [] } : state;\n }\n const trimmed = line.trim();\n const closes = FENCE_MARKER_ONLY.test(trimmed) && trimmed.length >= state.openLength;\n return closes\n ? { blocks: [...state.blocks, state.buffer.join(\"\\n\")], openLength: null, buffer: [] }\n : { ...state, buffer: [...state.buffer, line] };\n};\n\nexport const scanFencedBlocks = (text: string): readonly string[] =>\n text.split(\"\\n\").reduce(scanLine, { blocks: [], openLength: null, buffer: [] }).blocks;\n\n// Operator-facing trace for stderr/logs (never the fail-closed reasons, which stay generic): e.g. a\n// null structured_output points at a CLI not enforcing --json-schema.\nexport const ladderFailureDiagnostics = (input: ExtractInput): string => {\n const native = parseNativeForExtraction(input.native);\n const preview = (s: string): string => {\n const flat = s.replace(/\\s+/g, \" \").trim();\n return flat.length > 200 ? `${flat.slice(0, 200)}…` : flat;\n };\n const lines: string[] = [];\n if (input.kind === \"findings\") {\n lines.push(\n input.agentFilePath === undefined\n ? \"agent-file rung: no --agent-file given\"\n : `agent-file rung: ${input.agentFilePath} did not validate (or was unreadable)`,\n );\n if (input.agentFileFallbackPath !== undefined)\n lines.push(\n `last-valid rung: ${input.agentFileFallbackPath} did not validate (or was absent)`,\n );\n }\n lines.push(\n isNullish(native.structuredOutput)\n ? \"structured_output rung: absent (null) — the CLI's --json-schema likely did not enforce\"\n : \"structured_output rung: present but did not validate against the schema\",\n );\n lines.push(\n typeof native.result === \"string\"\n ? `result rung: ${String(native.result.length)} chars, ${String(scanFencedBlocks(native.result).length)} fenced JSON block(s), none validated; preview: ${preview(native.result)}`\n : \"result rung: absent or not a string\",\n );\n return lines.join(\"\\n\");\n};\n\nexport const describeLadderFailure = (outcome: Exclude<LadderOutcome, { kind: \"ok\" }>): string => {\n switch (outcome.kind) {\n case \"error-envelope\":\n return `review did not complete: ${outcome.detail}`;\n case \"none\":\n return `could not recover a validating candidate: ${outcome.detail}`;\n case \"ambiguous\":\n return `ambiguous candidates: ${outcome.detail}`;\n }\n};\n\nconst okOutcome = (gated: GatedCandidate): LadderOutcome => ({\n kind: \"ok\",\n version: gated.version,\n candidate: gated.candidate,\n});\n\n// Pure aside from an optional --agent-file read.\nexport const extractStructured = (input: ExtractInput): LadderOutcome => {\n const native = parseNativeForExtraction(input.native);\n\n // The agent-file and its last-valid snapshot are self-validated deliverables written OUTSIDE the\n // worktree (a PR can't plant them) and checkpointed by us during the run, so they outrank an error\n // envelope: a run that errored (max-turns, a captured API error) after producing a valid draft\n // should still post it, not \"did not complete\". The error-envelope short-circuit below still guards\n // the less-trusted native rungs (structured_output/result).\n if (input.kind === \"findings\") {\n for (const path of [input.agentFilePath, input.agentFileFallbackPath]) {\n if (path === undefined) continue;\n const fromFile = candidateFromJsonText(input.kind, readFileOrNull(path));\n if (fromFile) return okOutcome(fromFile);\n }\n }\n\n if (isErrorEnvelope(native)) {\n return { kind: \"error-envelope\", detail: describeErrorEnvelope(native) };\n }\n\n if (native.structuredOutput !== undefined) {\n const fromStructured = gateCandidate(input.kind, native.structuredOutput);\n if (fromStructured) return okOutcome(fromStructured);\n }\n\n if (typeof native.result === \"string\") {\n const fromResult = candidateFromJsonText(input.kind, native.result.trim());\n if (fromResult) return okOutcome(fromResult);\n\n const fencedCandidates = dedupCandidates(\n scanFencedBlocks(native.result)\n .map((block) => candidateFromJsonText(input.kind, block))\n .filter((gated): gated is GatedCandidate => gated !== null),\n );\n\n const [survivor, ...rest] = fencedCandidates;\n if (survivor !== undefined && rest.length === 0) return okOutcome(survivor);\n if (survivor !== undefined) {\n return {\n kind: \"ambiguous\",\n detail: `${String(fencedCandidates.length)} distinct fenced JSON blocks each validate against the ${input.kind} schema — refusing to pick one`,\n };\n }\n }\n\n const fallbackRung = input.agentFileFallbackPath ? \", last-valid snapshot\" : \"\";\n return {\n kind: \"none\",\n detail: `no --agent-file${fallbackRung}, structured_output, JSON result, or fenced block validated against the ${input.kind} schema`,\n };\n};\n","// Maps a coding-agent CLI's native result envelope onto the abstract envelope. An absent native\n// (undefined/null — the caller couldn't read/parse it, e.g. a wall-clock kill hit `claude -p`\n// mid-flush) still recovers findings from --agent-file and refills telemetry from the transcript\n// fallback; a present-but-wrong-shaped native is a Left. Never throws.\n\nimport * as t from \"io-ts\";\nimport type { Either } from \"fp-ts/Either\";\nimport { resolve } from \"./registry.js\";\nimport { extractStructured, describeLadderFailure } from \"./extract.js\";\nimport { DEFAULT_SCHEMA_VERSION, incompleteFindings } from \"./schema.js\";\nimport type { Findings, ModelUsageEntry, ResultEnvelope } from \"./schema.js\";\nimport { modelIdentity } from \"./util.js\";\n\n// No value-level fp-ts import: a bare \"fp-ts/Either\" subpath import breaks under strict Node ESM\n// (fp-ts ships no \"exports\" map), so Either values are plain tagged literals, as in validate.ts.\nconst left = <A>(message: string): Either<string, A> => ({ _tag: \"Left\", left: message });\nconst right = <A>(value: A): Either<string, A> => ({ _tag: \"Right\", right: value });\n\nexport type AdapterName = \"claude-code\";\n\nexport const isAdapterName = (name: string): name is AdapterName => name === \"claude-code\";\n\nconst ClaudeCodeModelUsageEntryCodec = t.intersection([\n t.type({\n inputTokens: t.number,\n outputTokens: t.number,\n }),\n t.partial({\n cacheReadInputTokens: t.number,\n cacheCreationInputTokens: t.number,\n costUSD: t.number,\n }),\n]);\n\nexport const ClaudeCodeEnvelopeCodec = t.intersection([\n t.type({\n modelUsage: t.record(t.string, ClaudeCodeModelUsageEntryCodec),\n num_turns: t.number,\n duration_ms: t.number,\n }),\n t.partial({\n total_cost_usd: t.union([t.number, t.null]),\n structured_output: t.unknown,\n }),\n]);\n\ntype ClaudeCodeEnvelope = t.TypeOf<typeof ClaudeCodeEnvelopeCodec>;\n\nconst sumUsage = (into: ModelUsageEntry, entry: ModelUsageEntry): ModelUsageEntry => ({\n ...into,\n input_tokens: into.input_tokens + entry.input_tokens,\n output_tokens: into.output_tokens + entry.output_tokens,\n ...(into.cache_read_tokens !== undefined || entry.cache_read_tokens !== undefined\n ? { cache_read_tokens: (into.cache_read_tokens ?? 0) + (entry.cache_read_tokens ?? 0) }\n : {}),\n ...(into.cache_write_tokens !== undefined || entry.cache_write_tokens !== undefined\n ? { cache_write_tokens: (into.cache_write_tokens ?? 0) + (entry.cache_write_tokens ?? 0) }\n : {}),\n});\n\n// The agent keys modelUsage by the CONFIGURED model id, so it carries any context-window suffix the\n// caller declared. Keying the fold by the model's identity (see modelIdentity) both canonicalizes it\n// and folds together the rows a mixed configuration splits, in one pass; order follows first\n// appearance, as it did when this was a plain map.\nconst mapModelUsage = (modelUsage: ClaudeCodeEnvelope[\"modelUsage\"]): ModelUsageEntry[] => [\n ...Object.entries(modelUsage)\n .reduce<Map<string, ModelUsageEntry>>((byModel, [configuredModelId, entry]) => {\n const model = modelIdentity(configuredModelId);\n const mapped: ModelUsageEntry = {\n model,\n input_tokens: entry.inputTokens,\n output_tokens: entry.outputTokens,\n ...(entry.cacheReadInputTokens !== undefined\n ? { cache_read_tokens: entry.cacheReadInputTokens }\n : {}),\n ...(entry.cacheCreationInputTokens !== undefined\n ? { cache_write_tokens: entry.cacheCreationInputTokens }\n : {}),\n };\n const prior = byModel.get(model);\n return byModel.set(model, prior === undefined ? mapped : sumUsage(prior, mapped));\n }, new Map())\n .values(),\n];\n\nexport interface TranscriptTelemetry {\n readonly models: readonly ModelUsageEntry[];\n readonly turns: number;\n readonly durationMs: number;\n}\n\n// transcriptFallback is a THUNK — the read can be megabytes on a large fan-out, so callers pass it\n// only when a transcript path was given.\nexport interface RunMeta {\n readonly route?: string;\n readonly effort?: string;\n readonly transcriptFallback?: () => TranscriptTelemetry;\n // Last valid draft snapshot, recovered when the live agent-file no longer validates (e.g. a\n // wall-kill truncated it).\n readonly agentFileFallbackPath?: string;\n // The agent-file still holds the pipeline's pre-seed SENTINEL (the agent died without writing a\n // review), decided by the caller from the file's content — the sentinel never validates, so no\n // rung can recover it as a review (issue #127). The flag only refines the \"did not complete\"\n // notice's message; the ladder still runs, so a real review living in the native envelope is\n // recovered rather than discarded with the seed.\n readonly seedUnrevised?: boolean;\n}\n\n// Every ladder outcome maps onto a findings result, never a fatal one — a findings miss must not\n// drop telemetry.\ntype FindingsOutcome =\n | { readonly kind: \"ok\"; readonly version: string; readonly findings: Findings }\n | { readonly kind: \"telemetry-only\"; readonly reason: string };\n\nconst findingsOutcome = (\n native: unknown,\n agentFilePath: string | undefined,\n agentFileFallbackPath: string | undefined,\n): FindingsOutcome => {\n const ladder = extractStructured({\n kind: \"findings\",\n native,\n agentFilePath,\n agentFileFallbackPath,\n });\n if (ladder.kind !== \"ok\")\n return { kind: \"telemetry-only\", reason: describeLadderFailure(ladder) };\n // Re-resolving materializes the typed, normalized value the ladder deliberately didn't keep.\n const resolution = resolve(\"findings\", ladder.candidate);\n return resolution.kind === \"ok\"\n ? { kind: \"ok\", version: resolution.version, findings: resolution.value }\n : {\n kind: \"telemetry-only\",\n reason:\n \"internal error: the extraction ladder validated a candidate the registry then rejected\",\n };\n};\n\ninterface Telemetry {\n readonly models: ModelUsageEntry[];\n readonly turns: number;\n readonly duration_ms: number;\n readonly vendor_cost_usd: number | null;\n readonly route?: string;\n readonly effort?: string;\n}\n\nconst withMeta = (base: Omit<Telemetry, \"route\" | \"effort\">, meta: RunMeta): Telemetry => ({\n ...base,\n ...(meta.route ? { route: meta.route } : {}),\n ...(meta.effort ? { effort: meta.effort } : {}),\n});\n\n// Each field from whichever source is authoritative for it — NOT always the transcript:\n// - Wall + turns: the transcript when available. The native envelope reports only the main agent's\n// active time/turns and wildly under-reports a fan-out (a 12-subagent ~12-min run reads as \"5\n// turns, 42s\"); the transcript tree spans the whole session.\n// - Per-model usage: native-authoritative when present. Summing the transcript's per-message usage\n// under-counts output badly (measured ~5.7× low), so DO NOT \"simplify\" this to always-transcript;\n// the transcript refills usage ONLY when the native has none (a `timeout` kill left it empty).\n// The vendor's own cost figure is carried through from the native whenever it had one.\nconst resolveTelemetry = (\n native: {\n models: ModelUsageEntry[];\n turns: number;\n durationMs: number;\n vendorCostUsd: number | null;\n },\n meta: RunMeta,\n): Telemetry => {\n // A thunk that throws degrades to \"no transcript\" (the native's own figures) — never fails adapt.\n const fb = ((): TranscriptTelemetry | undefined => {\n try {\n return meta.transcriptFallback?.();\n } catch {\n return undefined;\n }\n })();\n // Wall + turns move together — never one source for turns and another for the wall.\n const wallTurns =\n fb !== undefined && fb.durationMs > 0\n ? { turns: fb.turns, duration_ms: fb.durationMs }\n : { turns: native.turns, duration_ms: native.durationMs };\n return withMeta(\n {\n models: native.models.length > 0 ? native.models : fb ? [...fb.models] : native.models,\n ...wallTurns,\n vendor_cost_usd: native.vendorCostUsd,\n },\n meta,\n );\n};\n\nconst nativeTelemetry = (native: ClaudeCodeEnvelope, meta: RunMeta): Telemetry =>\n resolveTelemetry(\n {\n models: mapModelUsage(native.modelUsage),\n turns: native.num_turns,\n durationMs: native.duration_ms,\n vendorCostUsd: native.total_cost_usd ?? null,\n },\n meta,\n );\n\n// Native absent/unreadable (a wall-clock kill can leave no parseable envelope): the transcript\n// fallback refills real spend when present, else zeros. The findings ladder still runs (its\n// --agent-file rung needs no native), so a checkpointed $DRAFT survives the cutoff.\nconst absentTelemetry = (meta: RunMeta): Telemetry =>\n resolveTelemetry({ models: [], turns: 0, durationMs: 0, vendorCostUsd: null }, meta);\n\n// A ladder miss becomes a \"did not complete\" notice, never a discarded envelope.\nconst buildEnvelope = (\n telemetry: Telemetry,\n native: unknown,\n agentFilePath: string | undefined,\n agentFileFallbackPath: string | undefined,\n seedUnrevised: boolean,\n): ResultEnvelope => {\n // The sentinel never validates, so the ladder cannot recover the pre-seed from the agent-file or\n // last-valid rungs — but it still runs: a REAL review the agent produced in the native envelope\n // (structured_output/result) is recovered, not discarded with the seed. Only the miss is\n // re-worded: the untouched sentinel names the cause precisely (issue #127).\n // The run's completion instant (issue #170), stamped once here so cost recomputation prices a\n // time-slotted model deterministically at the run's UTC time rather than at each command's wall clock.\n const generated_at = new Date().toISOString();\n const outcome = findingsOutcome(native, agentFilePath, agentFileFallbackPath);\n switch (outcome.kind) {\n case \"ok\":\n return {\n schema_version: outcome.version,\n findings: outcome.findings,\n generated_at,\n ...telemetry,\n };\n case \"telemetry-only\": {\n const reason = seedUnrevised\n ? \"the review agent did not write a review (its draft is still the pre-seeded sentinel)\"\n : outcome.reason;\n return {\n schema_version: DEFAULT_SCHEMA_VERSION,\n findings: incompleteFindings(`### ⚠️ Review did not complete\\n\\n${reason}`),\n incomplete: true,\n generated_at,\n ...telemetry,\n };\n }\n }\n};\n\n// native undefined/null ⇒ the caller couldn't read/parse the envelope: emit a no-telemetry envelope\n// and still recover findings from --agent-file, rather than failing the run. A present but\n// wrong-shaped native is a Left (a real adapter mismatch).\nexport const adapt = (\n adapterName: AdapterName,\n native: unknown,\n agentFilePath?: string,\n meta: RunMeta = {},\n): Either<string, ResultEnvelope> => {\n switch (adapterName) {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- exhaustive by design; AdapterName grows (e.g. \"opencode\") without collapsing this switch to an if\n case \"claude-code\": {\n if (native === undefined || native === null)\n return right(\n buildEnvelope(\n absentTelemetry(meta),\n undefined,\n agentFilePath,\n meta.agentFileFallbackPath,\n meta.seedUnrevised === true,\n ),\n );\n const decoded = ClaudeCodeEnvelopeCodec.decode(native);\n if (decoded._tag === \"Left\")\n return left(\"native envelope does not match the Claude Code output shape\");\n return right(\n buildEnvelope(\n nativeTelemetry(decoded.right, meta),\n native,\n agentFilePath,\n meta.agentFileFallbackPath,\n meta.seedUnrevised === true,\n ),\n );\n }\n }\n};\n","// The review agent's whole hook discipline as one --settings file (data, not shell): the Stop\n// deliverable gate + the two budget hooks (one self-dispatching command wired to both tool events).\n\nimport { defaultHookCommand } from \"./stop-gate.js\";\nimport { budgetHookCommand } from \"./budget.js\";\n\ninterface CommandHook {\n readonly type: \"command\";\n readonly command: string;\n}\ninterface HookEntry {\n readonly hooks: readonly CommandHook[];\n}\n\n// PreToolUse/PostToolBatch carry no matcher — they run for every tool; the CLI decides per tool_name.\nexport interface ReviewHookSettings {\n readonly hooks: {\n readonly Stop: readonly HookEntry[];\n readonly PreToolUse: readonly HookEntry[];\n readonly PostToolBatch: readonly HookEntry[];\n };\n}\n\nexport interface ComposeSettingsOptions {\n readonly draftPath: string;\n readonly stop: {\n readonly kind?: string;\n readonly schema?: string;\n readonly schemaVersion?: string;\n readonly maxNudges?: string;\n readonly counter?: string;\n };\n readonly budget: {\n readonly budgetUsd?: string;\n readonly wall?: string;\n readonly prices?: string;\n readonly reserveFrac?: string;\n readonly reserveGrowth?: string;\n readonly reserveUsd?: string;\n readonly reserveWall?: string;\n };\n}\n\n// The budget command self-dispatches on the stdin event, so it is built once and wired to both.\nexport const composeReviewSettings = (opts: ComposeSettingsOptions): ReviewHookSettings => {\n const budgetCommand = budgetHookCommand(opts.draftPath, opts.budget);\n return {\n hooks: {\n Stop: [\n { hooks: [{ type: \"command\", command: defaultHookCommand(opts.draftPath, opts.stop) }] },\n ],\n PreToolUse: [{ hooks: [{ type: \"command\", command: budgetCommand }] }],\n PostToolBatch: [{ hooks: [{ type: \"command\", command: budgetCommand }] }],\n },\n };\n};\n","// The untrusted review agent's network jail as one sandbox-runtime (`srt`) settings file (data, not\n// shell). The allowlist is the model endpoint the CLI actually dials plus the GitHub API/host and any\n// consumer-supplied hosts; the host-side proxy denies everything else. Filesystem isolation is off —\n// the threat this closes is network exfil of the burner key, not the throwaway runner's disk — so the\n// jail confines only egress while the agent still reads the worktree and writes its draft freely.\n\nexport interface SandboxConfig {\n readonly network: {\n readonly allowedDomains: readonly string[];\n readonly deniedDomains: readonly string[];\n };\n readonly filesystem: {\n readonly allowRead: readonly string[];\n readonly denyRead: readonly string[];\n readonly allowWrite: readonly string[];\n readonly denyWrite: readonly string[];\n };\n}\n\n// GitHub hosts the agent may reach when it shells out to gh/git during a review.\nconst GITHUB_HOSTS = [\"api.github.com\", \"github.com\"] as const;\n\n// The model host from api_base_url (ANTHROPIC_BASE_URL) — the single source of truth for the endpoint\n// the CLI dials, rather than a hardcoded vendor. Bare hostname (no scheme/port/path) to match the\n// proxy's hostname rule. Throws rather than yield an empty entry that would deny the model itself.\nexport const deriveModelHost = (apiBaseUrl: string): string => {\n const host = URL.canParse(apiBaseUrl) ? new URL(apiBaseUrl).hostname : \"\";\n if (host === \"\") {\n throw new Error(\n `could not derive the model host from api_base_url ${JSON.stringify(apiBaseUrl)} — expected a URL like https://api.deepseek.com/anthropic`,\n );\n }\n return host;\n};\n\n// Built-in model-provider host suffixes the derived allowlist entry is expected to match. The jail\n// auto-derives its sole egress allowlist from api_base_url, so a typo'd or stale value now fails OPEN —\n// it dials, and hands MODEL_API_KEY to, whatever host that variable names (the old fixed, PR-reviewed\n// allowlist failed CLOSED instead). A derived host outside these providers (and any consumer-declared\n// host) is warned about loudly by the `sandbox-config` command, or rejected under `--strict-host`.\nconst KNOWN_MODEL_HOST_SUFFIXES = [\"anthropic.com\", \"deepseek.com\"] as const;\n\n// True when host is a SUBDOMAIN of a built-in provider (the model API always lives on a subdomain like\n// api.*, so the bare registrable domain is itself treated as a typo — e.g. a dropped \"api.\" — and the\n// `.`-prefixed suffix keeps the boundary honest, so notanthropic.com and api.anthropic.com.evil.com are\n// both unknown), or an EXACT match for a consumer-declared host. A consumer on another provider declares\n// their host so it passes while a typo of it (a different exact string) does not. Both sides are\n// normalized (lowercased, trailing FQDN dot dropped) so a case/dot variant of a declared host still\n// matches — deriveModelHost returns a URL-parser-lowercased hostname while a declared token is as typed.\nexport const isKnownModelHost = (host: string, declared: readonly string[] = []): boolean => {\n const normalize = (h: string): string => h.replace(/\\.$/, \"\").toLowerCase();\n const target = normalize(host);\n return (\n declared.some((d) => normalize(d) === target) ||\n KNOWN_MODEL_HOST_SUFFIXES.some((suffix) => target.endsWith(`.${suffix}`))\n );\n};\n\n// The consumer's extra_endpoints: the same whitespace-separated host[:port] list they already pass to\n// harden-runner. Ports are dropped — the proxy matches on hostname (the only form validated on the\n// runner), and for HTTPS-only egress a port scope adds nothing.\nexport const parseExtraEndpoints = (extra: string): readonly string[] =>\n extra\n .split(/\\s+/)\n .map((token) => token.replace(/:\\d+$/, \"\"))\n .filter((token) => token.length > 0);\n\nexport const buildSandboxConfig = (opts: {\n readonly apiBaseUrl: string;\n readonly extra?: string;\n}): SandboxConfig => ({\n network: {\n allowedDomains: [\n ...new Set([\n deriveModelHost(opts.apiBaseUrl),\n ...GITHUB_HOSTS,\n ...parseExtraEndpoints(opts.extra ?? \"\"),\n ]),\n ],\n deniedDomains: [],\n },\n filesystem: { allowRead: [], denyRead: [], allowWrite: [\"/\"], denyWrite: [] },\n});\n","// The `scope` workflow input — the languages/inputs a project accepts — surfaced to the review agent\n// so it can triage \"is this input a program the project accepts?\" BEFORE assigning severities (issue\n// #139). Pure parse + grammar; the CLI's `check-scope` command is the only caller, so the grammar the\n// prompt is built from and the grammar the tests pin are the same code.\n\nimport { UNSAFE_IN_SUMMARY } from \"./notice.js\";\n\n// A scope value is spliced into the review agent's system prompt, so the characters that break prompt\n// structure are rejected — the same render-safety denylist notice.ts uses for summary text (newline/\n// carriage-return start a new block, a backtick closes a code span, `<`/`>` close an HTML comment, `|`\n// breaks a markdown table). The value is trusted consumer config, but a malformed splice would silently\n// corrupt the instruction. Everything else printable and structure-safe is accepted (C++, C#, C/C++,\n// Objective-C). A multi-word name is not a unit here — whitespace separates tokens, so spell a\n// multi-word name with a dash (e.g. \"visual-basic\") or list its words separately.\n\nexport type ScopeParse =\n // Empty/whitespace — no declared scope; the reviewer infers it from the README's first paragraph.\n | { readonly kind: \"absent\" }\n | { readonly kind: \"ok\"; readonly languages: readonly string[] }\n // Malformed — the CLI fails loudly so a config typo surfaces, never a corrupted prompt.\n | { readonly kind: \"invalid\"; readonly reason: string };\n\n// Whitespace, commas, and semicolons are interchangeable separators (\"C C++\", \"c, c++\", \"python; rust\").\n// The separator consumes surrounding whitespace, so a split token carries none (no per-token trim).\nconst SCOPE_SEPARATOR_RE = /[\\s,;]+/;\n\nexport const parseScope = (raw: string | undefined): ScopeParse => {\n const trimmed = raw?.trim();\n if (trimmed === undefined || trimmed === \"\") return { kind: \"absent\" };\n if (UNSAFE_IN_SUMMARY.test(trimmed)) {\n return {\n kind: \"invalid\",\n reason:\n 'scope contains a character (newline, carriage return, backtick, \"<\", \">\", or \"|\") that would corrupt the review prompt — use plain language names/tags',\n };\n }\n // De-duplicate preserving first-seen order; a value that was only separators (\" , ; \") declares\n // nothing, so it reads as absent rather than an empty scope.\n const languages = Array.from(new Set(trimmed.split(SCOPE_SEPARATOR_RE).filter((t) => t !== \"\")));\n return languages.length === 0 ? { kind: \"absent\" } : { kind: \"ok\", languages };\n};\n","#!/usr/bin/env node\n// CLI entry point — the citty subcommands wired in `main` at the bottom.\n\n/* eslint-disable @typescript-eslint/require-await */\n// citty requires async run() even when the body has no explicit await\n\nimport { defineCommand, runMain } from \"citty\";\nimport { copyFileSync, readFileSync, statSync, unlinkSync, writeFileSync } from \"node:fs\";\nimport { randomBytes } from \"node:crypto\";\nimport { resolve } from \"node:path\";\nimport type { Either } from \"fp-ts/Either\";\nimport { render, isConvergenceRound, isReviewVerdict } from \"./render.js\";\nimport { buildInlineComments, renderStraysSection } from \"./inline.js\";\nimport { computeCost, costAxisAnnouncement, parseInstant, warnStalePrices } from \"./cost.js\";\nimport { readTranscriptTree, sumTranscriptUsage } from \"./transcript.js\";\nimport {\n evaluateBudgetHook,\n parseWallMs,\n parseFraction,\n parseEpochSecMs,\n anchoredElapsedMs,\n deadlineEpochSec,\n mainHasWrittenDraft,\n isSeedSentinel,\n SEED_SENTINEL,\n priorContextPath,\n priorAnswersPath,\n priorSuppressedPath,\n lastValidPath,\n costAxisDisengagedPath,\n isSubagentHookInput,\n DEFAULT_RESERVE,\n DEADLINE_ENV,\n} from \"./budget.js\";\nimport { decodeAnsweredEntry, isAnsweredDrop, type StagedAnsweredEntry } from \"./answered.js\";\nimport { validateAgainstSchema, unsafeUnwrap } from \"./validate.js\";\nimport { formatUtc } from \"./format.js\";\nimport {\n ResultEnvelopeCodec,\n FindingsCodec,\n PriceMapCodec,\n ScopeMetastasisCodec,\n TestSummaryCodec,\n isIncompleteFindings,\n RECOVERABLE_OPTIONAL_FIELDS,\n DEFAULT_SCHEMA_VERSION,\n anchoredSchemaVersionPattern,\n resolveFindingId,\n} from \"./schema.js\";\nimport type { Triage, Finding, Findings, PriceMap } from \"./schema.js\";\nimport {\n buildConvergence,\n computeScopeMetastasis,\n SURFACE_SCHEMA_VERSION,\n isBelowVisibilityFloor,\n isFullReviewAncestry,\n parseReviewedSha,\n priorTrajectory,\n priorBelowFloorNits,\n stripSurfaceFields,\n parseFindingsMarker,\n} from \"./surface.js\";\nimport {\n buildNoticeEnvelope,\n buildUnknownNoticeEnvelope,\n isNoticeKind,\n parseAgentAllowlist,\n NOTICE_KINDS,\n} from \"./notice.js\";\nimport { announce, loadClocDiff, post, reportIncomplete } from \"./post.js\";\nimport { type CheckIntent, checkRun } from \"./checkrun.js\";\nimport { parseCommand, renderCommandOutputs, safeHeredocDelim } from \"./command.js\";\nimport { react, isReaction, REACTIONS } from \"./react.js\";\nimport type { Reaction } from \"./react.js\";\nimport { awaitCiConclusion, renderCiOutputs } from \"./ci.js\";\nimport { gather, renderOutputs } from \"./gather.js\";\nimport { adapt, isAdapterName } from \"./adapt.js\";\nimport type { AdapterName, TranscriptTelemetry } from \"./adapt.js\";\nimport { extractStructured, describeLadderFailure, ladderFailureDiagnostics } from \"./extract.js\";\nimport type { ExtractKind, LadderOutcome } from \"./extract.js\";\nimport {\n schemaPathFor,\n declaredVersion,\n resolveTolerantFindings,\n defaultVersion,\n} from \"./registry.js\";\nimport type { SchemaKind } from \"./registry.js\";\nimport { validatePatch } from \"./patch.js\";\nimport {\n decideGate,\n draftState,\n readNudges,\n bumpNudges,\n defaultHookCommand,\n stopHookSettings,\n} from \"./stop-gate.js\";\nimport { composeReviewSettings } from \"./settings.js\";\nimport {\n buildSandboxConfig,\n deriveModelHost,\n isKnownModelHost,\n parseExtraEndpoints,\n} from \"./sandbox.js\";\nimport { parseScope } from \"./scope.js\";\nimport { annotationSafe, asRecord, errMsg, readFileOrNull, tryParseJson } from \"./util.js\";\n\n// The seed's upcast (the registry's resolveTolerantFindings — the ONE place the migration policy\n// lives): the ajv gate then validates the UPCAST value, never the raw doc: validating the raw legacy\n// doc against the 0.10 schema would reject every pre-0.10 prior and seed the sentinel-only cold\n// re-review the migration exists to prevent.\nconst resolvedPriorValue = resolveTolerantFindings;\n\nconst readJSON = (path: string): unknown => {\n try {\n return JSON.parse(readFileSync(resolve(path), \"utf-8\")) as unknown;\n } catch (err) {\n return fail(`Cannot read ${path}: ${errMsg(err)}`);\n }\n};\n\nconst fail = (msg: string): never => {\n process.stderr.write(`${msg}\\n`);\n process.exit(1);\n};\n\n/** Tolerant `readJSON`: returns `undefined` (never exits) when the file is unreadable, empty, or not\n * valid JSON, naming the specific cause on stderr. Used only for `adapt`'s native envelope, which a\n * wall-clock kill can leave empty/truncated — `adapt` then degrades to no telemetry rather than\n * crashing the review step. */\nconst readJSONOrAbsent = (path: string): unknown => {\n const read = ((): { readonly text: string } | { readonly error: string } => {\n try {\n return { text: readFileSync(resolve(path), \"utf-8\") };\n } catch (err) {\n return { error: errMsg(err) };\n }\n })();\n if (\"error\" in read) {\n process.stderr.write(\n `code-review: native envelope ${path} could not be read (${read.error}) — proceeding with no native telemetry\\n`,\n );\n return undefined;\n }\n if (read.text.trim() === \"\") {\n process.stderr.write(\n `code-review: native envelope ${path} is empty — proceeding with no native telemetry\\n`,\n );\n return undefined;\n }\n try {\n return JSON.parse(read.text) as unknown;\n } catch (err) {\n process.stderr.write(\n `code-review: native envelope ${path} is not valid JSON (${errMsg(err)}) — proceeding with no native telemetry\\n`,\n );\n return undefined;\n }\n};\n\n// The optional sandbox config a notice names its allowlist from. A MISSING/unreadable file is the\n// normal early-failure case (the jail is set up after triage), so it stays silent and is treated as\n// absent. A file that is PRESENT but unparseable is the diagnostic case this feature exists for (a\n// truncated or agent-tampered config), so it warns rather than vanishing. Either way ⇒ undefined, and\n// the notice omits the allowlist rather than crashing the assemble step.\nconst readSandboxConfigForNotice = (path: string): unknown => {\n const text = readFileOrNull(resolve(path));\n if (text === null) return undefined;\n const parsed = tryParseJson(text);\n if (!parsed.ok) {\n process.stderr.write(\n `::warning::${annotationSafe(`code-review notice: ${path} is present but not valid JSON — omitting the agent allowlist from the notice`)}\\n`,\n );\n return undefined;\n }\n return parsed.value;\n};\n\nconst readStdinJSON = (): unknown => {\n if (process.stdin.isTTY) return null;\n const raw = ((): string => {\n try {\n return readFileSync(0, \"utf-8\");\n } catch {\n return \"\";\n }\n })();\n if (raw.trim() === \"\") return null;\n const parsed = tryParseJson(raw);\n return parsed.ok ? parsed.value : null;\n};\n\nconst decode = <A>(either: Either<unknown, A>, label: string): A => {\n try {\n return unsafeUnwrap(either);\n } catch {\n return fail(`${label} does not match expected shape`);\n }\n};\n\n/** Unwrap an adapter's Either, surfacing its own message rather than a generic one. */\nconst unwrapAdapt = <A>(either: Either<string, A>): A => {\n try {\n if (either._tag === \"Left\") throw new Error(either.left);\n return either.right;\n } catch (err) {\n return fail(errMsg(err));\n }\n};\n\n/** Telemetry from a session transcript tree (main + subagents) for the true wall + turns the native\n * envelope under-reports, and for per-model usage when the native envelope is empty. A\n * missing/unreadable transcript yields empty models + a zero span, which `adapt` treats as \"no\n * transcript\". */\nconst transcriptFallbackFrom = (path: string): TranscriptTelemetry => {\n const tree = readTranscriptTree(resolve(path));\n if (tree.missing)\n process.stderr.write(\n `code-review adapt: transcript ${path} is unreadable — no telemetry fallback\\n`,\n );\n const usage = sumTranscriptUsage(tree.entries);\n return { models: usage.models, turns: usage.turns, durationMs: usage.durationMs };\n};\n\n/** Resolve a path bundled with the package (schema/, templates/) — same pattern as validate's default schema. */\nconst bundledPath = (...segments: string[]): string =>\n resolve(import.meta.dirname, \"..\", ...segments);\n\n// The repo's single version reader — the CLI's --version print and the copy-paste drift guard\n// (src/version-pins.test.ts) must model \"the repo's version\" identically.\nexport const readPackageVersion = (): string =>\n (JSON.parse(readFileSync(bundledPath(\"package.json\"), \"utf-8\")) as { version: string }).version;\n\nconst packageVersion = readPackageVersion();\n\nconst resolveTemplatePath = (templateArg: string | undefined): string =>\n templateArg ? resolve(templateArg) : bundledPath(\"templates\", \"comment.eta\");\n\nconst resolveInlineTemplatePath = (templateArg: string | undefined): string =>\n templateArg ? resolve(templateArg) : bundledPath(\"templates\", \"inline.eta\");\n\n// `provided` = a real caller map; `absent` = the bundled all-zero example. The render layer is told\n// which, so an absent map reports cost as N/A, never a false $0.00.\ntype PriceResolution =\n | { readonly kind: \"provided\"; readonly path: string }\n | { readonly kind: \"absent\"; readonly path: string };\n\nconst resolvePrices = (pricesArg: string | undefined): PriceResolution => {\n if (pricesArg) return { kind: \"provided\", path: resolve(pricesArg) };\n process.stderr.write(\n \"code-review: no --prices given — cost will be reported as N/A (no price map to recompute from)\\n\",\n );\n return { kind: \"absent\", path: bundledPath(\"schema\", \"prices.example.json\") };\n};\n\nconst TEST_REPORT_DESCRIPTION =\n 'Path to a JSON test summary: {\"passed\": number, \"failed\": number, \"total\": number, \"failures\"?: [{\"name\": string, \"message\"?: string}]}';\n\nconst CLOC_DIFF_DESCRIPTION =\n \"Path to a raw `cloc --git --diff <base> <head>` table, rendered verbatim in the sticky's cloc collapsible. Best-effort: an absent, unreadable, or empty file omits the collapsible.\";\n\nconst CONVERGENCE_THRESHOLD_DESCRIPTION =\n \"Advisory convergence tolerance: the per-finding convergence score (each finding's severity floor + confidence-and-likelihood-weighted headroom; ceilings critical 4 · major 2 · minor 1 · nit 0) at or below which the sticky reads as converged. The floor values and the systemic-likelihood rule are documented in the README and the findings schema (default: 1)\";\n\nconst NIT_VISIBILITY_FLOOR_DESCRIPTION =\n \"Nit visibility floor: nits whose confidence × likelihood falls below this are hidden from humans (no inline comment; a collapsed aside in the sticky) but kept in the machine blob as adjudicated. In [0, 1] (default: 0.25)\";\n\nconst renderCmd = defineCommand({\n meta: {\n name: \"render\",\n description: \"Render a code-review comment from findings + usage + prices\",\n },\n args: {\n findings: {\n type: \"positional\",\n description: \"Path to findings JSON\",\n required: true,\n },\n template: {\n type: \"string\",\n description: \"Path to Eta template file (default: bundled templates/comment.eta)\",\n },\n usage: {\n type: \"string\",\n description: \"Path to result envelope JSON (from agent CLI)\",\n required: true,\n },\n prices: {\n type: \"string\",\n description:\n \"Path to price map JSON (default: bundled schema/prices.example.json — all zero)\",\n },\n \"reviewed-sha\": {\n type: \"string\",\n description: \"SHA of the last reviewed commit\",\n },\n route: {\n type: \"string\",\n description:\n \"Review route label; overrides the envelope's route when set (default: read from the envelope)\",\n },\n effort: {\n type: \"string\",\n description:\n \"Effort label; overrides the envelope's effort when set (default: read from the envelope)\",\n },\n \"test-report\": {\n type: \"string\",\n description: TEST_REPORT_DESCRIPTION,\n },\n \"cloc-diff\": {\n type: \"string\",\n description: CLOC_DIFF_DESCRIPTION,\n },\n \"convergence-threshold\": {\n type: \"string\",\n description: CONVERGENCE_THRESHOLD_DESCRIPTION,\n },\n \"nit-visibility-floor\": {\n type: \"string\",\n description: NIT_VISIBILITY_FLOOR_DESCRIPTION,\n },\n },\n run: async ({ args }) => {\n const findings = decode(FindingsCodec.decode(readJSON(args.findings)), \"findings\");\n const envelope = decode(ResultEnvelopeCodec.decode(readJSON(args.usage)), \"envelope\");\n const templatePath = resolveTemplatePath(args.template);\n const priceResolution = resolvePrices(args.prices);\n const prices = decode(PriceMapCodec.decode(readJSON(priceResolution.path)), \"prices\");\n // The preview renders the snapshot date — it must carry the staleness signal too (issue #220\n // review r2). Null = the bundled example: a deliberate no-pricing choice, never stale.\n warnStalePrices(priceResolution.kind === \"provided\" ? prices : null);\n const template = readFileSync(templatePath, \"utf-8\");\n const testReport = args[\"test-report\"]\n ? decode(TestSummaryCodec.decode(readJSON(args[\"test-report\"])), \"test report\")\n : undefined;\n const clocDiff = args[\"cloc-diff\"] ? loadClocDiff(args[\"cloc-diff\"]) : undefined;\n // The render command renders ONE run with no PR history, so render's fallback (which requires a\n // completed round in the history) would show no convergence at all. A completed full-review run\n // IS round 1 of its conversation: pass its own counts as the history — the badge, the\n // trajectory, and the blob's stop signal all agree on it, and the shared predicates make this\n // the same decision post makes (issue #141 reviews r2 + r4).\n const route = args.route || envelope.route || null;\n const isRound =\n isConvergenceRound(route, envelope.incomplete === true || isIncompleteFindings(findings)) &&\n isReviewVerdict(findings.verdict);\n const threshold = parseConvergenceThreshold(args[\"convergence-threshold\"]);\n // The render command previews ONE run with no PR history. A completed full-review run IS round 1 of\n // its conversation, so stamp its convergence (issue #174): the badge, the numeric trajectory, and the\n // blob all read the same stored score, the same decision post makes (issue #141 reviews r2 + r4).\n // Mirror post's stamp: convergence is pipeline-owned and always overwritten, so a draft's echoed\n // value never rides the preview blob — a round previews a fresh round-1 stamp, a non-round none.\n // post's mechanic stamp needs the prior trajectory this command has no access to, so a mechanic\n // preview stamps none — exactly what post stamps for a no-prior mechanic (mechanicConvergence null).\n const stampedFindings = {\n ...findings,\n convergence: isRound ? buildConvergence(findings, threshold) : undefined,\n };\n // The `render` command previews the sticky CHROME (verdict, counts, convergence, cost) — it has no\n // diff, so it never places findings inline vs stray and shows no per-finding detail. It therefore\n // validates --nit-visibility-floor (issue #164) but does NOT apply the visible split or the\n // suppression aside: rendering shelved nits while the visible findings have no detail line would\n // invert the feature. The human/visible split is post's job — it has the diff and the prior sticky.\n const output = render({\n findings: stampedFindings,\n envelope,\n prices,\n pricesProvided: priceResolution.kind === \"provided\",\n template,\n reviewedSha: args[\"reviewed-sha\"],\n route: args.route,\n effort: args.effort,\n testReport,\n clocDiff,\n convergenceThreshold: threshold,\n nitVisibilityFloor: parseNitVisibilityFloor(args[\"nit-visibility-floor\"]),\n convergenceRound: isRound,\n postedAt: formatUtc(new Date()),\n pricedAt: new Date(),\n });\n process.stdout.write(output);\n // The standalone render command names no findings artifact (there is no --json-url flag), so\n // its output carries no machine channel — the same ::error:: post emits, because a preview that\n // looks like a review is worse than one that says what it lacks (issue #233 r2).\n process.stderr.write(\n \"::error::no --json-url was supplied, so this comment names no findings artifact — the review's prose is intact but its machine channel is gone, and the next round cannot seed from it\\n\",\n );\n },\n});\n\nconst inlineCmd = defineCommand({\n meta: {\n name: \"inline\",\n description: \"Build GitHub reviews comments[] payload from findings + diff\",\n },\n args: {\n findings: {\n type: \"positional\",\n description: \"Path to findings JSON\",\n required: true,\n },\n diff: {\n type: \"string\",\n description: \"Path to PR diff file\",\n required: true,\n },\n template: {\n type: \"string\",\n description: \"Path to inline comment Eta template (default: bundled templates/inline.eta)\",\n },\n \"nit-visibility-floor\": {\n type: \"string\",\n description: NIT_VISIBILITY_FLOOR_DESCRIPTION,\n },\n },\n run: async ({ args }) => {\n const findings = decode(FindingsCodec.decode(readJSON(args.findings)), \"findings\");\n const diff = readFileSync(resolve(args.diff), \"utf-8\");\n const inlineTemplate = readFileSync(resolveInlineTemplatePath(args.template), \"utf-8\");\n // Apply the FIXED-floor part of the nit-visibility split (issue #164): a below-floor nit gets no\n // inline comment. This standalone payload builder has no prior sticky, so no one-round stickiness\n // (post applies that); it also has no sticky to carry the collapsed aside, so a suppressed nit is\n // simply absent here — the aside is post's surface.\n const floor = parseNitVisibilityFloor(args[\"nit-visibility-floor\"]);\n const visibleFindings = findings.findings.filter((f) => !isBelowVisibilityFloor(f, floor));\n const { comments, strays } = buildInlineComments(visibleFindings, diff, {\n inlineTemplate,\n findings,\n });\n process.stdout.write(\n JSON.stringify({ comments, strays, stray_markdown: renderStraysSection(strays) }, null, 2),\n );\n },\n});\n\nconst costCmd = defineCommand({\n meta: {\n name: \"cost\",\n description: \"Recompute USD cost from the envelope's models array + price map\",\n },\n args: {\n envelope: {\n type: \"positional\",\n description: \"Path to result envelope JSON\",\n required: true,\n },\n prices: {\n type: \"string\",\n description: \"Path to price map JSON\",\n required: true,\n },\n },\n run: async ({ args }) => {\n const envelope = decode(ResultEnvelopeCodec.decode(readJSON(args.envelope)), \"envelope\");\n const prices = decode(PriceMapCodec.decode(readJSON(args.prices)), \"prices\");\n // The cost CLI's --prices is required, so a decoded map is always the consumer's own.\n warnStalePrices(prices);\n // Price a saved envelope at the RUN's own instant (issue #170), so re-running `cost` later prices\n // the same envelope to the same slot deterministically — not at whatever wall clock it is re-run at.\n const report = computeCost(\n envelope.models,\n prices,\n parseInstant(envelope.generated_at) ?? new Date(),\n );\n process.stdout.write(JSON.stringify(report, null, 2));\n },\n});\n\nconst checkCostCmd = defineCommand({\n meta: {\n name: \"check-cost\",\n description:\n \"Sum real USD spend from a Claude Code transcript tree (main + subagents) against a price map\",\n },\n args: {\n transcript: {\n type: \"positional\",\n description: \"Path to the session transcript JSONL (the hook's transcript_path)\",\n required: true,\n },\n prices: {\n type: \"string\",\n description:\n \"Path to price map JSON (default: bundled schema/prices.example.json — token totals stay real, cost reads as N/A)\",\n },\n },\n run: async ({ args }) => {\n const tree = readTranscriptTree(resolve(args.transcript));\n if (tree.missing) {\n process.stderr.write(\n `code-review check-cost: transcript ${args.transcript} is unreadable — reporting zero spend\\n`,\n );\n }\n const usage = sumTranscriptUsage(tree.entries);\n const priceResolution = resolvePrices(args.prices);\n const prices = decode(PriceMapCodec.decode(readJSON(priceResolution.path)), \"prices\");\n // Null = the bundled example (no --prices): a deliberate no-pricing choice, never stale.\n warnStalePrices(priceResolution.kind === \"provided\" ? prices : null);\n // Price at the transcript's last activity instant (deterministic — re-running `check-cost` on the\n // same transcript prices the same slot), not the invocation wall clock (issue #170 review r2).\n const report = computeCost(\n usage.models,\n prices,\n usage.lastTsMs !== null ? new Date(usage.lastTsMs) : new Date(),\n );\n process.stdout.write(\n `${JSON.stringify(\n {\n ...report,\n turns: usage.turns,\n durationMs: usage.durationMs,\n transcripts: tree.files,\n pricesProvided: priceResolution.kind === \"provided\",\n },\n null,\n 2,\n )}\\n`,\n );\n },\n});\n\n/** Read + decode a price map, degrading to null (cost axis disabled) on any failure — the budget\n * hook fires on every tool call, so it must never process-exit the way the strict `readJSON` does. */\nconst tryReadPrices = (path: string): PriceMap | null => {\n try {\n const decoded = PriceMapCodec.decode(JSON.parse(readFileSync(resolve(path), \"utf-8\")));\n return decoded._tag === \"Right\" ? decoded.right : null;\n } catch {\n return null;\n }\n};\n\n/** A non-negative, finite dollar amount, or null (absent/unparseable). `0` is kept, not nulled: as a\n * budget it disables the cost axis (decideBudget requires budgetUsd > 0); as a reserve floor it means\n * no flat floor. */\nconst parseBudgetUsd = (raw: string | undefined): number | null => {\n if (raw === undefined) return null;\n const n = Number.parseFloat(raw);\n return Number.isFinite(n) && n >= 0 ? n : null;\n};\n\n/** Parse `--convergence-threshold`: a non-negative decimal, or undefined when absent/blank (the render\n * layer then applies DEFAULT_CONVERGENCE_THRESHOLD as the SSOT default). An unset optional workflow\n * input expands to \"\" — treat empty/whitespace as absent so the step falls back to the default rather\n * than hard-failing under `set -euo pipefail`. Match the whole string before parsing — `parseFloat`\n * alone silently accepts a numeric prefix (`\"1,5\"`→1, `\"0x10\"`→0) — and reject a non-finite result\n * (a 309+-digit string parses to Infinity, which would make `score <= threshold` always true, a false\n * \"converged\"); a malformed value must fail loudly, the same class the prefix guard covers. */\nconst parseConvergenceThreshold = (raw: string | undefined): number | undefined => {\n const trimmed = raw?.trim();\n if (trimmed === undefined || trimmed === \"\") return undefined;\n if (!/^\\d+(\\.\\d+)?$/.test(trimmed)) {\n fail(`--convergence-threshold must be a non-negative number; got \"${trimmed}\"`);\n }\n const n = Number.parseFloat(trimmed);\n if (!Number.isFinite(n)) {\n fail(`--convergence-threshold is too large to be a meaningful tolerance; got \"${trimmed}\"`);\n }\n return n;\n};\n\n/** Parse `--nit-visibility-floor`: a decimal in [0, 1], or undefined when absent/blank (the render/post\n * layer then applies DEFAULT_NIT_VISIBILITY_FLOOR as the SSOT default). Same empty-string-is-absent\n * handling as --convergence-threshold (an unset optional workflow input expands to \"\"). Bounded to\n * [0, 1] because the value it gates — confidence × likelihood — is itself in [0, 1]: a value above 1\n * would silently hide EVERY nit (a fat-fingered \"25\" meant as \"0.25\"), so it fails loudly instead. */\nconst parseNitVisibilityFloor = (raw: string | undefined): number | undefined => {\n const trimmed = raw?.trim();\n if (trimmed === undefined || trimmed === \"\") return undefined;\n if (!/^\\d+(\\.\\d+)?$/.test(trimmed)) {\n fail(`--nit-visibility-floor must be a number in [0, 1]; got \"${trimmed}\"`);\n }\n const n = Number.parseFloat(trimmed);\n if (!Number.isFinite(n) || n < 0 || n > 1) {\n fail(\n `--nit-visibility-floor must be in [0, 1] (it gates confidence × likelihood); got \"${trimmed}\"`,\n );\n }\n return n;\n};\n\n/** seed-draft's best-effort floor parse: like parseNitVisibilityFloor but NEVER exits — seed-draft's\n * always-exit-0 contract forbids the process-exiting `fail` (it runs under the review job's `set -e`).\n * An absent/blank/malformed/out-of-range value degrades to undefined (priorBelowFloorNits then applies\n * the SSOT default); a genuine misconfiguration is still caught loudly at post, where the floor is\n * actually enforced. */\nconst parseNitVisibilityFloorLenient = (raw: string | undefined): number | undefined => {\n const trimmed = raw?.trim();\n if (trimmed === undefined || trimmed === \"\" || !/^\\d+(\\.\\d+)?$/.test(trimmed)) return undefined;\n const n = Number.parseFloat(trimmed);\n return Number.isFinite(n) && n >= 0 && n <= 1 ? n : undefined;\n};\n\n/** The `transcript_path` a hook payload carries, when present. */\nconst transcriptPathOf = (input: unknown): string | undefined => {\n const tp = (\n typeof input === \"object\" && input !== null ? (input as Record<string, unknown>) : {}\n )[\"transcript_path\"];\n return typeof tp === \"string\" ? tp : undefined;\n};\n\nconst statMtimeMsOrNull = (path: string): number | null => {\n try {\n return statSync(path).mtimeMs;\n } catch {\n return null;\n }\n};\n\nconst statSizeOrNull = (path: string): number | null => {\n try {\n return statSync(path).size;\n } catch {\n return null;\n }\n};\n\n/** Snapshot the draft to its last-valid sidecar when it passes the same extraction ladder `adapt`\n * will read it back through, so `adapt`'s fallback rung only ever sees a document it accepts.\n * The pre-seed sentinel never validates, so the untouched seed can never be checkpointed here.\n * Best-effort — a snapshot miss never perturbs the hook's stdout decision. */\nexport const snapshotIfValid = (draftPath: string): void => {\n try {\n // Skip the ladder when the draft is not newer than the snapshot already taken: the hook fires\n // on every main-agent PostToolBatch, and re-validating an unchanged draft each batch is the\n // same per-event I/O class the lazy-thunk change elsewhere eliminated.\n const snapPath = lastValidPath(draftPath);\n const draftMtime = statMtimeMsOrNull(draftPath);\n if (draftMtime === null) return;\n const snapMtime = statMtimeMsOrNull(snapPath);\n if (snapMtime !== null && draftMtime <= snapMtime) return;\n // Validate the LIVE draft only (no agentFileFallbackPath): passing the snapshot as a fallback\n // here would let a valid snapshot rescue an invalid live draft through the ladder, then copy that\n // invalid draft over the good snapshot — corrupting the last-valid state we exist to preserve.\n if (\n extractStructured({ kind: \"findings\", native: undefined, agentFilePath: draftPath }).kind ===\n \"ok\"\n )\n copyFileSync(draftPath, snapPath);\n } catch (err) {\n process.stderr.write(\n `code-review: could not snapshot the last-valid draft (${errMsg(err)}) — any prior snapshot is unchanged\\n`,\n );\n }\n};\n\nconst budgetHookCmd = defineCommand({\n meta: {\n name: \"budget-hook\",\n description:\n \"Self-dispatching Claude Code budget hook: on PostToolBatch steer the agent to converge as spend/wall-clock nears the budget; on PreToolUse deny budget-burning tools under the hard reserve, gate subagent spawns until the main agent has drafted, and run permitted spawns in the background. Reads the hook payload on stdin; degrades to a no-op on error.\",\n },\n args: {\n draft: {\n type: \"string\",\n description:\n \"Path to the findings draft that is the sole permitted write target under forced convergence\",\n required: true,\n },\n \"budget-usd\": {\n type: \"string\",\n description:\n \"Dollar budget for the run; the cost axis is measured against it (needs --prices)\",\n },\n wall: {\n type: \"string\",\n description: \"Wall-clock budget (e.g. 20m, 1200s, 2h); the time axis is measured against it\",\n },\n prices: {\n type: \"string\",\n description:\n \"Price map JSON to recompute real spend from the transcript (omit to disable the cost axis)\",\n },\n \"reserve-frac\": {\n type: \"string\",\n description:\n \"Base wind-down headroom as a fraction of each budget: converge once less than this remains (default: 0.15; the soft steer tier reserves 2× this)\",\n },\n \"reserve-growth\": {\n type: \"string\",\n description:\n \"How much the reserve grows as a budget is spent — added at full usage, so convergence lands earlier the longer the run has gone (default: 0.25; 0 = flat reserve)\",\n },\n \"reserve-usd\": {\n type: \"string\",\n description:\n \"Flat dollar wind-down floor, whichever is larger with --reserve-frac (default: 0.02)\",\n },\n \"reserve-wall\": {\n type: \"string\",\n description:\n \"Flat wall-clock wind-down floor (e.g. 2m, 120s), whichever is larger with --reserve-frac (default: 2m)\",\n },\n },\n run: async ({ args }) => {\n try {\n const draftPath = resolve(args.draft);\n const input = readStdinJSON();\n const transcriptPath = transcriptPathOf(input);\n const tree = transcriptPath ? readTranscriptTree(resolve(transcriptPath)) : undefined;\n const usage = tree ? sumTranscriptUsage(tree.entries) : undefined;\n const prices = args.prices ? tryReadPrices(args.prices) : null;\n const costReport =\n prices !== null && usage\n ? // Price at the transcript's last activity instant, not the wall clock (issue #170 review\n // r2). Silent warn: this budget-steering cost is recomputed on EVERY tool event, so a\n // misconfigured slot map would otherwise flood stderr; the final post's cost render warns.\n computeCost(\n usage.models,\n prices,\n usage.lastTsMs !== null ? new Date(usage.lastTsMs) : new Date(),\n () => undefined,\n )\n : null;\n // Unmeasurable spend is null, never a confident number: a report with an unpriced line\n // under-counts, so the steering degrades to unsteered rather than telling the agent $0.00\n // was spent (issue #221 review r1). An empty report stays ENGAGED at $0 — no usage was\n // consumed, which is honest, not unmeasurable.\n // The disengagement is announced on the STATE TRANSITION via the marker sidecar (each hook\n // invocation is a fresh process), skipped for subagents — their transcript view is their\n // own file, so they must not announce the aggregate's axis or clear its marker.\n if (!isSubagentHookInput(input)) {\n const axisPath = costAxisDisengagedPath(draftPath);\n const action = costAxisAnnouncement(costReport, readFileOrNull(axisPath) !== null);\n if (action === \"announce\") {\n process.stderr.write(\n \"code-review budget-hook: the price map does not cover every model in the transcript, or its slots leave the run instant uncovered — the cost axis is disengaged for this run; add the missing models (or fix the slot partition) and re-verify\\n\",\n );\n try {\n writeFileSync(axisPath, \"\");\n } catch {\n // Best-effort: a failed marker just means the next event re-announces.\n }\n } else if (action === \"clear\") {\n try {\n unlinkSync(axisPath);\n } catch {\n // Best-effort cleanup.\n }\n }\n }\n const spentUsd = costReport !== null && costReport.allKnown ? costReport.totalCostUSD : null;\n // The absolute anchor (set by the review job, inherited by every hook incl. fan-out subagents)\n // is the true remaining wall; the per-transcript first timestamp is only the fallback — it\n // reads ≈0 in a fresh subagent and leaves the fan-out unsteered.\n const wallMs = args.wall ? parseWallMs(args.wall) : null;\n const output = evaluateBudgetHook(input, {\n spentUsd,\n budgetUsd: parseBudgetUsd(args[\"budget-usd\"]),\n elapsedMs: anchoredElapsedMs({\n deadlineMs: parseEpochSecMs(process.env[DEADLINE_ENV]),\n wallMs,\n firstTsMs: usage?.firstTsMs ?? null,\n nowMs: Date.now(),\n }),\n wallMs,\n reserve: {\n frac: parseFraction(args[\"reserve-frac\"], DEFAULT_RESERVE.frac),\n growth: parseFraction(args[\"reserve-growth\"], DEFAULT_RESERVE.growth),\n flatUsd: parseBudgetUsd(args[\"reserve-usd\"]) ?? DEFAULT_RESERVE.flatUsd,\n flatMs: args[\"reserve-wall\"]\n ? (parseWallMs(args[\"reserve-wall\"]) ?? DEFAULT_RESERVE.flatMs)\n : DEFAULT_RESERVE.flatMs,\n },\n draftPath,\n // Lazy: the spawn gate is the only consumer, and the hook fires on every tool event.\n mainDraftWritten: (): boolean => mainHasWrittenDraft(readFileOrNull(draftPath)),\n });\n // Only the main agent writes the draft (single-writer), so a subagent batch never introduces a\n // new valid state to preserve — snapshot on the main agent's PostToolBatch only.\n if (asRecord(input)?.[\"hook_event_name\"] === \"PostToolBatch\" && !isSubagentHookInput(input))\n snapshotIfValid(draftPath);\n process.stdout.write(`${JSON.stringify(output)}\\n`);\n } catch (err) {\n process.stderr.write(`code-review budget-hook: degrading to no-op — ${errMsg(err)}\\n`);\n process.stdout.write(\"{}\\n\");\n }\n },\n});\n\nconst printSettingsCmd = defineCommand({\n meta: {\n name: \"print-settings\",\n description:\n \"Emit one Claude Code --settings JSON composing the Stop deliverable gate and the budget hooks (PreToolUse convergence + PostToolBatch steer) from one self-dispatching command\",\n },\n args: {\n draft: {\n type: \"string\",\n description:\n \"Path to the findings draft the agent must produce — the Stop gate's target and the only write allowed under forced convergence\",\n required: true,\n },\n kind: {\n type: \"string\",\n description: \"Schema kind for the Stop gate: findings | triage | prices (default: findings)\",\n },\n schema: {\n type: \"string\",\n description: \"Path to a schema file for the Stop gate (wins over --kind)\",\n },\n \"schema-version\": {\n type: \"string\",\n description: \"Schema major.minor for the Stop gate (default: the draft's declared version)\",\n },\n \"max-nudges\": {\n type: \"string\",\n description: \"Stop-gate nudge budget before relenting (default: 5)\",\n },\n counter: {\n type: \"string\",\n description: \"Path for the Stop-gate nudge counter (default: <draft>.nudges)\",\n },\n \"budget-usd\": {\n type: \"string\",\n description: \"Dollar budget the cost axis is measured against (needs --prices)\",\n },\n wall: {\n type: \"string\",\n description: \"Wall-clock budget the time axis is measured against (e.g. 20m, 1200s)\",\n },\n prices: {\n type: \"string\",\n description: \"Price map JSON to recompute real spend from the transcript\",\n },\n \"reserve-frac\": {\n type: \"string\",\n description:\n \"Base wind-down headroom as a fraction of each budget (default: 0.15; soft tier is 2×)\",\n },\n \"reserve-growth\": {\n type: \"string\",\n description:\n \"How much the reserve grows as a budget is spent, converging earlier the longer the run has gone (default: 0.25; 0 = flat)\",\n },\n \"reserve-usd\": {\n type: \"string\",\n description:\n \"Flat dollar wind-down floor, whichever is larger with --reserve-frac (default: 0.02)\",\n },\n \"reserve-wall\": {\n type: \"string\",\n description:\n \"Flat wall-clock wind-down floor (e.g. 2m), whichever is larger with --reserve-frac (default: 2m)\",\n },\n },\n run: async ({ args }) => {\n if (args.kind && ![\"findings\", \"triage\", \"prices\"].includes(args.kind))\n fail(`--kind must be one of findings|triage|prices (got '${args.kind}')`);\n const settings = composeReviewSettings({\n draftPath: resolve(args.draft),\n stop: {\n kind: args.kind,\n schema: args.schema,\n schemaVersion: args[\"schema-version\"],\n maxNudges: args[\"max-nudges\"],\n counter: args.counter,\n },\n budget: {\n budgetUsd: args[\"budget-usd\"],\n wall: args.wall,\n prices: args.prices,\n reserveFrac: args[\"reserve-frac\"],\n reserveGrowth: args[\"reserve-growth\"],\n reserveUsd: args[\"reserve-usd\"],\n reserveWall: args[\"reserve-wall\"],\n },\n });\n process.stdout.write(`${JSON.stringify(settings)}\\n`);\n },\n});\n\nconst deadlineCmd = defineCommand({\n meta: {\n name: \"deadline\",\n description:\n \"Print the run's absolute deadline as Unix epoch seconds (now + --wall) — exported as CODE_REVIEW_DEADLINE_EPOCH so every budget hook (main and subagents) measures the same remaining wall\",\n },\n args: {\n wall: {\n type: \"string\",\n description:\n \"Wall-clock budget for the run (e.g. 24m, 1200s, 2h) — the deadline is now + this\",\n required: true,\n },\n },\n run: async ({ args }) => {\n const wallMs = parseWallMs(args.wall);\n if (wallMs === null) {\n fail(`--wall must be a duration like 24m, 1200s, or 2h (got '${args.wall}')`);\n } else {\n process.stdout.write(`${String(deadlineEpochSec(wallMs, Date.now()))}\\n`);\n }\n },\n});\n\n/** The version to derive when neither --schema nor --schema-version is given: findings carries its\n * version in-data; triage/prices have no in-data signal (see registry.ts), so undefined selects the\n * registry default (latest) for the kind. */\nconst derivedSchemaVersion = (kind: SchemaKind, raw: unknown): string | undefined =>\n kind === \"findings\" ? declaredVersion(raw) : undefined;\n\n/** A bundled schema rendered for a CLI/agent to read: pretty-printed with the top-level `$schema`\n * draft declaration stripped. `claude -p --json-schema` silently disables enforcement when a schema\n * carries `$schema`, and the field DESCRIPTIONS are the authoritative spec the agent must follow, so\n * this is the form both `print-schema` and `validate --explain` emit. When `pinVersion` is set (the\n * caller resolved the LIVE findings schema — no version override, no legacy-stamped explain), the\n * schema_version's pattern is narrowed to the in-force minor so `--json-schema` enforces exactly\n * the versions the registry dispatches to the live entry — the FROZEN legacy copies keep their\n * tolerant shape, and the schema FILES stay version-tolerant: the registry dispatches on the\n * declared version, only the live enforcement copy pins. */\nexport const printableSchema = (schemaPath: string, pinVersion: boolean): string => {\n const schema = JSON.parse(readFileSync(schemaPath, \"utf-8\")) as Record<string, unknown>;\n const enforcementSchema = Object.fromEntries(\n Object.entries(schema).filter(([key]) => key !== \"$schema\"),\n );\n if (!pinVersion) return JSON.stringify(enforcementSchema, null, 2);\n const properties = enforcementSchema[\"properties\"];\n const schemaVersion =\n typeof properties === \"object\" && properties !== null\n ? (properties as Record<string, unknown>)[\"schema_version\"]\n : undefined;\n if (typeof schemaVersion === \"object\" && schemaVersion !== null) {\n (properties as Record<string, unknown>)[\"schema_version\"] = {\n ...(schemaVersion as Record<string, unknown>),\n pattern: anchoredSchemaVersionPattern(DEFAULT_SCHEMA_VERSION),\n };\n }\n return JSON.stringify(enforcementSchema, null, 2);\n};\n\nconst validateCmd = defineCommand({\n meta: {\n name: \"validate\",\n description: \"Validate a findings/triage/prices JSON document against the canonical schema\",\n },\n args: {\n document: {\n type: \"positional\",\n description: \"Path to the JSON document to validate (of the given --kind)\",\n required: true,\n },\n kind: {\n type: \"string\",\n description:\n \"Schema kind to validate against: findings | triage | prices (default: findings)\",\n },\n schema: {\n type: \"string\",\n description:\n \"Path to a schema file (wins over --kind; default: the bundled schema derived from --kind, --schema-version, the document's declared schema_version, or the bundled latest)\",\n },\n \"schema-version\": {\n type: \"string\",\n description:\n \"Schema major.minor version to validate against (default: the document's declared schema_version for findings, or the kind's latest)\",\n },\n explain: {\n type: \"boolean\",\n description:\n \"On failure, also print the schema after the errors — its field descriptions are the authoritative spec, so the document can be fixed in one pass instead of by trial and error\",\n },\n },\n run: async ({ args }) => {\n const kind = requireSchemaKind(args.kind || \"findings\");\n const documentRaw = readJSON(args.document);\n const schemaPath = args.schema\n ? resolve(args.schema)\n : requireSchemaPath(kind, args[\"schema-version\"] || derivedSchemaVersion(kind, documentRaw));\n const { valid, errors } = validateAgainstSchema(documentRaw, schemaPath);\n if (valid) {\n process.stdout.write(\"✅ valid\\n\");\n } else {\n process.stderr.write(\"❌ invalid\\n\");\n for (const e of errors) process.stderr.write(` - ${e}\\n`);\n if (args.explain) {\n process.stderr.write(\n `\\nThe ${kind} document must conform to this schema (the field descriptions are the authoritative spec — match the property names exactly):\\n${printableSchema(schemaPath, kind === \"findings\" && schemaPath === schemaPathFor(kind))}\\n`,\n );\n }\n process.exit(1);\n }\n },\n});\n\n// A decoded prior blob the pipeline stamped (surface version 0.8.0) — its scope_metastasis was\n// pipeline-stamped and is authoritative. Only 0.8.0 ever stamped the field: issue #150 added\n// scope_metastasis in the same commit that bumped the surface version 0.7.0 → 0.8.0, so a 0.7.0 blob\n// predates the field and any entry it carries is an echo, not a stamp; a draft blob's is likewise at\n// most an agent echo. Guards non-objects.\nconst isSurfaceStampedDoc = (doc: unknown): boolean =>\n typeof doc === \"object\" &&\n doc !== null &&\n !Array.isArray(doc) &&\n (doc as Record<string, unknown>)[\"schema_version\"] === SURFACE_SCHEMA_VERSION;\n\n// The prior document with the agent-echoable scope_metastasis removed — a stale echo would over-report\n// recurrence, so the seed re-derives it fresh below. The pipeline-stamped convergence is KEPT: it is the\n// last completed round's own trajectory (correct context, not a stale echo), and the review agent's only\n// view of prior state is this seed, so it must carry the convergence signal (issue #174). A no-op on a\n// non-object; mirrors the stripSurfaceFields filter idiom.\nconst withoutScopeMetastasis = (doc: unknown): unknown =>\n typeof doc === \"object\" && doc !== null && !Array.isArray(doc)\n ? Object.fromEntries(Object.entries(doc).filter(([key]) => key !== \"scope_metastasis\"))\n : doc;\n\nconst seedDraftCmd = defineCommand({\n meta: {\n name: \"seed-draft\",\n description:\n \"Initialize $DRAFT before the review runs: write a NON-REVIEW SENTINEL (no recovery path can validate it as a review), and deliver the decoded findings of a prior review OUT-OF-BAND to a read-only context file beside the draft when one exists and still validates (incremental re-review). Skips a prior that never completed (an error-verdict notice) or that a CI-fix mechanic pass produced — the seed chain is route-aware. Prints the mode to stdout (prior-same|prior-new when prior context was delivered, by whether the prior review examined this same commit; empty-had-prior when a prior review exists but its findings could not be loaded; empty on a first review; none when even the sentinel write failed) and always exits 0\",\n },\n args: {\n prior: {\n type: \"string\",\n description:\n \"Path to the prior-review JSON gather staged ({ id, body }, or the literal null); its embedded base64 findings marker is decoded and delivered as re-review context when it validates against the schema\",\n },\n \"prior-findings\": {\n type: \"string\",\n description:\n \"Path to the gather-staged prior findings document (prior_findings.json). gather resolves it — from the sticky's embedded blob, or by fetching the artifact the marker names — because gather holds the repo token and this step deliberately does not: it runs the jailed agent over untrusted PR code. Absent or null falls back to decoding an embedded blob out of --prior, which needs no token\",\n },\n \"prior-answers\": {\n type: \"string\",\n description:\n \"Path to the gather-staged answered-findings registry (answered.json) — the prior inline findings whose threads a human reply answered (issue #151). Delivered out-of-band to the .prior-answers sidecar beside the prior context so the next-round agent sees the already-answered state; best-effort, never fails the seed\",\n },\n \"nit-visibility-floor\": {\n type: \"string\",\n description:\n \"The nit visibility floor (issue #164), matched to the commenter's: the prior review's below-floor nits (confidence × likelihood below it) are re-derived from --prior and delivered to the .prior-suppressed sidecar as adjudicated context, so the next-round agent does not re-raise them as fresh nits; best-effort, never fails the seed. Empty ⇒ the default\",\n },\n \"head-sha\": {\n type: \"string\",\n description:\n \"Current head SHA, compared against the prior review's embedded reviewed-sha to distinguish a same-commit re-review from a new-commit one; an unknown or mismatched prior SHA is treated as a new commit\",\n },\n out: {\n type: \"string\",\n description: \"Path to write the sentinel $DRAFT to (an absolute path outside the worktree)\",\n required: true,\n },\n kind: {\n type: \"string\",\n description: \"Schema kind to validate the prior findings against (default: findings)\",\n },\n schema: {\n type: \"string\",\n description: \"Path to a schema file (wins over --kind/--schema-version)\",\n },\n \"schema-version\": {\n type: \"string\",\n description:\n \"Schema major.minor to validate the prior findings against (default: the kind's latest — an older-shaped prior review then delivers no context)\",\n },\n },\n run: async ({ args }) => {\n const outPath = resolve(args.out);\n const kindArg = args.kind || \"findings\";\n const kind: SchemaKind = isSchemaKind(kindArg) ? kindArg : \"findings\";\n if (kind !== kindArg) {\n process.stderr.write(\n `Warning: unknown --kind \"${kindArg}\" — validating against \"findings\"\\n`,\n );\n }\n\n // seed-draft is best-effort and must NEVER fail the review step (the workflow runs it under\n // `set -e`), so every path below either seeds or degrades — none uses the process-exiting\n // require* helpers. The only outcome that skips seeding is a sentinel write that itself throws\n // (e.g. a bad --out directory), which is warned and still exits 0: the agent then creates\n // $DRAFT itself, exactly as if no seeding ran.\n const writeSentinel = (): boolean => {\n try {\n writeFileSync(outPath, SEED_SENTINEL);\n process.stderr.write(\n `Seeded ${outPath} with the non-review sentinel — the agent must replace it with its review\\n`,\n );\n return true;\n } catch (err) {\n process.stderr.write(\n `Warning: could not write the seed sentinel to ${outPath} (${errMsg(err)}) — the agent will create $DRAFT itself\\n`,\n );\n return false;\n }\n };\n\n // The whole prior comment body gather staged, tolerating a missing/absent/\"null\"/malformed\n // file: it carries the embedded findings (delivered as context below when they still validate),\n // the reviewed-sha that distinguishes a same-commit re-review from a new-commit one, and the\n // route of the review that produced it.\n const priorBody = ((): string | null => {\n if (!args.prior) return null;\n const raw = ((): unknown => {\n try {\n return JSON.parse(readFileSync(resolve(args.prior), \"utf-8\")) as unknown;\n } catch {\n return null;\n }\n })();\n return typeof raw === \"object\" &&\n raw !== null &&\n \"body\" in raw &&\n typeof raw.body === \"string\"\n ? raw.body\n : null;\n })();\n // Resolved by GATHER, not here: the sticky names an artifact (issue #217) and fetching it needs\n // the repo token, which this step does not have and must not have — it runs the jailed agent over\n // untrusted PR code. gather stages the document; this reads it. The embedded fallback keeps a\n // pre-#217 sticky working with no staged file and no token at all.\n const stagedPrior = ((): unknown => {\n if (!args[\"prior-findings\"]) return null;\n try {\n return JSON.parse(readFileSync(resolve(args[\"prior-findings\"]), \"utf-8\")) as unknown;\n } catch {\n return null;\n }\n })();\n const parsedPrior =\n stagedPrior !== null\n ? stagedPrior\n : priorBody === null\n ? null\n : parseFindingsMarker(priorBody);\n // A legacy 0.8.0 surfaced blob had its scope_metastasis PIPELINE-stamped fresh every round, so a\n // carried entry is authoritative that round (a 0.7.0 blob predates the field, so its entry is not\n // a stamp — isSurfaceStampedDoc gates on 0.8.0 alone); the post-#156 blob is the agent's own\n // document (a draft version) and carries no pipeline stamp, so any scope_metastasis in it is the agent\n // ECHOING the entry the prior seed attached to its context — stale the moment the recurrence\n // changes. Drop that echo up front (the surface peel-back keeps a legacy blob's authoritative\n // entry) so the recurrence signal comes solely from the carried-trajectory re-derivation below,\n // never a carried copy that can outlive the streak it claims.\n const strippedPrior =\n parsedPrior === null\n ? null\n : stripSurfaceFields(\n isSurfaceStampedDoc(parsedPrior) ? parsedPrior : withoutScopeMetastasis(parsedPrior),\n );\n // The answered registry decoded ONCE, up front: the seed's pre-filter below and the sidecar\n // write at the end both consume it (issue #233 r2). null = no usable registry (the flag absent,\n // or the staged file malformed — the old contract: a malformed file warns and writes NO\n // sidecar, issue #151).\n const answeredRegistry = ((): readonly StagedAnsweredEntry[] | null => {\n if (!args[\"prior-answers\"]) return null;\n try {\n const raw = JSON.parse(readFileSync(resolve(args[\"prior-answers\"]), \"utf-8\")) as unknown;\n if (!Array.isArray(raw)) throw new Error(\"expected an array\");\n const decoded = raw.flatMap((row) => {\n const entry = decodeAnsweredEntry(row);\n return entry === null ? [] : [entry];\n });\n // A dropped row is a gap in the answered state, not a silent no-op: the agent would read\n // \"no answers\" for a thread that WAS answered (issue #151 review r1).\n if (decoded.length < raw.length) {\n process.stderr.write(\n `Warning: ${String(raw.length - decoded.length)} of ${String(raw.length)} answered-registry row(s) failed to decode — the seed's answered state is incomplete\\n`,\n );\n }\n return decoded;\n } catch (err) {\n process.stderr.write(\n `Warning: could not read the answered-findings registry ${args[\"prior-answers\"]} (${errMsg(err)}) — no prior-answers sidecar\\n`,\n );\n return null;\n }\n })();\n\n // The agent-facing scope_metastasis entry is derivable from the carried convergence trajectory —\n // the same computation post() ran when it stamped it — so the seed re-attaches it: the next-round agent\n // must see the recurrence signal. A legacy blob whose stripped doc still carries the authoritative\n // pipeline stamp keeps it. The re-attach is best-effort: if the in-force schema (a consumer-pinned\n // custom --schema predating the field) rejects the adorned doc, the un-adorned prior is seeded\n // instead — losing the recurrence entry beats losing ALL prior context.\n const priorFindings = ((): unknown => {\n if (\n strippedPrior === null ||\n typeof strippedPrior !== \"object\" ||\n Array.isArray(strippedPrior)\n )\n return strippedPrior;\n // The registry upcast runs FIRST (code → id, or the synthesized id), so the answered pre-filter\n // below and the scope_metastasis carry both see the 0.10 shape — a raw legacy prior's findings\n // have no `id`, and the pre-filter can only match an answered entry through one. A doc the\n // upcast rejects (a malformed carried field) falls through raw: the adorn below and the gate's\n // barePrior recovery still handle it.\n const resolved = resolvedPriorValue(strippedPrior);\n // The artifact holds the agent's PRE-FILTER draft — uploaded before post's answered-filter\n // dropped verbatim re-raises — so the seed applies the SAME drop via the SAME shared\n // predicate (isAnsweredDrop, issue #233 r2): a finding the prior round closed as answered is\n // not open, and showing it as open wastes the next round on a claim post will suppress anyway.\n const doc: Record<string, unknown> =\n resolved === null\n ? (strippedPrior as Record<string, unknown>)\n : {\n ...resolved,\n findings:\n answeredRegistry !== null && answeredRegistry.length > 0\n ? resolved.findings.filter((f) => {\n const resolvedId = resolveFindingId(f);\n return !answeredRegistry.some((e) => isAnsweredDrop(resolvedId, f, e));\n })\n : resolved.findings,\n };\n // A carried entry only counts when it VALIDATES as the entry shape — for a draft blob it is\n // already dropped (only a legacy pipeline-stamped blob reaches here with one), and an explicit\n // null, an array, or a malformed object (all possible in a corrupt blob; genuine posts omit the\n // key on null) falls through to the trajectory recovery like an absent one (issues #150\n // review r3 + r4). The derivation is also gated on the prior's verdict exactly like post's\n // stamp (isRound requires a review verdict): an error-verdict prior never carries a\n // re-derived entry (issue #150 review r4).\n const carried = doc[\"scope_metastasis\"];\n if (ScopeMetastasisCodec.decode(carried)._tag === \"Right\") return doc;\n if (doc[\"verdict\"] === \"error\") return doc;\n const computed = computeScopeMetastasis(priorTrajectory(parsedPrior, priorBody ?? \"\"));\n return computed === null ? doc : { ...doc, scope_metastasis: computed };\n })();\n\n // Validate + write WITHOUT the process-exiting require* helpers: any failure (bad\n // --schema-version, unreadable schema, non-matching shape, unwritable $DRAFT) degrades to the\n // sentinel-only seed so the always-exit-0 contract holds. The prior findings are NEVER written\n // into $DRAFT — only the sentinel goes there; the prior travels out-of-band to\n // priorContextPath, which no recovery path reads back (issue #127).\n // The answered-findings registry (issue #151), delivered beside the prior context: the prior\n // inline findings whose threads a human reply answered, so the next-round agent knows what it\n // must not re-raise verbatim. Best-effort and independent of whether the prior findings seeded —\n // even a prior that never completed (a notice) still has answered threads. A malformed staged\n // file warns and writes nothing; the workflow references the sidecar as possibly absent.\n if (answeredRegistry !== null) {\n writeFileSync(priorAnswersPath(outPath), `${JSON.stringify(answeredRegistry, null, 2)}\\n`);\n process.stderr.write(\n `Seeded ${priorAnswersPath(outPath)} with ${String(answeredRegistry.length)} answered finding(s) as context\\n`,\n );\n }\n\n // The prior round's below-visibility-floor nits (issue #164), re-derived from the SAME prior blob\n // the commenter split on — delivered as adjudicated context so the next-round agent does not\n // re-raise them as fresh nits. Best-effort and independent of whether the prior findings seeded:\n // a first review, an old blob without likelihood, or a link/omitted blob simply yields none. The\n // floor is read from the same workflow input the commenter uses, so seed and post agree within a\n // run. Correctness does not depend on this note — the blob keeps every nit and post re-suppresses a\n // re-raised still-nit by stickiness — it only spares the agent the wasted re-mining.\n // Gated exactly like the prior-context seed below (isFullReviewAncestry): a mechanic (CI-fix)\n // pass writes its OWN findings blob, so deriving \"prior round's below-floor nits\" from it would\n // deliver a CI-fix pass's nits as adjudicated prior-round context. Only a completed FULL review\n // is a prior round. The floor is parsed LENIENTLY — seed-draft must exit 0, so it cannot call\n // the process-exiting parseNitVisibilityFloor (post enforces the floor loudly).\n if (parsedPrior !== null && isFullReviewAncestry(priorBody ?? \"\")) {\n try {\n const belowFloor = priorBelowFloorNits(\n parsedPrior,\n parseNitVisibilityFloorLenient(args[\"nit-visibility-floor\"]),\n );\n if (belowFloor.length > 0) {\n writeFileSync(priorSuppressedPath(outPath), `${JSON.stringify(belowFloor, null, 2)}\\n`);\n process.stderr.write(\n `Seeded ${priorSuppressedPath(outPath)} with ${String(belowFloor.length)} below-floor nit(s) as adjudicated context\\n`,\n );\n }\n } catch (err) {\n process.stderr.write(\n `Warning: could not derive the prior below-floor nits (${errMsg(err)}) — no prior-suppressed sidecar\\n`,\n );\n }\n }\n\n const seededFromPrior =\n priorFindings === null\n ? false\n : ((): boolean => {\n try {\n const schemaPath = args.schema\n ? resolve(args.schema)\n : schemaPathFor(kind, args[\"schema-version\"]);\n // ALWAYS validate — no short-circuit: a natively-carried 0.8.0 entry must face the\n // in-force schema like any other doc. When that schema (or the codec) rejects the doc\n // solely because of a RECOVERABLE optional field (scope_metastasis, convergence, or\n // change_size — a consumer-pinned custom --schema predating one, an older pinned CLI in\n // the merge-to-release window, or a corrupt blob-carried entry), fall back to the\n // field-stripped doc: losing those fields beats losing ALL prior context (issue #150\n // review r2 + #174 + #182 review r2). Shares post's recovery set (SSOT) so the two\n // recovery sites can never diverge. Covers BOTH gates (ajv + codec) — and both run on\n // the UPCAST value (resolvedPriorValue), never the raw legacy doc.\n const barePrior =\n typeof priorFindings === \"object\" && !Array.isArray(priorFindings)\n ? Object.fromEntries(\n Object.entries(priorFindings as Record<string, unknown>).filter(\n ([key]) => !RECOVERABLE_OPTIONAL_FIELDS.has(key),\n ),\n )\n : priorFindings;\n const accepts = (doc: unknown): Findings | null => {\n const resolved = resolvedPriorValue(doc);\n return resolved !== null && validateAgainstSchema(resolved, schemaPath).valid\n ? resolved\n : null;\n };\n const seedDoc =\n accepts(priorFindings) ??\n ((): Findings | null => {\n const bare = accepts(barePrior);\n if (bare === null) return null;\n process.stderr.write(\n `Note: the in-force schema rejects a carried recoverable field (scope_metastasis/convergence/change_size) — seeding the prior without it (issue #150 review r2 / #182 review r2)\\n`,\n );\n return bare;\n })();\n if (seedDoc === null) return false;\n // Skip a prior that never completed (verdict \"error\" + no findings — the notice\n // signature, isIncompleteFindings) and a prior that is not unmistakably a completed\n // FULL review (route-aware seed chain): a CI-fix mechanic pass must not sit in the\n // seed chain as if it were the previous review. The route marker wins; a route-less\n // body counts as full-review ancestry ONLY through the carried completed-ancestor\n // marker (and never mechanic ancestry) — round history can't identify the last\n // review (a mechanic carries a full review's rounds forward), so any other no-route\n // prior is unknown and skipped: one cold review is cheaper than a false prior.\n if (isIncompleteFindings(seedDoc)) return false;\n if (!isFullReviewAncestry(priorBody ?? \"\")) return false;\n writeFileSync(outPath, SEED_SENTINEL);\n writeFileSync(priorContextPath(outPath), `${JSON.stringify(seedDoc, null, 2)}\\n`);\n process.stderr.write(\n `Seeded ${outPath} with the sentinel and wrote the prior review (${String(seedDoc.findings.length)} finding(s)) to ${priorContextPath(outPath)} as context\\n`,\n );\n return true;\n } catch (err) {\n process.stderr.write(\n `Warning: could not seed from the prior review (${errMsg(err)}) — seeding the sentinel only\\n`,\n );\n return false;\n }\n })();\n\n // prior-same/prior-new split on whether the seeded review examined this exact commit; an unknown\n // prior SHA (older comment, or the all-zeros placeholder) falls to prior-new so the agent\n // re-checks against the current diff rather than assuming the code is unchanged. When nothing\n // could be seeded, empty-had-prior still tells the agent a prior review exists (vs a true first\n // review), and none marks even the sentinel write failing.\n const mode = ((): string => {\n if (seededFromPrior) {\n const priorSha = priorBody === null ? null : parseReviewedSha(priorBody);\n return args[\"head-sha\"] && priorSha && priorSha === args[\"head-sha\"].toLowerCase()\n ? \"prior-same\"\n : \"prior-new\";\n }\n if (!writeSentinel()) return \"none\";\n return priorBody === null ? \"empty\" : \"empty-had-prior\";\n })();\n process.stdout.write(`${mode}\\n`);\n },\n});\n\nconst adaptCmd = defineCommand({\n meta: {\n name: \"adapt\",\n description: \"Map a native agent-CLI result envelope onto the abstract SPEC envelope\",\n },\n args: {\n native: {\n type: \"positional\",\n description: \"Path to the native result envelope JSON (from the agent CLI)\",\n required: true,\n },\n adapter: {\n type: \"string\",\n description: 'Adapter to use (currently: \"claude-code\")',\n required: true,\n },\n \"agent-file\": {\n type: \"string\",\n description:\n \"Path to a file the agent was told to write its own validated findings JSON to (wins over the native envelope's structured_output/result when it validates)\",\n },\n \"agent-file-fallback\": {\n type: \"string\",\n description:\n \"Path to the last-valid findings snapshot, tried after --agent-file and before the native envelope; recovers the last valid state when a wall-clock kill left --agent-file truncated, so the review posts that instead of a 'did not complete' notice\",\n },\n route: {\n type: \"string\",\n description:\n 'Review route label to stamp into the envelope (e.g. \"full review\" or \"mechanic\")',\n },\n effort: {\n type: \"string\",\n description: 'Effort label to stamp into the envelope (e.g. \"max\" or \"low\")',\n },\n transcript: {\n type: \"string\",\n description:\n \"Path to the session transcript (main .jsonl). Its tree (main + subagents) gives the true wall + turn count the native envelope under-reports, and refills per-model usage when the native envelope is empty (e.g. after a wall-clock kill)\",\n },\n },\n run: async ({ args }) => {\n // The agent-file still holds the pre-seeded SENTINEL when the agent never wrote its own review\n // (content check — the same isSeedSentinel test the budget hook uses via the budget.ts SSOT, so\n // a coarse-timestamp filesystem can't misclassify a fresh draft). The sentinel never validates,\n // so it can't be recovered as a review; the flag only refines the \"did not complete\" message.\n // A missing draft is inert (there is no seed to recover), and a non-seeded caller sees nothing.\n // Size-gated: only a sentinel-sized file (plus a trailing-newline tolerance) can be the\n // sentinel, so a real review — the largest input read back — is never read twice per run.\n const agentFile = args[\"agent-file\"];\n const agentFileSize = agentFile ? statSizeOrNull(agentFile) : null;\n const seedUnrevised =\n agentFileSize !== null &&\n agentFileSize <= Buffer.byteLength(SEED_SENTINEL) + 2 &&\n isSeedSentinel(readFileOrNull(agentFile));\n const envelope = unwrapAdapt(\n adapt(requireAdapterName(args.adapter), readJSONOrAbsent(args.native), agentFile, {\n route: args.route,\n effort: args.effort,\n agentFileFallbackPath: args[\"agent-file-fallback\"],\n seedUnrevised,\n ...(args.transcript\n ? {\n transcriptFallback: (): TranscriptTelemetry =>\n transcriptFallbackFrom(args.transcript),\n }\n : {}),\n }),\n );\n process.stdout.write(`${JSON.stringify(envelope, null, 2)}\\n`);\n },\n});\n\nconst noticeCmd = defineCommand({\n meta: {\n name: \"notice\",\n description:\n \"Emit an abstract envelope for a run that produced no completed review (security block, triage error, setup failure, checkout failure, or empty run) — flagged incomplete so the commenter renders it honestly and won't bury a real review\",\n },\n args: {\n kind: {\n type: \"positional\",\n description: `One of: ${NOTICE_KINDS.join(\", \")} (an unrecognized kind renders a generic incomplete notice rather than failing — the pinned CLI is older than the workflow)`,\n required: true,\n },\n reasons: {\n type: \"string\",\n description:\n \"security-blocked / triage-error only: the triage's fail-closed reason string (empty/omitted ⇒ the no-reason wording)\",\n },\n \"sandbox-config\": {\n type: \"string\",\n description:\n \"no-output / triage-error only: path to the agent's sandbox-runtime settings (sandbox.json); its network.allowedDomains is named in the notice so an egress-blocked review self-diagnoses. Missing or unreadable ⇒ the allowlist is omitted (an early failure runs before the jail is set up).\",\n },\n },\n // An unrecognized kind degrades to a generic incomplete notice instead of exiting non-zero: a\n // `notice <kind>` call under the workflow's `set -euo pipefail` must never crash the assemble\n // step into posting nothing, and an unknown kind almost always means version skew, not a typo.\n run: ({ args }) => {\n if (!isNoticeKind(args.kind)) {\n process.stderr.write(\n `::warning::code-review notice: unrecognized kind \"${annotationSafe(args.kind)}\" — the pinned CLI is older than the workflow calling it; rendering a generic incomplete notice\\n`,\n );\n process.stdout.write(`${JSON.stringify(buildUnknownNoticeEnvelope(args.kind), null, 2)}\\n`);\n return;\n }\n // Read the sandbox config only for the kinds that name the allowlist (a jailed agent ran), so the\n // \"no-output / triage-error only\" contract is enforced by the handler, not just documented.\n const namesAllowlist = args.kind === \"no-output\" || args.kind === \"triage-error\";\n const agentAllowlist =\n namesAllowlist && args[\"sandbox-config\"]\n ? parseAgentAllowlist(readSandboxConfigForNotice(args[\"sandbox-config\"]))\n : [];\n process.stdout.write(\n `${JSON.stringify(buildNoticeEnvelope(args.kind, args.reasons, agentAllowlist), null, 2)}\\n`,\n );\n },\n});\n\nconst isExtractSchemaKind = (s: string): s is ExtractKind => s === \"findings\" || s === \"triage\";\n\n// no \"prices\" — unlike print-schema's kinds.\nconst requireExtractSchemaKind = (name: string): ExtractKind =>\n isExtractSchemaKind(name)\n ? name\n : fail(`Unknown kind \"${name}\" for extract — expected one of: findings, triage`);\n\n/** Fail-closed triage synthesized when the ladder can't recover a validated triage verdict — never\n * defaults to safe. */\nconst failClosedTriage = (outcome: Exclude<LadderOutcome, { kind: \"ok\" }>): Triage => ({\n safe: false,\n reasons: describeLadderFailure(outcome),\n});\n\nconst extractCmd = defineCommand({\n meta: {\n name: \"extract\",\n description:\n \"Recover findings/triage JSON from a native agent-CLI result envelope via the deterministic extraction ladder\",\n },\n args: {\n native: {\n type: \"positional\",\n description: \"Path to the native result envelope JSON (from the agent CLI)\",\n required: true,\n },\n adapter: {\n type: \"string\",\n description: 'Adapter whose native envelope shape to extract from (currently: \"claude-code\")',\n required: true,\n },\n kind: {\n type: \"string\",\n description: \"Schema kind to extract: findings | triage\",\n required: true,\n },\n \"agent-file\": {\n type: \"string\",\n description:\n \"Path to a file the agent was told to write its own validated JSON to (findings only — a documented no-op for triage)\",\n },\n },\n run: async ({ args }) => {\n requireAdapterName(args.adapter);\n const kind = requireExtractSchemaKind(args.kind);\n const input = { kind, native: readJSON(args.native), agentFilePath: args[\"agent-file\"] };\n const outcome = extractStructured(input);\n\n if (outcome.kind === \"ok\") {\n process.stdout.write(`${JSON.stringify(outcome.candidate, null, 2)}\\n`);\n return;\n }\n // A recovery miss is otherwise opaque (only the generic reason reaches the comment); trace what\n // each rung saw to stderr so the CI log alone explains the failure — no local repro needed.\n if (outcome.kind === \"none\" || outcome.kind === \"ambiguous\") {\n process.stderr.write(`extract: recovery failed —\\n${ladderFailureDiagnostics(input)}\\n`);\n }\n if (kind === \"triage\") {\n process.stdout.write(`${JSON.stringify(failClosedTriage(outcome), null, 2)}\\n`);\n return;\n }\n fail(describeLadderFailure(outcome));\n },\n});\n\nconst withoutPatch = (finding: Finding): Finding => {\n const copy = { ...finding };\n delete copy.patch;\n return copy;\n};\n\nconst readFileLines = (path: string): readonly string[] | null => {\n try {\n const rawLines = readFileSync(path, \"utf-8\").split(\"\\n\");\n return rawLines.length > 0 && rawLines[rawLines.length - 1] === \"\"\n ? rawLines.slice(0, -1)\n : rawLines;\n } catch {\n return null;\n }\n};\n\n/** Align/keep/drop one finding's `patch` against the real file at `<repoRoot>/<finding.path>`:\n * aligned to the patch's removed range, kept as-is for a pure insertion, or dropped (logged) when\n * the file can't be read or the patch doesn't apply. Never throws; a no-patch finding passes through. */\nconst validateFinding = (finding: Finding, repoRoot: string): Finding => {\n if (finding.patch === undefined) return finding;\n const lines = readFileLines(resolve(repoRoot, finding.path));\n if (lines === null) {\n process.stderr.write(\n `validate-patches: ${finding.path}: could not read file at \"${repoRoot}\" — dropping patch\\n`,\n );\n return withoutPatch(finding);\n }\n const result = validatePatch(finding.patch, lines);\n switch (result.kind) {\n case \"anchored\":\n return { ...finding, start_line: result.startLine, end_line: result.endLine };\n case \"keep\":\n // Applies cleanly but has no removed range to anchor a suggestion — leave the finding's own\n // start_line/end_line as the inline anchor; the renderer projects the patch to a ```patch block.\n return finding;\n case \"drop\":\n process.stderr.write(\n `validate-patches: ${finding.path}:${String(finding.start_line)}: ${result.reason} — dropping patch\\n`,\n );\n return withoutPatch(finding);\n }\n};\n\nconst validatePatchesCmd = defineCommand({\n meta: {\n name: \"validate-patches\",\n description:\n \"Validate each finding's patch against the real PR-head tree: align the finding's range and keep the patch when it anchors, keep it unaligned for a pure insertion, or drop it when it doesn't apply\",\n },\n args: {\n findings: {\n type: \"positional\",\n description: \"Path to findings JSON\",\n required: true,\n },\n \"repo-root\": {\n type: \"string\",\n description:\n \"Directory to resolve each finding's path against — the review job's checked-out, clean PR-head tree (default: .)\",\n },\n },\n run: async ({ args }) => {\n const findings = decode(FindingsCodec.decode(readJSON(args.findings)), \"findings\");\n const repoRoot = args[\"repo-root\"] ? resolve(args[\"repo-root\"]) : process.cwd();\n const validated = {\n ...findings,\n findings: findings.findings.map((f) => validateFinding(f, repoRoot)),\n };\n process.stdout.write(`${JSON.stringify(validated, null, 2)}\\n`);\n },\n});\n\nconst requireAdapterName = (name: string): AdapterName =>\n isAdapterName(name) ? name : fail(`Unknown adapter \"${name}\" — supported: claude-code`);\n\nconst isSchemaKind = (s: string): s is SchemaKind =>\n s === \"findings\" || s === \"triage\" || s === \"prices\";\n\nconst requireSchemaKind = (name: string): SchemaKind =>\n isSchemaKind(name)\n ? name\n : fail(`Unknown schema \"${name}\" — expected one of: findings, triage, prices`);\n\nconst requireSchemaPath = (kind: SchemaKind, version: string | undefined): string => {\n try {\n return schemaPathFor(kind, version);\n } catch (err) {\n return fail(errMsg(err));\n }\n};\n\nconst printSchemaCmd = defineCommand({\n meta: {\n name: \"print-schema\",\n description:\n \"Print a bundled schema JSON, ready to hand to a CLI's --json-schema (the $schema draft declaration is stripped)\",\n },\n args: {\n name: {\n type: \"positional\",\n description: \"Schema to print: findings | triage | prices\",\n required: true,\n },\n \"schema-version\": {\n type: \"string\",\n description: \"Schema major.minor version to print (default: latest)\",\n },\n },\n run: async ({ args }) => {\n const schemaKind = requireSchemaKind(args.name);\n const schemaPath = requireSchemaPath(schemaKind, args[\"schema-version\"]);\n process.stdout.write(\n `${printableSchema(schemaPath, schemaKind === \"findings\" && schemaPath === schemaPathFor(schemaKind))}\\n`,\n );\n },\n});\n\nconst defaultVersionCmd = defineCommand({\n meta: {\n name: \"default-version\",\n description:\n \"Print the in-force schema version the installed registry resolves by default — the value a draft should stamp as schema_version\",\n },\n args: {\n kind: {\n type: \"string\",\n description: \"Schema kind (findings | triage | prices); default: findings\",\n },\n },\n run: async ({ args }) => {\n const kind = requireSchemaKind(args.kind || \"findings\");\n process.stdout.write(`${defaultVersion(kind)}\\n`);\n },\n});\n\nconst MAX_NUDGES_DEFAULT = 5;\n\n/** Drain the Stop-hook payload on stdin so the caller never sees EPIPE; its content is unused (the\n * decision comes from the draft on disk). Skips on a TTY, where readFileSync(0) would block forever\n * waiting for an EOF that never comes; the real Stop hook writes then closes, so a held-open pipe\n * isn't the production path. */\nconst drainStdin = (): void => {\n if (process.stdin.isTTY) return;\n try {\n readFileSync(0);\n } catch {\n // no stdin\n }\n};\n\n/** Parse `--max-nudges`: a strict positive integer (`>= 1`). A loose `Number.parseInt` accepts\n * `\"5abc\"`/`\"0x5\"` and `0 >= 0` allows on the first call — both silently DISABLE the gate. Reject\n * anything not matching `^\\d+$`, and reject `< 1`, loudly: a gate that never blocks must be an\n * explicit choice (omit the hook), never a typo. */\nconst requireMaxNudges = (raw: string | undefined): number => {\n if (raw === undefined) return MAX_NUDGES_DEFAULT;\n if (!/^\\d+$/.test(raw)) {\n fail(`--max-nudges must be a non-negative integer; got \"${raw}\"`);\n }\n const n = Number.parseInt(raw, 10);\n if (n < 1) {\n fail(`--max-nudges must be >= 1 — a gate that never blocks must be omitted, not set to ${raw}`);\n }\n return n;\n};\n\nconst stopGateCmd = defineCommand({\n meta: {\n name: \"stop-gate\",\n description:\n \"Claude Code Stop-hook gate: refuse to let the agent end its turn until --draft validates against the schema (bounded by --max-nudges). With --print-settings, emit the --settings JSON that wires this as the Stop hook.\",\n },\n args: {\n draft: {\n type: \"string\",\n description: \"Path to the findings document the agent must produce and keep valid\",\n required: true,\n },\n kind: {\n type: \"string\",\n description:\n \"Schema kind to validate against: findings | triage | prices (default: findings)\",\n },\n schema: { type: \"string\", description: \"Path to a schema file (wins over --kind)\" },\n \"schema-version\": {\n type: \"string\",\n description: \"Schema major.minor to validate against (default: the draft's declared version)\",\n },\n \"max-nudges\": {\n type: \"string\",\n description: `Times to block before relenting so the step fails downstream as before (default: ${String(MAX_NUDGES_DEFAULT)})`,\n },\n counter: {\n type: \"string\",\n description: \"Path for the nudge counter (default: <draft>.nudges)\",\n },\n \"print-settings\": {\n type: \"boolean\",\n description: \"Print the Stop-hook settings JSON that wires this gate, then exit\",\n },\n },\n run: async ({ args }) => {\n const draftPath = resolve(args.draft);\n\n if (args[\"print-settings\"]) {\n const command = defaultHookCommand(draftPath, {\n kind: args.kind,\n schema: args.schema,\n schemaVersion: args[\"schema-version\"],\n maxNudges: args[\"max-nudges\"],\n counter: args.counter,\n });\n process.stdout.write(`${JSON.stringify(stopHookSettings(command))}\\n`);\n return;\n }\n\n drainStdin();\n\n const kind = requireSchemaKind(args.kind || \"findings\");\n const maxNudges = requireMaxNudges(args[\"max-nudges\"]);\n const counterPath = args.counter ? resolve(args.counter) : `${draftPath}.nudges`;\n\n // schemaPathFor throws (rather than the process-exiting requireSchemaPath) so that a draft\n // declaring an unsupported schema_version is caught by draftState and treated as invalid —\n // i.e. a block with a helpful message — instead of crashing the hook and letting the agent stop.\n const state = draftState(draftPath, (parsed) =>\n args.schema\n ? resolve(args.schema)\n : schemaPathFor(kind, args[\"schema-version\"] || derivedSchemaVersion(kind, parsed)),\n );\n\n const nudges = readNudges(counterPath);\n const decision = decideGate(state, nudges, maxNudges, draftPath, kind);\n if (decision.kind === \"block\") {\n // CRITICAL ordering: bump the counter FIRST, and emit the block ONLY after the increment is\n // durably persisted. If the write fails, do NOT block — a block we can't bound loops forever\n // (the counter never advances → `nudges >= maxNudges` is never reached). Allow the stop and\n // log: a missed nudge is far less bad than an unbounded block loop.\n try {\n bumpNudges(counterPath, nudges);\n } catch (err) {\n process.stderr.write(\n `stop-gate: cannot persist nudge counter at ${counterPath} → allowing to avoid an unbounded block loop: ${errMsg(err)}\\n`,\n );\n return;\n }\n process.stdout.write(`${JSON.stringify({ decision: \"block\", reason: decision.reason })}\\n`);\n }\n },\n});\n\nconst gatherCmd = defineCommand({\n meta: {\n name: \"gather\",\n description:\n \"Resolve the PR from the CI head SHA and gather review inputs (diff with git-diff fallback, PR context, prior bot review, untrusted PR conversation to triage, failing-job logs and the failing jobs' identities in failed_jobs.json) as files for the review agent\",\n },\n args: {\n repo: { type: \"string\", description: \"Repository (owner/name)\", required: true },\n \"head-sha\": {\n type: \"string\",\n description: \"Trusted head SHA to resolve the PR (from workflow_run.head_sha)\",\n required: true,\n },\n \"head-branch\": {\n type: \"string\",\n description: \"Head branch to disambiguate the PR when multiple share a commit\",\n },\n \"default-branch\": {\n type: \"string\",\n description:\n \"The repo's default branch — the trusted base the review checks out, and the reference for the full (triage) diff; a PR based on any other branch is treated as stacked\",\n required: true,\n },\n \"run-id\": {\n type: \"string\",\n description:\n \"CI run id (from workflow_run.id); its failing jobs' logs are downloaded on failure\",\n required: true,\n },\n conclusion: {\n type: \"string\",\n description:\n \"CI conclusion (e.g. success | failure); failure triggers failing-job log download\",\n required: true,\n },\n \"bot-login\": {\n type: \"string\",\n description:\n \"Bot login whose last PR comment is captured as prior review (default: github-actions[bot])\",\n },\n \"out-dir\": {\n type: \"string\",\n description: \"Directory to write gathered files into (default: current directory)\",\n },\n },\n run: async ({ args }) => {\n const result = await gather({\n repo: args.repo,\n headSha: args[\"head-sha\"],\n headBranch: args[\"head-branch\"],\n defaultBranch: args[\"default-branch\"],\n runId: args[\"run-id\"],\n conclusion: args.conclusion,\n botLogin: args[\"bot-login\"] || \"github-actions[bot]\",\n outDir: args[\"out-dir\"] ? resolve(args[\"out-dir\"]) : process.cwd(),\n });\n process.stdout.write(renderOutputs(result));\n },\n});\n\nconst postCmd = defineCommand({\n meta: {\n name: \"post\",\n description:\n \"Post a complete review (inline comments + sticky summary) from findings + envelope + diff\",\n },\n args: {\n findings: {\n type: \"positional\",\n description: \"Path to findings JSON\",\n required: true,\n },\n \"head-sha\": {\n type: \"string\",\n description: \"Trusted head SHA to resolve the PR (from workflow_run.head_sha)\",\n required: true,\n },\n repo: {\n type: \"string\",\n description: \"Repository (owner/name)\",\n required: true,\n },\n usage: {\n type: \"string\",\n description: \"Path to result envelope JSON (from agent CLI)\",\n required: true,\n },\n prices: {\n type: \"string\",\n description:\n \"Path to price map JSON (default: bundled schema/prices.example.json — all zero)\",\n },\n template: {\n type: \"string\",\n description:\n \"Path to Eta template file for the summary comment (default: bundled templates/comment.eta)\",\n },\n \"inline-template\": {\n type: \"string\",\n description: \"Path to inline comment Eta template (default: bundled templates/inline.eta)\",\n },\n route: {\n type: \"string\",\n description:\n \"Review route label; overrides the envelope's route when set (default: read from the envelope)\",\n },\n \"bot-login\": {\n type: \"string\",\n description: \"Bot login to trust for sticky comment upsert (default: github-actions[bot])\",\n },\n \"head-branch\": {\n type: \"string\",\n description: \"Head branch to disambiguate PR when multiple share a commit\",\n },\n effort: {\n type: \"string\",\n description:\n \"Effort label; overrides the envelope's effort when set (default: read from the envelope)\",\n },\n \"test-report\": {\n type: \"string\",\n description: TEST_REPORT_DESCRIPTION,\n },\n \"cloc-diff\": {\n type: \"string\",\n description: CLOC_DIFF_DESCRIPTION,\n },\n \"run-url\": {\n type: \"string\",\n description:\n \"Workflow run URL (transcript/traces), rendered as a link in the LLM Disclosure aside and in the review-object body\",\n },\n \"json-url\": {\n type: \"string\",\n description:\n \"URL to the machine-readable findings JSON artifact, pointed at from the sticky and each inline comment\",\n },\n \"convergence-threshold\": {\n type: \"string\",\n description: CONVERGENCE_THRESHOLD_DESCRIPTION,\n },\n \"nit-visibility-floor\": {\n type: \"string\",\n description: NIT_VISIBILITY_FLOOR_DESCRIPTION,\n },\n inline: {\n type: \"boolean\",\n description:\n \"Also render findings as inline review comments on the diff. Off by default: an inline thread cannot be revised by a later round, so stale threads accumulate. The review object is posted either way; with this off the sticky lists the findings instead\",\n },\n \"unverified-no-logs\": {\n type: \"boolean\",\n description:\n \"Mark the review unverified: the fast-fix route ran with no failing-job logs staged, so its findings came from the diff alone. The caller decides this — the logs are staged in the review job, not here\",\n },\n },\n run: async ({ args }) => {\n const priceResolution = resolvePrices(args.prices);\n await post({\n repo: args.repo,\n // The workflow's post step threads HEAD_REPO env (the fork's owner/name) — a finding\n // permalink targets the tree the reviewed SHA lives in (issue #231 r1). Absent/empty ⇒ the\n // base repo. Env rather than a flag: an older pinned CLI simply ignores it.\n headRepo: process.env[\"HEAD_REPO\"] || undefined,\n headSha: args[\"head-sha\"],\n botLogin: args[\"bot-login\"] || \"github-actions[bot]\",\n findingsPath: args.findings,\n envelopePath: args.usage,\n pricesPath: priceResolution.path,\n pricesProvided: priceResolution.kind === \"provided\",\n templatePath: resolveTemplatePath(args.template),\n inlineTemplatePath: resolveInlineTemplatePath(args[\"inline-template\"]),\n route: args.route,\n headBranch: args[\"head-branch\"],\n effort: args.effort,\n testReportPath: args[\"test-report\"],\n clocDiffPath: args[\"cloc-diff\"],\n runUrl: args[\"run-url\"],\n jsonUrl: args[\"json-url\"],\n convergenceThreshold: parseConvergenceThreshold(args[\"convergence-threshold\"]),\n nitVisibilityFloor: parseNitVisibilityFloor(args[\"nit-visibility-floor\"]),\n inline: args.inline,\n unverifiedNoLogs: args[\"unverified-no-logs\"],\n postedAt: formatUtc(new Date()),\n pricedAt: new Date(),\n });\n },\n});\n\nconst announceCmd = defineCommand({\n meta: {\n name: \"announce\",\n description:\n \"Post (or update) the sticky the moment a review starts — an in-progress placeholder linking the run — so a workflow_run review, which runs from the default branch and is otherwise invisible on the PR, is visibly under way. Preserves a prior sticky's embedded findings + reviewed-sha markers so the re-review seed survives the swap.\",\n },\n args: {\n \"head-sha\": {\n type: \"string\",\n description: \"Trusted head SHA to resolve the PR (from workflow_run.head_sha)\",\n required: true,\n },\n repo: {\n type: \"string\",\n description: \"Repository (owner/name)\",\n required: true,\n },\n \"run-url\": {\n type: \"string\",\n description: \"Workflow run URL the placeholder links to\",\n required: true,\n },\n \"bot-login\": {\n type: \"string\",\n description:\n \"Bot login to trust for the sticky comment upsert (default: github-actions[bot])\",\n },\n \"head-branch\": {\n type: \"string\",\n description: \"Head branch to disambiguate the PR when multiple share a commit\",\n },\n },\n run: async ({ args }) => {\n // Best-effort, like `react`: the in-progress sticky is cosmetic, so a transient API error must\n // warn and exit 0 rather than fail its job (the review + real comment proceed regardless).\n await announce({\n repo: args.repo,\n headSha: args[\"head-sha\"],\n botLogin: args[\"bot-login\"] || \"github-actions[bot]\",\n runUrl: args[\"run-url\"],\n headBranch: args[\"head-branch\"],\n }).catch((err: unknown) =>\n // `::warning::` so a persistently broken announce shows up in the run's annotations, not only\n // buried in the step log — `announce` otherwise reports success while having posted nothing.\n process.stderr.write(\n `::warning::code-review announce: could not post the in-progress sticky (${annotationSafe(errMsg(err))}) — continuing (cosmetic)\\n`,\n ),\n );\n },\n});\n\nconst isCheckIntent = (s: string): s is CheckIntent =>\n s === \"in_progress\" || s === \"neutral\" || s === \"failure\" || s === \"cancelled\";\n\nconst checkRunCmd = defineCommand({\n meta: {\n name: \"check-run\",\n description:\n \"Upsert the native 'Code review' check-run on the head SHA — the attribution surface that appears in the PR's own checks list and (writing to the base repo) works for fork PRs too. `in_progress` at review start, `neutral` when the review completes, `failure` when it didn't, `cancelled` when a cancelled review settles its own check (matched by details_url, so it never touches a superseding run's check). Forward-only: `failure`/`cancelled` never overwrite a completed review.\",\n },\n args: {\n repo: { type: \"string\", description: \"Repository (owner/name)\", required: true },\n \"head-sha\": {\n type: \"string\",\n description: \"Head SHA the check-run is anchored to\",\n required: true,\n },\n status: {\n type: \"positional\",\n description: \"One of: in_progress, neutral, failure, cancelled\",\n required: true,\n },\n \"run-url\": {\n type: \"string\",\n description:\n \"Workflow run URL the check-run's details link to (also the ownership key for `cancelled`)\",\n required: true,\n },\n },\n run: async ({ args }) => {\n if (!isCheckIntent(args.status)) {\n // Best-effort like `announce`: the check-run is an attribution aid, so an unknown status (version\n // skew) warns and exits 0 rather than failing the job the review otherwise proceeds through.\n process.stderr.write(\n `::warning::code-review check-run: unrecognized status \"${annotationSafe(args.status)}\" — expected in_progress, neutral, failure, or cancelled; skipping\\n`,\n );\n return;\n }\n await checkRun({\n repo: args.repo,\n headSha: args[\"head-sha\"],\n intent: args.status,\n runUrl: args[\"run-url\"],\n }).catch((err: unknown) =>\n process.stderr.write(\n `::warning::code-review check-run: could not upsert the check-run (${annotationSafe(errMsg(err))}) — continuing (attribution aid)\\n`,\n ),\n );\n },\n});\n\nconst reportIncompleteCmd = defineCommand({\n meta: {\n name: \"report-incomplete\",\n description:\n \"Post (or update) the sticky when a review job hard-failed and posted nothing — an attributed 'did not complete' notice linking the run, telling the reader to re-request; with --cancelled, the informational 'superseded — no action needed' notice instead (issue #139). Never buries a completed review, and never overwrites a superseding run's live in-progress placeholder.\",\n },\n args: {\n repo: { type: \"string\", description: \"Repository (owner/name)\", required: true },\n \"head-sha\": {\n type: \"string\",\n description: \"Trusted head SHA to resolve the PR (from workflow_run.head_sha)\",\n required: true,\n },\n \"run-url\": {\n type: \"string\",\n description: \"Workflow run URL the notice links to\",\n required: true,\n },\n \"bot-login\": {\n type: \"string\",\n description:\n \"Bot login to trust for the sticky comment upsert (default: github-actions[bot])\",\n },\n \"head-branch\": {\n type: \"string\",\n description: \"Head branch to disambiguate the PR when multiple share a commit\",\n },\n cancelled: {\n type: \"boolean\",\n description:\n \"This run was CANCELLED before completing (typically superseded by a newer run on the same branch) — post the informational 'superseded' notice, not the failure notice (issue #139)\",\n },\n },\n run: async ({ args }) => {\n await reportIncomplete({\n repo: args.repo,\n headSha: args[\"head-sha\"],\n botLogin: args[\"bot-login\"] || \"github-actions[bot]\",\n runUrl: args[\"run-url\"],\n headBranch: args[\"head-branch\"],\n cancelled: args.cancelled,\n }).catch((err: unknown) =>\n process.stderr.write(\n `::warning::code-review report-incomplete: could not post the notice (${annotationSafe(errMsg(err))}) — continuing\\n`,\n ),\n );\n },\n});\n\n/** Parse a `--max-duration`/ceiling flag to whole seconds; a bad value is trusted-config error, so\n * fail loudly rather than silently disabling the clamp. undefined ⇒ no ceiling. */\nconst requireCeilingSec = (raw: string | undefined): number | null => {\n if (raw === undefined) return null;\n const ms = parseWallMs(raw);\n if (ms === null)\n return fail(`--max-duration must be a duration like 60m, 3600s, or 1h (got \"${raw}\")`);\n return Math.floor(ms / 1000);\n};\n\nconst requireCeilingUsd = (raw: string | undefined): number | null => {\n if (raw === undefined) return null;\n const n = Number.parseFloat(raw.replace(/^\\$/, \"\"));\n if (!Number.isFinite(n) || n < 0) fail(`--max-usd must be a non-negative number (got \"${raw}\")`);\n return n;\n};\n\nconst requireMaxInstructions = (raw: string | undefined): number => {\n if (raw === undefined) return 4000;\n if (!/^\\d+$/.test(raw)) fail(`--max-instructions must be a non-negative integer (got \"${raw}\")`);\n return Number.parseInt(raw, 10);\n};\n\nconst requirePositiveInt = (raw: string, flag: string): number => {\n const n = Number.parseInt(raw, 10);\n return Number.isInteger(n) && n > 0 && /^\\d+$/.test(raw)\n ? n\n : fail(`${flag} must be a positive integer; got \"${raw}\"`);\n};\n\nconst requireWallMs = (raw: string | undefined, flag: string, fallback: string): number => {\n const ms = parseWallMs(raw || fallback);\n return ms === null\n ? fail(`${flag} must be a duration like 30m, 15s, or 1h (got \"${raw ?? \"\"}\")`)\n : ms;\n};\n\nconst parseCommandCmd = defineCommand({\n meta: {\n name: \"parse-command\",\n description:\n 'Resolve a PR\\'s head (SHA/branch/repo) from its NUMBER via the API and parse a ChatOps trigger comment (\"/code-review [24m] [$1.00] <instructions>\") into $GITHUB_OUTPUT lines. The untrusted comment is parsed here in type-safe code, never in workflow bash, and the head is resolved from the trusted PR number, never from the comment text. Emits should_run=false (and nothing else) when the comment is not the trigger, the PR is closed, or resolution fails.',\n },\n args: {\n repo: { type: \"string\", description: \"Repository (owner/name)\", required: true },\n pr: {\n type: \"string\",\n description: \"PR number (from github.event.issue.number — trusted event data)\",\n required: true,\n },\n \"comment-body\": {\n type: \"string\",\n description:\n \"The comment body to parse (default: the CODE_REVIEW_COMMENT_BODY env var — the safe way to pass untrusted text without shell interpolation)\",\n },\n trigger: {\n type: \"string\",\n description: 'Trigger token the comment must begin with (default: \"/code-review\")',\n },\n \"max-duration\": {\n type: \"string\",\n description:\n \"Ceiling the requested duration is clamped to (e.g. 60m); omit for no clamp — a comment could then request an unbounded wall, so set this\",\n },\n \"max-usd\": {\n type: \"string\",\n description: \"Ceiling the requested USD budget is clamped to (e.g. 5); omit for no clamp\",\n },\n \"max-instructions\": {\n type: \"string\",\n description: \"Max characters of free-form instructions kept (default: 4000)\",\n },\n },\n run: async ({ args }) => {\n const body = args[\"comment-body\"] || process.env[\"CODE_REVIEW_COMMENT_BODY\"] || \"\";\n const result = await parseCommand({\n repo: args.repo,\n prNumber: requirePositiveInt(args.pr, \"--pr\"),\n body,\n options: {\n trigger: args.trigger || \"/code-review\",\n maxDurationSec: requireCeilingSec(args[\"max-duration\"]),\n maxUsd: requireCeilingUsd(args[\"max-usd\"]),\n maxInstructionsLen: requireMaxInstructions(args[\"max-instructions\"]),\n },\n });\n if (result.kind === \"skip\") {\n process.stderr.write(`code-review parse-command: not running — ${result.reason}\\n`);\n process.stdout.write(renderCommandOutputs(result, \"UNUSED\"));\n return;\n }\n for (const note of result.args.notes)\n process.stderr.write(`code-review parse-command: ${note}\\n`);\n const delim = safeHeredocDelim(result.args.instructions, () => randomBytes(16).toString(\"hex\"));\n process.stdout.write(renderCommandOutputs(result, delim));\n },\n});\n\nconst requireReaction = (name: string): Reaction =>\n isReaction(name) ? name : fail(`Unknown reaction \"${name}\" — one of: ${REACTIONS.join(\", \")}`);\n\nconst reactCmd = defineCommand({\n meta: {\n name: \"react\",\n description:\n \"Add and/or remove a GitHub reaction on a PR/issue comment — the ChatOps acknowledgement (👀 on receipt, swapped to 🚀 on completion). Cosmetic: warns and exits 0 on any API error so a reaction never fails the job.\",\n },\n args: {\n repo: { type: \"string\", description: \"Repository (owner/name)\", required: true },\n \"comment-id\": {\n type: \"string\",\n description: \"Comment id to react on (github.event.comment.id)\",\n required: true,\n },\n add: { type: \"string\", description: `Reaction to add: ${REACTIONS.join(\" | \")}` },\n remove: {\n type: \"string\",\n description: \"Reaction (of the token owner) to remove after adding — for the 👀→🚀 swap\",\n },\n },\n run: async ({ args }) => {\n const commentId = requirePositiveInt(args[\"comment-id\"], \"--comment-id\");\n const add = args.add ? requireReaction(args.add) : undefined;\n const remove = args.remove ? requireReaction(args.remove) : undefined;\n if (add === undefined && remove === undefined)\n fail(\"react: nothing to do — pass --add and/or --remove\");\n await react({ repo: args.repo, commentId, add, remove }).catch((err: unknown) =>\n process.stderr.write(\n `code-review react: reaction update failed (${errMsg(err)}) — continuing (reactions are cosmetic)\\n`,\n ),\n );\n },\n});\n\nconst awaitCiCmd = defineCommand({\n meta: {\n name: \"await-ci\",\n description:\n \"Wait for the PR head's CI workflow run to conclude, then emit its REAL conclusion + run id to $GITHUB_OUTPUT (ci_settled, ci_conclusion, ci_run_id). The on-demand comment trigger uses this so it routes on the same CI result the CI-completion trigger would — success → full review, failure → mechanic with that run's logs — instead of reviewing blind. Polls until the run completes or the timeout elapses; ci_settled=false ⇒ no conclusive result (caller should decline to review, not guess).\",\n },\n args: {\n repo: { type: \"string\", description: \"Repository (owner/name)\", required: true },\n \"head-sha\": {\n type: \"string\",\n description: \"PR head SHA to find the CI run for (resolved from the trusted PR number)\",\n required: true,\n },\n \"ci-workflow\": {\n type: \"string\",\n description: 'CI workflow name to wait for — the name: of your CI workflow (default: \"CI\")',\n },\n timeout: {\n type: \"string\",\n description: \"Give up waiting after this wall (default: 30m)\",\n },\n \"poll-interval\": {\n type: \"string\",\n description: \"How often to re-check the run status (default: 15s)\",\n },\n },\n run: async ({ args }) => {\n const workflowName = args[\"ci-workflow\"] || \"CI\";\n const outcome = await awaitCiConclusion(args.repo, args[\"head-sha\"], {\n workflowName,\n pollIntervalMs: requireWallMs(args[\"poll-interval\"], \"--poll-interval\", \"15s\"),\n timeoutMs: requireWallMs(args.timeout, \"--timeout\", \"30m\"),\n });\n process.stderr.write(\n outcome.kind === \"concluded\"\n ? `code-review await-ci: CI run ${String(outcome.runId)} (\"${workflowName}\") concluded \"${outcome.conclusion}\"\\n`\n : `code-review await-ci: no run named \"${workflowName}\" concluded before the timeout — not reviewing.${\n outcome.seenNames.length > 0\n ? ` Workflow names seen for this head SHA: ${outcome.seenNames.join(\", \")} — check --ci-workflow matches one.`\n : \" No workflow runs were seen for this head SHA at all.\"\n }\\n`,\n );\n process.stdout.write(renderCiOutputs(outcome));\n },\n});\n\nconst checkScopeCmd = defineCommand({\n meta: {\n name: \"check-scope\",\n description:\n \"Validate + normalize the workflow's `scope` input — the languages/inputs the project accepts (issue #139). Prints the normalized space-separated language list for splicing into the review prompt, or nothing when the scope is empty (the reviewer then infers it from the README's first paragraph). A structurally malformed value is rejected rather than spliced in as-is.\",\n },\n args: {\n scope: {\n type: \"string\",\n description:\n 'The raw scope value — whitespace/comma/semicolon-separated language names (e.g. \"C C++\"); empty ⇒ absent',\n },\n },\n run: ({ args }) => {\n const parsed = parseScope(args.scope);\n switch (parsed.kind) {\n case \"absent\":\n return;\n case \"invalid\":\n return fail(`check-scope: ${parsed.reason}`);\n case \"ok\":\n process.stdout.write(`${parsed.languages.join(\" \")}\\n`);\n }\n },\n});\n\nconst sandboxConfigCmd = defineCommand({\n meta: {\n name: \"sandbox-config\",\n description:\n \"Emit the sandbox-runtime (srt) settings that jail the untrusted review agent's egress: allow the model host (derived from api_base_url), the GitHub API/host, and the consumer's extra_endpoints; deny all else; filesystem isolation off\",\n },\n args: {\n \"api-base-url\": {\n type: \"string\",\n description:\n \"The model endpoint the CLI dials (ANTHROPIC_BASE_URL) — its host is allowlisted\",\n required: true,\n },\n extra: {\n type: \"string\",\n description:\n \"Whitespace-separated host[:port] list of extra domains to allow (the extra_endpoints input)\",\n },\n out: {\n type: \"string\",\n description: \"Write the settings JSON here instead of stdout\",\n },\n \"known-model-host\": {\n type: \"string\",\n description:\n \"Additional model HOST(S) to treat as known (space-separated bare hostnames, not URLs) — the consumer's declared host(s) for a provider outside the built-in set; a derived host outside the built-ins and this list warns (or fails under --strict-host)\",\n },\n \"strict-host\": {\n type: \"boolean\",\n description:\n \"Fail (instead of warning) when the model host derived from api_base_url is not a well-known or declared host — closes the fail-open-on-typo gap where a mistyped api_base_url would still be allowlisted and sent the key\",\n },\n },\n run: ({ args }) => {\n // The jail derives its ONLY egress allowlist entry from api_base_url; a typo now fails OPEN (dials\n // whatever it names). Warn loudly on an unknown host so a misconfiguration is visible in the setup\n // log, or hard-fail under --strict-host. A consumer on a provider outside the built-in set declares\n // it via --known-model-host so it passes while a typo of it does not.\n const modelHost = deriveModelHost(args[\"api-base-url\"]);\n // Both --known-model-host AND --extra count as declared: extra_endpoints already allowlists a\n // consumer's self-hosted model host through this same jail (and the reusable documents that use),\n // so treating it as known avoids warning on a host the admin explicitly vouched for.\n const declaredHosts = [\n ...(args[\"known-model-host\"] ? parseExtraEndpoints(args[\"known-model-host\"]) : []),\n ...(args.extra ? parseExtraEndpoints(args.extra) : []),\n ];\n if (!isKnownModelHost(modelHost, declaredHosts)) {\n const message = `code-review sandbox-config: derived model host \"${modelHost}\" is not a well-known or declared host — the jail will allow egress to it and send MODEL_API_KEY there; verify api_base_url is correct`;\n // Both paths surface as GitHub annotations (::error:: hard-fails, ::warning:: continues), so the\n // same condition is visible the same way whether or not --strict-host is set.\n if (args[\"strict-host\"]) {\n process.stderr.write(`::error::${annotationSafe(message)}\\n`);\n process.exit(1);\n }\n process.stderr.write(`::warning::${annotationSafe(message)}\\n`);\n }\n const config = buildSandboxConfig({ apiBaseUrl: args[\"api-base-url\"], extra: args.extra });\n const json = `${JSON.stringify(config, null, 2)}\\n`;\n if (args.out) {\n writeFileSync(resolve(args.out), json);\n } else {\n process.stdout.write(json);\n }\n },\n});\n\nexport const main = defineCommand({\n meta: {\n name: \"code-review\",\n version: packageVersion,\n description: \"Deterministic commenter for agentic PR review\",\n },\n subCommands: {\n gather: gatherCmd,\n \"parse-command\": parseCommandCmd,\n react: reactCmd,\n \"await-ci\": awaitCiCmd,\n render: renderCmd,\n inline: inlineCmd,\n post: postCmd,\n announce: announceCmd,\n \"check-run\": checkRunCmd,\n \"check-scope\": checkScopeCmd,\n \"report-incomplete\": reportIncompleteCmd,\n cost: costCmd,\n \"check-cost\": checkCostCmd,\n validate: validateCmd,\n \"seed-draft\": seedDraftCmd,\n adapt: adaptCmd,\n notice: noticeCmd,\n extract: extractCmd,\n \"validate-patches\": validatePatchesCmd,\n \"print-schema\": printSchemaCmd,\n \"default-version\": defaultVersionCmd,\n \"stop-gate\": stopGateCmd,\n \"budget-hook\": budgetHookCmd,\n \"print-settings\": printSettingsCmd,\n deadline: deadlineCmd,\n \"sandbox-config\": sandboxConfigCmd,\n },\n});\n\n// Skip auto-invocation under the test runner — tests drive `main` directly via citty's runCommand.\nif (!process.env[\"VITEST\"]) {\n await runMain(main);\n}\n"]}