@cyd-prc/dsh-audit-chain
v0.1.2
Published
The one tamper-evident JSONL audit chain every dsh guard shares: a multi-writer-safe writer (exclusive lock, fresh tail, torn-tail termination) and the chain-grading contract verifier. Extracted from dsh-entropy-guard and dsh-shape-guard, where the copies
Maintainers
Readme
dsh-audit-chain —— 一条链,一份实现
供 dsh 守卫插件(dsh-entropy-guard、dsh-shape-guard、dsh-threat-gate)共用的
防篡改 JSONL 审计链。它存在的原因:这条链过去活在两份副本里(entropy-guard 的
AuditLog 与 shape-guard 外抄出去的 lib/ledger.js),而副本会漂移——一个分级缺陷
(S3)曾搭车进两个已发布包;一份副本有的锁(wx + 新鲜链尾),要付出一次实测分叉事故
才传到另一份。
这个包终结漂移:一个写入者、一个分级器、一份契约。
是什么
import { ChainLog, verifyChain } from '@cyd-prc/dsh-audit-chain';
const chain = new ChainLog('/path/to/session.jsonl'); // 或 null(内存账本)
chain.record('gate_decision', { admitted: true }); // 带锁、新鲜链尾
chain.seal('acknowledged'); // 人类确认
const reading = chain.verify(); // 按契约分级- 写入者——每次追加取独占锁(
<chain>.lock:wx原子创建、超时破旧锁、 持锁过久则 fail-closed),在锁内重读磁盘链尾,并先终止崩溃撕断的破行再写入。 两个插件共享一条链,不可能再写出分叉。 - 分级器——
verify()实现共享链分级契约八条:内容哈希恒重算;分叉感知链接 (悬空 = 改写,可解析 = 分支);分叉计数永不提前停;封存界定顺序类发现(链化轴按seq、无链化轴按文件位置);篡改永不封存;不可解析行恒上报但不单独定级。 - 字节兼容两代历史写入者:
entropy-guard ≤ 0.3.3或shape-guard ≤ 0.1.6写的链 照常通过校验,本包写的链在两边的旧实现下也照常通过。哈希载荷的等价性由测试钉住, 不靠散文。
契约
docs/CHAIN-GRADING-CONTRACT.md 随包带一份逐字节镜像
(md5 500f62b603140477317ed03bec167553,v4)。权威件归测试侧;两份副本若哪天不一致,
指纹就是发现的方式,且以测试侧的读数为准。
工具
node tools/verify-chain.mjs <chain.jsonl> [--json] # 构造上只读;exit 0 = verified
node tools/verify-release.mjs --pack --run-tests # 发布前自证
node tools/verify-release.mjs --spec @cyd-prc/dsh-audit-chain@<v> --run-tests --wait 120verify-chain 刻意没有报告模式:当年的报告路径正是让旧工具往它审的链里写字的原因
(entropy-guard 缺陷 16)。这个工具只读,读完就走。
API 面
| 导出 | 是什么 |
|---|---|
| ChainLog | 链本体:record、seal、verify、entries、corruptLines、failures/lastError |
| verifyChain(path) | new ChainLog(path).verify() 的函数孪生,给纯读者 |
| encodeEntry / auditReplacer / hashEntry | 字节格式本身公开,写入者与分级器再无漂移空间 |
| chainStem / resolveChainDir | 守卫们定位共享文件的方式 |
| LOCK_TIMEOUT_MS / LOCK_BACKOFF_MS | 锁的调参常量 |
三个插件的迁移注记
- entropy-guard:
AuditLog变为子类,只加自己的读数(replayState、gearHistogram、gateAcceptanceRate)。一处措辞预期内变化:交错原因的文案在这里是 「two generations wrote this chain」(本包不预设插件)。 - shape-guard:
ShapeLedger成为ChainLog的别名;lib/ledger.js变成 re-export 适配层,引用方一行不动。 - threat-gate:删除 vendored 副本;
lib/VENDORED.md退役,换成真依赖。
测试
node --test test/core.test.mjs # 33 项,无依赖变更节
0.1.2
- 代码引用扫描跳过
node_modules/——内嵌依赖自己的测试文件不归本包担保 (它自己的verify-release已经担过)。entropy-guard 迁移现场咬出:第一份带内嵌依赖的--pack把内嵌进来的本包套件标记了出来。
0.1.1
ChainLog.readAll()——shape-guard 一侧历史上使用的读取形状({ entries, corrupt }), 迁移时的适配层因此是纯 re-export。verify-release现在检查根 packument(M6,测试侧咬出)。 版本文档与 tarball 都已 200 时npm install <name>仍可能失败——根文档传播更慢(实测:新包晚约 2.5 分钟)。这个窗口内--spec校验不再报绿;dist-tags.latest与被验版本不一致时打印一条 note (验旧版本是正常工作,不算失败)。verify-release认识bundleDependencies。 内嵌副本退出树比较(那是别人家的包), 但它们的版本是本发布的契约:每个内嵌副本必须与dependencies里的精确钉版一致—— 区间会让实件的字节取决于打包的时间。这正是三个插件迁移到本包时采取的形状。
0.1.0
- 首版,从两份漂移的副本抽出。见溯源节。
套件是两份历史实现的锚的并集(entropy-guard 缺陷 14/15/16/19/20、shape-guard I7–I13 / S1–S4),外加字节兼容针。
溯源
对照已发布实现写作(@cyd-prc/dsh-entropy-guard 0.3.3、@cyd-prc/dsh-shape-guard
0.1.6),并用契约点名的冻结真实 fixture 双向交叉验证:本包以契约合规读数读 fixture,
本包写的链在两份历史实现下都判 verified。MIT © Wang Miaosheng(ORCID: 0009-0003-2767-2421)。
