feat(sessions): patch source/policies home expansion - #372
Conversation
|
Note Currently processing new changes in this PR. This may take a few minutes, please wait... ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughThis PR implements home directory ( ChangesHome directory expansion in patch resolution
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related issues
Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@crates/sessions/docs/RESOLUTION.md`:
- Around line 179-181: Update the documentation to list all inner variants
returned by ResolveError::HomeUnresolved: explicitly include
HomeResolutionFailure::NotAbsolute alongside HomeResolutionFailure::Unavailable
and HomeResolutionFailure::NotUtf8 so the docs match the resolver's error
surface; locate the paragraph referencing ResolveError::HomeUnresolved and
change the inner variant enumeration to `HomeResolutionFailure::{Unavailable,
NotUtf8, NotAbsolute}` (or equivalent wording) to reflect the current API.
In `@crates/sessions/src/composable.rs`:
- Around line 551-555: The doc comment for the HomeUnresolved variant is out of
sync with the HomeResolutionFailure enum: update the documentation on
HomeUnresolved to enumerate all actual failure modes in HomeResolutionFailure
(no home available, non-UTF-8 home path, and NotAbsolute/non-absolute home path)
and keep the guidance to match on the inner HomeResolutionFailure to distinguish
causes (reference the HomeUnresolved variant and the HomeResolutionFailure enum
in your wording so callers aren't misled).
- Around line 1198-1202: The current checks use starts_with('~') and thus match
`~user/...` which expand_home doesn't handle, leading to
ResolveError::HomeUnresolved; update the logic to only treat a pattern as
home-expansion candidate when it is exactly "~" or begins with "~/". Change the
function any_tilde (and the other occurrences that currently call
starts_with('~') around the expand_home use) to check fs.pattern() == "~" ||
fs.pattern().starts_with("~/") (or the equivalent string checks where patterns
are plain &str) so only bare "~" and "~/..." are passed to expand_home and other
code paths that expect home expansion.
In `@crates/sessions/src/loadout.rs`:
- Around line 14-20: The file-level doc comment in loadout.rs is inconsistent:
it currently states "dest `~` is expanded at apply time", but the resolver/patch
layer now treats destination `~` as non-expanded and validates it as
sandbox-home-relative. Update the doc paragraph (the "~-expansion is split by
realm" section referencing "source `~`" and "dest `~`") to state that source `~`
is expanded at session-resolution (host home) while dest `~` is left unexpanded
by the resolver and is validated as sandbox-home-relative (with expansion
occurring only in the sandbox runtime), ensuring the wording matches the
resolver/patch contract.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 3f6d12e8-d742-408f-ab93-d136f1211655
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (5)
crates/sessions/Cargo.tomlcrates/sessions/docs/RESOLUTION.mdcrates/sessions/src/composable.rscrates/sessions/src/loadout.rscrates/sessions/src/patches.rs
dc3df0e to
dc11611
Compare
| /// The home argument is unconditional: callers are expected to gate | ||
| /// the call on whether any tilde pattern is in scope, so by the time | ||
| /// this function runs we always know a usable home is available. | ||
| fn expand_home<'a>( |
There was a problem hiding this comment.
format!("{home}/{suffix}") feeds the home into a glob unescaped — a home containing *?[]{}\ (e.g. /home/u[1]) reinterprets the home segment, so walk_root() truncates at the metachar and the patch silently matches nothing.
There was a problem hiding this comment.
Thanks. Good catch!
This is actually being completely replaced in the var expansion stuff I'm currently working on and the bug should no longer be present. I'll add an explicit test for this case in that change though.
Patch source
FileSetpatterns andPatchPolicyallow/deny/ignorepatterns are commonly written
~/-relative (source = "~/dotfiles/...",deny = ["~/.ssh/**"]). The walker doesn't interpret~, so todaythose silently match nothing — a dotfile patch contributes zero files,
a
~/.ssh/**deny rule never fires.The resolver now expands
~against a configurable host home(
HomeLookup—dirs::home_dirby default) before walking and beforepolicy
check. Both halves keep their~/-relative form in thereturned policy, so save/load is lossless.
Behavior:
~-prefixed patternis in scope. A loadout with no
~anywhere never asks for home.~-prefixedrule and home wasn't previously needed.
PatchDestis unchanged — destinations are implicitly relative to thesandbox user's home and reject
~/ absolute paths at construction.Failures surface as
ResolveError::HomeUnresolved(HomeResolutionFailure)distinguishing three causes (
Unavailable,NotUtf8,NotAbsolute) sothe user knows whether to set
$HOME, fix encoding, or report a buggylookup. No silent fallback to root or to an empty path.
Type choices that came out of review along the way:
resolve_homereturnsHostAbsPath, surfacing relative results asNotAbsoluteinstead of letting them flow through.expand_homeandexpand_policy_hometake&HostAbsPathunconditionally; the
Optionlives at the caller, so the"tilde + no home" combination is impossible at the type level rather
than enforced by
expect.compute_dest's strip_prefix is camino's path-component-awarevariant, so
/etc/xdgno longer falsely matches/etc/xdgfoo.Tests cover all three home-failure modes, the lazy-lookup precondition,
hook-introduced tilde rules, and the path-component-aware strip-prefix
regression. 127 lib tests pass.
Resolves https://github.com/gominimal/inbox/issues/196
Summary by CodeRabbit
New Features
~are expanded against the host home during session resolution; raw~is preserved in saved/returned policies.~patterns exist.~rules are re-expanded and enforced.Documentation
~semantics for sources vs destinations, the resolution stages, and explicit failure cases for unresolved home paths.