/** 拒体里逐字回显的键名条数上限。键名原样回显(不猜语义),但**条数有界** —— 一个塞满键的体不许把 400 响应 * 放大成流量面。超出部分只报数。 */ export declare const MAX_KEY_ECHO = 20; /** 键名回显的清洗:剥控制/双向字符(键名进的是 JSON 错误体与运维日志,一个 RLO 能把两行字读反), * 再按 {@link MAX_KEY_ECHO_CHARS} 截断。清洗之外**逐字**,不做大小写/近似猜测。 */ export declare function echoKeyName(prefix: string, key: string): string; /** 一次键闭集裁决的产物:一句 wire 文案 + 两张分类键名表(消费端可机读,不必解析文案)。 */ export interface KeyClosureIssue { message: string; /** 词表外的键(拼错/未来键),全路径形,已清洗+截断+排序+封顶。 */ unknownKeys: string[]; /** 上游合约(CC / SDK / 引擎)里合法、但本 service 不在这一面接线的键,同形。 */ unsupportedKeys: string[]; } /** 逐键分拣:受理集内跳过,`tolerated` 命中进 `unsupported`,其余进 `unknown`。两桶都拒,标签只影响文案。 */ export declare function scanKeyClosure(bag: object, prefix: string, accepted: ReadonlySet, tolerated: ReadonlySet, into: { unknown: string[]; unsupported: string[]; }): void; /** 一张分类表的文案片段(封顶后只报数)。 */ export declare function keyClosureClause(names: string[], label: string): string; /** 剥掉索引签名,只留**具名**键 —— `TaskRequestBody` 上那条 `[k: string]: unknown` 会让 * `keyof` 退化成 `string`,双向门就永远恒真(零判别力)。 * 🔴 **导出**(S-405):姊妹门 `request-value-closure.ts` 的双向钉要同一个剥法 —— 抄第二份 = 两处哪天 * 分岔(一边看得见索引签名、一边看不见)谁都发现不了,而两边的判别力都建立在「剥干净了」这句话上。 */ export type NamedKeysOf = { [K in keyof T as string extends K ? never : number extends K ? never : K]: T[K]; }; /** * FRESH 提交面的**顶层**键闭集裁决:受理集之外的键 ⇒ 返回拒体(调用方 400 `request.body_shape`); * 全部受理 ⇒ `null`。 * * 判据边界(与 settings 那只同源,有意窄):只判**键名**;体本身非对象 ⇒ 本门不判(留给既有的 * 「missing 'objective' string」那道门,免得同一个体被两句话抢答)。 */ export declare function taskBodyKeyIssue(raw: unknown): KeyClosureIssue | null; //# sourceMappingURL=request-key-closure.d.ts.map