Skip to content

feat(sessions): load and apply user policy - #733

Merged
evanspearman merged 1 commit into
mainfrom
evan/policy
Jul 14, 2026
Merged

feat(sessions): load and apply user policy#733
evanspearman merged 1 commit into
mainfrom
evan/policy

Conversation

@evanspearman

@evanspearman evanspearman commented Jul 13, 2026

Copy link
Copy Markdown
Member

Load user_policy.toml from <config>/minimal/ and thread it through
activation. Fills in the placeholder UserPolicy::empty() /
UserPolicy::default() sites that were shipping unenforced.

  • sessions::core::policyread_user_policy_file / _or_default
    loaders (empty policy on NotFound).
  • minimal::config::read_user_policy — helper mirroring
    read_client_config. Loaded once in cmd_activate, passed into
    both compose_user_contribution and drive_pending_to_active.
  • drive_pending_to_active now takes UserPolicy + ComposeOptions
    (was defaults) — daemon-response pending items get gated against
    the real policy.

Policy semantics fixes

Two behavior corrections uncovered while wiring this up:

  • Deny beats ignore on single-path check in both VarsPolicy and
    ExpandedPatchPolicy. Deny is the emergency stop — it can't be
    silently hidden behind an overlapping ignore glob. PathDecision::combine
    was already correct; single-path decide / check were inverted.
  • Policy patterns don't need to be absolute. Split
    expand_source (patch-source, must-be-absolute walker input) from
    expand_policy_pattern (matcher against real paths). deny = ["**/*.pem"] in user_policy.toml now works. ~name/ tilde-user
    form still rejected loudly (was previously caught by the absolute
    check; now has its own ExpandError::UnsupportedTildeUser variant
    so both code paths surface the footgun).

Summary by CodeRabbit

  • New Features
    • Added support for loading user policy rules from user_policy.toml, with missing files defaulting to an empty policy.
    • User-defined variable and patch rules are now used during session composition/activation.
    • Policy pattern matching now supports non-absolute globs while still expanding home-directory paths.
  • Bug Fixes
    • deny rules now consistently take precedence over ignore for both variables and patch matching, including overlapping rules.
    • Per-user tilde patterns (for example ~name/...) are rejected earlier with a clearer error.

@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3434e02d-69bc-4b58-9ab1-bec4ad495ad5

📥 Commits

Reviewing files that changed from the base of the PR and between b72188a and 4e87874.

📒 Files selected for processing (6)
  • crates/minimal/src/config.rs
  • crates/minimal/src/lib.rs
  • crates/minimal/src/loadouts.rs
  • crates/sessions/src/core/compose.rs
  • crates/sessions/src/core/expansion.rs
  • crates/sessions/src/core/policy.rs
🚧 Files skipped from review as they are similar to previous changes (6)
  • crates/minimal/src/config.rs
  • crates/sessions/src/core/compose.rs
  • crates/minimal/src/loadouts.rs
  • crates/minimal/src/lib.rs
  • crates/sessions/src/core/policy.rs
  • crates/sessions/src/core/expansion.rs

📝 Walkthrough

Walkthrough

User policy loading and enforcement now flow through minimal activation. Policy expansion supports non-absolute patterns, rejects per-user tilde prefixes, and applies deny-over-ignore precedence. Activation passes loaded policy and compose options through contribution composition and pending handling.

Changes

User policy flow

Layer / File(s) Summary
Policy pattern expansion
crates/sessions/src/core/expansion.rs, crates/sessions/src/core/compose.rs
Adds policy-specific expansion, conditional absolute-path validation, unsupported per-user tilde errors, and corresponding tests.
Policy precedence and file loading
crates/sessions/src/core/policy.rs
Makes deny rules override ignore rules, expands policy patterns through the new API, and adds TOML loading helpers with missing-file defaults and tests.
Minimal activation integration
crates/minimal/src/config.rs, crates/minimal/src/loadouts.rs, crates/minimal/src/lib.rs
Loads user policy, composes contributions with it, derives compose options from client configuration, and passes both through pending activation handling.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant cmd_activate
  participant config_read_user_policy
  participant read_user_policy_or_default
  participant compose_user_contribution
  participant drive_pending_to_active
  participant handle_response

  cmd_activate->>config_read_user_policy: load user_policy.toml
  config_read_user_policy->>read_user_policy_or_default: read policy or return empty policy
  read_user_policy_or_default-->>config_read_user_policy: UserPolicy
  cmd_activate->>compose_user_contribution: compose loadouts with UserPolicy and ComposeOptions
  cmd_activate->>drive_pending_to_active: pass UserPolicy and ComposeOptions
  drive_pending_to_active->>handle_response: handle pending response with policy and options
Loading

Poem

I’m a rabbit with policies tucked tight,
Deny hops first in the lantern light.
Tildes behave, paths stay neat,
Loadouts compose with rules complete.
Through activation, the burrow beats.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: loading and applying user policy during session activation.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

Comment @coderabbitai help to get the list of available commands.

@twitchyliquid64 twitchyliquid64 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cargo fmt && cargo clippy --all-targets --fix --allow-dirty -- -D warnings && cargo fmt

@evanspearman
evanspearman force-pushed the evan/policy branch 2 times, most recently from b72188a to 4e87874 Compare July 14, 2026 20:07
@evanspearman
evanspearman merged commit 0db0123 into main Jul 14, 2026
28 checks passed
@evanspearman
evanspearman deleted the evan/policy branch July 14, 2026 20:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants