fix(engine): read a file under the scope it sits in - #1912
Conversation
resolve_versions opened every file record under the vault root scope and its read seed. A grant re-seals the granted folder into a scope of its own, and a file below a grafted root is sealed under the sharer's scope, so both reads failed with a TrustViolation at the unseal stage. The read now picks the scope from the file's position (the nearest enclosing scope root this session knows, or the vault root), its read seed, and the floor namespace of that scope. A node below no known scope root is ContentUnavailable. One helper, scope_floors, serves both the seed cache and the adopter.
|
Warning Review limit reachedNext included review available in 49 minutes. View limit detailsLimit details: You’ve used the included review currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Review configuration: ⚙️ Run configurationConfiguration used: Repository: FSM1/cipher-box/.coderabbit.yaml Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (6)
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository: FSM1/cipher-box/.coderabbit.yaml Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (3)
Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review. WalkthroughThe engine now resolves content reads under the enclosing scope root and its floor store. Tests cover unavailable reads, multi-version reads for owners and recipients, and downloaded byte equality in the contact-grant browser flow. ChangesScoped content reads
Priority: ➖ Normal Estimated code review effort: 3 (Moderate) | ~25 minutes Change: Bug fix · Severity of issue fixed: Medium Sequence Diagram(s)sequenceDiagram
participant Reader
participant Engine
participant ScopeResolver
participant ChildAdopter
Reader->>Engine: request content or version history
Engine->>ScopeResolver: find enclosing scope root
ScopeResolver-->>Engine: return scope root
Engine->>ChildAdopter: resolve using scoped floors
ChildAdopter-->>Engine: return content or ContentUnavailable
Engine-->>Reader: return read result
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Full details: Docstring CoverageExplanation Docstring coverage is 72.73% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 11 functions across 2 files. (1 skipped: 1 too large.) ✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@coderabbitai review |
|
|
…s it The grant or invite link that mints a scope now hands back the minted scope's read seed and epoch, and the facade deposits it at once. The owner's own scope roots for the floor namespace now include the roots this session minted, so the seed lookup and the tick's eviction pass keep that seed while no boundary walk has proved the scope.
|
Review disposition for d60afbc:
|
Result
A file read opened every record under the vault root scope and its read seed. Two cases failed with
TrustViolation(adoption gate rejected at stage [unseal]: [seal-open-failed]):mainatd1f05ee30: the new testthe_owner_reads_a_file_inside_a_folder_it_grantedfails on the granting device for a file written before the grant. A grant re-seals the folder interior into the new scope, so every file in a shared folder became unreadable to its owner, on every device.the_recipient_reads_a_file_below_a_grafted_rooton a read grant and on a write grant.Both tests fail on
mainand pass with this change.The change
resolve_versionsincrates/engine/src/facade.rsnow picks the scope from the position of the file:authored_scope_roots: minted, proved, unproved and grafted roots), or the vault root.scope_read_seedfor that scope.scope_floors, which is thefloor_viewdecision.scope_read_seednow uses the same helper, so the seed and the floors cannot come from two different decisions. A grafted scope is measured in the floor namespace of the granting contact.ContentUnavailable, not a read under the vault root seed (security rule 6). An unproved scope root or a scope with no held seed is alsoContentUnavailable.Every read path goes through
resolve_versions:read_content,read_version_content,file_versions,open_content_stream, and the version commandsRestoreVersionandDeleteVersion. No new durable record, no seam change, no wire change.Tests
crates/engine/tests/mount_convergence.rsthe_owner_reads_a_file_inside_a_folder_it_granted: head content, version list and prior version content, for a file written before the grant and a file written after it, on the granting device and on a second owner device.the_recipient_reads_a_file_below_a_grafted_root: a real recipient session accepts the share through its mailbox and contact book, then reads both files (head, version list, prior version) under a read grant and under a write grant.crates/engine/src/facade.rsa_file_below_no_held_scope_root_is_unavailable: a mutation check. With a vault root fallback in place of the refusal, the read returns the plaintext and the test fails.tests/web-e2e/tests/contact-grant.spec.ts(smoke slice): the owner downloads the file added after the grant and the recipient downloads the same file from the received share. Both compare the bytes.A file the grantee wrote is not covered here: the facade write guard on
mainrefuses a write below a grafted root. The file is sealed under the same scope seed, so the same path reads it.Local gates
cargo fmt --all --check,cargo clippy --workspace --all-targets -- -D warnings,cargo clippy -p cipherbox-engine -p cipherbox-wasm --target wasm32-unknown-unknown -- -D warnings: pass.cargo test -p cipherbox-engine: pass.pnpm lint:tracker-refs, eslint and prettier on the spec: pass.coderabbit review --agent:review_completed, 0 findings.Review passes
Zeroizingwith the adopter as its terminal owner.Closes #1909.
Body checks / follow-ups filed
TrustViolation [epoch]: [epoch-below-floor]until a write re-seals it. Measured onmain. This PR does not change it.RestoreVersionbelow a grafted root only because of this defect. After this PR merges, that refusal can be lifted. This PR does not touch it.Note
Fix
engineto read files under their enclosing scope rootscope_floorshelper, and passes the floor view toChildAdopter.ContentUnavailablefor both content reads and version-history lookups.ChildAdoptercallers in facade.rs and any out-of-tree consumers that relied on vault-root-only resolution will seeContentUnavailableinstead of a best-effort read for nodes below non-held scope roots.Macroscope summarized d7651dd.
Summary by CodeRabbit
Bug Fixes
Tests