refactor(authority): unify retained journals and enforce scan snapshots - #4287
Conversation
huangruiteng
left a comment
There was a problem hiding this comment.
Request changes conclusion (author-owned PR; GitHub blocks formal self-review)
English verdict: REQUEST_CHANGES — exact head 4287@1588949ccc4c7ff5cf96250db9fc25807db91925. The required Node 22.6 minimum-runtime job cannot parse the new scanner and the merge-gate is failing.
动机
PR #4287 试图统一 File、NoKV、SQLite、PostgreSQL 四个 authority provider 的 retained-journal scan 解码与分页规则,补上 limit+1 lookahead、连续 cursor、operation identity 和 head lineage 校验,并让 PostgreSQL 的 head 与 rows 来自同一个 repeatable-read snapshot。基线中这些规则分散在 provider 内,腐败数据和分页边界需要多处同步修复。此 PR 保留每个 provider 的真实存储/事务边界,只抽出 provider-neutral 的 retained decoder 和 page validator;没有新增 RPC、capability 或写权限。
改动思路
AuthorityStore.scanCommitted 仍是唯一入口,caller 提供 after cursor 和 limit;provider 负责打开一次文件/NoKV/SQLite 读取或 PostgreSQL read-only transaction,构造同一快照的 head 与最多 limit+1 行;AuthorityJournalScan 负责跨 provider 的 range、精确行数、cursor 连续性、operation 唯一性和最终 head bytes/revision 匹配。decodeRetainedAuthorityJournal 负责 File/NoKV 的完整 revision/cursor/head chain。next_cursor 和 has_more 是由 head 与已验证 lookahead 派生的 projection,不是人工维护的 state。PostgreSQL 的 read-only path 改为 REPEATABLE READ READ ONLY,以避免 head/rows 跨 snapshot。
具体改动
本头涉及 18 个文件:新增 authority_journal_scan.ts(64 行),把 File/NoKV 的 retained decoder/append 逻辑集中到 authority_store_transactions.ts,四个 provider 的 scanCommitted 改为窄适配,PostgreSQL read transaction 使用 repeatable-read,更新 codec、conformance/transaction/PG 测试、Python readback 测试和中英文 RFC。
关键代码讲解
loopx/control_plane/coordination/authority_journal_scan.ts:16的prepare统一解析 cursor 和 positive safe limit,并在输入非法时返回invalid_scan_request。loopx/control_plane/coordination/authority_journal_scan.ts:37的page要求 rows 精确覆盖 retained interval,逐行验证 cursor offset、唯一 operation,并验证落在 head cursor 的 transaction 与 head projection/revision 一致。loopx/control_plane/coordination/authority_store_transactions.ts:53的decodeRetainedAuthorityJournal继续验证 File/NoKV 的全量 revision chain、cursor length 和末项 head lineage,provider revision 算法通过 callback 保持 provider-owned。loopx/control_plane/coordination/postgresql_authority_store.ts:319的beginTenantTransaction将 read-only 事务提升为 repeatable-read;scanCommitted再在同事务读取 head、查询 limit+1 rows,并交给 common page validator。loopx/control_plane/coordination/file_authority_store.ts:355的 provider adapter 只读取单一 document、做 range check、传入 lookahead;NoKV/SQLite 采用同一适配模式。
对主干的风险
P1 blocker:GitHub Actions run 34702796801 的 node-minimum-compatibility 使用 Node.js v22.6.0,加载 loopx/control_plane/coordination/authority_journal_scan.ts 时在第 12 行 private constructor(after: string | null, offset: bigint, limit: number) 处报 SyntaxError: Unexpected identifier 'constructor'。这是 Node 22.6 的 TypeScript strip-types 解析限制,导致 37 个最低版本测试文件/子测试失败,随后 merge-gate 也失败;因此不是运行时数据边界的可选告警,而是 shipped minimum runtime 的导入级回归。请把参数属性改为 Node 22.6 可解析的显式字段/赋值(或等价兼容写法),然后在新精确 head 上重跑 node-minimum 与 merge-gate,并保留一个直接导入该模块的最低版本 smoke。
此外,本地 Node 25.5 的 typecheck、完整 TS 1265 tests(1264 pass、1 skip)和聚焦 scan/decoder 23 tests 通过,Python readback 3 tests 通过;但本地没有 LOOPX_TEST_POSTGRES_URL,PostgreSQL integration 只能记录为 skip,不能替代真实 PG snapshot 证据。分页/authority 语义和 default-off isolation 未发现额外问题,新增状态均为由 retained journal/head 推导的 typed projection。
我的整体评价
四 provider 的 owner placement 和分页不变量集中方向合理,改动量与 demonstrated consistency problem 相称;但当前 exact head 在声明支持的 Node 22.6 上无法解析,导致 required compatibility gate 失败。这里应先修复语法并在最低版本与 merge-gate 全绿后再判断 PG snapshot 的完整证据;当前结论是 REQUEST_CHANGES。
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
1588949 to
c1f513a
Compare
|
Self-refinement for exact head The Node 22.6 blocker from the prior review is resolved by rebasing onto current Validation:
No post-rebase review blocker remains. Proceeding with the authorized admin self-merge. |
|
Post-merge LoopX-side evidence from the NoKV plane, as agreed in #4069. The review was bound to exact head Invariants checked
Validation actually run (Node 24.11.1, macOS)
Not run: the PostgreSQL integration test (no local database). Non-blocking notes
|
Authority journal readers could acknowledge a positive checkpoint against an empty store, and PostgreSQL scans could mix an older head with concurrently committed rows or silently skip missing history. This refactor gives all four providers one scan contract and gives File/NoKV one retained-journal decoder and append builder.
Validation: final TypeScript typecheck and 1,312 tests passed without failures/skips, including isolated PostgreSQL 16.15; 73 Python CLI/projection/runtime tests passed. Four-provider baseline/candidate comparisons preserve legal six-commit histories, receipts and pagination; File/NoKV byte digests match. An owner-authorized read-only snapshot (474 Todos, 59 leases) preserves archive selection/order and exact File/PostgreSQL journal pages in disposable copies. Source state is unchanged.
Scope: 18 files, product code +200/-319 (net -119), no new RPC, bridge, capability or provider. The related simplification pass removes the callerless clone helper. Existing capability editor descriptors, configuration and user-visible schemas are unchanged, so no frontend companion change is required; affected CLI status/drain/projection interactions are covered. This qualifies the requested scan interval, not arbitrary historical corruption, retention/compaction, service readiness or Goal promotion. No default-provider change. Independent of open #4286; base is main at bfd1ec8.
Exact-source premerge passed: 4 direct checks plus 17 selected checks, zero failures/warnings/manual holds. Change-quality receipt
cqr_f0971e17e0b38e1e9267verifies the final diff. An initial installed-wrapper run selected another checkout and is excluded from candidate evidence; the passing run explicitly uses this worktree's source.