Skip to content

[Task]: Qualify SQLite D2 capacity and crash/replay recovery on the merged provider #4224

Open

Description

@LIHUA919

Task ID or area

Shared authority RFC D2 / section 7.2: first SQLite capacity and recovery qualification slice after #4121.

Technical direction

Shared Goal Authority and cross-host coordination

Intent

I am proposing a bounded follow-up task and would like to own it after maintainer scope confirmation.

Summary

#4121 is merged. At main e602dd9273ff08a7c392129989366ac9be696cae, SQLite supplies the opt-in AuthorityStore conformance and real CLI path. D2 remains open: the existing examples/coordination/sqlite-capacity.ts measures a fixed 4 KiB payload at 10k/100k commits, but does not exercise section 7.2's matched 64 KiB profile or report all required latency, growth, recovery and consumer evidence.

The store retains complete historical projections and verifies cursor continuity with a covering-index count. This is an identified qualification boundary, not a demonstrated budget failure. The next useful deliverable is a reproducible measurement and recovery slice over this implementation, before selecting a checkpoint/delta redesign.

Source-backed preflight on this main: 50 SQLite conformance/admission tests and 5 real Python-to-TypeScript SQLite CLI tests passed on Node 22.14.0. A disposable 64 KiB, 100/1,000-commit rehearsal preserved the original receipt and ordered full-projection scan and verified cleanup. That rehearsal does not qualify the RFC's 10k/100k profile, concurrency, recovery matrix or elapsed-time horizon.

Proposed scope

In scope:

  • Extend the existing capacity helper into an explicitly invoked, reproducible D2 measurement entrypoint. Keep a small rehearsal mode separate from the 64 KiB 10k/100k matched profile; use fresh disposable databases, fixed live-state dimensions, explicit read/write mix and comparable sample windows. Represent workload settings, source/provider revision and missing evidence in the result.
  • Measure p50/p95/p99 and sample counts for commits, head loads, original-receipt lookup and 100-transaction historical scans. Separate warm-process store calls from cold subprocess/CLI reads. Report runtime/database/durability settings, RSS and database/WAL size. Final WAL size is not cumulative WAL traffic or logical writes; unmeasured metrics must remain unknown and prevent a full-pass claim.
  • Reuse the shared production-scale coordination fixture for a representative real CLI/readback arm, separately from the fixed-byte storage axis. Verify historical receipts/projections, operation-digest conflict behavior and cursor ordering against independently authored expectations, including after reopen and intervening commits.
  • Extend the existing real SQLite/process tests with the missing bounded interrupted-transaction and storage-capacity failure cases. Verify no lost acknowledged commit, no partially published head/receipt/outbox, and no duplicated effect on retry. Distinguish real process interruption, SQLite capacity injection and actual filesystem exhaustion; do not label an injected SQLite limit as an OS disk-full test.
  • Produce a compact qualification ledger mapping each section 7.2/D2 requirement to passed, failed or missing evidence. A runner can be correct while the provider remains unqualified. Keep large runs opt-in and ordinary CI focused on durable correctness and report validity.

Out of scope:

  • No provider default change, new store, Todo/lease rule change, checkpoint/delta schema redesign, retention deletion, or migration API in this first slice.
  • No active user Goal mutation, live file-to-SQLite migration, promotion, PostgreSQL deployment or scheduled soak.
  • The 1 MiB/300k headroom axes, full mixed-writer recovery/lag coverage and actual >=10-day synthetic soak remain explicit D2 requirements. This first slice must not mark D2 complete while they are absent.
  • No raw run dumps, host-local paths, private data or credentials in commits. Only reusable helper/test code and compact public-safe evidence belong in the PR.

Placement and dependency rationale

Owner: the existing built-in shared-goal coordination domain and TypeScript AuthorityStore contract; provider: the merged opt-in sqlite_v0. Reuse examples/coordination/, existing provider tests and shared fixtures. No new capability, extension, storage engine or semantic owner is needed.

D2 is independent of the T1/T2 transaction work and PostgreSQL deployment. No open PR touching the SQLite store or shared store-conformance helper was found in this preflight. Keep T1–T3, D1 and D3 approval/cutover gates independent of this evidence.

Intended base branch

main, refreshed again after admission, using a dedicated clean codex/ worktree.

Relevant files or commands

  • examples/coordination/sqlite-capacity.ts
  • tests/control_plane_ts/sqlite_authority_store.test.ts
  • tests/control_plane_ts/sqlite_authority_process.ts
  • tests/control_plane_ts/authority_store_conformance.ts
  • tests/control_plane_ts/production_scale_coordination_fixture.ts
  • tests/control_plane/test_sqlite_authority_cli.py
  • tests/control_plane/canonical_authority_fixture.py
  • loopx/control_plane/coordination/sqlite_authority_store.ts (behavior under qualification)
  • docs/architecture/rfcs/shared-goal-authority-state-provider-v0.md, section 7.2 and D2

Validation plan

  • Real SQLite conformance, recovery/process and public CLI tests, with isolated synthetic runtime state.
  • A small deterministic rehearsal verifies runner execution and report completeness; independent negative tests reject missing/failed required evidence instead of deriving pass criteria from observed timings.
  • An opt-in 64 KiB 10k/100k matched run records budgets without relaxing the RFC. Preserve failed measurements; do not average away a failing axis.
  • npm run typecheck:control-plane, npm run test:control-plane, affected CLI tests, exact-path loopx check, git diff --check, and risk-based loopx canary premerge --from-git-diff.
  • If a discovered defect requires changing shared transaction/provider semantics, narrow and confirm that repair separately, including all affected real-provider suites.

Requested maintainer confirmation

Please confirm this first measurement/recovery slice and its ownership. I will keep tracked implementation on hold until the scope is admitted; any storage redesign will follow the measured gap rather than be bundled speculatively.

Public/private boundary

  • This issue contains no private benchmark traces, verifier output, credentials, internal links, raw sessions or local runtime state.
  • This proposal does not launch maintainer-owned experiments or a scheduled soak.

Activity

  1. huangruiteng commented on Sep 12, 2026

    @huangruiteng
    Collaborator

    @LIHUA919 确认由你继续负责 SQLite D2。感谢你完成 #4121,也欢迎把这条线持续推进到一个有完整证据、可以提交本地 profile 晋升评审的阶段,而不只停在第一份测量报告。你提出的“先测量现有实现,再根据缺口决定设计”很合适。

    建议分成几个可独立评审、但共享同一验证入口的完整批次:

    1. 先交付本 issue 的测量与恢复切片。 更新到最新 main,完成 64 KiB、10k/100k 的匹配负载;保留小型 CI rehearsal。分别报告 cold CLI / warm store 的 p50/p95/p99、样本数、RSS、锁等待和数据库/WAL 大小。逻辑写入量、累计 WAL 流量、最终文件大小分开,不可互相替代。用表格明确每项 RFC 条件是 passed、failed 还是 missing。
    2. 根据证据闭合存储成本。 测量后如果 full projection、COUNT、in-head receipt index 或其他路径违反预算,请继续提出并实现相关修复。checkpoint/delta/immutable block 应服务于测出的问题;涉及持久格式时,先在这里贴出精简方案和兼容/回滚合同,再开展对应 PR。复用现有 TS AuthorityStore,不要另建 provider 或第二个业务语义 owner。历史 scanCommitted 必须仍能返回精确完整 projection,原 operation/digest/receipt 在重启和无关提交后仍可验证。
    3. 补齐 D2,而非把首批通过等同于完成。 后续覆盖 1 MiB/300k 余量、真实进程中断、并发 CAS、响应丢失、落后 consumer、空间不足、backup/restore lineage,以及受支持 runtime/OS。区分 SQLite 容量注入与实际文件系统耗尽。复用复杂合成 fixture,验证真实 CLI 的读取、修改、重放和投影恢复,并保留独立旧基线;公共测试不复制用户真实状态。
    4. 完成自然时间与交付证据。 准备可恢复的 >=10 天 synthetic-goal soak 方案,写清资源上限、停止条件、每日 reopen、第 1 天 receipt 重放、consumer lag、升级/回滚和结果存放方式。先提交方案,再单独确认持续任务的启动。加速容量结果不能代替自然时间。最终交付要明确唯一合格 profile/revision、剩余 hold、操作文档和下一步 cutover 条件。

    本次确认允许你开始第一批实现,并继续承担 D2 的后续闭合;不要求把所有内容塞进一个 PR。发现真实缺陷应保留失败证据并修复,不要为了“全绿”缩小负载或放宽预算。默认 provider 切换、活跃 Goal 迁移、D3 promotion 和 PostgreSQL 服务部署仍分别评审,不由 D2 测试通过自动授权。

    避免撞车:我们会把另一条重构放到永久投影交付/相关 typed owner,暂不推进 SQLite checkpoint 格式草稿。当前还有 #4283、#4286、#4287 的 authority/fixture 工作,请在修改共同文件前核对最新合并状态,尤其 #4287 的 journal scan 校验,尽量复用已有合同。

    请先回复首批的实施顺序与预计交付节点;有证据支持时可以主动推进后续批次,并及时把设计决策、结果和阻塞点同步到这里。期待把 SQLite 的这条长程存储主线完整做扎实。

  2. LIHUA919 commented on Sep 20, 2026

    @LIHUA919
    ContributorAuthor

    @huangruiteng 收到,按批次 1 推进。以下是首批实施顺序与预计节点,并同步当前长线状态:

    实施顺序(批次 1:测量与恢复切片,基于最新 main 的 loopx_sqlite_authority_store_v2 保留层)

    1. 补齐三项分离测量(一个 PR,只含可复用 helper/测试代码,不改 provider 语义):
      • 累计 WAL 流量:在已填充至 10k/100k 深度的真实库上,由观测连接持有读快照(阻止 WAL reset、保证帧计数单调),追加一个有界提交窗口,按 WAL 文件增量精确计量该窗口的帧数/字节数;以"每提交 WAL 字节在两个深度是否持平"评估 <=15x 累计增长预算,方法与前提写进报告的 metric 边界。
      • 逻辑写入量:从真实填充库测量 commits 行(delta+events+receipts)、head 行(每提交全量 projection 重写)、checkpoints 行的实际序列化字节,给出每提交逻辑写入量与累计核算;与 WAL 流量、最终文件大小三列分立,不得互相替代。
      • 锁等待:node:sqlite 不暴露 busy-handler 内部计时,改为应用侧观测值——探针连接受控持写锁一段时长,测 store 提交端到端等待相对无争用基线的增量分布;方法边界如实标注,不再以 missing 兜底。
    2. 账本与 rehearsal 同步:capacityLedger 新增 logical_write_growth / wal_traffic_growth / lock_wait_observed 行(passed/failed/missing 语义不变);CI rehearsal 保持小规模并断言新行语义;负例防止"用最终文件大小冒充 WAL 流量或逻辑写入"。
    3. 恢复故障用例核对:fix(sqlite): retain fast COUNT and add D2 qualification checks #4328 已带 crash-before/crash-after/capacity-full 真实进程用例与中断 head 发布回滚用例;本批先核对 fix(sqlite): retain fast COUNT and add D2 qualification checks #4328 后是否仍有缺口,若有则最小补齐并单独说明,不与测量改动混在同一不可回滚单元。
    4. 正式运行:分支定稿后用参考运行时(Node 22.22.3 / SQLite 3.51.3)执行 matched-64k(10k/100k + --cli),把每项 RFC 条件 passed/failed/missing 的紧凑表格贴回本 issue;只公布数字证据,不含原始 dump、本机路径或私有状态。

    预计节点:测量代码 + rehearsal/账本 PR 目标 2026-09-21 前送审;正式运行证据在其后 72 小时内贴回。批次 1 不标记 D2 完成:1 MiB/300k 余量、并发 CAS/响应丢失恢复矩阵、backup/restore lineage、受支持 runtime/OS 矩阵与 >=10 天自然时间 soak 仍为 missing 或独立评审。

    长线状态同步:10 天 synthetic soak 已于 2026-09-14 在一次性 goal 上启动(pinned e98191faa,Node 22.22.3/SQLite 3.51.3,8 agents;当前 ~20.2k commits、2777 ticks、无 recovery 事件,minimum_end 2026-09-25)。批次 1 的正式测量与该 soak 同机并行,负载互不重叠(soak 为每分钟级轻量 tick),并将在报告 host 节披露这一并发负载。

    撞车核对:#4283/#4286/#4287 均已合并;#4328 之后的 checkpoint/delta 保留层已在 main,本次测量直接基于它。

  3. LIHUA919 commented on Sep 20, 2026

    @LIHUA919
    ContributorAuthor

    @huangruiteng 批次 1 的测量能力 PR 与正式 matched-64k 运行证据如下。

    测量能力 PR:#4778(codex/sqlite-d2-batch1-metrics,含 runner/report/ledger/负例测试/参考文档与 RFC 证据段落更新;typecheck、容量测试 6/6、store 套件 176/176、全量 control-plane 套件仅 7 个与改动无关的预存失败、loopx check 边界干净、canary premerge 通过)。

    正式运行:matched-64k(10k + 100k 独立一次性库,各 +1000 提交 WAL 窗口 + 12 样本锁探针 + 20 样本 ×3 冷 CLI 命令),参考运行时 Node 22.22.3 / SQLite 3.51.3,WAL + synchronous=FULL 未为测量改动;分支 head f5b41f451。同机并行一个轻量 10 天 soak(每分钟级 tick),已按约定披露。报告原文保留在忽略的本地存储,以下为全部资格账本与关键数字。

    三项分离测量(10k → 100k,每提交)

    量 10k 100k 预算 结果
    逻辑写入(commits 行 + head 全量重写 + 摊销 checkpoint) 70,326 B 70,324 B 累计增长 ≤15x 10.00x passed
    WAL 流量(钉读标记窗口精确帧计数,各 1000 提交窗口:5,488 / 5,491 帧) 22,611 B 22,623 B 累计增长 ≤15x 10.01x passed
    锁等待(探针进程持写锁 200ms,应用侧观测) p50 210ms / p95 257ms p50 235ms / p95 244ms 报告要求(无数值预算) measured passed

    最终文件大小独立分列:DB 51.7MB / 515.8MB,WAL 归零(clean close),三列互不替代。方法边界如实标注:整跑 WAL 总量、busy-handler 内部计时、物理设备写入仍为 missing。

    完整资格账本(passed 14 / failed 0 / missing 9)

    RFC 7.2 条件 结果 观测值 预算
    matched_profile_execution passed 10k+100k 完整、样本数符合声明 —
    commit_p95 passed 2.94 ms ≤100 ms
    head_p95 passed 1.09 ms ≤50 ms
    receipt_p95 passed 20.42 ms ≤50 ms
    scan_100_p95 passed 60.22 ms ≤250 ms
    commit/head/receipt history growth passed 1.02 / 1.17 / 0.98 ≤2
    cold_cli_status_p95 passed 1,477 ms ≤2,000 ms
    cold_cli_mutation_increment_p95 passed −59 ms(100k 反而更快) ≤200 ms
    bounded_retained_state passed 108.6 MB ≤819.2 MB
    logical_write_growth passed 10.00x ≤15x
    wal_traffic_growth passed 10.01x ≤15x
    lock_wait_observed passed p95 244 ms @200ms 持锁 报告要求
    domain_workload / steady_state_rss / large_history_recovery / payload_and_headroom(1 MiB+300k)/ consumer_lag / restore_upgrade_rollback / os_runtime_matrix / elapsed_soak / promotion missing 批次 2–4 范围,保持 hold —

    其他关键观测:填充 183.5s / 1,825.6s(预算 2,400s);RSS 峰值 171→226MB(不随历史 10x 线性放大,但按账本语义仍不构成 steady-state 证明);recovery tail 15/31 commits、replay budget 63;两轴 cleanup 验证通过。

    结论:64 KiB 匹配轴上全部 14 项预算通过,写入放大按设计线性(每提交逻辑 ~70KB 中 head 全量重写占 65.5KB —— 这是批次 2 存储成本闭合时最明显的优化对象);D2 不标记完成,9 项 missing 保持 hold。下一步按既定批次推进批次 2/3(1 MiB+300k 余量、真实进程恢复矩阵、backup/restore lineage)。

  4. LIHUA919 commented on Sep 22, 2026

    @LIHUA919
    ContributorAuthor

    @huangruiteng 批次 2 开工说明(存储成本闭合 —— 余量轴测量)。

    依据:批次 1 实测 64 KiB 匹配轴全部 14 项预算通过、写入放大按设计线性(logical 10.00x / WAL 10.01x,均 ≤15x),无需要先修的违反。"根据证据闭合存储成本"的下一步是把同一测量臂推进到 RFC 7.2 的余量维度,看违反是否在更大 payload 或更深历史处出现。

    交付(一个 PR,仍只含 helper/测试/文档,不改 provider 语义与阈值):

    1. --profile matched-1m:1 MiB live projection,10k/100k 匹配负载;读/写、WAL 窗口、锁探针、冷 CLI 臂与已合并的 64 KiB profile 完全同构,只有 payload 维度不同,保证跨轴可比。
    2. --profile headroom-64k:64 KiB、单报告内 100k→300k 双轴(30 天余量轴);增长预算按 3x 深度比 × 每提交流量评估(per-commit 放大 5x 以内仍过、超出即 failed),fill 预算按轴规模同比放大并在报告 budgets 里声明。
    3. 账本行按 profile 前缀化(one_mib_* / headroom_300k_*),预算矩阵不变;负例延续"三列不可互相替代、窗口无效即 missing"的语义。payload_and_headroom 行改为按报告实际覆盖的轴声明缺失面。
    4. 工作负载披露不变:固定 padding 隔离历史增长(与已接受的 64 KiB 轴同语义);每提交 projection 变化的真实 churn 由 CLI 变更臂单独覆盖,不混入存储轴。

    结论规则(按你批次 2 的要求):若 1 MiB/300k 出现预算违反,先在本 issue 贴精简修复方案(含持久格式兼容/回滚合同)再开实现 PR;若无违反,余量行转 passed、存储成本线以"按证据无需修复"闭合,剩余 hold 只剩恢复矩阵与自然时间证据。

    运行计划:正式运行仍在本机参考运行时(Node 22.22.3 / SQLite 3.51.3)执行、与 soak 并行并披露(soak 现 ~37k commits,minimum_end 2026-09-25)。1 MiB 报告预计 ~1 小时、300k 报告预计 ~2 小时,完成后把资格账本贴回。

  5. LIHUA919 commented on Sep 23, 2026

    @LIHUA919
    ContributorAuthor

    SQLite D2 批次 2 的正式结果与修复方案如下。先记录失败,再提交实现 PR;本评论不申请 provider 晋升。

    正式测量与账本。 matched-1m(1 MiB,10k→100k)和 headroom-64k(64 KiB,100k→300k)均完成了声明的独立一次性库、样本窗口、冷 CLI、WAL 窗口和清理。两份报告的测量源码均为 e99a83b63c149685625ecc80e5065c31b2ad36d6、source-stable=true,macOS arm64、Node 22.22.3 / SQLite 3.51.3、WAL + synchronous=FULL;存储介质未采集。用已合并 #4910 的 4a9729d603fe4fa85ba6e5526991df788171858e 精确 profile 账本重算后,行状态、观测值和预算均与原报告一致。

    轴 passed failed missing 关键结果
    1 MiB / 10k→100k 12 2 10 100k receipt p95 269.03 ms > 50 ms;scan 100 p95 801.81 ms > 250 ms。10k 对应 277.60 / 744.76 ms,故不是随历史深度增长的退化。
    64 KiB / 100k→300k 14 0 10 300k receipt p95 19.81 ms、scan 100 p95 60.84 ms;逻辑写入增长 3.000x、WAL 流量增长 3.010x,均在既定预算内。

    其余 D2 缺口(真实 domain workload、steady-state RSS、large-history recovery、consumer lag、restore/upgrade/rollback、自然时间 soak、OS/runtime、promotion)仍按各自证据保留 missing;两个报告不合并成“D2 通过”。

    定位。 SQLite readReceipt 从覆盖该笔的 checkpoint 重放并证明最多 64 行;scanCommitted(100) 证明返回页和 lookahead。v2 的每行证明均对完整投影重复做 canonical JSON 编码与 SHA-256。1 MiB 固定投影下,原始 SQL 回执查找 p95 < 0.01 ms、101 行读取 p95 < 1 ms;独立真实 SQLite 小样本重现回执窗口末端约 300 ms、scan 100 约 500 ms。CPU 样本主要落在规范字节生成。该证据支持读取证明成本为主要原因;同机负载可能影响绝对数值,不能用它抹去正式失败。

    拟议修复(先限 v2 读取证明,不动持久格式)。 在单次历史验证/审计调用内,对重复的长 JSON 字符串复用有上限的规范编码;每笔仍按原始 v0 commit_digest 证明完整投影/事件/回执,并逐行校验 state digest。后续空 delta 可继承已经验证的前驱 state digest,但仍与本行声明的 state digest、parent lineage 对照;根提交仍独立计算。缓存不跨调用,不以旧验证结果授权新读取。DDL、schema version、磁盘行、原始 receipt/digest、writer、默认 provider 和 RFC 阈值均不变;回滚只需撤回这次读路径改动,前后 v2 数据互相可读,无迁移或清理历史的步骤。

    本地隔离原型在相同 Node 22 的 1 MiB / 128 笔真实 SQLite 小样本上,将固定投影的窗口末端回执约 302→43 ms、scan 100 约 503→98 ms;动态改变投影的回执约 302→63 ms,仍超过 50 ms,因此不将小样本等同于 1 MiB 通用资格。协议摘要等价、篡改历史行与空根等负例已加入验证;#4910 的错误深度准入负例继续保留。当前候选源码的 SQLite TS 回归为沙箱内 292/296,余下四项因本地 runtime socket 被沙箱阻断而在隔离实环境 4/4 通过;迁移/保留/容量 19/19、真实 Python CLI 5/5、TypeScript 类型检查通过。正式同负载复测仍须以实现 PR 的精确 head 报告。若正式复测仍失败,保留 failed,并另行评审支持范围或持久证明格式,不通过改预算或缩小样本消除失败。

  6. huangruiteng commented on Oct 3, 2026

    @huangruiteng
    Collaborator

    Current-main diagnostic checkpoint, not a replacement for the frozen D2 reports.

    Source d74554b48758ce484633c9088af85c55143630af, macOS arm64, Node 24.21.0 / SQLite 3.53.4, WAL/FULL. Disposable synthetic stores only; source remained unchanged and all stores/processes were cleaned up.

    1. Ran the existing examples/coordination/sqlite-capacity.ts --profile rehearsal --cli against the source-checkout Python environment. Both 64 KiB axes (100 and 1,000 commits) passed their functional assertions: original history audit, canonical Todo in status/quota, three real CLI mutations per axis and final cursor readback. The report correctly remains incomplete, not D2-qualified.
    2. At 1,000 commits, warm head/receipt medians were 1.88/2.80 ms; cold Node first-load median was 80 ms. Fresh-process CLI medians were status 1.74 s, quota 2.47 s, mutation 1.51 s (3 samples each, not stable tail evidence). The 100-commit axis included cold status/quota observations of 9.70/7.10 s; these remain in the report. These are different entrypoint workloads: the gap is a reason to profile startup/transport/shared command work, not a subtraction proving Python overhead or a current-release regression comparison.
    3. Separately probed 128 commits with nominal 1 MiB projections, unchanged or changing one scalar per commit; 20 samples per operation. Original receipts, all 100 returned projections, and full retained history were checked. Window-tail receipt p95 was 78.68/113.17 ms; scan-100 p95 was 157.96/229.73 ms. The corresponding nominal 64 KiB receipt medians were 9.95/13.25 ms, versus 67.43/78.45 ms at 1 MiB. Actual JSON sizes include a 12–14-byte scalar field beyond the nominal payload. This small probe does not pass the 10k/100k payload axis or erase its previous failures.
    4. A separate V8 capture, read through performance-diagnosis, points at retained-window SHA-256 work: hash-update leaf samples account for roughly 77% of receipt-path and 84% of scan-path observed CPU weight. These are sample weights, not uninstrumented latency. The payload-size intervention supports a byte/proof-cost hypothesis; it does not justify dropping integrity checks or changing a persistent digest format.

    Next useful work remains split at the existing boundaries: diagnose fresh CLI/Effect startup on an independent current-release control; preserve the common replay and complete proof contract for large historical reads; obtain the completed soak and missing recovery/consumer evidence separately. The shadow-capture drain-cursor is a pre-promotion source-capture cursor, so its tests alone cannot certify a post-promotion lagged projection consumer. No new consumer framework, timeout relaxation, provider-default change or live migration was introduced by this checkpoint.

    Same-source replication in a clean dedicated worktree (64 KiB first, then 1 MiB) again preserved complete readback/history. Window-tail receipt p95 was 8.27/11.34 ms at nominal 64 KiB and 64.31/125.47 ms at nominal 1 MiB (unchanged/changing scalar); scan-100 at 1 MiB was 128.50/243.39 ms. Run-to-run variation reinforces that these are diagnostic observations on a shared machine, not stable formal tail or release-baseline comparisons.

  7. huangruiteng commented on Oct 3, 2026

    @huangruiteng
    Collaborator

    Follow-up: separate cold CLI cost from SQLite retention cost

    This follows the previous current-source probe. It is diagnostic evidence, not a new D2 pass or a change to admission thresholds.

    • Current source: d74554b48758ce484633c9088af85c55143630af; installed-source control: 9ac4efa902c50b0d52348513eae807da323bd8cd (all 1,473 tracked LoopX Python/TS/JSON files matched this revision; generated assets/dependencies were outside that comparison). Same Python 3.13.13 / Node 24.21.0 / SQLite 3.53.4, macOS arm64, sequential execution on a shared host.
    • Four disposable real stores: current/control × File/SQLite, each with 128 commits, a 64 KiB complete projection, one native Todo, original events/receipts and an engaged writer fence. Every CLI read preserved the canonical Todo. Final audit compared all 512 retained transaction projections and original receipts against the seeded data; every head remained at cursor 128. All owned workers were stopped and temporary stores removed. No active Goal, default, migration or decision rule changed.

    Important measurement correction: sqlite-capacity.ts invokes status/quota without an explicit scan root. Those commands default to scanning the LoopX package directory, so the elapsed time includes public-boundary discovery/classification as well as imports, Effect startup and backend work. The initial 48 cold/warm calls retained those defaults; their different source/package trees must not be treated as an identical-input source regression comparison.

    A follow-up fixed the same complete package scan input across all four arms: 1,275 files, no boundary errors or warnings, 24 fresh-Python/fresh-Effect calls in alternating source/provider order. No scan was disabled and no timing threshold was relaxed. Three samples per cell are diagnostic only:

    Source Provider Cold status median (range), seconds Cold quota median (range), seconds
    Installed control File 2.794 (2.450–3.547) 4.031 (3.233–4.536)
    Current File 4.211 (2.202–4.606) 4.363 (3.219–6.958)
    Installed control SQLite 3.569 (3.116–3.785) 4.718 (2.963–5.289)
    Current SQLite 4.305 (2.826–4.706) 3.519 (3.473–4.141)

    These results retain the slow observations. They do not establish statistical equivalence, a regression, p95, or satisfaction of the formal cold-status budget. Host load was variable; source/provider selection alone does not explain the latency. This fixture is not the production-complex Goal or formal large-history matrix.

    Independent local-only profiles explain where to investigate next:

    • Pyinstrument 5.1.3 captured status and quota with cold and already-running Effect workers. Public-boundary scan inclusive observations were 564/563 ms for status and 1,726/886 ms for quota; Python import/discovery cost remained visible. Profiled durations are not benchmark samples and inclusive rows are not summed.
    • The actual isolated TS worker was separately captured with V8 CPU profiling through startup and four CLI requests. Of 22.900 s recorded stack weight, 21.005 s was idle, 1.449 s had the startup-module stack, and 0.221 s had a SQLite-store frame. The observed startup-to-ready wall time was 1.667 s. These are capture-scope observations, not a subtraction-based latency attribution or a claim that provider work is free.

    Next boundary: reuse #5283's existing lazy-loading/compilation work and qualify cold CLI separately from its long-lived MCP reuse result. Preserve the complete scan/decision contract; do not mask costs by dropping checks or trimming inputs. Keep the existing large-receipt proof-cost result, actual elapsed soak, recovery/lagged-consumer evidence and installed adoption open. No additional provider abstraction or parallel Python decision owner is justified by this probe.

    中文:这轮把“命令整体慢”和“SQLite 历史读取慢”拆开了。容量演练的 CLI 时间还包含整份 LoopX 包扫描,之前不能直接归因给 SQLite。固定同一批 1,275 文件后,两种 provider 都有秒级公共成本;完整投影与原始回执核对通过,但小样本和共享主机波动不支持新的准入结论。后续复用 #5283 的既有冷路径工作,单独验证 CLI;不删检查、不放宽预算、不重复造缓存或决策层。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions