@@ -46,6 +46,7 @@ import {
4646} from "./auto-tune" ;
4747import { computeGateEval } from "./parity" ;
4848import { LOOPOVER_NATIVE_SOURCE } from "./parity-wire" ;
49+ import { computeBlendedRuleGateEval , rulesBelowClosePrecisionFloor } from "./rule-gate-eval" ;
4950
5051/** PURE: parse the PR number an "Reverts #N / Reverts owner/repo#N" body refers to (GitHub's revert PRs).
5152 * Mirrors reviewbot runtime.ts parseRevertedPrNumber. Returns undefined when the body isn't a revert. */
@@ -224,6 +225,46 @@ export function createFlagStore(env: Env): FlagStore {
224225 } ;
225226}
226227
228+ // #7986: which deterministic rule codes currently sit below their OWN measured close-precision floor
229+ // (rulesBelowClosePrecisionFloor over computeBlendedRuleGateEval, #7984) — a cheap, cron-refreshed cache of an
230+ // otherwise-expensive fleet-wide aggregate, reusing system_flags (a generic key/value table, not booleans-only
231+ // despite its FlagStore-facing name above) so no schema change is needed. Mirrors the SAME "expensive compute
232+ // on a cron tick, cheap single-row read at decision time" split isHoldOnly/isCloseHoldOnly already use for the
233+ // project-level breaker flags. FAIL-SAFE: a read error, missing row, or unparseable value degrades to an EMPTY
234+ // set — exactly #7986's own "insufficient/unavailable data defaults to keeping the exemption" rule, never the
235+ // opposite direction (a read failure must never spuriously revoke every rule's exemption at once).
236+ const UNTRUSTWORTHY_RULE_CODES_FLAG_KEY = "rule_untrustworthy_codes:global" ;
237+
238+ /** Read the cron-cached set of rule codes currently below their close-precision floor. See this constant's own
239+ * doc comment above for the fail-safe contract. */
240+ export async function readUntrustworthyRuleCodes ( env : Env ) : Promise < ReadonlySet < string > > {
241+ try {
242+ const row = await env . DB . prepare ( "SELECT value FROM system_flags WHERE key = ?" )
243+ . bind ( UNTRUSTWORTHY_RULE_CODES_FLAG_KEY )
244+ . first < { value : string } > ( ) ;
245+ if ( ! row ?. value ) return new Set ( ) ;
246+ const parsed : unknown = JSON . parse ( row . value ) ;
247+ if ( ! Array . isArray ( parsed ) ) return new Set ( ) ;
248+ return new Set ( parsed . filter ( ( code ) : code is string => typeof code === "string" ) ) ;
249+ } catch {
250+ return new Set ( ) ;
251+ }
252+ }
253+
254+ /** Write the cron-computed set of rule codes currently below their close-precision floor, replacing whatever
255+ * was cached before (this is a SNAPSHOT, not an append-only log — a code that recovers or that no longer has
256+ * a large enough sample must disappear from the set on the next tick, not linger). Best-effort: a write
257+ * failure is swallowed, matching every other cron-tick cache write in this module — the NEXT tick will retry,
258+ * and until then {@link readUntrustworthyRuleCodes} keeps serving the last successfully-written snapshot. */
259+ async function writeUntrustworthyRuleCodes ( env : Env , codes : readonly string [ ] ) : Promise < void > {
260+ await env . DB . prepare (
261+ "INSERT OR REPLACE INTO system_flags (key, value, updated_at) VALUES (?, ?, CURRENT_TIMESTAMP)" ,
262+ )
263+ . bind ( UNTRUSTWORTHY_RULE_CODES_FLAG_KEY , JSON . stringify ( [ ...codes ] ) )
264+ . run ( )
265+ . catch ( ( ) => undefined ) ;
266+ }
267+
227268// ── review_audit append (the canonical eval/parity store) ───────────────────────────────────────────────────
228269
229270/** The target_id the gate-decision writer (parity-wire.ts) stamps — `project#pr`. The pr_outcome/reversal rows
@@ -828,6 +869,16 @@ export async function runSelfTuneBreaker(env: Env): Promise<void> {
828869
829870 await runBreakerPassForReport ( flags , plainPass . report , plainPass . engagedHoldonly , plainPass . engagedClosehold , nowMs , "" ) ;
830871 await runBreakerPassForReport ( flags , minerPass . report , minerPass . engagedHoldonly , minerPass . engagedClosehold , nowMs , "miner_" ) ;
872+
873+ // #7986: refresh the per-rule track-record cache the concrete-evidence breaker exemption reads
874+ // (readUntrustworthyRuleCodes) -- SAME window, pooled cross-project (a rule's trustworthiness is a
875+ // property of the rule, not of any one repo it happened to trip). Independent of the two passes above:
876+ // a failure here must not prevent (and does not roll back) the merge/close breaker engagement that just
877+ // completed -- computeBlendedRuleGateEval and writeUntrustworthyRuleCodes are both already fail-safe on
878+ // their own, so no extra try/catch is needed beyond this function's own outer one.
879+ const ruleReport = await computeBlendedRuleGateEval ( env , { days : BREAKER_EVAL_WINDOW_DAYS , nowMs, source : LOOPOVER_NATIVE_SOURCE } ) ;
880+ const untrustworthyCodes = rulesBelowClosePrecisionFloor ( ruleReport . rows ) . map ( ( row ) => row . ruleCode ) ;
881+ await writeUntrustworthyRuleCodes ( env , untrustworthyCodes ) ;
831882 } catch ( error ) {
832883 console . warn (
833884 JSON . stringify ( {
0 commit comments