采集与门禁方法

13 条零人工测量线 · 公开来源 · 数字自带生成日期 · 失败记事件不记零 · 更新 2026-10-30

这个站点每周/每月从公开来源抓取 13 条时间序列。没有人工填数,也没有估算:能抓到就写数字并附生成日期,抓不到就把该线隔离(quarantine)并公开原因,不用旧值冒充本期、不写 0 来凑一个"完整看板"。下面把采集状态机、真实遇到的失败以及发布前必须过的四道门禁逐项公开,便于任何人复核。

1. 一页数据怎么被判成可用

请求 → 200/202/204/403/417/429
       ├ 202 / 403 / 417 / 429 / 空正文  → RETRYABLE,退避后重试一次
       ├ 仍失败 → unavailable,写一条 data-source-unavailable 事件(带 HTTP 状态码与字节数)
       │           ├ 该源在 portfolio 中声明 tolerate:true → 只记事件,不阻断整轮
       │           ├ 命中反爬/限流状态码 → throttled,只记事件(环境性拦截,非数据消失)
       │           └ 其余 → blocking;仅当 blocking>0 或全线皆挂,本轮才判 collectFailure
       └ 恢复 200 → 写 data-source-recovered 事件,保留中断前的最后有效版本

实现见 scripts/line.mjs(RETRYABLE = new Set([202, 403, 417, 429]))。第三条分支是 2026-10-30 修出来的:原设计"任一页不可用即阻断整轮",会让一个反爬页面静默拖垮一整周的积累与发布。

2. 真实故障与处置(不是示例,是线上记录)

时间(UTC)线 / 页面观测处置与结果
2026-10-30 09:06:48sb253-docket / sb253-reportingHTTP 403,919 B(挑战页)按 RETRYABLE 重试;09:10:34 恢复 200,58,613 B,写 recovered 事件,数据未中断
2026-10-30 09:09:34sb253-docket / sb253-programHTTP 403,919 B重试;09:10:43 恢复 200,61,221 B
持续sb253-docket / sb261-docketCARB 对非浏览器客户端返回 417/202在 portfolio.json 声明 tolerate:true 并写明原因:该分卷长期不可抓取,主线数据由 sb253-reporting / sb253-program 承担。只记事件,不阻断
持续compute-futures / cme-computeHTTP 404(路径已下线)同法声明豁免;该线仍因其他源缺失而拒绝给出成功退出,不拿旧值顶替

事件原文见 data/lines/*.json 的 collect.events,每条带 date、page、status、bytes、reason。

为什么 417 被当成"环境性拦截"而不是"数据源死了":反爬挑战页会返回 417/202 与一段 HTML(本例 919 B),内容不是数据。把它记成不可用并阻断发布,等于让对方的反爬策略决定我们有没有数据;把它悄悄记成 0,等于编数字。所以只记事件、保留最后有效版本、并在页面与 llms.txt 里说明该源受限。

3. 发布前的四道门禁

scripts/assurance-gate.mjs 依次跑四项,任一非零退出即整轮拦下,publish.mjs 还会校验门禁结果是否来自同一 commit 与同一输入指纹。

门禁检查什么2026-10-30 结果
verify页面存在、含生成日期、页面数字与重算值一致、事件必须带日期PASS
contracts数据契约 schema、单位、去重、非空13 条契约 / 105 条断言 全通过
fixtures39 个构造样本(正常/空/缺字段/类型错/单位错/重复/HTTP 429)39/39 PASS(3 条 not_applicable,3 条 marker)
fault-injection往副本里注入 6 类故障,要求 gate 拦下且真实数据哈希不变6/6 全部 BLOCKED,真实数据未变

门禁结果落盘于 assurance/.gate/result.json:passed:true、head:df87cd6、inputs_hash:ef6f2815f12d0053…,四项 exitCode 均为 0。
故障注入 nightly 记录(docs/assurance/fault-injection.md):column-rename 与 unit-mw-to-gw 拦在 fixtures;empty-response 与 truncated-data-file 拦在 verify;http-429 与 duplicate-rows 拦在 contracts——拦截点是分散的,说明门禁不是只靠一条规则兜底。

4. 可复算产物

每轮门禁都会导出一份自包含的校验快照,含各检查的退出码、样本清单、数据文件 sha256 与首次观测时间,可直接下载后重算:

assurance/artifact-2026-10-30.json

本地复算:

git clone https://github.com/xka0085-byte/longgame && cd longgame
npm i
node scripts/assurance-gate.mjs      # 四项检查,等价于上面的门禁
sha256sum data/lines/sb253-docket.json   # 与快照里的 raw_sha256 对齐

5. 这套流程被谁用过

站点里 mcpreflight-weekly 这条线做的是 MCP 生态周度普查,工具就是开源项目 mcpreflight。它在这套门禁下的实际表现(含端点普查口径、随机样本复算方式、以及同样被反爬拦下的处置)写在对方的案例页里:
mcpreflight 案例:longgame 的 MCP 端点周度普查

6. 边界

7. 口径变更记录

判定定义发生过变化的,全部记在这里。旧口径产生的历史事件保留原样,不重建、不回填,也不追改已经发出的数字。

生效线变更原因与影响
2026-11-04 修复,下一个跨周采集起生效trust-delta变更判定从「每次刷新的差」改为「ISO 自然周口径」:同日或同周的重跑只刷新已存状态,不产生事件;事件只能来自 baselineEligible 的锚点,且必须跨自然周2026-11-02 的同一日内重跑(scanDate 等于 comparedAgainst)在 41 条事件里贡献了 40 条(20 条升级 + 20 条降级),使页面报出「变更 171 次」。这不是周变化,是重扫波动。修复见提交 44a3bc6;11-02 及之前的事件流按旧口径保留,该线数字在下一次跨周采集后按新口径重算

新增口径先写进本表再上线。本表只追加、不删行;口径变更不修改历史记录,只影响此后产生的判定。