Skip to content

v0.1.7 pair 2: implement portable history, staging and conditional publication #210

Description

@yifanxuaaa

Status: Proposal; target LayerFS v0.1.7; not a released contract.

Merged implementation; qualification remains open — 2026-09-21

Pair 2 is merged into main at 152b9c3a2. GitHub reports #211 (design), #212 (implementation) and #213 (review remediation and bridge consolidation) as MERGED. Original source branches and worktrees are retained. The newer main storage changes and #214/#215 additions are preserved.

M0–M3, the remediation packages P0–P7 and M5 are complete at the implemented scope. M4 remains incomplete, so #210 remains OPEN under the owner's instruction to close it only when all work is finished:

  • H04: real overlapping C2-save lifetimes with reverse completion/failure and retained stage are unverified.
  • H06: independent-stack upload overlap is NOT_RUN.
  • H08: real failures at all four boundaries and identical-root failed/unknown versus successful writer schedules are NOT_RUN.
  • H14: unchanged full history-consumer substitution across distinct compatible C1-only/C2-only/combined revisions remains UNVERIFIED. The earlier C1/C2-only component harness is narrower proof.

Final integration verification used the existing core/.cargo/config.toml profile, with commands run from core/, CARGO_TARGET_DIR=/Users/yifanxu/.codex/worktrees/b995/layerfs/target/remediation-core, LAYERFS_CONSTRUCTION_WORKERS=1, toolchain +1.85.1 and offline/locked dependencies:

  • cargo +1.85.1 test --manifest-path Cargo.toml --offline --locked --workspace: 605 passed, no failures, 3 declared ignored entries. The test tree was e21549050; subsequent main integration changed only documentation and a measurement example, which the final examples build/Clippy covers.
  • cargo +1.85.1 build --manifest-path Cargo.toml --offline --locked --workspace --examples --bins: PASS.
  • cargo +1.85.1 fmt --manifest-path Cargo.toml --all -- --check: PASS.
  • cargo +1.85.1 clippy --manifest-path Cargo.toml --offline --locked --workspace --all-targets -- -D warnings: PASS.
  • cargo +1.85.1 build --manifest-path Cargo.toml --offline --locked -p layerfs-history --no-default-features: PASS.
  • python3 tools/check_product_boundary.py: PASS, 194 production files; python3 -m unittest discover -s tools -p 'test_*.py': 6 passed.
  • Fresh production host route: 14 PASS. Fresh Linux Docker daemon → rebuilt macOS service route: 14 PASS, cleanup PASS. The Linux image layerfs-history-bridge:7a6db4c2 (sha256:53a9b1bfd21b68cffbebb8bb4ab7a3dcf94a1910ed69c47316ab81d9e53bac58) was reused after exact daemon/bridge/telemetry source, manifest/lock and core-profile equality checks; the service includes main's newer storage source.

Initial attempts are retained, not promoted to passing evidence: running Cargo from the repository root skipped the core profile and produced a host/image cipher mismatch, so initial Linux routes failed before the first reply. Rebuilding from core/ made the unchanged standard route pass. The initial root-profile test run also hit an unchanged telemetry retention NotFound; the native-feature rerun and complete correct-profile run passed. A default-feature telemetry-only run did not exercise native tests and is not evidence for that case. No product, worker, timeout, cache or dependency change was made for these diagnostics; no benchmark or release claim.

First-parent production LOC for the merge commits:

Commit Core Reference Combined
4ae8e668c design merge 25403 → 25403 (+0) 65417 → 65417 (+0) 90820 → 90820 (+0)
e21549050 implementation/remediation merge 25403 → 30860 (+5457) 65417 → 65417 (+0) 90820 → 96277 (+5457)
152b9c3a2 concurrent-main integration 30860 → 30860 (+0) 65417 → 65417 (+0) 96277 → 96277 (+0)

Method: tools/production_loc.py --root <exact git-archive snapshot> --detail --json, first parent versus final staged tree, with committed tree equality verified. First-party Rust/runtime SQL only; comments/blanks, inline legacy tests, external tests, examples, docs, tooling, manifests and artifacts excluded. Counter SHA-256 c6e853c2280e2ee96caa6cafff4b221fa9201e1f5bf40d12e8251f70387210fc. No relocation/retirement. The combined total includes 9 production lines already landed independently on main; Pair 2's net addition is 5457 and final bridge production LOC is 3658.

The existing repaired-boundary handoff retains the earlier source-pinned evidence and qualification details. Integration raw logs and exact source/count manifests are retained in the task's target/pair2-main-merge/ directory.

Historical review and remediation checklist — 2026-09-21

Original review-time disposition: not ready; remediation required. The current merged disposition and remaining qualifications are recorded above. Independent review pinned PR #212 at 92e56635ae4559d175fe3cd455f36f9fe6b5b498 with a clean tree before and after the review. The governing implementation specification and pre-publication audit remain pinned at c85cf6b69b3809d860caaad764a09e86a54ece9a.

The existing workspace checks passed at the reviewed head (580 tests; 97 test executables plus 6 doc-test invocations), as did the 13-case host daemon/service route. Independent probes nevertheless reproduced contract violations. Earlier milestone/coverage claims in PR #212 or its handoff must not be used as evidence that these defects are fixed.

Remediation checklist

  • P0: freeze repaired profile-2 typed failure/context, root-descriptor and cursor capability/format boundaries while preserving legacy profile-1 bytes.
  • P1 / R01, R07: preserve expected/actual and known exact-stage context; handle unknown C5 outcomes without guessed rollback or reusing an uncertain writer.
  • P2 / R03, R12–R14: repair legal minimum record widths, enforce 16 KiB reply budgets, correctly classify content-writing history commands, and restore legacy mutation ResultData rejection.
  • P3 / R02, R04, R05: prevent rehashed sibling-ancestry cursor forgery, support all legal names within the cursor cap, and resume anchored pages after the actual subject advances.
  • P4 / R06, R08: initialize every manifest directory, accept valid interleaved parent declarations, and validate/read the complete filesystem root descriptor including root serial.
  • P5 / R09, R10: validate frozen schema/binding on open and enforce stale-base publication precedence even with a refreshed expected stack head.
  • P6 / R11: make catalog reservation success and checked terminal endpoints agree before allocation exposure.
  • P7: add regressions and source-accurate documentation, preserve historical receipts, run fresh current-head checks/routes, report exact per-commit production LOC, and obtain independent review of the repaired head. Record R15 as a pre-existing baseline observation rather than a new reachable-panic defect.

Qualification remains separate

H04 real overlapping-save/reverse-failure observation, H06 independent-stack upload overlap, H08 actual boundary/identical-root failure schedules, the Linux Docker route, and H14 component substitution are not established by the host route or code inspection. H01/H10/H13 PASS labels are contradicted by the review's manifest/allocation/page counterexamples and require fresh evidence. During review, Linux targets were installed for toolchain 1.85.1; the former missing-target explanation must not be repeated as a current observation. Record any genuinely unavailable schedule/capability as NOT_RUN/UNVERIFIED with its exact reason; no fabricated product hooks, sleeps or implied PASS.

A separate Codex task is being launched to execute this specification in an isolated checkout. Keep the original reviewed worktree untouched; use a separate remediation branch and a reviewable follow-up PR. No merge/closure is authorized here. No benchmark/performance campaign, worker/timeout/cache retuning, dependency patch/vendor/fork, CI or retired preflight. Preserve W=2, Q=0, exact-finish staging, metadata-only save exclusion and the selected continuity envelope.

This planning/evidence commit changes no production source: Production LOC: 95665 -> 95665 (delta 0); core 30248 unchanged, reference 65417 unchanged. It does not claim implementation of any remediation item or close #179/#180/#192/#193/#209.

Implementation sub-issue of #180. Pair 3 and its schema-7 multi-writer implementation have landed. Implement pair 2 independently through the existing service; a non-FUSE client supplies the first consumer, and later pair 1 (#179) consumes this contract.

Specification: Implementation specification
Pre-publication audit: Three-subagent audit and dispositions

Outcome

Deliver layerfs-history, a separate versioned catalog, real service initialization/staging and history operations through the existing bridge. Preserve C1/C2 canonical content, physical encoding and public save contracts. No FUSE/Workspace implementation is required for this issue.

Inspected baseline: a02168adbb1b02571941654919cefca12dbc1f42, including multi-writer landing eb319aaa9. C2 stays schema 7 with six tables and two private saves per Store; service admission stays W=2, Q=0, one construction producer per ordinary operation; namespace init retains its existing exception.

Operations

  • init_layerstack: Empty or bounded logical namespace manifest -> genesis Layer/stack and root descriptor, through production C1/C2 code.
  • fork: from a Layer or an authorized existing Commit -> Branch sharing the selected root/ancestry.
  • read_branch: coherent stack/base/head/root/profile/scope/root-serial descriptor.
  • stage_changes: validated existing-inode prepared changes -> saved candidate and exact stage token.
  • commit_staged: atomic immutable Commit + conditional Branch advancement + exact stage removal.
  • commit: convenience composition of stage_changes and commit_staged, one service admission, separate persistence boundaries.
  • add_layer: reuse Commit root, insert Layer and conditionally advance LayerStack; Branch base/head unchanged.
  • discard_stage: delete only the exact matching stage; no content deletion or serial recycling.
  • reserve_inodes: checked scope-wide range under the continuing-authority contract.
  • Typed get/list/Commit-history/Layer-history/stage inspection with bounded pages.

Tables

Create seven tables in C5 catalog schema 1, separate from C2:

Table Contents / main invariant
history_meta Catalog/incarnation, stable Store/authority binding, identity-format version, monotonic stage-token allocator
layer_stacks Name, scope/profile, conditional head Layer
layers Immutable stack/parent/root/source; unique genesis, child and published source
branches Stack/name/base Layer/optional head Commit; coherent conditional head/base
commits Immutable root/parent Commit/base Layer; ancestry shared by forks
workspace_stages Workspace incarnation/token, candidate root, frozen expected head/base/root and construction context
scope_allocator One checked high-water authority per shared inode scope; no exposed-range recycling

C2's saves is physical ownership, not a history stage or Commit. No foreign key or transaction crosses databases; service validates root provenance and binding. A Workspace ID is opaque: no runtime workspaces table or live Workspace dependency.

Relationships

LayerStack S.head -> L0(root R0)
                     ^
                     | base
Branch A.head -> K2(root R2, base L0) -> parent K1 -> None

Stage W/token17:
  branch=A, expected=(K2,L0,R2), candidate=R3

commit_staged(17):
  insert K3(root R3,parent K2,base L0)
  CAS A.head K2 -> K3; delete exact stage17

add_layer(A,K3,expected=L0):
  insert L1(root R3,parent L0,source A/K3)
  CAS S.head L0 -> L1
  A.head=K3 and A.base=L0 remain unchanged

Fork-from-Commit uses that selected Commit's base, not the source Branch's current base. Layer publication reuses the same root without content copying/re-encoding. Same-Branch concurrent changes get one state-changing winner and a retained losing stage, whether file edits overlap or not. No automatic rebase or conflict resolution.

File and LOC plan

core/crates/layerfs-history/
  src/{lib,identity,records,catalog,error}.rs
  src/sqlite/{mod,open,rows,branch,staging,commit,layerstack,allocation,query}.rs
  sql/schema-v1.sql
  tests/{lifecycle,conditional_updates,allocation,reopen,history_pages}.rs

core/crates/layerfs-service/
  src/operation/{history,history_bootstrap}.rs
  extend owner, dispatch/failure, native configuration/startup
  tests/history.rs

core/crates/layerfs-bridge/
  src/contract/history.rs
  extend request/outcome, metadata/response/state codecs and client matching
  tests/history_protocol.rs

core/crates/layerfs-daemon/tests/history_route.py
Production scope Central planning LOC
History Rust + runtime SQL 2,505
Service bootstrap/history/validation/wiring 900
Bridge contract/codecs/classification 650
Total 4,055; expected 3,500–5,000

These are estimates, not measured counts or caps. External tests/helpers/drivers are another 1,800–3,000 LOC, excluded from production. The revised estimate includes bootstrap, role validation and permission/protocol work exposed by audit. Each commit still requires exact first-parent/staged/committed production LOC, reference/core subtotals and counting method. Product files <=999 physical lines; lib.rs/mod.rs <=200 and declarations/delegation only; external tests.

Integration decisions and explicit limits

  • Keep C1/C2 in the service. Stage only after that exact validated operation's known C2 finish. Root presence, an authenticated wrong-role object or another writer publishing identical bytes does not prove success.
  • Initial staging requires construction base = captured Branch root and intended Commit base = captured Branch base. If the head races during saving, retain the candidate stage; commit_staged enforces the authoritative CAS.
  • C5 holds only short metadata transactions with immediate Busy refusal; no catalog lock across upload/construction/C2 finish, no nested cross-database locks.
  • Add HistoryQuery/HistoryCommand as grouped opcodes 6/7 under operation profile 2. Preserve legacy profile1/opcodes1–5 and mask31; explicit Store-wide history grants, exhaustive mutation classification, separate metadata-only dispatch and checked response matching.
  • Native initialization supports Empty or at most 128 logical manifest entries within 32 KiB metadata, assigning fresh scoped serials in the service. Attributes/symlinks are saved before filesystem construction if retained roots are required. Host scanning/arbitrary imported roots are not included.
  • Initial stage_changes remains existing-inode only. Live new-inode/metadata extensions for complete writable Workspace are later pair-1 work; allocation alone does not enable create/mkdir.
  • Fresh writable catalog creation occurs inside its owning service process. One continuing authority writes; read-only reopen works. Arbitrary writable process restart/restore/copy fails ContinuityUnavailable until a trustworthy continuity capability is implemented. No clean-flag/root-scan proof or added sync/WAL.
  • Portable C5 contract; initial native C1/C2 composition is Linux/macOS. No native Windows/WASM/cloud qualification is implied.

Milestones / acceptance

  • M0: freeze IDs/DDL, catalog application ID, wire tags/grants, bootstrap manifest, bounded cursor grammar and writable-authority lifecycle.
  • M1: real catalog/IDs/schema validation, genesis/Branch/fork/allocation/queries and external public tests.
  • M2: exact staging/discard, Commit/Branch CAS, Layer/stack CAS, no-change and prior-publication precedence tests.
  • M3: production bootstrap and trusted save-to-stage composition; role validation, authorization, profile/codecs and non-FUSE client lifecycle.
  • M4: actual service/daemon route plus H01–H14 from the spec, with W2 isolation, stale-head retention, failure/unknown outcomes, bounded resources and continuity refusals.
  • M5: independent implementation audit, exact checks/LOC, source-backed architecture update and pair-1 handoff.

H04's reverse-completion proof must observe overlapping real C2 save lifetimes. Delayed metadata/END_INPUT or submission order alone is not that proof. If unavailable, retain the exact gap as NOT_RUN alongside separate C2 W2 and actual service/history evidence; no product test hooks/delays or implied PASS.

Run explicit core-manifest locked workspace tests, examples, fmt, warning-denying Clippy, boundary guard and its self-tests. Add no-native feature and actual daemon-route checks. No CI/aggregate preflight; no worker, cache, timeout or workload change to pass a gate. Runtime/benchmark acceptance is NOT_RUN at issue creation.

Out of scope: full FUSE/Workspace, diff/conflict resolution (#164), GC, force-reset, automatic replay/rebase, arbitrary host/root import, transparent migration, cross-store crash atomicity and stronger durability. This issue does not close #180, #179, #192, #193 or #209 by implication.

Pre-publication review

Three subagents audited reference history semantics, landed C1/C2 multiwriter integration, and service/bridge portability. The spec incorporates their corrections for construction-base binding, typed-root provenance, production bootstrap, opcode/grant capacity, metadata-only dispatch, continuity, anchored cursors and proof quality. The linked audit records findings/dispositions. Review is not implementation verification.

Activity

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