/** * [ref] —— **热键登记表**([ref] §4 机器门)。 * * 一个键「是不是热的」在本仓有三个互相独立的说法:①代码里真的接了写入面;②测试里真的有黑盒断言; * ③文档里对运维的承诺。三者任一漂了,受害者都是运维(改了配置,不知道该不该重启)。本表是**闭集单源**: * 键 → 组 → 换代手法 → **参数化用例 ID**(不是文件名——文件名粒度挡不住「文件在、用例没了」)。 * * 机器门在 test/config-hot/batch1-hot-keys-registry.test.ts:登记为热却没有三断言用例 = 红; * 表的键集与 stage 真正消费的键集(`BATCH1_LIMIT_KEYS`)不等 = 红。 * * ⚠️ 本表**只登记已落地的批**。批2-4 的键在各自批次里追加(设计稿 §6),不提前写进来 —— 一个「登记为热 * 但没接线」的条目正是本表要消灭的那种谎。 */ import type { ServiceConfigFlat, ServiceConfigGroups } from "../config-types.js"; /** 换代手法([ref] §2):A′=写入面接线(消费侧本就现读);B=值换代座位(对象已建、值被冻住)。 */ export type HotKeyForm = "A-prime" | "B-setter"; /** 三断言的用例 ID —— 与 test/config-hot 的参数化生成规则(`HK--`)逐字一致。 */ export interface HotKeyCases { /** 生效:改配置源 ⇒ ≤2 tick 行为面翻转。 */ readonly effect: string; /** 坏值拒:响亮拒 + 旧值继续服务。 */ readonly refuse: string; /** 回滚:改回 / center 撤键 ⇒ 行为回原状(无粘滞)。 */ readonly rollback: string; } export interface HotKeyEntry { readonly key: keyof ServiceConfigFlat; readonly group: keyof ServiceConfigGroups; readonly form: HotKeyForm; /** 落地批次(设计稿 §6 的批号)。 */ readonly batch: 1; readonly cases: HotKeyCases; } /** * 批1(cost 族)真正接线的 14 键 —— **stage 消费的单一真源**:`stage-limits.ts` 按本表遍历, * 所以「表里有、stage 不写」或「stage 写、表里没有」都不可能悄悄发生。 * * 前 3 个是 B 簇1(限额座 setter);其余 11 个是 limitsHttp 组的 A′ 接线键。 */ export declare const BATCH1_LIMIT_KEYS: readonly ["rateLimitPerMin", "maxPrincipalCostUsd", "costQuotaWindowSec", "maxTaskCostUsd", "maxTaskTokens", "infraCostRates", "attachmentOrphanGraceMs", "workspaceFileMaxBytes", "attachmentMaxBytes", "attachmentMimeAllowlist", "attachmentUnboundTtlMs", "drainGraceMs", "runStaleSec", "toolResultTtlSec"]; export type Batch1LimitKey = (typeof BATCH1_LIMIT_KEYS)[number]; /** * 🔴 **stage 消费但不热**的键(codex R2-F2,验真后降档)。 * * `costQuotaWindowSec` 在设计稿里归 B 簇(「加个 setter 就好」),那个判断的前提是「限额是比较参数,不是 * 行状态」—— 对**限额**成立,对**窗长**不成立:SQL 腿的窗长是**桶键的一部分**(`floor(now/windowMs)`, * 进 DB 主键)。热切窗长于是有两个真后果:①A→B→A 会在原 A 窗内**复活**切换前的花费(旧桶还在,桶号又 * 撞上);②B 期间 A 的高编号旧桶不被 `window_bucket < current` 的 reap 清理。内存腿只能靠「换窗即清」 * 才安全,于是两腿语义必然分裂 —— 同一条发布在不同后端给出相反的成本判决(后端相关的 fail-open)。 * * 处置:窗长**降为 restart-to-apply**(值仍逐次校验,变更逐次铸因、进世代账的 deferredKeys + 一条响亮 * warn),而不是给一个「在某些后端上会复活旧账」的热能力。真做热要给桶键加**世代隔离**(把窗长世代并进 * 持久化主键 + 跨副本一致的世代来源),那是独立的一件,归后续批。 */ export declare const DEFERRED_LIMIT_KEYS: ReadonlyArray<{ readonly key: Batch1LimitKey; readonly restartReason: string; readonly why: string; }>; /** 热键表 = 批1 消费键集**减去**显式 deferred 的那些(表只登记真的热的键)。 */ export declare const HOT_KEYS_REGISTRY: readonly HotKeyEntry[]; //# sourceMappingURL=hot-keys-registry.d.ts.map