@@ -165,6 +165,12 @@ export type FocusManifestGateConfig = {
165165 * `linkedIssueSatisfaction` immediately above in shape, but is a purely structural check, not an AI
166166 * opinion, so it carries none of that feature's AI-budget/confidence-floor machinery. */
167167 contentLaneDeliverable : GateRuleMode | null ;
168+ /** `gate.backtestRegression` (#8105, epic #8082): off|advisory|block, advisory by default — governs what a
169+ * REGRESSED pre-merge backtest verdict (#8138 threshold / #8139 logic) does. `advisory` renders the
170+ * comparison but never blocks (the shipped pre-#8105 behavior); `block` escalates it into a
171+ * `backtest_regression` hard blocker; `off` silences the backtest advisory entirely. DB-backed
172+ * (dashboard-settable too); this overrides the stored value like every other `gate:` field. */
173+ backtestRegression : GateRuleMode | null ;
168174 dryRun : boolean | null ;
169175 /** `gate.premergeContentRecheck` (#2550): for a PR touching `migrations/**`, re-verify against a live,
170176 * freshly-fetched tip of the base branch — unioned with this PR's own new migration filenames — for a
@@ -1303,6 +1309,7 @@ const EMPTY_GATE_CONFIG: FocusManifestGateConfig = {
13031309 selfAuthoredLinkedIssue : null ,
13041310 linkedIssueSatisfaction : null ,
13051311 contentLaneDeliverable : null ,
1312+ backtestRegression : null ,
13061313 dryRun : null ,
13071314 premergeContentRecheck : null ,
13081315 requireFreshRebaseWindowMinutes : null ,
@@ -1788,6 +1795,7 @@ function parseGateConfig(value: JsonValue | undefined, warnings: string[]): Focu
17881795 selfAuthoredLinkedIssue : normalizeOptionalGateMode ( record . selfAuthoredLinkedIssue , "gate.selfAuthoredLinkedIssue" , warnings ) ,
17891796 linkedIssueSatisfaction : normalizeOptionalGateMode ( record . linkedIssueSatisfaction , "gate.linkedIssueSatisfaction" , warnings ) ,
17901797 contentLaneDeliverable : normalizeOptionalGateMode ( record . contentLaneDeliverable , "gate.contentLaneDeliverable" , warnings ) ,
1798+ backtestRegression : normalizeOptionalGateMode ( record . backtestRegression , "gate.backtestRegression" , warnings ) ,
17911799 dryRun : normalizeOptionalBoolean ( record . dryRun , "gate.dryRun" , warnings ) ,
17921800 premergeContentRecheck : normalizeOptionalBoolean ( record . premergeContentRecheck , "gate.premergeContentRecheck" , warnings ) ,
17931801 requireFreshRebaseWindowMinutes : normalizeOptionalPositiveInteger ( record . requireFreshRebaseWindow , "gate.requireFreshRebaseWindow" , warnings ) ,
@@ -1845,6 +1853,7 @@ function parseGateConfig(value: JsonValue | undefined, warnings: string[]): Focu
18451853 gate . selfAuthoredLinkedIssue !== null ||
18461854 gate . linkedIssueSatisfaction !== null ||
18471855 gate . contentLaneDeliverable !== null ||
1856+ gate . backtestRegression !== null ||
18481857 gate . dryRun !== null ||
18491858 gate . premergeContentRecheck !== null ||
18501859 gate . requireFreshRebaseWindowMinutes !== null ||
0 commit comments