/** * Canonical JSON(键递归排序、零空白、数组保序)—— 本仓所有「先序列化再 sha256 / 指纹自比」站点的**单一序列化器** * ([ref] / [ref],2026-08-31 合并批)。 * * ## 为什么只能有一个 * 合并前本仓有 **5 处**手写复刻(memory-origin-fence / permission-rule-store-sql / bench-l8 artifact / * config-center restart-signal / mcp-revocation),每处一份「排 key、递归、拼串」——同一个算法五份实现, * 语义在边缘(undefined 值键、函数成员、非有限数)各自漂了一点。指纹型代码的病灶恰恰在边缘:同一份内容算出 * 两个指纹 = 落库 checksum 失配 / 误签 restart / 包完整性自校验对不上。 * * ## 语义 = core `canonicalJsonStringify` 的**逐字港**(fidelity 高于「更漂亮」) * 治理携出包(`POST /v1/memory/export`)的 `integrity.sectionHashes.entries` 必须与 core 铸包/校验时算的 * 哈希**逐字节相同**(core `memoryBundleInvalid` 三向对账),而 core 公共面只出口 `computeMemoryBundleHash` * (Record 特化),不出口这只序列化器(`dist/core/memory-engine/file-backend.js#canonicalJsonStringify`, * exports 封死)——所以本仓必须持有一份逐字港,且**不得**在下游「修」它的边缘行为(源头修复纪律: * core 若改形,港随之改;本仓不做第二个写者)。防漂移钉 = `test/memory-origin-fence.test.ts` §④(期望哈希全 * 经 core 出口独立算出)。 * * 语义表(与 core 逐字同;`test/canonical-json.test.ts` 逐行钉): * · 对象:own 可枚举键,**值为 `undefined` 的键省略**(与 `JSON.stringify` 同),其余按 UTF-16 码元序排序 * (`Object.keys().sort()`,数字形键同样按字符串序:`"10" < "2"`);键经 `JSON.stringify` 转义。 * · 数组:保序;元素 `undefined` / 函数 / symbol ⇒ `null`(与 `JSON.stringify` 同)。 * · 标量:`JSON.stringify`(`NaN`/`±Infinity` ⇒ `null`、`-0` ⇒ `0`、字符串转义与 `JSON.stringify` 同)。 * · **非 JSON 输入的港继承形(不是本仓的设计,是 core 的形,如实记)**:对象成员为函数/symbol 时,键**保留** * 而值经 `JSON.stringify` 得 `undefined` ⇒ 拼出字面 `undefined`(非法 JSON 文本);顶层 `undefined`/函数/symbol * ⇒ 返回 `undefined`(非字符串)。五个站点的真实输入全是 JSON 形(JSON.parse 产物 / DB 行 / zod 解析产物), * 这两条**不可达**;需要「非法输入响亮拒」的站点用 {@link canonicalJsonStrict}。 * · `Date`/`Map`/`Set`/类实例:按普通对象处理(own 可枚举键 ⇒ `Date` 成 `{}`),**不调 `toJSON`**——与 core 同。 * · `bigint`:`JSON.stringify` 抛 TypeError,原样上抛。 * * ## 不在本文件里的第二形(如实登记) * `src/config-center/restart-signal.ts#stableStringify`(mcp-revocation 同源改调)是**另一个语义**:undefined 值键 * **保留为 `"k":null`**。两族在 JSON 形输入上逐字节相同(golden 交叉读数已证),分歧只在进程内构造的 * `{k: undefined}` 形——restart 指纹的输入正是进程内切片对象,该形原则上可达,而 `{k:undefined}` 与 `{}` 是否 * 同指纹是 restart-signal 轴上的**行为**(多签/少签一次 fleet 滚动重启),不是序列化器的私事 ⇒ 本批不并 * (语义恒等才可合并),golden 各自钉,K→O 统一另立件走三问。 */ /** core `canonicalJsonStringify` 的逐字港(语义表见文件头)。 */ export declare function canonicalJson(value: unknown): string; /** * 严格形:先按**同一遍历序**校验,再交 {@link canonicalJson} 序列化 —— 被签名/被内容哈希的载荷(bench/l8 部署 * 真实性 artifact)不许把 `NaN`/`Infinity` 静默写成 `null`(签名盖在坏字节上),也不许把函数/bigint/顶层 * `undefined` 当作可序列化。校验通过的输入域上,输出与 {@link canonicalJson} **逐字节相同**(golden 钉); * 拒绝集与错误文案 = 合并前 `src/bench/l8/artifact.ts#serialize` 逐字(`test/l8-deploy-contract.test.ts` 钉 * `/non-finite/`): * · 非有限数(任意深度)⇒ `canonicalJson: non-finite number is not serializable` * · `undefined`(顶层)/ 函数(任意深度,数组元素亦然)⇒ `canonicalJson: is not serializable` * · `bigint` ⇒ `canonicalJson: bigint is not serializable`;symbol ⇒ `canonicalJson: unsupported type symbol` * · 数组元素 `undefined` ⇒ `null`(放行);对象成员 `undefined` ⇒ 省略(放行)。 * 遍历序 = 数组下标序、对象**排序后**键序(多处坏值时抛出的是遍历序上第一处——与合并前行为同)。 */ export declare function canonicalJsonStrict(value: unknown): string; //# sourceMappingURL=canonical-json.d.ts.map