Context
src/review/outcomes-wire.ts's resolveDispositionReason (lines 282-297) is fully implemented and has a dedicated test suite (test/unit/outcomes-wire.test.ts:1100, describe("resolveDispositionReason (enriched Discord reason)"...)), but has zero call sites anywhere in src/ outside its own test file (confirmed via a repo-wide grep excluding test/).
Its own doc comment (lines 279-281) promises real, user-facing behavior: "Enrich a disposition notification with the AI's reasoning: the latest recorded gate verdict (the reasonCode summary on the most recent gate_decision row for this PR). Falls back to the plain disposition reason when no verdict is recorded or the read fails."
src/queue/processors.ts (lines 614-619) imports only isCloseHoldOnly, isHoldOnly, recordPrOutcome, recordReversalSignals from outcomes-wire.ts — not resolveDispositionReason. The very next comment block in outcomes-wire.ts itself (lines 370-373) acknowledges where real disposition notifications actually get sent: "Discord/Slack action notifications are emitted by the action executor... This outcome recorder only stores realized ground truth." That means the "enriched reason" this function was built to supply is never spliced into any live disposition notification today — it's complete, tested plumbing that was never wired to its intended caller.
Requirements
- Locate the action executor code path that actually emits Discord/Slack disposition notifications (per
outcomes-wire.ts:370-373's own pointer) and call resolveDispositionReason there in place of the plain disposition reason, so the enriched, verdict-aware reason the function already builds is the one users actually see.
- If investigation finds this function was deliberately built ahead of a not-yet-shipped consumer (rather than simply un-wired), document that finding in the PR instead of force-wiring it — but the default expectation, given the doc comment's unconditional promise and the fully-built test suite, is that this is a genuine missing wire-up.
- Do not change
resolveDispositionReason's own logic — it is already correct and tested; this is about calling it from the right place.
Deliverables
Test Coverage Requirements
This repo's Codecov patch gate is 99%+ patch coverage, hard, for src/**. The new call site and its branch (enriched vs. fallback reason) must be covered.
Expected Outcome
A PR's disposition notification (Discord/Slack) shows the AI's actual gate-verdict reasoning when one is on record, instead of only ever showing the plain disposition reason — matching what resolveDispositionReason's own doc comment has promised since it was built.
Links & Resources
src/review/outcomes-wire.ts (resolveDispositionReason, lines 279-297; the pointer comment at lines 370-373)
src/queue/processors.ts:614-619 (confirms the function is not currently imported there)
test/unit/outcomes-wire.test.ts:1100 (existing test suite for the function itself)
Context
src/review/outcomes-wire.ts'sresolveDispositionReason(lines 282-297) is fully implemented and has a dedicated test suite (test/unit/outcomes-wire.test.ts:1100,describe("resolveDispositionReason (enriched Discord reason)"...)), but has zero call sites anywhere insrc/outside its own test file (confirmed via a repo-wide grep excludingtest/).Its own doc comment (lines 279-281) promises real, user-facing behavior: "Enrich a disposition notification with the AI's reasoning: the latest recorded gate verdict (the reasonCode summary on the most recent
gate_decisionrow for this PR). Falls back to the plain disposition reason when no verdict is recorded or the read fails."src/queue/processors.ts(lines 614-619) imports onlyisCloseHoldOnly, isHoldOnly, recordPrOutcome, recordReversalSignalsfromoutcomes-wire.ts— notresolveDispositionReason. The very next comment block inoutcomes-wire.tsitself (lines 370-373) acknowledges where real disposition notifications actually get sent: "Discord/Slack action notifications are emitted by the action executor... This outcome recorder only stores realized ground truth." That means the "enriched reason" this function was built to supply is never spliced into any live disposition notification today — it's complete, tested plumbing that was never wired to its intended caller.Requirements
outcomes-wire.ts:370-373's own pointer) and callresolveDispositionReasonthere in place of the plain disposition reason, so the enriched, verdict-aware reason the function already builds is the one users actually see.resolveDispositionReason's own logic — it is already correct and tested; this is about calling it from the right place.Deliverables
resolveDispositionReasoncalled from the actual Discord/Slack disposition-notification code path (the "action executor" referenced inoutcomes-wire.ts:370-373)Test Coverage Requirements
This repo's Codecov patch gate is 99%+ patch coverage, hard, for
src/**. The new call site and its branch (enriched vs. fallback reason) must be covered.Expected Outcome
A PR's disposition notification (Discord/Slack) shows the AI's actual gate-verdict reasoning when one is on record, instead of only ever showing the plain disposition reason — matching what
resolveDispositionReason's own doc comment has promised since it was built.Links & Resources
src/review/outcomes-wire.ts(resolveDispositionReason, lines 279-297; the pointer comment at lines 370-373)src/queue/processors.ts:614-619(confirms the function is not currently imported there)test/unit/outcomes-wire.test.ts:1100(existing test suite for the function itself)