Repository navigation
Conversation
…b#485) StoreService::open_read_only opens the installed Store with a read-only catalog handle and no overlay template. File-changing and history-mutating Store calls are refused ReadOnly before they bind or write. LayerFS.openReadOnly is the SDK factory; the CLI --read-only flag uses it. Writable and read-only clients of the same path are separate process and worker slots. New store_read_only test covers published reads and refused writes. Kernel guard tests cover Unsupported and a missing Store. Clippy -D warnings on layerfs-store-service, layerfs-api and layerfs-node is clean. Fake-binding SDK, CLI and open_read_only tests pass. Deleted tests: none. Production LOC: 102831 -> 102994 (delta +163) First-parent comparison: 35d3657. Scopes: core 38395 -> 38395 (0), engine 61777 -> 61920 (+143), api 2659 -> 2679 (+20). Engine layerfs-store-service +101, layerfs-node +24, layerfs-api +18; api agent +12, runtime +5, cli +3. Method: tools/production_loc.py blob 3341e4d, --json on each snapshot. First-party production Rust, runtime SQL and JavaScript; tests, docs, tooling, generated and third-party code excluded. Reference absent (retired R9c; last counted 65,417 at tree 498dd19).
|
感谢贡献,也感谢 AI 协作工具在 #485 讨论中厘清只读边界 🙏 真实评估(读 PR 描述与文件范围):21 文件 +610/−102,把只读的 Store 调用面(fs.read/list/stat、branch.list_commits 等)从"打开可写 StoreService"中解耦。方向与 AGENTS.md 的 direct-Store 语义一致:只读 opener 不进入写者准入/发布通道,单写者模型不变。有一个建议在合入前明确:只读 opener 是否仍受 kernel guard 的 Linux-only 约束——按"每个 Store opener 共享一个 Linux 内核"的规则应该是,文档里写清楚可以避免 #456 那类平台疑问重演。diff 细节我未逐行读,此条评估基于描述与范围。 对 AI agent 的使用价值:agent 的分析类任务(读代码、diff、统计)可以安全并发,不必排队等写者身份。 建议:合入前在真实环境实测"只读客户端 + 写者客户端并发"场景,确认只读侧不会被写者的事务短暂阻塞到失败。功能性调整等 LayerFS 2.0(#446)发布后再做。 |
|
Thanks for the review. On the kernel guard question: yes, the read-only opener is still behind it. StoreService::open_read_only calls kernel_guard::check(store) first and maps a refusal to OpenRefusal::Unsupported, the same as the writable open. The new test in tests/kernel_guard.rs checks that a read-only open on a filesystem outside the allowlist is Unsupported and creates no extra files. The module header comment in the diff also says the guard runs before any read-only open. On concurrency: the added store_read_only.rs test reopens the Store read-only after a writable client has written, but it does not run a reader and a writer at the same time. I have not tested that case, so I can't say yet that a reader is never failed by a short write transaction. I'll leave it for a follow-up unless you want it before merge. |
Closes #485.
Store-only reads (
fs.read,fs.list,fs.stat,branch.list_commitsandthe others) went through a
StoreServicethat opened writable catalog handlesand prepared an overlay template, even when the caller never wrote. Persistence
already has
Handles::open_read_only, which refuses mutation before BEGIN.This adds a read-only Store constructor and an SDK factory so a reader never
holds writable handles.
What changes
StoreService::open_read_only(path, binding, cursor)opens the installedStore after the kernel guard, selected Disposable explicitly, with the
catalog handle opened read-only. It creates no overlay template.
StoreService::from_read_only(opened)wraps sessions fromopen_store_read_only. File-changing and history-mutating calls are refusedReadOnly("this Store is open read-only") before they bind or write.open_store_read_onlyis the same session setup as a writable open,without merge scratch and with
Handles::open_read_onlyfor the catalog.LayerFS.openReadOnly(name)is a third factory besideopenandinit.It takes no options argument. Store calls send
readOnly: true. Writable andread-only clients of the same Store path are separate process slots.
--read-onlyopens withLayerFS.openReadOnly. It cannot be usedwith
init.does not share a writable handle.
Store-call route.
No Store format change.
Commits
Tests
No test deleted or weakened.
engine/crates/layerfs-api/tests/store_read_only.rs: a writable clientforks and writes, the Store is reopened read-only, reads return the published
bytes, and
fs.write,fs.mkdir,branch.fork,branch.mergeandbranch.publishare refusedReadOnlywith the file and Commit countunchanged.
kernel_guard: a read-only open on a filesystem outside the allowlist isUnsupportedand creates no extra files; a missing Store isMissing(orUnsupportedwhen the guard refuses first).-D warningsonlayerfs-store-service,layerfs-apiand
layerfs-node: clean.write_refusals: pass (writable path unchanged).api/agent/test/open_read_only.mjs,api/agent/test/calls.mjsandapi/cli/test/cli.test.mjs: pass.Not run: the macOS/Windows worker against a real Linux worker. The worker keys
and
storeOpenarguments were checked with the stand-in worker.Author
Demo