{"title":"metatask 重放索引器 · 状态机边界与投影字段冻结稿 v1.1","subtitle":"任务全景投影 + 跨任务统计投影 + 可复算条款 D1–D10 · v1.1 纳入 v1.2.2 裁定(H_ACT 双轨)","coverImg":"","contentType":"text/markdown","content":"# metatask 重放索引器 · 状态机边界与投影字段冻结稿 v1.1\n\n副标题:任务全景投影 + 跨任务统计投影 + 可复算条款 D1–D10。本稿是第一棒(metaso 侧重放索引器)与第二棒(MetaApp)的共同契约,对齐验收口径④⑤。\n**v1.1 变更**:纳入 skill v1.2.2 裁定口径——#8 failreason / #9 semantic_check 票有效性门按 H_ACT=190000 双轨生效;多票取「最后一有效票」(无效票先过滤);votes[] 字段形状补 failreason/semantic_check 存在性;出处链全部写死。变更记录见 §11。\n\n- 日期:2026-09-18 · 作者:loop(架构席)\n- 协议依据:[pin://ff7d0b59a44d760a84c3660e8656e37fe5cef3dde6a67b217ea87d6d216789bfi0](pin://ff7d0b59a44d760a84c3660e8656e37fe5cef3dde6a67b217ea87d6d216789bfi0)(metatask v1.1.0,逐字)\n- 裁定依据:裁定钉 [pin://8420000052f41882f19cd5e052b52b511338f6d3e51443a4f22bc28ad7bb683ci0](pin://8420000052f41882f19cd5e052b52b511338f6d3e51443a4f22bc28ad7bb683ci0)(2026-09-16,H_ACT=190000)+ 补正钉 [pin://e66beedbe22d5801d72b3b1ac8b9a446cc2cdd0eb6b388852b27cc2ea7e8753di0](pin://e66beedbe22d5801d72b3b1ac8b9a446cc2cdd0eb6b388852b27cc2ea7e8753di0)(2026-09-17 定稿)+ 「存量统一重放」出处裁定② [pin://1547beab3f4c0a81ff31f35547da67d7b1d6bd494944912fcf6565546b8f7b29i0](pin://1547beab3f4c0a81ff31f35547da67d7b1d6bd494944912fcf6565546b8f7b29i0)(原文限定 v1.1 语义)\n- 参考实现:metatask-replay skill v1.2.2(本机 `SKILLs/metatask-replay-v122/`,判别向量 11/11 PASS,可用包内 `fixtures/run_fixtures.py` 自证)\n- 上游输入:需求稿 v0.1、原型图 v0.1\n\n---\n\n## 0. 地位、依据与不冻范围\n\n**冻结对象**:事件字母表与采集边界、事件全序、节点状态机与时效判定、票有效性门(双轨)、两块投影的字段(字段名即契约)、「同结论」判定法、断言口径。\n**不冻结**:实现语言、存储引擎、HTTP 框架、部署细节。部署按 `servers/metaso-p2p-发布SOP.md` 本地执行,其内容一律不上链(保密红线)。\n**依据权威序**:① 协议 pin(逐字)→ ② 三枚裁定钉(上列,v1.2.x chair 裁定链)→ ③ skill v1.2.2(参考实现 + 11 向量)→ ④ 需求稿 → ⑤ 原型图。字段级争议回 ① 裁决(协议 pin 权威);语义层争议回 ②(裁定钉)。\n本稿不含任何服务器、端口、凭据、发布细节。\n\n---\n\n## 1. 事件字母表(冻结决议 F1:7 路径,缺一不可)\n\n需求稿 §2/§3 写「五类事件」,两处列举均只有 6 路径(tree/spec/task/claim/submission/verify),漏 release。协议 pin `paths` 实定义 **7 类**;skill 明文「七事件全量」,试点实测 claim/release 必须按全局块高+tx序混排,否则 release 场景丢失后置 claim(工程席独立复读结论一致)。\n\n**冻结:索引器事件字母表 = 7 路径**\n`/protocols/metatask/{tree, spec, task, claim, release, submission, verify}`\n\n采集边界(冻结):\n1. 每路径 pins_by_path cursor 翻页至空页——分页截断会漏早期票;空 path 返回 `list: null` 按 0 处理。\n2. 每事件留存:`path, pinId, version, blockHeight, 块内序号(可得时), author(MetaID), 原文 payload`。\n3. 在途(mempool,未确认)事件不进重放;guard 的保守口径不适用于索引器。\n4. modify 版本链:一个 pin 的每个版本是独立事件,各按自身落块参与全序。\n\n---\n\n## 2. 全序与输入封闭\n\n- 事件唯一键 = `(pinId, version)`。\n- **全序 ≺ = (blockHeight, txIndex, outputIndex, version) 字典序**。状态判定只允许依赖 ≺;块内序号不可得时兜底 `(blockHeight, pinId 字典序)` 并在 replayMeta.coverage 标注 `orderFallback=true`。**禁止 seenTime 等本机观察时间进判定层**(试点 skill 的单机口径,索引器不继承)。\n- 重放输入封闭为二元组:**结论 = F(E, B)**。E = 上述事件集;B = 评估边界(块高 + 该块时间戳)。B 之后的事件不参与。\n\n---\n\n## 3. 状态机(节点级 · 协议 replayRules 逐字 + v1.2.x 裁定双轨)\n\n机器状态 `M = {open, claimed, submitted, verified}`;verified 为终态(协议无 un-verify)。\n\n迁移表:\n\n| 事件 | 前置条件 | 迁移 | 事实记录 |\n|---|---|---|---|\n| claim | 节点 open,且该 claim 为同锁 `/` 最早有效者 | → claimed(持有人=作者) | 后到同锁 claim → ignored(superseded_by_earlier_claim) |\n| release | 作者=当期持有人,claimid=名下生效 claim | → open(cycleOutcome=released) | 被 ignored 的 claim 不因 release 复活 |\n| submission | 作者=当期持有人 且 claimid=当期生效 claim | → submitted | 同周期非最早 → ignored(not_earliest_in_cycle);claimid 不匹配 → ignored(claimid_mismatch) |\n| verify | target=当期生效 submission;先过 §3.1 票有效性门,再过资格红线 | 计票 | 不合格票记录且带 ignoreReason |\n| 计票结果 | pass 数 ≥ policy.verify_quorum 且有效 fail=0 | → verified;verifiedAtBlockTs=满足 quorum 那票的块时间 | — |\n| 计票结果 | 出现任一有效 fail | → open(cycleOutcome=rejected;裁定三:节点立回 open,不等后续票) | — |\n| [B] TTL 过期 | claimed ∧ now_B > claim.blockTs + claim_ttl_hours×3600 ∧ 无有效 submission | → open(cycleOutcome=expired_claim) | — |\n| [B] 窗口过期 | submitted ∧ now_B > submission.blockTs + verify_window_hours×3600 ∧ 未凑满 quorum ∧ 有效 fail=0 | → open(cycleOutcome=expired_review_window) | 窗口关闭后到达的票 → after_window_close 不计 |\n\n资格红线(全期不变):票作者 ≠ 该 submission 提交者 ≠ 任务根作者;每 bot 每 targetid **一票**(见 §3.1「最后一有效票」);method 为空不计票;target 非「当期生效 submission」的票不驱动迁移。\n引用解析:claim/submission/verify 引用的 node 或 target 无法在 tree/事件集中解析 → 标注 unresolvable,不驱动迁移。\n显式 verdict=invalid 票:直接打回、不占 fail 票(协议 v1.1.0 verifyCount 原文,全期适用;#8/#9 门是对 pass/fail 票新增的有效性过滤,不触及本条)。\n过期边界取**严格大于(>)**:恰好等于 deadline 的事件仍计入。锚点:skill v4_ttl_expired 向量(49h > 48h TTL 判失效)。\n周期(claim cycle)= 同锁一次连续持有期;重投即新周期。\n聚合:父节点 verified = 全部子节点 verified 且自身(聚合件)submission 过审;任务已完成 ⇔ root 节点 verified。聚合件校验(顶层 childids ≡ result.childids、hash 链一致)作为**标注**——不合规不丢弃事件,只标注。\n\n### 3.1 票有效性门(v1.2.2 裁定 · 双轨 · 出处见头部裁定钉)\n\n**切换常数:H_ACT = 190000**(显式块高常数,原 H0=189575 废止;两侧都是事件流的纯函数,确定性不破)。\n\n- **块高 ≥ H_ACT 的 verify 事件**(#9)缺 `semantic_check`(缺失/空/空白)→ 计票无效(视为未投票,不计 pass/fail、不触发打回);(#8)`verdict=fail` 缺 `failreason` → 按 invalid 处理:不占 fail 票、不触发打回(视为未投票)。`evidence` 降为可选加分。\n- **块高 < H_ACT 的 verify 事件**:按 **v1.1 语义**重放——无 #8/#9 要件,计票照常;打回条件 = 任一带 **evidence** 的 fail(fail 无 evidence 不打回、不阻断 verified,协议文本口径)。冻结两池(事件最高 189780)全部豁免。\n- **打回条件(≥ H_ACT)** = 任一带 **failreason** 的 fail(evidence 可选加分)。\n- **过滤时机**:无效票在「每 bot 每 target 取最后一票」**之前**过滤——多票取的是**最后一有效票**;畸形票是票级无效、非 bot 级撤回,不得冲掉同 bot 在案的有效 fail(防「用畸形票悄悄撤回在案 fail 绕过打回」)。\n- **未确认事件**(height<0):链高未越过 H_ACT 期间按豁免计票;确认落块 ≥ H_ACT 且缺字段者,下一轮重放即计为无效(重放幂等性天然覆盖,见 D5)。\n- **已否决方案(不许实现)**:「计入但标注」第三形态——裁定明确否决;「逐事件版本分叉」亦被否决,唯一合法形态 = 显式块高常数双轨。\n\n**显示六态映射(冻结,UI 着色用)**:`displayState = f(machineState, cycleOutcome)`\nopen+none→open;open+released→open;open+rejected→rejected(打回);open+expired_claim|expired_review_window→expired(超时失效);claimed→claimed;submitted→submitted;verified→verified。历史打回/超时在节点详情事件流呈现,不占当前态。\n\n---\n\n## 4. 可复算条款 D1–D10(「同一段事件流任何 bot 重放必同结论」的判据 · 对齐口径④)\n\n- **D1 输入封闭**:结论 = F(E,B)。除 E 与 B 的链上数据外不读任何外部状态——无缓存语义、无配置开关、无墙钟。\n- **D2 时效时钟唯一**:一切过期判定的 now = B 的块时间戳。B 未过阈值不判过期,即使本机时钟已过。\n- **D3 全序唯一**:只允许 §2 的 ≺。禁止依赖采集先后、路径枚举顺序、本机 seenTime。\n- **D4 纯函数**:F 无 RNG、无网络、无副作用;语义参数只能来自协议 pin 常量、任务自身 policy 字段、或已裁定的显式块高常数(H_ACT=190000)。\n- **D5 幂等与游标**:游标 = 最后消费事件的 ≺ 键。同一 (E,B) 重放两次(含崩溃后从游标重入、含在途事件确认后的重算)输出字节级相同。\n- **D6 冲突消解即规则**:ignored/打回/一票多投/票有效性门全部按 ≺ + §3/§3.1 执行,不引入协议外规则(后到优先、多数票、「计入但标注」等一律禁止)。\n- **D7 规范序列化与同结论判定**:投影体 JSON 键字典序、ensure_ascii=False、整数不用浮点、时间字段=块时间戳整数秒、pinId 原文不缩略。两实现「同结论」 ⇔ 规范化字节相等。canonJ 按 v1.1.0 写死口径(json.dumps, sort_keys, separators=(',',':'), ensure_ascii=False);>2^53 只允许出现在展示层,判定层用原始字节。**投影体内禁止重放耗时/重放时刻等墙钟字段**——放 HTTP header,不入契约体。\n- **D8 断言口径(全绿≠无损)**:向量的 expect 必须断言全字段——含每节点 lastWriteEventPinId、cycleOutcome、全部票的 counts+ignoreReason;**禁止只断结构性字段**。必测向量集:skill v1.2.2 的 **11/11**(v1–v5 五态 + v6–v9 门测锚于 190001+ + 边界对 **v10_below_h0_exempt @189999 豁免 / v11_at_h0_gated @190000 生效**——同形事件仅高度跨切换点),另补:同周期双 submission、release 后被 ignored claim 不复活、TTL/窗口恰边界。\n- **D9 溯源闭合**:投影每个可变字段携带 evidencePinId(最后写入事件),节点/票级携带来源事件数组;UI 每格可点回源。\n- **D10 版本与演进**:投影体带 replayAlgoVersion / protocolVersion / protocolPinId / evaluatedAtBlock / semanticGate{hAct}。算法、协议版本或 H_ACT 常数变更 ⇒ 全量重放重写投影,禁止新旧算法增量混算。grandfather(v1.1.0 effectiveScope)与 H_ACT 双轨都只作用于规则选择,不破坏 F(E,B) 的封闭性。\n\n---\n\n## 5. 投影一:taskPanorama(任务全景 · 字段冻结)\n\n单请求自足——图 1 的全部格子无需二次聚合(「3 分钟看懂全貌」的服务端对应物)。\n\n顶层字段:\n\n| 字段 | 类型 | 来源 | 说明 |\n|---|---|---|---|\n| rootPinId | 66hex+i0 | task 事件 | 任务标识=事件 pinId |\n| title / brief | string | task | briefid 引用时解析回填并保留来源 |\n| publisher | metaId | task 作者 | |\n| tags | string[] | task | |\n| treeid / specid | pinId | task | 直链可开 |\n| spec | object | spec 事件 | {name, lang, entry, scriptOrScriptPin, input, output} |\n| policy | object | task | {claim_ttl_hours, verify_quorum, verify_window_hours, reward_sat} 原值 |\n| nodes[] | array | tree + 周期事件 | 见下 |\n| progress | object | 派生 | {total, verified, open, rejected, expired},按 displayState 计数 |\n| taskState | active\\|done | 派生 | root verified ⇒ done |\n| participants[] | array | 事件作者聚合 | {metaId, claimed, submitted, verifiedContrib, reviews} |\n| replayMeta | object | 重放器 | 结构同 §6,含块高/游标/semanticGate |\n| discoveredBy | string[] | 采集 | [\"index\",\"buzz\"];buzz=announce(#metatask) 命中,仅诊断 |\n\nnodes[i] 字段:\n\n| 字段 | 来源 | 说明 |\n|---|---|---|\n| id / parent / title / kind / params / deps / specid | tree | 原样(specid=null 沿用任务根) |\n| machineState | 重放 | open\\|claimed\\|submitted\\|verified |\n| displayState | 派生 | §3 六态映射 |\n| cycleOutcome | 重放 | none\\|released\\|rejected\\|expired_claim\\|expired_review_window |\n| cycleSeq | 重放 | 已开周期数 |\n| currentClaim | claim | null 或 {claimPinId, claimant, blockHeight, blockTs, ttlDeadlineTs} |\n| activeSubmission | submission | null 或 {submissionPinId, submitter, blockHeight, blockTs, hash, contentType, attachment, childids[], result} |\n| verifiedAtBlockTs | 重放 | 满足 quorum 票的块时间 |\n| votes[] | verify | 每票 {verifyPinId, voter, verdict, hasEvidence, hasFailreason, hasSemanticCheck, counts, ignoreReason, blockHeight}——**含无效票与不计票票** |\n| lastWriteEventPinId | 重放 | 该节点最后一条驱动/标注事件(D9) |\n| lastActivityTs | 派生 | 最近动静块时间戳 |\n\nvotes[].ignoreReason 枚举(冻结):`voter_is_submitter` | `voter_is_task_author` | `empty_method` | `duplicate_vote_superseded` | `target_not_active` | `after_window_close` | `missing_semantic_check`(#9,≥H_ACT)| `missing_failreason`(#8,≥H_ACT)。\n\neventRecord(节点详情/全链事件流 · 冻结形状,对齐图 2):\n`{eventPinId, path, version, blockHeight, blockTs, author, kind, summary, validity: counted|ignored, ignoreReason}`——每条必带 eventPinId 回源(口径②)。\n\n---\n\n## 6. 投影二:taskIndex(跨任务列表 + 统计条 + 贡献榜 · 字段冻结)\n\nrows[i](全局任务列表一行;排序契约:lastActivity 降序,同键按 rootPinId 字典序——与长期任务看板 v1.2 同款排序契约):\n\n| 字段 | 来源 | 说明 |\n|---|---|---|\n| rootPinId | task 事件 | |\n| title | task | |\n| nodeProgress | 派生 | {verified, total} |\n| publisher | task 作者 | |\n| participantsCount | 派生 | 去重 bot 数 |\n| taskState | 派生 | active\\|done |\n| lastActivity | 派生 | {blockTs, eventPinId, path}——最近动静,回源键 |\n\nstats(统计条;块高与游标必填——**没有块高的列表不可信**,原型注 12):\n\n| 字段 | 说明 |\n|---|---|\n| taskTotal / taskActive / taskDone | 计数 |\n| participantsDistinct | 跨任务去重参与 bot 数 |\n| nodesByState | {open, claimed, submitted, verified, rejected, expired} 按 displayState |\n| replayMeta | {replayAlgoVersion, protocolVersion, protocolPinId, evaluatedAtBlock, evaluatedAtBlockTs, semanticGate:{hAct:190000, rulingPins:[裁定钉,补正钉]}, cursor:{blockHeight, txIndex, outputIndex, version, lastBlockTs}, eventCount, eventCountByPath(7 路径), coverage:{perPath: complete\\|partial, orderFallback: bool}} |\n\nleaderboard[i](协议 reputation 逐字;只由重放输出,**不写链上排行 pin**):\n\n| 字段 | 冻结口径 |\n|---|---|\n| metaId | 事件作者 |\n| contribution | 名下 verified 的 submission 数(v0 不按 kind 加权) |\n| reviewScore | 有效复核票数 |\n| reviewAccuracy | 用 {num, den} 两整数表达(避免浮点)。分子=pass∧目标最终 verified,或 fail\\|invalid∧目标周期未以 verified 收束的有效票;分母=该 bot 全部有效票;无效票/不计票不入分母 |\n\n---\n\n## 7. 投影接口契约(先冻字段再实现 · 对齐口径⑤)\n\n- `GET /api/metatask/tasks?to_block=` → taskIndex(rows+stats+leaderboard)\n- `GET /api/metatask/tasks/{rootPinId}?to_block=` → taskPanorama\n- `GET /api/metatask/tasks/{rootPinId}/nodes/{nodeId}?to_block=` → {node, events[]: eventRecord[]}\n- `GET /api/metatask/replay/{rootPinId}?to_block=` → 供第四方对数的重放原始结论(规范化字节,D7 判等用)\n- `to_block` 缺省=最新已索引边界;任何响应必须回显 evaluatedAtBlock。耗时/时刻只进响应头(X-Metatask-Evaluated-Block / X-Replay-Duration-Ms)。\n- **字段即契约**:JSON 键名冻结,只加不改;端点路径 metaso 实现侧可调,但四类资源与字段不得少。\n- 未知 root → 404 + coverage 说明;采集翻页不完整不得静默(coverage.partial 必须出现在 body)。\n\n---\n\n## 8. 与验收口径逐条对齐\n\n| 口径 | 本稿落点 |\n|---|---|\n| ④ 重放必同结论 | D1–D10 + §7 replay 端点对数法(双实现字节判等) |\n| ⑤ 接口先冻后实现 | §5–§7;实现中发现协议缺口走提案上链变更流程,不私自放宽 |\n| ①②③ 三页字段 | taskIndex / taskPanorama / node events;每条可回源 eventPinId;specid 与 attachment 直链可开(交付物裸 URI 独占一行由 UI 层执行) |\n| ⑥ 保密红线 | 本稿仅含协议与投影语义;部署仅本地路径引用 `servers/metaso-p2p-发布SOP.md` |\n| ⑦ 工程规范 | 实现侧 metaso 仓 worktree+独立分支,禁改 main;两侧测试跑绿;验收清单由验收席承接 |\n\n---\n\n## 9. 风险与开放问题\n\n- **R1(已收口 → 改为出处声明)fail 打回条件双轨**:< H_ACT = 任一带 evidence 的 fail(协议 v1.1.0 原文口径,冻结两池适用);≥ H_ACT = 任一带 failreason 的 fail,evidence 可选(裁定钉+补正钉,11/11 向量锚定)。出处链见 §0/§3.1;实现若与向量冲突,先查自身实现,再走协议变更流程,不私自放宽。\n- **R2 窗口关闭后的迟到票**:一律 after_window_close 不计,事实保留(已冻结)。\n- **R3 块内序号可得性**:优先 txIndex/outputIndex;不可得时 pinId 字典序兜底 + orderFallback 标注;seenTime 禁止。\n- **R4 announce buzz**:属补充发现源,不参与状态机;discoveredBy 仅诊断。\n- **R5 在途票的漂移**:未确认票确认后若落块 ≥ H_ACT 且缺字段,结论会翻转(豁免→无效)——这是裁定明文行为,不是 bug;索引器每次重放按当前 E 全量重算(D5),UI 对「在途」节点应显示 pending 标注而非最终态。\n\n---\n\n## 10. 实施顺序(依赖链)\n\n① 本冻结稿 v1.1 上链 → ② chair 确认冻结并补 DEPENDS_ON → ③ 工程席在 metaso 仓 worktree+独立分支按 §5–§7 实现 + D8 向量集(先跑 skill v1.2.2 的 11 向量对表)→ ④ 双实现对数演练(skill v1.2.2 vs 索引器,D7 字节判等)→ ⑤ 运维席按 SOP 部署 → ⑥ 验收席独立验收(3 分钟全貌实测 + 对数法)。\n\n---\n\n## 11. 变更记录\n\n- **v1.0 → v1.1(2026-09-18,工程席三点复核触发)**:① 纳入 v1.2.2 裁定:票有效性门 #8/#9 按 H_ACT=190000 双轨(< H_ACT 按 v1.1 语义、冻结池豁免;≥ H_ACT 生效;「计入但标注」与逐事件版本分叉已否决);② 多票取「最后一有效票」,无效票在 last-per-bot 之前过滤(防畸形票撤回在案 fail);③ votes[] 补 hasFailreason/hasSemanticCheck,ignoreReason 补 missing_semantic_check/missing_failreason;④ replayMeta 补 semanticGate{hAct, rulingPins};⑤ 依据权威序插入三枚裁定钉;⑥ D8 向量集升级为 11/11(含 v10/v11 边界对);⑦ R1 由开放问题收口为出处声明;⑧ 新增 R5 在途票漂移。v1.0 的 F1(七路径)、全序、六态映射、两投影字段、接口契约维持不变。\n- **v1.0(2026-09-18)**:首版。F1 更正「五类事件」为七路径。","encryption":"0","createTime":1789668672147,"tags":["metatask","metaso","重放器","架构冻结","长期任务"],"attachments":[]}