Repository navigation
D8: split core into core, engine and api layers (#463) - #465
Merged
Merged
Conversation
Remove test-only modules and private-helper includes from the Node binding. Replace their eight tests with external Rust tests that load the built addon in Node, using bounded Engine/daemon fixtures. Preserve the forked-child lock regression through a test-only preload fixture; no product API is added. Keep binding integration targets outside the owner-excluded CI lanes. Deleted test locations (all behavior re-covered externally): - discovery.rs::tests::a_dropped_guard_releases_the_lock_while_a_forked_child_holds_a_copy -> tests/native_discovery.rs - tests/unit/admission.rs (2 tests) -> tests/native_admission.rs - tests/unit/reclaim.rs (5 tests) -> tests/native_discovery.rs The public admission deadline test exercises the full 60 s wait; private 300 ms deadline injection is no longer used. Checks: Linux layerfs-node build and tests --no-run; native_discovery 6/6 (30 s ceiling); native_admission 2/2 (90 s ceiling, 60.52 s); node all-target Clippy -D warnings; workspace fmt check; full boundary guard; core/tools unittest suite 63/63 (120 s ceiling); Ruff 0.17.2 format; diff --check. The tests use the registered private Linux Cargo home/target. Node 24 is copied from the pinned runtime image into that target for these checks. No Store profile executes in these fixtures. No production behavior changes. Production LOC: 102158 -> 102158 (delta 0) Scope: all first-party product scopes; core 96788, api 5370, dsh absent. Method: tools/production_loc.py --json from exact parent and staged snapshots; Rust-aware comments and inline test items excluded, shipped SQL and JS included. Counter SHA256: 7e0c3c1ab2fd52895b484c56d18b907cc33b5adbe9a89f8eca77a21ad82b45f0 reference absent (retired R9c; last counted 65,417 at tree 498dd19).
Map all Rust crates (including layerfs-node) to core, engine and api. Check production/build/dev edges, target-table aliases, resolved test path includes, and the core rusqlite ban. Unknown crates fail closed. Keep layout knowledge in one crate-root helper and preserve the production edge allowlist. Temporary exception: daemon -> api dev dependency and only the six includes from merge_report, concurrent_commits and lane_merge to the two named API helpers. Step 2b removes the exception. DOMAIN_CRATES is unchanged for step 1. G1: owner instructed proceeding with MIGRATION_SPEC.md; D8 accepted. Subsequent owner answers allow project -> bridge, select engine, and authorize relocation once branch conflicts are resolved. No push, PR or merge is authorized. Checks: full-tree boundary guard PASS (953 production inputs); core/tools unittest discovery 63/63 PASS under 120 s timeout (includes all guard tests); Ruff 0.17.2 format and check PASS; git diff --check PASS. Tooling only; Rust compilation/runtime tests are inapplicable to this step. No tests deleted. The binding prerequisite is commit 05db985. Production LOC: 102158 -> 102158 (delta 0) Scope: all first-party product scopes, core 96788 and api 5370; dsh absent. Method: tools/production_loc.py --json from exact parent and staged snapshots; Rust-aware comments/inline tests excluded, shipped SQL and JS included. Counter SHA256: 7e0c3c1ab2fd52895b484c56d18b907cc33b5adbe9a89f8eca77a21ad82b45f0 reference absent (retired R9c; last counted 65,417 at tree 498dd19).
Move the unchanged Init and install bodies into layerfs-project::store, retain API re-exports, and call Project Init directly from the native binding. Approve only the owner-selected Project bridge/persistence edges in the layer guard. Checks: all fifteen packages all-target no-run build and Clippy -D warnings; full boundary and fuser guards; 64 Python tool tests; fmt and Ruff format; literal native build, paired Linux SDK build and sealed SDK Init refusal proof. 234 executable runs passed and 112 reuse completed unaffected proofs. Verification exception explicitly authorized by owner: fp21_detach_stages retains two FAILs on the unchanged warmed-reader/provider-gate assumption. Failure output, original container, scratch and execution plan retained; no assertion weakened and no rerun. No unrun executable selections remain. No tests deleted or moved in this step. Production LOC: 102158 -> 102162 (delta +4) Scope: all first-party product implementation, including shipped SQL and JavaScript. before: api 5370, core 96788. after: api 5368, core 96794. Method: tools/production_loc.py --json; exact parent and staged trees; inline tests/comments excluded; shipped SQL and JS included. Counter SHA256: 7e0c3c1ab2fd52895b484c56d18b907cc33b5adbe9a89f8eca77a21ad82b45f0. reference absent (retired R9c; last counted 65,417 at tree 498dd19).
Move mount_control, kernel_mount_routes, kernel_application, observed_application, r5_1_actual_daemon_commit, merge_report, concurrent_commits and lane_merge to layerfs-api/tests. Keep their assertions and existing lower-layer fixtures; locate the ordinary separately built daemon binary from three API tests. Install-only daemon tests, fixtures and the resource_prepare example now use Project's Store entrypoint directly. Remove daemon's API dev edge and every temporary upward guard exception. API adds daemon, FUSE and the existing pinned nix as test dependencies only. CI selection follows the moved heavy and Linux mount targets. No versions or production behavior change. No tests deleted. Checks: full fifteen-package all-target no-run compilation and Clippy -D warnings; focused Project/API/daemon executable proofs; native binding build; full product and fuser guards; 64 Python self-tests; Rust fmt, Ruff format and whitespace. The unchanged FP-21 failure remains FAIL under the explicit owner exception; its original proof is retained and is not rerun. Unaffected proofs are reused. Production LOC: 102162 -> 102162 (delta +0) Scope: all first-party product implementation, including shipped SQL and JavaScript. before: api 5368, core 96794. after: api 5368, core 96794. Method: tools/production_loc.py --json; exact parent and staged trees; inline tests/comments excluded; shipped SQL and JS included. Counter SHA256: 7e0c3c1ab2fd52895b484c56d18b907cc33b5adbe9a89f8eca77a21ad82b45f0. reference absent (retired R9c; last counted 65,417 at tree 498dd19).
Keep the four algorithm crates in core, move nine engine crates and the Rust API to their selected layers, and move the manifest, lock, nextest, tools and authorized fuser package/provenance to their owning roots. Fix relative manifests, test includes, launcher input/target paths, native scripts and CI path selection. The fixture-seal test now locates the root manifest and scans the relocated first-party roots; it retains every original assertion. Its initial path failure is retained, the repaired case passes, and its five unchanged passing cases reuse their initial proof. The root LOC counter retains both layouts and assigns crates by name. All 954 production files retain identical body bytes and per-file LOC; 572 are relocated. Cargo metadata retains the same fifteen packages, first-party edges (including kinds, targets and aliases), package/dependency features and versions. The lockfile and third-party package bytes are unchanged. Only the redundant core tooling counter is deleted. No tests deleted. All moved files are detected as renames with -M20%; the two extensively rewritten path manifests fall below Git's default similarity threshold. The fixture-seal scan-root assumption is an additional live path hit found by execution beyond the spec's initial inventory. Other edits are in its listed path/tool scope. Exact path, body, graph and LOC receipts are retained outside Git. Checks: root all-target no-run build and warning-denying Clippy for all fifteen packages; per-executable Linux tests under 100-second ceilings; native script and paired daemon/addon SDK build; full boundary and fuser provenance guards; 154 combined Python self-tests; Rust fmt, pinned Ruff format and whitespace. The unchanged FP-21 test retains its original FAIL under the explicit owner verification exception and is not rerun. Only this worktree's resource record was prepared for the new target path. Other owners confirmed ready to rebase; their branches/records are untouched. Production LOC: 102162 -> 102162 (delta +0) Scope: all first-party product implementation, including shipped SQL and JavaScript. before: api 7281, core 38241, engine 56640. after: api 7281, core 38241, engine 56640. Method: tools/production_loc.py --json; exact parent and staged trees; inline tests/comments excluded; shipped SQL and JS included. Counter SHA256: 2903e1aed42f0eebb022b82b5fc2220278ccb870bbc06389adc79c4d340bad59. The new counter classifies crates by name in both old and new layouts. reference absent (retired R9c; last counted 65,417 at tree 498dd19).
The migration's full Linux functional run measured the existing layerfs-persistence::writer_admission target at 9.74 seconds. Record that observation in SLOW as the repository rule requires; keep this selection change separate from the path relocation. This is test scheduling, not a performance qualification or product change. Checks: six CI-selection/executable self-tests under a 120-second ceiling; pinned Ruff formatting and whitespace. No Rust product or test body changes, so the completed relocation's Rust/runtime proofs remain applicable. No tests deleted or moved. Production LOC: 102162 -> 102162 (delta +0) Scope: all first-party product implementation, including shipped SQL and JavaScript. before: api 7281, core 38241, engine 56640. after: api 7281, core 38241, engine 56640. Method: tools/production_loc.py --json; exact parent and staged trees; inline tests/comments excluded; shipped SQL and JS included. Counter SHA256: 2903e1aed42f0eebb022b82b5fc2220278ccb870bbc06389adc79c4d340bad59. reference absent (retired R9c; last counted 65,417 at tree 498dd19).
Split the implementation guide into core, engine and API responsibilities, retain common source/verification/profile rules, and update root workstream and manifest navigation. Document Project Store composition and approved edges. Update maintained guides, crate READMEs, current design navigation and SDK skill references. Preserve historical claims/receipts, archived documents and the reference retirement; link retired source at verified immutable commits. Record every migration part, exact LOC methods, moved/re-covered tests, the fixture-seal path repair, owner gates, branch rebases and external consumer follow-ups. Retain the explicit FP21 FAIL exception and its original evidence. Export and apply exact private cache releases after byte-verifying the archived failure executable; preserve its scratch, sealed SDK bundles and diagnostics. Checks: all 438 local links/anchors in 34 changed documents resolve; one status banner per document; path/command and scope review; whitespace. Rust/runtime checks do not apply to this docs-only change. Completed relocation verification is recorded without turning the FP21 failure into PASS. No tests changed. Production LOC: 102162 -> 102162 (delta +0) Scope: all first-party product implementation, including shipped SQL and JavaScript. before: api 7281, core 38241, engine 56640. after: api 7281, core 38241, engine 56640. Method: tools/production_loc.py --json; exact parent and staged trees; inline tests/comments excluded; shipped SQL and JS included. Counter SHA256: 2903e1aed42f0eebb022b82b5fc2220278ccb870bbc06389adc79c4d340bad59. reference absent (retired R9c; last counted 65,417 at tree 498dd19).
The caller preparation warms mounted-reader caches even when the shared canonical cache is disabled. Both OPEN and READDIR could finish without reaching the provider gate, so the fixture failed before any unmount attempt. Displace prepared pooled inode values through the same Workspace's public Store ports using 73 valid leaves with 7,300 distinct inline metadata values. The count derives from the existing cache bound. Keep the default policy, all product code, timeouts and original teardown assertions unchanged. Report request, provider and caller state when staging fails. Checks: diagnostic reproduces both original staging failures (10.13 s); final Linux focused proof 2/2 (0.25 s, 90 s command ceiling); separate no-run build; focused Clippy -D warnings; fmt; boundary guard (954 inputs), its 34 self-tests; fuser provenance; record links and whitespace. Original migration failure evidence is retained. No tests deleted. Production LOC: 102162 -> 102162 (delta 0) Scope: all first-party product Rust, shipped SQL and JavaScript; core 38241, engine 56640, API 7281. Method: tools/production_loc.py --root SNAPSHOT --json on exact first-parent and staged-tree archives with the same counter; comments and all tests excluded. Exact trees and counter hash retained in registration artifacts/loc.json. Test/docs-only change. Reference absent (retired R9c; last counted 65,417 at tree 498dd19).
api/ now holds only the published JavaScript packages; both Rust crates
join the engine.
Moves:
- api/layerfs-api -> engine/crates/layerfs-api
- api/binding -> engine/crates/layerfs-node (addon now builds at
engine/crates/layerfs-node/layerfs.node)
- api/agent/sdk -> api/agent
- api/agent/cli -> api/cli
- api/how-to-use -> api/docs
api/backend, api/runtime, api/scripts and api/package.json stay.
Relative and repository paths are rewritten in code, manifests, tests,
skills, plugin install guides and maintained docs. Historical records
(core/docs/issues, docs/versioned, docs/release-notes, docs/research)
are left unchanged.
Tooling follows the move: Cargo members are core/crates/* and
engine/crates/*; the guard and the LOC counter classify layerfs-api and
layerfs-node as engine by crate name, in both the old and new layouts;
the sealed bundle (copy_sdk) mirrors the new api/ layout; CI path filters
exclude engine/crates/layerfs-node (the binding stays outside CI);
layer guides (root, engine, api AGENTS.md and api/README.md) updated.
fixture_seal's scan roots drop the old api crate paths, now under engine.
Verified: cargo metadata unchanged (15 packages, same edges/targets);
cargo +1.85.1 check --workspace --all-targets and fmt --check pass;
guard PASS (954 files, --skip-sdk 818); 155 Python tool tests pass;
Ruff 0.17.2 format clean, no new lint findings; agent, backend, runtime,
packaging (dispatch with the addon built at its new path), trace and
exec_output stand-in tests pass; CLI 70/70. NOT_RUN on macOS: agent
binary_write, init_refusals and reinit (Linux binding + Store needed).
Deleted tests: none.
Production LOC: 102162 -> 102162 (delta 0)
Scope and method: tools/production_loc.py --root on git archive of the
parent (ff7ccee) and of the staged tree; per-file paths and counts
match (954 files). Subtotals by the counter's name-based classification:
core 38,241, engine 61,288, api 2,633. The parent's own counter recorded
engine 56,640 / api 7,281; the difference is layerfs-api (1,913) and
layerfs-node (2,735) reclassified to engine, a relocation, not a
simplification. Reference absent (retired R9c; last counted 65,417 at
tree 498dd19).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add the 2026-10-27 owner decision to the #463 implementation record: layerfs-api and the Node binding move to engine/crates and api/ holds only the JavaScript packages (commit b98ac4c), with its LOC and checks. Fix three record links to the binding tests (now engine/crates/layerfs-node/tests) and three migration-spec links to tools/ that the relocation broke. Checks: every local link in core/docs/issues/463 resolves; whitespace. Docs only; Rust/runtime checks do not apply. No tests changed. Production LOC: 102162 -> 102162 (delta 0) Scope: all first-party product implementation (core 38241, engine 61288, api 2633). Docs-only change; tools/production_loc.py counts no docs. Reference absent (retired R9c; last counted 65,417 at tree 498dd19). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
Author
|
Merged as Production LOC: 102158 -> 102162 (delta +4) |
yifanxuaaa
pushed a commit
to ImmuneFOMO/layerfs
that referenced
this pull request
Oct 26, 2026
…phemeral-AI-Lab#456) Production LOC: 102162 -> 102162 (delta 0) core 38241 -> 38241, engine 61288 -> 61288, api 2633 -> 2633; reference absent (retired R9c; last counted 65,417 at tree 498dd19). Counted with tools/production_loc.py; docs only. Rebased onto main after Ephemeral-AI-Lab#465 moved api/how-to-use/ to api/docs/.
yifanxuaaa
added a commit
that referenced
this pull request
Oct 26, 2026
…456) Says where LAYERFS_STORE_PATH points on each route (ImmuneFOMO, 36cf50b): on Linux this process opens the Store, on macOS and Windows the worker does, so the path is inside the worker's Linux. runtime.md adds what an agent process needs on the worker route. The contributor tested macOS with OrbStack; the Windows paths are read from source, not run. Rebased by the maintainer onto main after #465 moved api/how-to-use/ to api/docs/. Production LOC: 102162 -> 102162 (delta 0) First-parent comparison (main 939d68c -> this merge). core 38241, engine 61288, api 2633, unchanged; reference absent (retired R9c; last counted 65,417 at tree 498dd19). Counted with tools/production_loc.py; docs only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
yifanxuaaa
pushed a commit
that referenced
this pull request
Oct 26, 2026
Render the retained HTTP error prefix in ErrorDiagnostic Debug output so SDK failures include the daemon's reason. Keep the capture bound and metadata, escape controls and replace invalid UTF-8. Cover version refusals, truncation and encoding, and document the v1.54 requirement. Related to #457. Validation: 32 sandbox tests; 57 Python tooling tests; all-target Clippy for sandbox/API/Node with -D warnings; workspace formatting; real SDK before/after checks on Docker 29.1.3 and 29.9.2 passed. The full boundary guard retains four unchanged baseline SDK violations; core scope passes. Production LOC: 102162 -> 102164 (delta +2) Scope: first-party core, engine and API production source. Core: 38241 -> 38241; engine: 61288 -> 61290; API: 2633 -> 2633; dsh absent (moved out, #428). Reference absent (retired R9c; last counted 65,417 at tree 498dd19). Method: tools/production_loc.py --root <snapshot> (blob 3341e4d) on git archive snapshots of the first parent and committed trees: b8b8ff3 -> 9f65159. Recounted by the maintainer after the rebase onto main a9d5add (#465 moved the sandbox crate to engine/).
yifanxuaaa
added a commit
that referenced
this pull request
Oct 26, 2026
#465 moved api/how-to-use/agent.md to api/docs/agent.md; the rebased README paragraph still linked the old path. Production LOC: 102164 -> 102164 (delta 0) core 38241, engine 61290, api 2633, unchanged; reference absent (retired R9c; last counted 65,417 at tree 498dd19). Counted with tools/production_loc.py; docs only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
yifanxuaaa
added a commit
that referenced
this pull request
Oct 26, 2026
SDK failures for Docker HTTP errors now show the retained bounded error prefix (at most 1024 bytes, lossy UTF-8, controls escaped), so callers see the Engine's reason, such as an API v1.54 version refusal (#457). The owner accepted dropping the old redacted Debug for these diagnostics; docs 71 and 72 are updated. Request paths and single-attempt behaviour are unchanged; Docker servers that reject v1.54 still fail. Rebased by the maintainer onto main after #465 moved the sandbox crate to engine/ and api/how-to-use/ to api/docs/, with one fix commit for the README link. layerfs-sandbox: 32 tests pass on macOS (cargo 1.85.1), fmt and Clippy -D warnings clean. Production LOC: 102162 -> 102164 (delta +2) First-parent comparison (main a9d5add -> this merge). core 38241, engine 61288 -> 61290, api 2633; reference absent (retired R9c; last counted 65,417 at tree 498dd19). Counted with tools/production_loc.py. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
yifanxuaaa
pushed a commit
that referenced
this pull request
Oct 26, 2026
fs.stat answered a symlink's size as the length of the canonical object that stores its target: the object envelope plus the LFS4LNK header, 27 bytes more than the target (a link to `a.txt` reported 32). A mounted Workspace reports the target's length (base/view.rs stat_resolved and the FUSE attributes), so the two views of one symlink disagreed. snapshot::size now decodes the stored target with SymlinkTarget::decode, as the Workspace base view does, and returns its byte length. The operator file history and stats use the same helper and now count a symlink the same way. Tests: new layerfs-api tests/stat_symlink.rs (now under engine/ after #465) (a link and a dangling link); it fails on main with `left: Some(Int(32)) right: Some(Int(5))` and passes with the fix. The fs.stat reference in the layerfs-js-sdk skill now says what `size` means for each type. Verification (Linux arm64 VM, Rust 1.85.1): cargo fmt --all --check; clippy -p layerfs-store-service -p layerfs-api --all-targets -D warnings; test -p layerfs-store-service and each of the 46 layerfs-api test targets under a 120 s timeout: all passed. check_product_boundary.py reports the same 4 violations as main, none in the changed files. No tests deleted. Production LOC: 102164 -> 102165 (delta +1) Scope: first-party core, engine and API production source. Core: 38241 -> 38241; engine: 61290 -> 61291 (layerfs-store-service 10009 -> 10010); api: 2633 -> 2633. Method: tools/production_loc.py --root <extracted tree> (blob 3341e4d) on git archive of the first parent and the committed tree: 13477d9 -> bb3f715. Reference absent (retired R9c; last counted 65,417 at tree 498dd19). Recounted by the maintainer after the rebase onto main a944016 (#465 moved the crates to engine/).
yifanxuaaa
added a commit
that referenced
this pull request
Oct 26, 2026
fs.stat answered a symlink's size as the length of the object storing its target (target + 27 bytes); it now decodes the target and returns its length, as a mounted Workspace's lstat does. The operator storage and revision answers use the same helper, so they count a symlink the same way. No stored format changes. Rebased by the maintainer onto main after #465 moved the crates to engine/; the new test moved with it to engine/crates/layerfs-api/tests/. Checked on macOS (cargo 1.85.1): stat_symlink passes and fails on main's snapshot.rs with 32 vs 5; layerfs-store-service tests; layerfs-api sdk_method_golden, diff_resume, sdk_compare, write_refusals, sdk_reads_during_publish and init; fmt and Clippy -D warnings clean. Production LOC: 102164 -> 102165 (delta +1) First-parent comparison (main a944016 -> this merge). core 38241, engine 61290 -> 61291 (layerfs-store-service 10009 -> 10010), api 2633; reference absent (retired R9c; last counted 65,417 at tree 498dd19). Counted with tools/production_loc.py. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
yifanxuaaa
pushed a commit
that referenced
this pull request
Oct 26, 2026
…er_reclamation The Store binds no busy handler, so reclaim_space can be refused Busy without effect while the concurrent reader holds its snapshot. The test unwrapped that outcome and failed intermittently (4 of 80 local runs, and PR #402 CI). Treat Busy as the documented refused job and run a later one, bounded by JOBS. No tests deleted; no assertion changed. Production LOC: 102165 -> 102165 (delta 0) Test-only. core 38241, engine 61291, api 2633, unchanged; reference absent (retired R9c; last counted 65,417 at tree 498dd19). Method: tools/production_loc.py --root on git archive of the first parent and the committed tree (bb3f715 -> 7cf6e7b). Added by the maintainer after the rebase onto main 3828268 (#465 moved the crate to engine/).
yifanxuaaa
added a commit
that referenced
this pull request
Oct 26, 2026
…amation The Store binds no busy handler, so reclaim_space can be refused Busy, without effect, when it meets the concurrent reader; the test unwrapped that and failed intermittently (seen in #402 CI). The test now treats Busy as the documented refused job and sends a later one, at most JOBS times; other errors still fail and no assertion changed. Test-only; the owner accepted this caller-side retry in a test as consistent with the reclaim_space contract (a refused job is never replayed automatically, a caller may issue another). Rebased by the maintainer onto main after #465 moved the crate to engine/, and the missing LOC line added. Checked on macOS (cargo 1.85.1): immutable_reads_under_reclamation passes (1147 jobs during 89 read rounds); all 36 layerfs-persistence test binaries pass (118 tests); fmt and Clippy -D warnings clean. Production LOC: 102165 -> 102165 (delta 0) First-parent comparison (main 3828268 -> this merge). core 38241, engine 61291, api 2633, unchanged; reference absent (retired R9c; last counted 65,417 at tree 498dd19). Counted with tools/production_loc.py; test-only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
yifanxuaaa
pushed a commit
that referenced
this pull request
Oct 26, 2026
A write call naming a path below a regular file or a symlink (/a.txt/x, /dlink/x) walked into it: the content layer answered WrongLogicalRole, the write route mapped it to Unknown, and an Unknown keeps its Store call Workspace. fs.write/rm/edit/cp/mv each then held one, and after as many such calls as the Store has call Workspaces every write was refused Capacity. Mutation::resolve now refuses a name below a non-directory as NotDirectory at that entry, as fs.mkdir on the same route already does, so the call is a known refusal and its Workspace is closed. The SDK guide lists NotDirectory among the shared write refusals. Test added: layerfs-api/tests/write_refusals.rs a_write_through_a_non_directory_is_not_directory. No tests deleted. Production LOC: 102165 -> 102171 (delta +6) Scope: first-party core, engine and API production source. Core: 38241 -> 38241; engine: 61291 -> 61297 (layerfs-store-service 10010 -> 10016); api: 2633 -> 2633. Method: tools/production_loc.py --root on git archive of the first parent and the committed tree (7cf6e7b -> 5c005e0). Reference absent (retired R9c; last counted 65,417 at tree 498dd19). Test and docs are not counted. Recounted by the maintainer after the rebase onto main 41a848f (#465 moved the crates to engine/). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
yifanxuaaa
added a commit
that referenced
this pull request
Oct 26, 2026
…372) A write call naming a path below a regular file or a symlink (/a.txt/x, /dlink/x) was refused Unknown (Content WrongLogicalRole), and an Unknown keeps its Store call Workspace: 16 such calls refused every later write with Capacity until the Store reopened. Mutation::resolve now refuses a name below a non-directory as NotDirectory at that entry, as fs.mkdir already does, so the call is a known refusal and its Workspace closes. Symlinks are not followed by Store calls, as before. Rebased by the maintainer onto main after #465 moved the crates to engine/; LOC recounted. Checked on macOS with the pinned cargo 1.85.1: write_refusals passes and fails on main's mutation.rs with ("Unknown", "Content(WrongLogicalRole)"); layerfs-api concurrent_commits, method_refusal_order, lane_merge, sdk_chunk_deltas, sdk_method_golden (write_cost is ignored by default); layerfs-store-service tests; fmt and Clippy -D warnings clean. Known follow-ups from review: other read-only resolve errors still map to Unknown, and a symlink to a directory in the middle of a path is refused although the mount follows it. Production LOC: 102165 -> 102171 (delta +6) First-parent comparison (main 41a848f -> this merge). core 38241, engine 61291 -> 61297 (layerfs-store-service 10010 -> 10016), api 2633; reference absent (retired R9c; last counted 65,417 at tree 498dd19). Counted with tools/production_loc.py. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
jiangkoumo
added a commit
to jiangkoumo/layerfs
that referenced
this pull request
Oct 27, 2026
…) into PR Ephemeral-AI-Lab#402 (local port)
jiangkoumo
added a commit
to jiangkoumo/layerfs
that referenced
this pull request
Oct 27, 2026
…) into PR Ephemeral-AI-Lab#427 (local port)
jiangkoumo
added a commit
to jiangkoumo/layerfs
that referenced
this pull request
Oct 27, 2026
…Ephemeral-AI-Lab#427) D8 (Ephemeral-AI-Lab#465) made tools/check_product_boundary.py fail closed on any LayerFS crate missing from its core/engine/api layer map. Ephemeral-AI-Lab#427's layerfs-nfs (the loopback NFSv3 export, beside layerfs-fuse under engine/crates) was not in it, so the full and the CI (--skip-sdk) runs reported "crate missing from layer map: layerfs-nfs" for layerfs-nfs and for layerfs-daemon, which depends on it. It is an engine crate like layerfs-fuse; its dependencies (content, overlay, workspace, fuse) are at or below that layer. Production LOC: 108596 -> 108596 (delta 0) (tools/production_loc.py --root ., core+engine+api; development tool only)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Splits the Rust workspace into three layers,
core < engine < api(D8, #446). The Cargo workspace moves to the repository root.Closes #463.
Layout
core/crates/: content, history, storage and telemetry. They depend only on each other and don't use rusqlite.engine/crates/: bridge, daemon, fuse, overlay, persistence, project, sandbox, store-service, workspace, and the SDK method surfacelayerfs-apiand Node bindinglayerfs-node.api/: only the published JavaScript packages:agent,cli,backend,runtime,docs,scripts.The owner's gate decisions and the change to keep Rust out of
api/are recorded on #463. The full record is core/docs/issues/463/IMPLEMENTATION.md.Commits
05db9856932775b3fa440f442d5bb7layerfs-project3cae8b1a1ece2c0eb411ef4c26b02b853abcbe2bff7ccee2f6b98ac4c2f7api/; packages flattenedf406638c80Every commit message gives its counting method. Reference absent (retired R9c; last counted 65,417 at tree 498dd1917812).
Checks
cargo +1.85.1 check --workspace --all-targetsandfmt --checkpass.ff7ccee2f6.Not run here: three agent tests that need Linux and a real Store (
binary_write,init_refusals,reinit). CI's fast and nightly lanes report after the push.After merging
core/crates/*orapi/need a rebase. Git follows plain moves.target/; prepare again after rebasing.layerfs-463-api-paths) and a pin bump.common/lib.shstill usescore/target.🤖 Generated with Claude Code