8000 fix(minimald): refuse at activate a session package that does not resolve by norrietaylor · Pull Request #1935 · gominimal/minimal · GitHub
[go: up one dir, main page]

Skip to content

fix(minimald): refuse at activate a session package that does not resolve - #1935

Merged
norrietaylor merged 4 commits into
mainfrom
fix/session-activate-refuses-unknown-packages
Oct 6, 2026
Merged

norrietaylor merged 4 commits into
mainfrom
fix/session-activate-refuses-unknown-packages

Conversation

@norrietaylor
@norrietaylor norrietaylor commented Oct 4, 2026 •
Copy link
Copy Markdown
Member

Refs gominimal/inbox#816 (packages half)

Problem

min session activate returned 0 and a session id for a session that named a package nobody declares, either in [session] packages or in a loadout's packages. The failure only appeared on the first exec or attach, as session spawn: no such package: ….

Session::finalize promotes a Materializing record to Active after checking only the patches and hook-script markers. Package names were first resolved in Env::build, at launch.

Change

  • crates/minimald/src/env.rs: the by_name lookup that Env::build runs on each session package is now one helper, session_package. Env::build behaves as before.
  • crates/minimald/src/session.rs: in the Materializing arm of finalize, before the patches are materialized and before any activate hook runs, check_composed_packages builds the session context, evaluates the package graph on the blocking pool (as the launch does), and resolves every composed package name through session_package. Any unknown name fails the finalize with InvalidInput, so the record is not promoted. The error lists each unknown name and who declared it, for example no such package: no-such-pkg-qq (declared by user loadout `editor`); the session was not activated. The check builds nothing and keeps no graph; the launch still evaluates its own.
  • When the context or graph cannot be evaluated at all, the check logs a warning and steps aside. The launch then reports the failure exactly as it does today.
  • The check is on in every production build. Under test/test-support it defaults off, because those sessions run offline and compose names (the scaffolded base/vim) that only an upstream declares. A test-only actor message turns it on.

Not in this PR

A bad locked_commit or an upstream repo that does not exist also activates today and fails on first exec. Refusing those at activate is a follow-up.

Note

Finalize now evaluates the graph, and it may clone the upstream on a cold cache. That work used to happen at the first attach. It now falls inside the FinalizeSession deadline (60 s base, plus the activate-hook budget).

Tests

New tests in crates/minimald/src/sessions.rs:

  • finalize_refuses_an_unknown_session_package
  • finalize_refuses_an_unknown_loadout_package
  • finalize_with_resolvable_packages_still_activates

Verification

  • just ci (macOS scope): ci: local PR gates green
  • cross clippy -p minimald --all-targets --target aarch64-unknown-linux-musl --locked -- -D warnings: clean
  • cross test -p minimald --lib -- sessions::tests::finalize sessions::tests::needed_packages sessions::tests::create_active: test result: ok. 5 passed; 0 failed
  • cross test -p minimald --lib -- sessions::tests: test result: ok. 35 passed; 0 failed

Summary by CodeRabbit

  • Bug Fixes
    • Sessions with compositions that reference unknown packages are now rejected during finalization, with an error identifying the package and where it was declared.
    • Sessions with resolvable packages continue to activate normally. If the validation cannot complete before its deadline or the required context is unavailable, finalization proceeds.

…olve

Session finalize promoted a Materializing record to Active without
resolving the composition's package names, so an unknown package (from
the project or a loadout) surfaced only at the first spawn as
`no such package`. Finalize now evaluates the session graph and resolves
every composed name with the lookup Env::build uses, refusing with
InvalidInput and naming each unknown package and its declarer.

Refs gominimal/inbox#816 (packages half)
@norrietaylor
norrietaylor requested a review from a team as a code owner October 4, 2026 05:03
@coderabbitai
coderabbitai Bot commented Oct 4, 2026 •
Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Essentials
  • Run ID: e134bc8b-676d-46b6-ad7a-c3bb774f292f
📥 Commits

Reviewing files that changed from the base of the PR and between 5ec89e9 and c4a6251.

📒 Files selected for processing (3)
  • crates/minimald/src/env.rs
  • crates/minimald/src/session.rs
  • crates/minimald/src/sessions.rs

Included review availability: This review used your included allowance. 4 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 5 reviews per hour.


📝 Walkthrough

Walkthrough

The change adds a shared package lookup and checks composed package names during session finalization. Unknown names prevent promotion. Context or graph failures and deadline expiry are logged, and the check proceeds without blocking finalization.

Changes

Package Validation

Layer / File(s) Summary
Shared package lookup
crates/minimald/src/env.rs
session_package resolves a package name through the graph and returns an error for unknown names. Env::build now uses this helper.
Finalize-time package check
crates/minimald/src/session.rs, crates/minimald/src/sessions.rs
Session finalization checks composed package names before promotion. Unknown names produce InvalidInput errors with declaration provenance. Tests cover unknown and resolvable packages, plus deadline expiry.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix

Sequence Diagram(s)

sequenceDiagram
  participant Finalization
  participant SessionPackageGraph
  participant SessionRecord
  Finalization->>SessionPackageGraph: Resolve composed package names
  SessionPackageGraph-->>Finalization: Return resolution results
  alt Unknown package
    Finalization-->>SessionRecord: Return InvalidInput and prevent promotion
  else Packages resolve or the deadline expires
    Finalization->>SessionRecord: Continue finalization
  end
Loading

Suggested reviewers: 0chroma

Merge Risk: ⚪ Minimal · up to c4a62

Session finalization now rejects unknown package names up front instead of failing on the first exec or attach. The check steps aside on timeout or on context errors, so the existing behavior is preserved in those cases. No merge-blocking risk was identified.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title identifies the main change: refusing to activate a session when a package does not resolve. The phrase “refuse at activate” is awkward, but the intent is clear.
Description check ✅ Passed The description explains the problem, change, limitations, behavior, and test results. It covers the template’s summary and testing requirements, but does not include the requested Checklist section.
Docstring Coverage ✅ Passed Docstring coverage is 88.89% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 18 functions across 3 files.
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
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

A rabbit checks names in the session’s green field
Unknown ones pause promotion, their source revealed
A known name hops through the graph without delay
If the clock runs out, finalization finds its way
Then the rabbit bounds home, with the records in play

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

@minimal-foundry
minimal-foundry Bot commented Oct 4, 2026 •
Copy link
Copy Markdown
Contributor

Approved: no findings at c4a625163f34.

Nothing to do.

Clobber: none: git log --oneline -8 on both touched files shows the last change to this code is the PR's own prior commit (2561159d), and the head is a clean merge of origin/main — nothing a recent fix wrote is reverted.

@minimal-foundry minimal-foundry Bot left a comment
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

minimal-review — advisory review

Verdict COMMENT — 1 finding, 1 inline.

Comment thread crates/minimald/src/session.rs Resolved
@norrietaylor
Copy link
Copy Markdown
Member Author

/revise fix review concerns

@minimal-foundry
minimal-foundry Bot commented Oct 6, 2026 •
Copy link
Copy Markdown
Contributor

Round 1 of 1 is on this pull request.

branch fix/session-activate-refuses-unknown-packages

Updated 2026-10-06T05:03:07.486Z.

The package check the activation path added evaluates the session
graph inside the FinalizeSession round-trip, and that evaluation can
clone the upstream repo when the daemon's cache is cold — network I/O
with no bound of its own. The only deadline on the round-trip was the
client's (minimal-client's 60 s base plus the activate-hook budget),
and a client that expires does not cancel the daemon-side finalize:
the session actor runs on, promotes the record, and runs the
activate hooks on the way, while the client — which has already
reported a failed activation and best-effort-destroyed the session —
believes nothing was activated.

The daemon now bounds the work itself: past PACKAGE_CHECK_DEADLINE
(30 s, half the client's base, so patch materialization and a hook's
host mint keep the other half) the check logs a warning and steps
aside, and finalize proceeds exactly as it did before the check
existed — the launch resolves names at first exec, as it always has.
Expiry cancels the wait, not the evaluation: the detached
spawn_blocking runs to completion and warms the cache the launch
reads.

The expiry path is provable without a slow graph: the test-only
switch now carries the check's deadline, and a zero deadline
exercises the step-aside (the check body cannot complete in the
single poll a zero deadline gives it, since its graph evaluation
round-trips the blocking pool).
@minimal-foundry
Copy link
Copy Markdown
Contributor

Round 1 of 1 on a /revise note, pushed as c4a625163f34.

No test: line was run.

Review threads the coder judged:

  • 👍 valid — crates/minimald/src/session.rs: Fixed: the check is now bounded server-side — past PACKAGE_CHECK_DEADLINE (30 s, half the client's 60 s base) it warns and steps aside and finalize proceeds as before the check existed, so the work this PR moved into the activate round-trip can no longer outrun the client's deadline on a cold cache;

A cold-cache min session activate can no longer diverge from the daemon over the package check: the check the PR added to FinalizeSession is now bounded server-side (PACKAGE_CHECK_DEADLINE, 30 s), and past it the daemon warns and steps aside, so the check's upstream-clone-on-a-cold-cache can no longer hold the record's promotion past the client's deadline while the client has already reported failure and best-effort-destroyed the session. The expiry path is proven by a new test: with a zero deadline the check steps aside and the session still activates, with its unknown name surfacing at first exec exactly as before the check existed.

Notes from the agent: The finding was judged valid against the code (Finalize runs inline in the session actor; serve_finalize_session has no server-side deadline; graph_from_all_packages clones the upstream on a cold cache) and fixed by bounding the check rather than all of finalize: patch materialization and the activate-hook host mint are still bounded only by the client's window, exactly as before this PR, and giving the whole finalize a server-side deadline would have changed hook semantics — so the residual window that predates the PR remains, but the PR no longer widens it. The expiry path is testable because the test-only CheckPackagesAtFinalize switch now carries the check's deadline; a zero deadline deterministically exercises expiry (tokio polls the future once before the delay, and the check body cannot complete in that single poll since its graph evaluation round-trips the blocking pool). just e2e-native and the VM lanes could not be completed on this box: no /dev/kvm (just e2e, just test-vm impossible; jq/cpio also absent) and no network for the e2e-native's upstream package fetch — its activate half passed and its exec failure reproduces identically at the branch head without this round's changes. just clippy's 4 hits on this box are toolchain skew (rustc 1.98.1 installed directly, no rustup, repo pins 1.9…[truncated]

@minimal-foundry minimal-foundry Bot left a comment
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

minimal-review — approved

Verdict APPROVE — No findings.

@minimal-foundry minimal-foundry Bot added the review:approved minimal-review approved the current head label Oct 6, 2026
@norrietaylor
norrietaylor enabled auto-merge October 6, 2026 05:27
@norrietaylor
norrietaylor added this pull request to the merge queue Oct 6, 2026
Merged via the queue into main with commit e7533f5 Oct 6, 2026
34 checks passed
@norrietaylor
norrietaylor deleted the fix/session-activate-refuses-unknown-packages branch October 6, 2026 06:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

review:approved minimal-review approved the current head

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

0