Skip to content

chore: re-arranged the code in the sessions module to prepare for theclient/daemon split - #427

Merged
evanspearman merged 2 commits into
mainfrom
evan/split01
Jun 16, 2026
Merged

chore: re-arranged the code in the sessions module to prepare for theclient/daemon split#427
evanspearman merged 2 commits into
mainfrom
evan/split01

Conversation

@evanspearman

@evanspearman evanspearman commented Jun 16, 2026

Copy link
Copy Markdown
Member

This is a refactor to prepare for the client/daemon split in session/loadout logic. There are some other minor changes that were required due to some of the moves, but no functional changes.

Summary by CodeRabbit

  • New Features

    • Added a policy hooks API that can externally decide or approve undecided variables and patch-source items during session resolution.
  • Refactor

    • Consolidated policy, provenance, and expansion behavior into shared core types for consistent attribution of decisions and errors.
    • Improved patch source enumeration, including optional symlink-aware canonicalization and provenance-carrying results.
  • Breaking Changes

    • Public module/API layout was reorganized; the previous policy/vars surfaces were removed and replaced with new client/core/wire exports.
    • Error types for variable/patch handling were updated to the new core primitives model.

@coderabbitai

coderabbitai Bot commented Jun 16, 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: e8963612-75c2-40ac-85ee-ff2c8b92a268

📥 Commits

Reviewing files that changed from the base of the PR and between 0f6b6da and b71028a.

📒 Files selected for processing (4)
  • crates/sessions/src/client/composer.rs
  • crates/sessions/src/core/expansion.rs
  • crates/sessions/src/core/policy.rs
  • crates/sessions/src/wire/mod.rs
✅ Files skipped from review due to trivial changes (1)
  • crates/sessions/src/wire/mod.rs
🚧 Files skipped from review as they are similar to previous changes (3)
  • crates/sessions/src/core/expansion.rs
  • crates/sessions/src/core/policy.rs
  • crates/sessions/src/client/composer.rs

📝 Walkthrough

Walkthrough

Restructures the sessions crate by introducing core and client sub-module hierarchies. Previously flat top-level modules (vars.rs, policy.rs, patches.rs, expansion.rs, etc.) are consolidated into core/{primitives,decision,policy,source,expansion,lifecyclehook,loadout} and client/{composer,enumerate,hooks}. The crate's public module surface is updated to export the new hierarchy, and all dependent types and functions are rewired to use the restructured import paths.

Changes

Sessions crate module restructure

Layer / File(s) Summary
Crate public module surface and wire module
crates/sessions/src/lib.rs, crates/sessions/src/wire/mod.rs
lib.rs now exports client, core, store, and wire instead of the old flat module set; vars.rs and policy.rs are deleted. wire/mod.rs gains documentation describing its role as a placeholder for RPC wire-form types.
Core primitive error types: VarError and PatchError
crates/sessions/src/core/primitives.rs
Adds VarError and PatchError enums; changes FileSet::try_new, FileSet::resolve, and PatchDest::try_new signatures to return PatchError variants; updates module-level documentation; updates error assertions in patch-destination tests.
Core variable primitives: names, values, and ResolvedVar
crates/sessions/src/core/primitives.rs
Introduces StrictVarName, LenientVarName, LenientVarEntry, VarName, VarValue, and ResolvedVar with validation constructors, serde TOML support, FromStr parsing, and environment-lookup resolution surfacing VarError; adds comprehensive unit tests covering parsing, serde round-tripping, and resolution semantics.
Core policy decision enums and module surface
crates/sessions/src/core/decision.rs, crates/sessions/src/core/mod.rs
Adds Decision<T>, CheckOutcome<T>, and ItemDecision enums to core/decision.rs encoding resolver verdicts and hook responses; declares all core submodules in core/mod.rs.
Core provenance types: Source and Provenanced wrappers
crates/sessions/src/core/source.rs
Adds Source enum (UserLoadout, Project, Package), Provenanced trait, and wrapper structs (ProvenancedVar, ProvenancedPatch, ProvenancedPackage, ProvenancedHook) pairing primitives with provenance and exposing into_parts destructuring; implements Display for human-readable provenance strings.
Core policy types and precedence logic
crates/sessions/src/core/policy.rs
Adds core/policy.rs with VarNameGlobs, VarsPolicy, PatchPolicy, UserPolicy, and ExpandedPatchPolicy; implements check method with decision precedence (ignore > deny > allow > NeedsApproval), TOML serialization/deserialization, and expand_with for patch pattern expansion; includes comprehensive unit tests.
Core expansion: VarLookup trait and ExpandError rewiring
crates/sessions/src/core/expansion.rs
Introduces VarLookup trait decoupling variable resolution from SessionVar carrier; changes expand_source signature to accept &(impl VarLookup + ?Sized); updates ExpandError::PostExpansionInvalid to derive From<crate::core::primitives::PatchError>; updates test construction to use core primitive types.
core/loadout Composable impl and lifecyclehook doc paths
crates/sessions/src/core/loadout.rs, crates/sessions/src/core/lifecyclehook.rs
Migrates Loadout's Composable impl from crate::composable to crate::client::composer; updates lifecyclehook.rs Rustdoc example import paths to sessions::core::lifecyclehook; updates test imports to reference core primitive types.
client/hooks: PolicyHooks trait, HookResult, and Unapproved wrapper
crates/sessions/src/client/hooks.rs, crates/sessions/src/client/mod.rs
Introduces Unapproved<'a,T> borrowed wrapper with item/source accessors, HookResult<P> enum with Decided/Abort variants and constructor helpers, and the PolicyHooks trait with on_var_unapproved and on_patch_unapproved callbacks; declares client submodules in mod.rs.
client/enumerate: PatchFile, file enumeration, and path computation
crates/sessions/src/client/enumerate.rs
Adds PatchFile struct storing optional link path, canonical target path, computed sandbox-relative destination, and provenance; ExpandedProvenancedPatch handoff type; enumerate_patch_files function that walks patches, accumulates errors, filters by policy, and tracks symlink dual-paths; canonicalize_utf8 helper; compute_dest for single-file (verbatim) vs multi-file (append suffix) path computation with invariant panics; includes unit tests.
client/composer: error types, resolution helpers, and core integration
crates/sessions/src/client/composer.rs
Updates imports to pull types from crate::core submodules and crate::client::hooks; rewires Error and ResolveError variant types to core error types; implements VarLookup for [SessionVar]; makes apply_decision, resolve_vars, and expand_patch_sources pub(crate); updates resolution functions to use accessor APIs and Unapproved views; updates expand_patch_sources to call core expand_source and thread ExpandedProvenancedPatch; removes relocated tests; updates remaining test imports and error assertions to use core types.

Sequence Diagram(s)

sequenceDiagram
  participant App
  participant Composer
  participant ResolveVars
  participant PolicyHooks
  participant ExpandPatch
  participant EnumerateFiles
  App->>Composer: resolve(provenanced_items)
  Composer->>ResolveVars: resolve per-domain vars
  ResolveVars->>ResolveVars: check policy (ignore/deny/allow)
  alt needs approval
    ResolveVars->>PolicyHooks: on_var_unapproved(Unapproved)
    PolicyHooks-->>ResolveVars: HookResult::Decided or Abort
  end
  Composer->>ExpandPatch: expand_patch_sources
  ExpandPatch->>ExpandPatch: call expand_source(VarLookup)
  alt expansion error
    ExpandPatch-->>Composer: Err(ExpandError)
  end
  Composer->>EnumerateFiles: enumerate_patch_files
  EnumerateFiles->>EnumerateFiles: walk, canonicalize, compute_dest
  alt walk/canonicalize error
    EnumerateFiles-->>Composer: Err(ResolveError::PatchWalk)
  end
  Composer-->>App: Ok(resolved session) or Err
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related issues

  • gominimal/inbox#198: Requires the new Source enum with Project and Package variants in crate::core::source and the moved Composable trait in crate::client::composer to wire project and package contributors into the resolver architecture.

Possibly related PRs

  • gominimal/minimal#348: Both PRs modify the sessions "composability/resolution" pipeline, especially the composer/policy-hook/patch-enumeration code paths, with this main PR refactoring those same components to use the new core policy/provenance/expansion primitives.
  • gominimal/minimal#389: Shares the same sessions "var expansion + path canonicalization" pipeline, especially the symlink-aware patch enumeration via PatchFile carrying link_path/target_path and expansion of patch-source patterns.

Suggested reviewers

  • twitchyliquid64
  • norrietaylor

Poem

🐇 "My modules were scattered, a flat tangled mess,
Now core and client bring order and rest.
Source tracks provenance, Decision decides,
PolicyHooks callback wherever code hides.
With enumerate_patch_files walking the tree,
The sessions crate hops along neatly—like me!" 🌿

🚥 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 PR title accurately summarizes the primary objective of the changeset: a code reorganization/rearrangement within the sessions module to prepare for a future client/daemon split.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
crates/sessions/src/wire/mod.rs (1)

1-2: 💤 Low value

Placeholder module with no content.

This module currently only contains a comment referencing "step 2". Consider adding a brief module-level doc comment (//!) explaining the intended purpose of wire types, or remove the file until actual content is added to avoid confusion.

🤖 Prompt for 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.

In `@crates/sessions/src/wire/mod.rs` around lines 1 - 2, The wire/mod.rs file
currently contains only a placeholder comment without actual module
documentation or content. Replace the existing comment with a module-level doc
comment (starting with `//!`) that clearly explains the purpose and
responsibility of the wire module, or alternatively remove the file entirely if
it is not yet ready for implementation. A proper doc comment should describe
what wire types are and how they function within the sessions crate to reduce
confusion for future developers.
🤖 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/src/core/policy.rs`:
- Around line 499-503: The `expand_with` method in `PatchPolicy` creates an
unwanted dependency where the core module depends on a client-layer type
`crate::client::composer::SessionVar`. To decouple these modules, create a new
core-owned type or trait in the core module to represent the resolved variable
contract, update the `expand_with` method signature to accept this new core type
instead of `SessionVar`, and then adapt the client-layer code (in
`crate::client::composer`) to convert its `SessionVar` instances to the new core
type before calling `expand_with`.

---

Nitpick comments:
In `@crates/sessions/src/wire/mod.rs`:
- Around line 1-2: The wire/mod.rs file currently contains only a placeholder
comment without actual module documentation or content. Replace the existing
comment with a module-level doc comment (starting with `//!`) that clearly
explains the purpose and responsibility of the wire module, or alternatively
remove the file entirely if it is not yet ready for implementation. A proper doc
comment should describe what wire types are and how they function within the
sessions crate to reduce confusion for future developers.
🪄 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: a97b36bb-1f4c-42e1-a2fb-2e8e2d39cfc8

📥 Commits

Reviewing files that changed from the base of the PR and between 3633dfb and d522405.

📒 Files selected for processing (16)
  • crates/sessions/src/client/composer.rs
  • crates/sessions/src/client/enumerate.rs
  • crates/sessions/src/client/hooks.rs
  • crates/sessions/src/client/mod.rs
  • crates/sessions/src/core/decision.rs
  • crates/sessions/src/core/expansion.rs
  • crates/sessions/src/core/lifecyclehook.rs
  • crates/sessions/src/core/loadout.rs
  • crates/sessions/src/core/mod.rs
  • crates/sessions/src/core/policy.rs
  • crates/sessions/src/core/primitives.rs
  • crates/sessions/src/core/source.rs
  • crates/sessions/src/lib.rs
  • crates/sessions/src/policy.rs
  • crates/sessions/src/vars.rs
  • crates/sessions/src/wire/mod.rs
💤 Files with no reviewable changes (2)
  • crates/sessions/src/policy.rs
  • crates/sessions/src/vars.rs

Comment thread crates/sessions/src/core/policy.rs

@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.

I think this is good to go after a cargo clippy --all-targets --fix --allow-dirty -- -D warnings && cargo fmt

@evanspearman
evanspearman force-pushed the evan/split01 branch 2 times, most recently from 0f6b6da to b71028a Compare June 16, 2026 19:46
@evanspearman
evanspearman merged commit 768d6c4 into main Jun 16, 2026
22 checks passed
@evanspearman
evanspearman deleted the evan/split01 branch June 16, 2026 19:59
@gominimal-aw-bot gominimal-aw-bot Bot added the needs-human An agent handed off; a human must act, then clear this label. label Jul 31, 2026
@gominimal gominimal deleted a comment from gominimal-aw-bot Bot Jul 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-human An agent handed off; a human must act, then clear this label.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants