Context
Part of the review-stack architecture audit (parent epic — duplication dimension). Two smaller,
mechanical consolidations bundled together since both are low-risk, no-behavior-change cleanups:
Finding 1 — a second, unrelated githubHeaders duplication cluster
Outside review-enrichment/analyzers/ (tracked in a separate issue), there is a second cluster with no
shared implementation at all: src/github/app.ts:1174, src/scoring/model.ts:183,
src/services/contributor-issue-draft.ts:574, src/upstream/ruleset.ts:1277 — each with yet another
signature (token, accept params). Evidence there's no shared "GitHub HTTP client" helper anywhere in
src/, not just inside the enrichment package.
Fix: extract one shared helper (in src/github/ — check for an existing suitable home like
src/github/client.ts first) and replace all 4 call sites.
Finding 2 — inconsistent parameter convention in the CI/merge-state cache cluster
processors.ts:772-941's CI-aggregate cache cluster
(cachedFetchLiveCiAggregate/fetchLiveCiAggregateWithRequiredContexts/cachedLiveCiAggregate/
refreshLiveCiAggregate) takes 8-9 positional params including three consecutive same-shaped
optional strings (headSha, baseRef, token) with no compiler protection against transposition, while
neighboring large functions in the same file use a single labeled options object.
Note: the 3-layer cache architecture itself (cachedLiveCiAggregate → refreshLiveCiAggregate → reuseOrRefreshLiveCiAggregate) is NOT a finding — it implements three real, distinct, individually-
necessary cache semantics (durable cross-webhook cache; forced-live for act-boundary reads per the
documented #4220 correctness bug; same-pass reuse) and should be preserved as-is. Only the parameter
convention is the issue.
Fix: convert to a single options object — mechanical, no behavior change, removes a
TypeScript-invisible transposition risk.
Acceptance criteria
Context
Part of the review-stack architecture audit (parent epic — duplication dimension). Two smaller,
mechanical consolidations bundled together since both are low-risk, no-behavior-change cleanups:
Finding 1 — a second, unrelated
githubHeadersduplication clusterOutside
review-enrichment/analyzers/(tracked in a separate issue), there is a second cluster with noshared implementation at all:
src/github/app.ts:1174,src/scoring/model.ts:183,src/services/contributor-issue-draft.ts:574,src/upstream/ruleset.ts:1277— each with yet anothersignature (
token, acceptparams). Evidence there's no shared "GitHub HTTP client" helper anywhere insrc/, not just inside the enrichment package.Fix: extract one shared helper (in
src/github/— check for an existing suitable home likesrc/github/client.tsfirst) and replace all 4 call sites.Finding 2 — inconsistent parameter convention in the CI/merge-state cache cluster
processors.ts:772-941's CI-aggregate cache cluster(
cachedFetchLiveCiAggregate/fetchLiveCiAggregateWithRequiredContexts/cachedLiveCiAggregate/refreshLiveCiAggregate) takes 8-9 positional params including three consecutive same-shapedoptional strings (
headSha,baseRef,token) with no compiler protection against transposition, whileneighboring large functions in the same file use a single labeled options object.
Note: the 3-layer cache architecture itself (
cachedLiveCiAggregate → refreshLiveCiAggregate → reuseOrRefreshLiveCiAggregate) is NOT a finding — it implements three real, distinct, individually-necessary cache semantics (durable cross-webhook cache; forced-live for act-boundary reads per the
documented
#4220correctness bug; same-pass reuse) and should be preserved as-is. Only the parameterconvention is the issue.
Fix: convert to a single options object — mechanical, no behavior change, removes a
TypeScript-invisible transposition risk.
Acceptance criteria