Skip to content

Live override mutation is written before its audit record, and the audit write silently swallows errors — a config change can go live with zero audit trail #6420

Description

@JSONbored

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

maintainer-onlyOwner-only work — yields no Gittensor points.

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions