Severity: MEDIUM
Location: src/review/auto-apply.ts:190
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
writeLiveOverride (auto-apply.ts:189-195) does mergeOverride(await loadOverride(env, project), o) then INSERT OR REPLACE INTO tunables_overrides (project, confidence_floor, scope_cap_files, scope_cap_lines, applied_at) VALUES (...) — the column list omits clear_at, and SQLite's REPLACE deletes the existing row before inserting, so any previously-set clear_at (an operator's temporary-override expiration) is unconditionally nulled on the next write (e.g. the next shadow promotion). Separately, the internal loadOverride(env, project) call on that same line passes no nowIso argument, so inside rowToOverride (line 67) the row.clear_at && nowIso && ... guard short-circuits on the missing nowIso and an ALREADY-EXPIRED override (clear_at in the past) would be merged back in as still active rather than being dropped — this exact nowIso-omission behavior is asserted as expected in test/unit/auto-apply.test.ts:305-307, but only for the pure rowToOverride function in isolation, not for this call site's consequence. writeShadowOverride (auto-apply.ts:209-218) has the analogous column-drop for its own clear_at.
Impact
Currently low real-world impact because no code path in this repo writes a non-null clear_at (grep confirms it is set nowhere), so the bug is latent rather than actively firing today. But the moment a clear_at-based temporary-override feature is wired up (the schema is already provisioned for it), any subsequent live-override write (a manual force-apply, or a later shadow promotion) will silently strip the expiration and/or resurrect an override that should have already lapsed, turning an intended temporary tightening into a permanent one with no error or log signal.
Severity: MEDIUM
Location:
src/review/auto-apply.ts:190Found 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
writeLiveOverride (auto-apply.ts:189-195) does
mergeOverride(await loadOverride(env, project), o)thenINSERT OR REPLACE INTO tunables_overrides (project, confidence_floor, scope_cap_files, scope_cap_lines, applied_at) VALUES (...)— the column list omitsclear_at, and SQLite's REPLACE deletes the existing row before inserting, so any previously-set clear_at (an operator's temporary-override expiration) is unconditionally nulled on the next write (e.g. the next shadow promotion). Separately, the internalloadOverride(env, project)call on that same line passes nonowIsoargument, so inside rowToOverride (line 67) therow.clear_at && nowIso && ...guard short-circuits on the missing nowIso and an ALREADY-EXPIRED override (clear_at in the past) would be merged back in as still active rather than being dropped — this exact nowIso-omission behavior is asserted as expected in test/unit/auto-apply.test.ts:305-307, but only for the pure rowToOverride function in isolation, not for this call site's consequence. writeShadowOverride (auto-apply.ts:209-218) has the analogous column-drop for its own clear_at.Impact
Currently low real-world impact because no code path in this repo writes a non-null clear_at (grep confirms it is set nowhere), so the bug is latent rather than actively firing today. But the moment a
clear_at-based temporary-override feature is wired up (the schema is already provisioned for it), any subsequent live-override write (a manual force-apply, or a later shadow promotion) will silently strip the expiration and/or resurrect an override that should have already lapsed, turning an intended temporary tightening into a permanent one with no error or log signal.