fix(authority): paginate canonical snapshots without mixing revisions - #4922
huangruiteng wants to merge 5 commits into
Conversation
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
a07903f to
a5acb89
Compare
… check Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
huangruiteng
left a comment
There was a problem hiding this comment.
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
Exact head: 373ae0f
English verdict: APPROVE — no blocking finding on this head.
动机:已验证旧的 one-shot canonical Todo/lease RPC 在完整集合超过 2 MiB 时失效;这会让已提升的长期 Goal 无法读取 Todo。此次交付是有用且独立可回滚的有界读传输增量,不宣称解决总体内存/IO 或后续 D1–D3。
改动思路:TypeScript 继续拥有 canonical Todo 选择和排序,复用同一 collection owner;新 page RPC 把 store identity、revision、cursor、query digest、数量与偏移绑定到 continuation,并限制每页字节和条数。Python 只校验、组装完整结果;任一页变更/异常就丢弃此前页面,不混合 revision、不回退 legacy。原 one-shot RPC 保留给既有直接调用者。
具体改动:检查了完整 base→head 28 文件差异、schema/handler/provider、Python promoted 与 pre-fence 分支、文档/RFC和相关调用者。源工作树验证:Python canonical snapshot 34 passed;TypeScript File/SQLite page 26 passed;旧路径/写入栅栏 72 passed;独立临时 PostgreSQL 16 数据库的完整 authority-store suite 288/288 passed(无 skip);control-plane typecheck 与 diff check 均通过。首次 PostgreSQL 运行的 4 个失败来自子进程误用系统旧 Python,改为工作树 uv 解释器后全套通过;不归因于此 PR。私有路径/凭据扫描无命中。
对主干的风险:最强反例是两页之间发生同内容或不同内容的 provider commit,导致表面合法的页面被拼成混合快照;负例覆盖了 revision/identity/offset 拒绝以及 Python 不返回部分结果。每页仍重读完整 head,最终 Python 结果仍占用总量内存,繁忙写入时可能反复重启;文档明确承认,这是后续按实测决定是否引入 pinned revision/streaming 的范围。没有对活动 Goal 做 promotion、迁移或原始数据改写,PostgreSQL 验证只用隔离的合成数据库。远端 CI 按本轮 review 契约不作为等待条件。
我的整体评价:未发现阻塞项。范围与已复现的 2 MiB 故障相称,规则仍归属于 TS 的 canonical owner,off/default legacy 分支有回归覆盖;可由 maintainer 合并。相关小型未来重构已通过共享 canonicalTodoCollection 完成,暂不扩展为无依据的流式框架。
Problem and result
A valid long-lived Goal could exceed the unchanged 2 MiB Python/TypeScript RPC response ceiling when a canonical read returned every Todo, archived dependency, lease and acceptance guard at once. The public list/status call then failed despite a healthy authority store. This PR assembles complete, byte-bounded pages tied to one provider incarnation, revision, cursor and query. An overlapping commit rejects the whole read; no partial collection or legacy display fallback escapes.
This is the TS T3 / shared-authority L5 read-transport slice for #4574. It does not change the default provider or promote an active Goal.
Implementation and semantics
missingwith the existing recovery response; reading never creates a replacement store. An existing head with an unreadable identity remains an identity failure. The public result schema also stays present on failure.mainintroduced a bilingual RFC without the repository-required semantic-mirror declaration. A separate two-line docs commit repairs that pre-existing governance-smoke failure; it does not change this RFC's normative contract.The bilingual RFC checkpoint lists seven principal PR boundaries including this one; after merge, six remain, or up to eight when SQLite qualification and migration each need a second reviewable batch. In-flight #4920 covers shadow-drain planning only; merged #4910 adds SQLite capacity axes but does not close the D2 soak/recovery gate. PostgreSQL service, tenant, restore and capacity qualification remains a separate medium-term lane.
Validation on
373ae0fa4add247abd316f9e4be25de21527156b33d86fc50fc36bf261c802933eaa4c40cbdb6b872dedd3c49ee5e6fdd2332e68; receiptcqr_33d86fc50fc36bf261c8verified valid. No blockers or warnings; one efficiency advisory.Each page currently reloads the full head, and Python ultimately holds the complete collection. The RPC is bounded; total provider I/O and client memory are not. Busy writers may force an explicit full-read restart. This does not qualify SQLite D2 durability/soak, persistent projection freshness, whole-Goal migration or PostgreSQL deployment.
The CLI is the affected entrypoint. Dashboard, Chat and Lark continue to consume the same assembled public list/status contracts; there is no new setting or frontend asset. This control-plane PR stays open for maintainer review and merge.