Severity: MEDIUM
Location: src/review/auto-apply.ts:282
Found via a full-system adversarial audit of the ORB review/scoring engine (2026-07-15) — 2 independent skeptic passes, both had to vote "confirmed" for this to survive.
Failure scenario
applyOverrideRecommendation (auto-apply.ts:276-291) calls await writeLiveOverride(env, project, payload) (or writeShadowOverride) FIRST, then await recordOverrideAudit(...) second; the promotion branch of runAutoApplyRecommendations (auto-apply.ts:358-362) does the same: writeLiveOverride, then deleteShadowOverride, then recordOverrideAudit. recordOverrideAudit (auto-apply.ts:241-250) wraps its own D1 INSERT in try/catch and swallows any error with only a comment ("telemetry must never break the apply path") — no retry, no re-throw, no alert. If the D1 write to override_audit transiently fails (e.g. a momentary D1 blip, which the module's own comments acknowledge happen — "a query error yields the base config") at exactly that moment, the live tunables_overrides row (or the promoted qualityGateMinScore, via resolveRepositorySettings) has already taken effect, but override_audit has no row for it.
Impact
The audit route (GET /v1/repos/:owner/:repo/selftune/overrides/audit) is the ONLY operator-facing visibility into why the autonomous loop changed their live gate config (there is no other alert/webhook). A silently-dropped audit row for a real mutation directly contradicts the subsystem's stated safety invariant ("Every action is recorded to override_audit", selftune-wire.ts:11; "every write is recorded to override_audit", migration 0047 header) and leaves the operator unable to explain or trace an unexpected strictness change in their gate.
Severity: MEDIUM
Location:
src/review/auto-apply.ts:282Found via a full-system adversarial audit of the ORB review/scoring engine (2026-07-15) — 2 independent skeptic passes, both had to vote "confirmed" for this to survive.
Failure scenario
applyOverrideRecommendation (auto-apply.ts:276-291) calls
await writeLiveOverride(env, project, payload)(or writeShadowOverride) FIRST, thenawait recordOverrideAudit(...)second; the promotion branch of runAutoApplyRecommendations (auto-apply.ts:358-362) does the same: writeLiveOverride, then deleteShadowOverride, then recordOverrideAudit. recordOverrideAudit (auto-apply.ts:241-250) wraps its own D1 INSERT in try/catch and swallows any error with only a comment ("telemetry must never break the apply path") — no retry, no re-throw, no alert. If the D1 write tooverride_audittransiently fails (e.g. a momentary D1 blip, which the module's own comments acknowledge happen — "a query error yields the base config") at exactly that moment, the livetunables_overridesrow (or the promoted qualityGateMinScore, via resolveRepositorySettings) has already taken effect, but override_audit has no row for it.Impact
The audit route (
GET /v1/repos/:owner/:repo/selftune/overrides/audit) is the ONLY operator-facing visibility into why the autonomous loop changed their live gate config (there is no other alert/webhook). A silently-dropped audit row for a real mutation directly contradicts the subsystem's stated safety invariant ("Every action is recorded to override_audit", selftune-wire.ts:11; "every write is recorded to override_audit", migration 0047 header) and leaves the operator unable to explain or trace an unexpected strictness change in their gate.