# Sigrid 宪章 v1.0 · 链上锚定记录 > 本文是《Sigrid宪章_v1.0.md》的**锚定凭证**,不是宪章的一部分。 > 宪章正文一经锚定即被 sha256 固定;本文与宪章分文件,正是为了让宪章永远可验证。 --- ## 1. 生效事实 宪章附则二规定:「本宪章 v1.0 自其全文 `sha256` 首次锚定于 Arweave 之时生效。」 **该条件已于 2026-11-11 满足。宪章 v1.0 自此生效。** | 项 | 值 | |---|---| | 交易 ID | `CIVyhQSDJKdpFWHFclD0vp-T-na8TnWE2AbP1tNnC_4` | | 出块高度 | `2040013` | | 区块 indep_hash | `V2OqzfCOUnlhSja2Pg1I2PhOhPFU0QzGkB8HIwnzD_NZjr8Zfuf7bDJs8BVp0Rg5` | | 内容 sha256 | `024d16b82c7b49b0eb279239d1f5cf4b2e6ab43f3a74285885c1b83115d2d93f` | | 内容字节数 | `19499` | | 签名钱包 | `APrs3ZdMsbZp_uAxIP3RacDVyLk9KjCVGu3woqLRxik`(金库,与 `EXPECTED_TREASURY` 一致) | | 实付费用 | `3538801190` winston = `0.003539` AR(≈ $0.011) | | 余额变动 | `5.982705` → `5.979166` AR(**扣款成功即交易已上链**) | | 锚定时刻 | `2026-11-11T09:39:39.796Z`(tag `Anchored-At`) | **tag(链上可查)**:`App-Name=sigrid`、`App-Version=1.0`、`Type=charter`、`Title=Sigrid 宪章 v1.0`、 `Content-SHA256=024d16b8…`、`Content-Bytes=19499`、`Sigrid-Kind=charter`、`Sigrid-Entity=Sigrid宪章`、 `Charter-Version=1.0`、`Effective-Rule=on-arweave-anchor`。 --- ## 2. 任何人可独立复核(不信本文件,信数学) ```bash # ① 取回原始字节 curl -L https://arweave.net/raw/CIVyhQSDJKdpFWHFclD0vp-T-na8TnWE2AbP1tNnC_4 -o charter.md # ② 自己算哈希 sha256sum charter.md # 应输出:024d16b82c7b49b0eb279239d1f5cf4b2e6ab43f3a74285885c1b83115d2d93f # ③ 查交易元信息与 tag curl https://arweave.net/tx/CIVyhQSDJKdpFWHFclD0vp-T-na8TnWE2AbP1tNnC_4 curl https://arweave.net/tx/CIVyhQSDJKdpFWHFclD0vp-T-na8TnWE2AbP1tNnC_4/status # 应返回 {"block_height":2040013, ...} ``` **实测复核结果(2026-11-11,出块后)**:三个不同运营方的网关均取回 `19499B`, sha256 全部等于 `024d16b8…`: | 网关 | 运营方 | 结果 | |---|---|---| | `arweave.net` | Arweave 官方 / HyperBEAM | ✅ 19499B,哈希一致 | | `turbo-gateway.com` | Turbo | ✅ 19499B,哈希一致 | | `ar-io.dev` | ar.io | ✅ 19499B,哈希一致 | | `permagate.io` | permagate | ⚠️ TLS 证书错配(`*.up.railway.app`),**该网关自体故障**,与本交易无关 | --- ## 3. 一条硬规矩:宪章不能再被就地编辑 宪章的效力挂在那个 sha256 上。因此: - **禁止**直接修改 `Sigrid宪章_v1.0.md` 的任何字节(包括标点、空行、frontmatter) - 任何修订 = **新版本号**(v1.1)+ **新的锚定交易**,旧版本留在链上,形成附则二所说的「版本链」 - 修订程序按附则一执行(宪法层:提前 90 天公示;运营层:提前 14 天公示) - 本文第 5 节记录已发现的待修订项,供 v1.1 处理 > 这不是形式主义。若允许就地改字,"宪章"就退化为一份随时可被运营者改写 README, > 第一条「人类最终放电权」与第八条「不可让渡底线」也就失去了可验证性。 --- ## 4. 本次锚定的工程前提(为什么以前做不到) ### 4.1 一直被当成"Arweave 挂了",其实是两条腿被混成一条 | 通道 | 实测 | 结论 | |---|---|---| | `arweave.net/info` 直连 | `000`(`UND_ERR_CONNECT_TIMEOUT`) | 不通 | | `arweave.net/info` 经代理 `127.0.0.1:7897` | `200` | **通** | | `up.arweave.net/info` 经代理 | `200` | **通** | | AO push 机队 | 8/9 ECONNRESET、push-5 证书过期 | 瘸的 | **Arweave 与 AO 是两条腿。Arweave 是通的,只有 AO 瘸。** 此前把两者混为一谈, 导致"宪章生效"被错误地绑定在一个其实不需要的依赖上。 ### 4.2 真正的阻塞点:Node 的 fetch 不读代理 Node ≥ 18 的全局 `fetch`(undici)**不读** `HTTPS_PROXY` / `HTTP_PROXY`, 也不读 Windows 系统代理(WinINET)。实测 Node `v22.23.3`:设了环境变量照样 `UND_ERR_CONNECT_TIMEOUT`。于是浏览器里能打开,脚本却说网络不通 —— 「同一台机器两个结论」,正是上次根因误判的形态。 解法:`ops/arweave/proxy-fetch.mjs` 手写零依赖 CONNECT 隧道 (`net.connect(proxy) → CONNECT host:443 → 200 → tls.connect({socket})`), 再把已握手的 socket 交给原生 `http.request({ createConnection })`。 不引 undici,不破坏本仓库的零依赖纪律。 ### 4.3 顺带挖出的第二个缺陷:写侧"假成功" 修好代理后第一次上传,报告 `✓ 已上传 `,但: - 余额**一分未扣**(`5.982705` 未变) - GraphQL 查不到该 tx,网络队列为 0 - 6 轮读回全 404 根因:`UPLOAD_GATEWAYS` 只有 `https://ar-io.dev`,而它**对任意 POST /tx 都返回 `200 text/html "OK"`** —— 它不是提交入口,是个静默黑洞。`uploadChunked` 当时只判 `r.ok`,于是每笔"上传成功"都是假的。 同一具 body(`{}`)的对照实测: | 端点 | 回应 | 语义 | |---|---|---| | `ar-io.dev/tx` | `200` + `text/html` + `OK` | **假成功** | | `up.arweave.net/tx` | `400` + AO 错误信封 | 真校验 | | `arweave.net/tx` | `400` + AO 错误信封 | 真校验 | | `turbo-gateway.com/tx` | `400` `Invalid JSON.` | 真校验 | 修法:写端点改为 `up.arweave.net` / `arweave.net`,并新增纯函数 `judgePostedTx()` 在**写侧**做内容校验(拒 HTML、拒 `"OK"`、拒含 `error`/`ao-result` 的 JSON、 拒回显 id 不一致)。回归 `uploader-writegate.test.mjs` 17 断言。 失败的交易 `WCWMNmMJJue_XlDWurRAl8Ojm_VMkuY95EiN_PehqwQ` 从未进入网络,未造成损失。 > 教训与 2026-10-15 那次同源:**"这家通"不等于"这家是那个服务"。** > 只判 HTTP 状态码,等于把"站点首页能打开"当成"API 能用"。 ### 4.4 未出块窗口的 multipart 包装体(已于 2026-11-11 修复) `arweave.net/raw/{tx}` 在交易**未出块**时返回 `multipart/form-data` 包装体 (19757B,比原文多 258B 的边界头),出块后才返回裸字节。 任何在"未出块"窗口里拿它比 sha256 的门禁都会失败,且失败原因看起来像"哈希不对"。 **为什么必须修而不是靠重试跨过**:重试只是把误报推迟。真正的危害是那句错误信息: 取回内容 ≠ 期望产物:19757B(期望 19499B)· ct="multipart/form-data; …" 它读起来是"内容被篡改",而真实原因是"还在等出块"。**哈希门禁误报成内容不对, 比不报更危险** —— 它会让人怀疑整个存证体系,信任一旦崩了很难修。 修法(`ops/arweave/uploader.mjs`):新增纯函数 `unwrapMultipart()`,`fetchRaw()` 改为 **先解包再算哈希**;解包成功仍由 sha256 裁决(标准未放宽)。fail-closed 判据: | 情形 | 处置 | |---|---| | 恰好 1 个 part | 解包,继续 sha256 | | ≥2 个 part | 拒绝(无法判断哪份是产物) | | 缺 boundary / 头部未闭合 / 缺结束标记 | 拒绝 | | 正文里恰好出现 boundary | 拒绝(宁可不给,也不交切错的字节) | 错误分型也随之分开:包装体解不开 ⇒ 专属错误码 `ARWEAVE_MULTIPART_UNCONFIRMED` (`isUnconfirmedWindow()` 可识别,措辞明确是"尚未出块");解包成功但内容真不对 ⇒ 仍报"`≠ 期望产物`",并附注"(multipart 已解包)"。 回归:`ops/arweave/uploader-multipart.test.mjs` 27 条断言。 ### 4.5 一次"看起来上传成功、其实从未进块"的重试(WCWMNmM…) 2026-11-11 09:29Z 的那次锚定尝试,脚本结尾打印了: ✓ 已上传:WCWMNmMJJue_XlDWurRAl8Ojm_VMkuY95EiN_PehqwQ 持久化校验:(未确认,见下) ! 独立复核未通过:Hostname/IP does not match certificate's altnames: Host: permagate.io… 当时的读回校验被 **permagate.io 的证书配置错误**挡住(证书只覆盖 `*.up.railway.app`), 于是 6 轮读回全部失败 —— 那一刻**无法区分**「网关坏了」与「交易根本没进块」。 事后用四个网关重查(`permagate.io` / `arweave.net` / `ar-io.dev` / `turbo-gateway.com`): | txId | 四网关结果 | 判定 | |---|---|---| | `CIVyhQSDJKdpFWHFclD0vp-T-na8TnWE2AbP1tNnC_4` | `ar-io.dev` 返回 19499B,sha256 命中 | ✅ 有效锚点 | | `WCWMNmMJJue_XlDWurRAl8Ojm_VMkuY95EiN_PehqwQ` | **全部 404** | ❌ 从未进块,作废 | **为什么值得写进记录**:那份失败记录里 `durable.ok=false`,但同一行的 `gateway` 与 `txId` 都在,看起来像"传上去了只是校验没成"。如果后来者(或未来的我)引用了 `WCWMNmM…`,就会指向一笔不存在的交易 —— 而它旁边还躺着一份"已上传"的日志。 **这个坑的形态与 §4.4 的 multipart 是同一类**:校验器必须能把「我这边看不到」 与「那边没有」分开。前者要换通路重试,后者要判定失败;把两者混成一句 「校验未通过」,就会出现"以为传上去了、其实没有"。 `anchors.jsonl` 已追加一条 `durable_recheck` 记录(只增不改),明确写死这条作废结论。 --- ## 5. 待 v1.1 修订的已知问题(不在本次锚定范围内) 锚定后发现的三处内部张力,需按附则一走 v1.1 修订,**不得就地改 v1.0**: 1. **附则二门槛(1 个锚点)低于第 3.2 条义务(≥2 个独立锚点)** ⇒ 宪章"生效即不满足自己"。建议 v1.1 改为「锚定于至少两个独立锚点之时生效」, 或明文允许「Arweave 先锚定即生效,须在 30 日内补齐 OTS,期间公示未达标」。 2. **第 3.3 条把「速率歧视」列为违宪,但未定义边界** `POST /api/anchor/verify` 实现了 16 KiB 请求体上限。判断:体量上限对**所有调用者一致**, 属资源边界而非歧视(否则任何人都能发一个请求让我们替他算上百万片叶子)。 v1.1 应在附则中加入一句定义:「体量上限属资源边界,不构成速率歧视;速率歧视指按调用者身份区别对待」。 3. **附则三「条款↔代码映射总表」在 M1 完成后已过期** 存证地基(`anchor/pipeline`、`canonical`、`merkle`、`guard`)已落地并通过 212 断言, 表中仍标「待实现(M1-M3)」。同时技术方案 §2 的 `AnchorStatus` 仍含 `SUBMITTED`, 与已修正的术语(`PENDING → BATCHED → ANCHORED`)冲突。 --- ## 6. 台账 机器可读台账:`ops/arweave/anchors.jsonl`(只增不改,一条一行)。 本次记录: ```json {"file":"Sigrid宪章_v1.0.md","bytes":19499,"sha256":"024d16b82c7b49b0eb279239d1f5cf4b2e6ab43f3a74285885c1b83115d2d93f","txId":"CIVyhQSDJKdpFWHFclD0vp-T-na8TnWE2AbP1tNnC_4","gateway":"https://up.arweave.net","winston":"3538801190","independent":{"ok":true,"gateway":"https://arweave.net"}} ``` --- *记录人:Cursor · 2026-11-11* *本记录本身尚未锚定。它证明的是宪章 v1.0 的链上存在性;它自身若需永久化,应另行锚定。* --- ## 附录(2026-11-11 晚 · 补记,不改动上文任何字节) 第 5 节第 1 项「宪章生效即不满足自己」已开始处理,但**尚未解决**: - 已把宪章同一份 sha256(`024d16b8…`)提交至 **3 个独立 OpenTimestamps 日历** (alice / bob / finney),证明存于 `ops/arweave/ots/024d16b8….ots`。 - 当前状态 **PENDING** —— 只有 `PendingAttestation`,日历尚未聚合成比特币交易。 - 因此第 3.2 条「≥2 个独立锚点」**仍差半步**,须待聚合完成并经 `--verify` 通过后才算达成。 详细记录见《Sigrid宪章_OTS锚定记录_v1.0.md》。 上文第 4、5 节所述 Arweave 事实与待修订项均未变化。