8000 feat(min): refuse GitHub grants at activation that the box or the host cannot honour by minimal-foundry[bot] · Pull Request #2365 · gominimal/minimal · GitHub
[go: up one dir, main page]

Skip to content

feat(min): refuse GitHub grants at activation that the box or the host cannot honour - #2365

Merged
norrietaylor merged 7 commits into
mainfrom
agent/2264-refuse-github-grants-at-activation-that-the-box
Oct 20, 2026
Merged

norrietaylor merged 7 commits into
mainfrom
agent/2264-refuse-github-grants-at-activation-that-the-box

Conversation

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

T13 — Refuse GitHub grants at activation that the box or the un-enrolled host cannot honour

slice: S0
kind: task
covers: BEP-008, BEP-009, BEP-010, BEP-016, BEP-017, BEP-056
size: L
est: 400 code, 480 tests
executor: agent
difficulty: needs care
model: strongest
diagnostics: a refused activation exits 3 and prints, for a missing host, "This box declares a GitHub grant, but its egress does not allow: . Add them to egress.allow_dns_hosts." on stderr, pinned by prop_grant_host_set_outside_egress_is_exit_3
observability: one debug log line per activation refusal naming the rule and the fields
layers:
- spec:
- crates/boxes/src/core/bep.rs (new): steering (default dns), proxy_env, no_proxy, quic443 and the GitHub grants; the BEP-008, 009, 010, 017 and 056 refusals
- crates/boxes/src/core/mod.rs: module line
- crates/boxes/src/lib.rs: CredentialedUpstream carries the settings, defaulting so an empty declaration reads as before
- crates/boxes/Cargo.toml: proptest as a dev-dependency
- Cargo.lock: the dev-dependency edge
test: cargo nextest run -p boxes prop_grant_host_set_outside_egress_is_exit_3
test: cargo nextest run -p boxes prop_none_mode_with_grant_is_exit_3
test: cargo nextest run -p boxes steering_off_with_grant_warns_and_injects_no_ca
test: cargo nextest run -p boxes steering_off_with_proxy_env_is_refused
test: cargo nextest run -p boxes steering_defaults_to_dns
test: cargo nextest run -p boxes prop_dns_steering_without_resolver_is_exit_3
test: cargo nextest run -p boxes prop_installation_mode_unenrolled_is_exit_3
- read:
- crates/mfile/src/lib.rs: reads [session.network.bep] and [session.secrets] from the project's [session] table
- crates/minimal/src/cmd/session.rs: validates before the create, passing the module's host set
- crates/minimal/src/main.rs: maps the refusal to exit 3
test: cargo nextest run -p minimal activation_refuses_grant_before_create_with_exit_3
produces:
- crates/boxes/src/core/bep.rs
consumes:
- crates/bep/src/module.rs
proof: Activating a grant box whose egress omits a GitHub host exits 3 naming each missing host.
depends on:
- blocked by #2258

Proof

A project whose minimal.toml declares a GitHub grant under [session.secrets.] (a github: scope), activated with egress that omits GitHub hosts, makes min activate stop before the daemon starts or a box is created. It exits 3 and prints on stderr: "This box declares a GitHub grant, but its egress does not allow: uploads.github.com, codeload.github.com. Add them to egress.allow_dns_hosts." The message names each missing host. The same activation refuses network mode none with a grant, steering = "off" with proxy_env = true, dns or both steering (also the default) with no box DNS resolver, and mode = "installation" on this un-enrolled host. It warns when steering is off with a GitHub grant.

Notes from the agent: Files outside the layers: (1) crates/minimal/Cargo.toml gains bep = { path = "../bep" }. session.rs passes the GitHub module's host set, and minimal had no edge to the bep crate. bep is not in [workspace.dependencies], so I used a path dependency and did not touch the root Cargo.toml. (2) crates/minimald/src/net/switch.rs (2 lines) and crates/minvmd/src/box_registry.rs (1 line) are test code that wrote boxes::CredentialedUpstream {}. That form stops compiling once the struct has fields, so each now uses ::default(). I did not compile the minimald or minvmd test targets. The change is mechanical because Default is derived.

Design choices the spec excerpt does not fix: a grant is [session.secrets.<VAR>] with source, scopes and mode. It is a GitHub grant when a scope starts with github:. The settings ride CredentialedUpstream as nested bep and secrets fields, because serde cannot combine flatten with deny_unknown_fields. Empty settings are skipped, so {} reads and writes as before. Any grant or [session.network.bep] setting now makes the box declare a credentialed upstream, even without --credentialed-upstream. For BEP-017, "declares a credentialed upstream" means at least one grant, so a bare --credentialed-upstream flag…[truncated]

Tests

line exit tail
cargo nextest run -p boxes prop_grant_host_set_outside_egress_is_exit_3 0 Applying loadouts: default Running task runtime-implement-test-0 in session task-runtime-implement-test-0-fb9f... Compiling args v0.0.1 (/workbench/crates/args) Compiling ot v0.0.1 (/workbench/crates/ot) Compiling paths v0.0.1 (/workbench/crates/paths) Compiling common v0.0.1 (/workbench
cargo nextest run -p boxes prop_none_mode_with_grant_is_exit_3 0 Applying loadouts: default Running task runtime-implement-test-1 in session task-runtime-implement-test-1-3b4d... Finished 'test' profile [unoptimized] target(s) in 1.22s ──────────── Nextest run ID 802ff3f3-511a-4039-bf1b-7a3216803a58 with nextest profile: default Starting 1 test across 3
cargo nextest run -p boxes steering_off_with_grant_warns_and_injects_no_ca 0 Applying loadouts: default Running task runtime-implement-test-2 in session task-runtime-implement-test-2-8b02... Finished 'test' profile [unoptimized] target(s) in 0.79s ──────────── Nextest run ID 3e766c7f-07de-49c8-8108-f08f92078fd7 with nextest profile: default Starting 1 test across 3
cargo nextest run -p boxes steering_off_with_proxy_env_is_refused 0 Applying loadouts: default Running task runtime-implement-test-3 in session task-runtime-implement-test-3-fdbd... Finished 'test' profile [unoptimized] target(s) in 1.21s ──────────── Nextest run ID 1d08b49c-d0eb-4b0d-9ea1-c033fde70f01 with nextest profile: default Starting 1 test across 3
cargo nextest run -p boxes steering_defaults_to_dns 0 Applying loadouts: default Running task runtime-implement-test-4 in session task-runtime-implement-test-4-f027... Finished 'test' profile [unoptimized] target(s) in 0.89s ──────────── Nextest run ID 09a77f18-8075-4d11-83a3-e7f325a36141 with nextest profile: default Starting 1 test across 3
cargo nextest run -p boxes prop_dns_steering_without_resolver_is_exit_3 0 Applying loadouts: default Running task runtime-implement-test-5 in session task-runtime-implement-test-5-69c6... Finished 'test' profile [unoptimized] target(s) in 0.82s ──────────── Nextest run ID ff8fb7b5-3a11-4cd9-b616-4cc3a6193ffe with nextest profile: default Starting 1 test across 3
cargo nextest run -p boxes prop_installation_mode_unenrolled_is_exit_3 0 Applying loadouts: default Running task runtime-implement-test-6 in session task-runtime-implement-test-6-8b53... Finished 'test' profile [unoptimized] target(s) in 0.79s ──────────── Nextest run ID e961e3ea-5bf4-4e91-9b8d-3ee3cdf50629 with nextest profile: default Starting 1 test across 3
cargo nextest run -p minimal activation_refuses_grant_before_create_with_exit_3 0 Applying loadouts: default Running task runtime-implement-test-7 in session task-runtime-implement-test-7-dcc8... Compiling ot v0.0.1 (/workbench/crates/ot) Compiling args v0.0.1 (/workbench/crates/args) Compiling paths v0.0.1 (/workbench/crates/paths) Compiling stdlib v0.0.22 (/workbenc

Verify

min task run agent-verify exited 101 under rustc 1.98.1, which the repository does not pin (1.97.0 in rust-toolchain.toml); the PR is not a draft on that alone — CI, which honours the pin, is the gate.

the sandbox ran rustc (1.98.1), the repository pins 1.97.0 in rust-toolchain.toml; a failure here may be the newer toolchain's, not this change's
Applying loadouts: default
Running task runtime-implement-verify in session task-runtime-implement-verify-8f0f...
    Checking opentelemetry v0.33.0
    Checking ot v0.0.1 (/workbench/crates/ot)
    Checking args v0.0.1 (/workbench/crates/args)
    Checking paths v0.0.1 (/workbench/crates/paths)
   Compiling version v0.8.0 (/workbench/crates/version)
    Checking switch v0.0.1 (/workbench/crates/switch)
   Compiling minvmd v0.8.0 (/workbench/crates/minvmd)
    Checking opentelemetry_sdk v0.33.0
    Checking tracing-opentelemetry v0.34.0
    Checking opentelemetry-http v0.33.0
    Checking opentelemetry-appender-tracing v0.33.0
   Compiling stdlib v0.0.22 (/workbench/crates/stdlib)
    Checking google-cloud-gax-internal v0.7.20
    Checking opentelemetry-proto v0.33.0
   Compiling serial_test_derive v4.0.1
    Checking diagnostics v0.0.1 (/workbench/crates/diagnostics)
    Checking opentelemetry-otlp v0.33.0
    Checking async-dialog v0.0.1 (/workbench/crates/async-dialog)
    Checking wait-timeout v0.2.1
    Checking rusty-fork v0.3.1
    Checking serial_test v4.0.1
    Checking mlog v0.0.1 (/workbench/crates/mlog)
    Checking rand_xorshift v0.4.0
    Checking bep v0.0.1 (/workbench/crates/bep)
    Checking proptest v1.11.0
    Checking google-cloud-longrunning v1.14.0
    Checking google-cloud-iam-v1 v1.13.0
    Checking google-cloud-lro v1.11.0
    Checking google-cloud-storage v1.20.0
    Checking common v0.0.1 (/workbench/crates/common)
    Checking boxes v0.0.1 (/workbench/crates/boxes)
    Checking sandbox v0.0.1 (/workbench/crates/sandbox)
    Checking minimald-rpc v0.0.1 (/workbench/crates/minimald-rpc)
    Checking mfile v0.0.1 (/workbench/crates/mfile)
    Checking checkouts v0.0.1 (/workbench/crates/checkouts)
    Checking decode v0.0.1 (/workbench/crates/decode)
    Checking graph v0.0.1 (/workbench/crates/graph)
error: using `chunks_exact` with a constant chunk size
   --> crates/minimald-rpc/src/trace.rs:199:46
    |
199 |     for (byte, pair) in out.iter_mut().zip(s.chunks_exact(2)) {
    |                                              ^^^^^^^^^^^^^^^
    |
help: consider using `as_chunks::<2>()` instead
   --> crates/minimald-rpc/src/trace.rs:199:46
    |
199 |     for (byte, pair) in out.iter_mut().zip(s.chunks_exact(2)) {
    |                                              ^^^^^^^^^^^^^^^
    = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.98.0/index.html#chunks_exact_to_as_chunks
    = note: `-D clippy::chunks-exact-to-as-chunks` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::chunks_exact_to_as_chunks)]`

error: could not compile `minimald-rpc` (lib) due to 1 previous error
warning: build failed, waiting for other jobs to finish...

Out of scope

These files are outside the task's layers:, so this PR is a draft:

  • crates/minimal/Cargo.toml
  • crates/minimald/src/net/switch.rs
  • crates/minvmd/src/box_registry.rs

Closes #2264

Layer exception

Accepted by the epic owner on 2026-10-19 under the same rule as #2361 and #2363 (required one-line changes outside the planned layers): bep = { path = "../bep" } in crates/minimal/Cargo.toml, and the CredentialedUpstream::default() test-code updates in crates/minimald/src/net/switch.rs and crates/minvmd/src/box_registry.rs that the new struct fields require.


Generated by Claude Code

Add core::bep: the [network.bep] settings (steering defaults to dns),
the [secrets] grants, and the BEP-008, 009, 010, 017 and 056 checks.
CredentialedUpstream carries the settings and an empty one still
serializes as {}. Two test literals in minimald and minvmd move to
CredentialedUpstream::default() because the struct now has fields.
Read [session.network.bep] and [session.secrets] from the project's
minimal.toml onto the box's credentialed-upstream declaration, check it
against the GitHub module's host set before the daemon starts, and end
a refused activation with exit 3. minimal gains a path dependency on
bep for the host set.
@coderabbitai
coderabbitai Bot commented Oct 19, 2026 •
Copy link
Copy Markdown
Contributor

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 4651405b-b03d-461e-aa01-17910a54fb9e

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

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

Reviewed: 1 finding, none blocking at 19d59f1df531.

Address the comments on the diff.

Clobber: none seen.

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

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 — 2 findings, 1 inline.

Panel: 3 of 3 personas ran (correctness, security, supply-chain).

Comment thread crates/minimal/src/cmd/session.rs Resolved
@minimal-arch minimal-arch 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.

arch-review: CONDITIONS · 2 conditions · the full ruling

The checks are in the correct crate, and the refusal comes before the daemon starts. BEP-008, 010, 016 and 056 conform. The change counts every [secrets] entry as a credentialed upstream, a client_env copy included. It also opens the credentialed lane for a [network.bep] table alone. Networking design §5.4 line 157 and architecture.md line 917 say that the set is derived from broker grants and never declared. Make C1 in bep.rs and C2 in session.rs. Then the change conforms.

Ruled at b01c66c against gominimal/arch@3dab1097cda1 by claude-opus-5-5.

Comment thread crates/boxes/src/core/bep.rs Resolved
Comment thread crates/minimal/src/cmd/session.rs Resolved
A project file that failed to load read as no grants declared, so a
broken file skipped every GitHub grant check. Only a missing file now
declares nothing. Any other load error refuses before the create.
@minimal-foundry minimal-foundry Bot left a comment
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

APPROVE withheld: 3 unresolved threads — minimal-foundry[bot] crates/minimal/src/cmd/session.rs, minimal-arch[bot] crates/boxes/src/core/bep.rs:192, minimal-arch[bot] crates/minimal/src/cmd/session.rs:597.

minimal-review — advisory review

Verdict COMMENT — No findings.

Panel: 2 of 3 personas ran (correctness, security); did not complete: supply-chain.

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

arch-review: CONDITIONS · 3 conditions · the full ruling

The checks are in the right place, and the host-set and installation refusals conform. Three things deviate. The change counts every [secrets] grant as a credentialed upstream, client_env included. Section 5.4 line 157 derives that set from broker grants only, so BEP-009 and BEP-017 refuse boxes the design admits (C1). A [network.bep] setting alone also opens the credentialed lane (C2). A minimal.toml that does not load exits 1, but the Exit codes table gives 3 (C3). The off plus proxy_env refusal is escalated as a design question.

Ruled at b0dcc36 against gominimal/arch@3dab1097cda1 by claude-opus-5-5.

Comment thread crates/boxes/src/core/bep.rs Resolved
Comment thread crates/boxes/src/core/bep.rs Resolved
Comment thread crates/boxes/src/core/bep.rs Resolved
Comment thread crates/minimal/src/cmd/session.rs Resolved
Comment thread crates/minimal/src/cmd/session.rs Resolved
@minimal-foundry
Copy link
Copy Markdown
Contributor Author

Round 1 of 10 on the runtime's review findings, pushed as b0dcc365b3e5.

line exit tail
cargo nextest run -p boxes prop_grant_host_set_outside_egress_is_exit_3 0 piling rand v0.10.3 Compiling malachite-base v0.9.2 Compiling lalrpop v0.23.1 Compiling h2 v0.4.18 Compiling tower v0.5.3 Compiling tokio-stream v0.1.19 Compiling hyper v1.11.0 Compiling tower-http v0.6.11 Compiling rand v0.9.5 Compiling prost v0.14.4 Compiling google-c
cargo nextest run -p boxes prop_none_mode_with_grant_is_exit_3 0 Applying loadouts: default Running task runtime-implement-test-1 in session task-runtime-implement-test-1-7d47... Finished 'test' profile [unoptimized] target(s) in 0.79s ──────────── Nextest run ID d14324fe-2cc1-4abe-b705-7aacd5a15e92 with nextest profile: default Starting 1 test across 3
cargo nextest run -p boxes steering_off_with_grant_warns_and_injects_no_ca 0 Applying loadouts: default Running task runtime-implement-test-2 in session task-runtime-implement-test-2-2f0a... Finished 'test' profile [unoptimized] target(s) in 0.99s ──────────── Nextest run ID cd559438-1b41-4063-ad9e-2e9b5816f250 with nextest profile: default Starting 1 test across 3
cargo nextest run -p boxes steering_off_with_proxy_env_is_refused 0 Applying loadouts: default Running task runtime-implement-test-3 in session task-runtime-implement-test-3-206a... Finished 'test' profile [unoptimized] target(s) in 1.00s ──────────── Nextest run ID 3b50bbf6-3182-479a-820a-3beefec37214 with nextest profile: default Starting 1 test across 3
cargo nextest run -p boxes steering_defaults_to_dns 0 Applying loadouts: default Running task runtime-implement-test-4 in session task-runtime-implement-test-4-4145... Finished 'test' profile [unoptimized] target(s) in 0.96s ──────────── Nextest run ID e06c70e5-7d49-4797-9031-368dda1a6fb6 with nextest profile: default Starting 1 test across 3
cargo nextest run -p boxes prop_dns_steering_without_resolver_is_exit_3 0 Applying loadouts: default Running task runtime-implement-test-5 in session task-runtime-implement-test-5-d69c... Finished 'test' profile [unoptimized] target(s) in 0.66s ──────────── Nextest run ID a6dbed4d-7a8a-47ed-a260-00450d6e833f with nextest profile: default Starting 1 test across 3
cargo nextest run -p boxes prop_installation_mode_unenrolled_is_exit_3 0 Applying loadouts: default Running task runtime-implement-test-6 in session task-runtime-implement-test-6-d649... Finished 'test' profile [unoptimized] target(s) in 1.06s ──────────── Nextest run ID bbababda-0a38-4b9b-a6c0-5cb8f3f7c22c with nextest profile: default Starting 1 test across 3
cargo nextest run -p minimal activation_refuses_grant_before_create_with_exit_3 0 Applying loadouts: default Running task runtime-implement-test-7 in session task-runtime-implement-test-7-598f... Compiling args v0.0.1 (/workbench/crates/args) Compiling ot v0.0.1 (/workbench/crates/ot) Compiling paths v0.0.1 (/workbench/crates/paths) Compiling stdlib v0.0.22 (/workbenc

Verify min task run agent-verify exited 101 under rustc 1.98.1, which the repository does not pin (1.97.0 in rust-toolchain.toml); the PR is not a draft on that alone — CI, which honours the pin, is the gate.

ge's
Applying loadouts: default
Running task runtime-implement-verify in session task-runtime-implement-verify-37b0...
    Checking opentelemetry v0.33.0
    Checking ot v0.0.1 (/workbench/crates/ot)
    Checking args v0.0.1 (/workbench/crates/args)
    Checking paths v0.0.1 (/workbench/crates/paths)
   Compiling version v0.8.0 (/workbench/crates/version)
    Checking switch v0.0.1 (/workbench/crates/switch)
   Compiling minvmd v0.8.0 (/workbench/crates/minvmd)
   Compiling stdlib v0.0.22 (/workbench/crates/stdlib)
    Checking opentelemetry_sdk v0.33.0
    Checking tracing-opentelemetry v0.34.0
    Checking opentelemetry-http v0.33.0
    Checking opentelemetry-appender-tracing v0.33.0
   Compiling serial_test_derive v4.0.1
    Checking google-cloud-gax-internal v0.7.20
    Checking opentelemetry-proto v0.33.0
    Checking diagnostics v0.0.1 (/workbench/crates/diagnostics)
    Checking async-dialog v0.0.1 (/workbench/crates/async-dialog)
    Checking opentelemetry-otlp v0.33.0
    Checking wait-timeout v0.2.1
    Checking google-cloud-longrunning v1.14.0
    Checking google-cloud-iam-v1 v1.13.0
    Checking mlog v0.0.1 (/workbench/crates/mlog)
    Checking serial_test v4.0.1
    Checking bit-vec v0.8.0
    Checking quick-error v1.2.3
    Checking google-cloud-lro v1.11.0
    Checking bit-set v0.8.0
    Checking rusty-fork v0.3.1
    Checking google-cloud-storage v1.20.0
    Checking rand_xorshift v0.4.0
    Checking unarray v0.1.4
    Checking bep v0.0.1 (/workbench/crates/bep)
    Checking proptest v1.11.0
    Checking common v0.0.1 (/workbench/crates/common)
    Checking boxes v0.0.1 (/workbench/crates/boxes)
    Checking sandbox v0.0.1 (/workbench/crates/sandbox)
    Checking minimald-rpc v0.0.1 (/workbench/crates/minimald-rpc)
    Checking mfile v0.0.1 (/workbench/crates/mfile)
    Checking decode v0.0.1 (/workbench/crates/decode)
    Checking checkouts v0.0.1 (/workbench/crates/checkouts)
    Checking graph v0.0.1 (/workbench/crates/graph)
    Checking lcache v0.0.1 (/workbench/crates/lcache)
    Checking rcache v0.0.1 (/workbench/crates/rcache)
error: using `chunks_exact` with a constant chunk size
   --> crates/minimald-rpc/src/trace.rs:199:46
    |
199 |     for (byte, pair) in out.iter_mut().zip(s.chunks_exact(2)) {
    |                                              ^^^^^^^^^^^^^^^
    |
help: consider using `as_chunks::<2>()` instead
   --> crates/minimald-rpc/src/trace.rs:199:46
    |
199 |     for (byte, pair) in out.iter_mut().zip(s.chunks_exact(2)) {
    |                                              ^^^^^^^^^^^^^^^
    = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.98.0/index.html#chunks_exact_to_as_chunks
    = note: `-D clippy::chunks-exact-to-as-chunks` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::chunks_exact_to_as_chunks)]`

error: could not compile `minimald-rpc` (lib) due to 1 previous error
warning: build failed, waiting for other jobs to finish...

Outside the task's layers::

  • crates/minimal/Cargo.toml
  • crates/minimald/src/net/switch.rs
  • crates/minvmd/src/box_registry.rs

Converted to a draft: something above needs a person before review.

Review threads the coder judged:

  • 👍 valid — crates/minimal/src/cmd/session.rs: credentialed_upstream_for now treats only mfile::Error::NotFound as no declaration. Any other load error refuses the activation before the create. A new test pins this: activation_refuses_unloadable_project_file_before_create.

Activating a grant box whose egress omits a GitHub host exits 3 and names each missing host. A project whose minimal.toml exists but does not load is now refused before the create, so a broken file can no longer skip the grant checks.

Notes from the agent: Revise round 1. The one thread is valid and is fixed in crates/minimal/src/cmd/session.rs: credentialed_upstream_for now returns a Result. Only mfile::Error::NotFound means no declaration. Any other load error refuses with "Cannot start the box: the project's minimal.toml does not load: " and one debug log line. This refusal is a plain error (exit 1), not exit 3, because the box spec was not read. I did not run the boxes test lines again this round because this round changed no file in crates/boxes. cargo clippy -p minimal --all-targets shows no warning in minimal. Its warnings are in minimald and minimald-rpc, which this round did not change.

8BD0

@minimal-foundry
minimal-foundry Bot marked this pull request as draft October 20, 2026 00:20
Copy link
Copy Markdown
Member

/revise minimal-arch ruled CONDITIONS on b0dcc36 (check run 118380202174). Three code conditions, all yours this round; the escalated design question (steering off with proxy_env = true) is with the epic owner, so keep the BEP-010 refusal as it is.

C1, crates/boxes/src/core/bep.rs. Make SecretGrant.source a required enum GrantSource { Broker, ClientEnv } (serde snake_case, no default), so a grant with no source or an unknown one does not parse. ActivationSpec::has_credentialed_upstream() returns true only when a grant has source = Broker. github_grants() and SecretGrant::is_github() count only Broker grants with a github: scope. The BEP-009 refusal (NoNetworkWithGrant) lists and fires on Broker grants only, so a client_env grant never triggers BEP-009, BEP-017, the GitHub host-set check or inject_ca. Add a client_env-only case to prop_none_mode_with_grant_is_exit_3 and prop_dns_steering_without_resolver_is_exit_3 that expects no refusal.

C2, crates/minimal/src/cmd/session.rs credentialed_upstream_for(). Compute declared = flag || secrets.values().any(|g| g.source == GrantSource::Broker). A [session.network.bep] setting or a client_env grant alone no longer opens the credentialed lane. Run check_activation on the project's bep and secrets whether or not the lane is declared, so steering = "off" with proxy_env = true is still refused; refuse_unhonourable_grants() must not return early on credentialed_upstream: None before that check. Update the doc comment that says any [session.network.bep] setting declares the upstream. Add a test: a project with only [session.network.bep] steering = "proxy_env" activates with credentialed_upstream: None.

C3, same function and crates/minimal/src/main.rs. The Err(e) arm for a minimal.toml that does not load returns a typed error (for example ProjectFileInvalid) in place of anyhow::bail!, and failure_exit_code() maps that type to 3 as spec 24 line 360 gives. activation_refuses_unloadable_project_file_before_create also asserts failure_exit_code(&err) == 3.

Then reply on the three arch threads with the commit.


Generated by Claude Code

@norrietaylor
norrietaylor marked this pull request as ready for review October 20, 2026 00:33
SecretGrant.source is now a required GrantSource enum (broker or
client_env). Only a broker grant opens the credentialed upstream, so a
client_env grant never fires BEP-009, BEP-017, the GitHub host-set check
or the CA injection.
Only the flag or a broker grant opens the lane. The activation checks the
project's bep settings and grants even with no lane, so steering off with
proxy_env stays refused. An unloadable minimal.toml is now a typed
ProjectFileInvalid error that exits 3.
@minimal-foundry minimal-foundry Bot left a comment
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

minimal-review — approval withheld

Verdict COMMENT — APPROVE withheld: 8 unresolved threads — minimal-foundry[bot] crates/minimal/src/cmd/session.rs, minimal-arch[bot] crates/boxes/src/core/bep.rs, minimal-arch[bot] crates/minimal/src/cmd/session.rs, minimal-arch[bot] crates/boxes/src/core/bep.rs, minimal-arch[bot] crates/boxes/src/core/bep.rs, …. No findings.

Panel: 3 of 3 personas ran (correctness, security, supply-chain).

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

arch-review: CONDITIONS · 2 conditions · the full ruling

The compare fixes the baseline points. Only a broker grant now makes a credentialed upstream, and an unloadable minimal.toml exits 3. One placement deviation is still open. The code reads quic443 from [session.network.bep], but architecture.md lines 874–889 and Gatehouse §6.3.2 put it in [network]. A project that writes it there is now refused with exit 3. Make the change in C1, and correct the module doc in C2.

Ruled at 9fc1593 against gominimal/arch@3dab1097cda1 by claude-opus-5-5.

Comment thread crates/boxes/src/core/bep.rs Resolved
Comment thread crates/mfile/src/lib.rs Resolved
Comment thread crates/boxes/src/core/bep.rs Resolved
@minimal-foundry
Copy link
Copy Markdown
Contributor Author

Round 2 of 10 on a /revise note, pushed as 9fc159337806.

line exit tail
cargo nextest run -p boxes prop_grant_host_set_outside_egress_is_exit_3 0 Applying loadouts: default Running task runtime-implement-test-0 in session task-runtime-implement-test-0-e48e... Compiling args v0.0.1 (/workbench/crates/args) Compiling ot v0.0.1 (/workbench/crates/ot) Compiling paths v0.0.1 (/workbench/crates/paths) Compiling common v0.0.1 (/workbench
cargo nextest run -p boxes prop_none_mode_with_grant_is_exit_3 0 Applying loadouts: default Running task runtime-implement-test-1 in session task-runtime-implement-test-1-adf6... Finished 'test' profile [unoptimized] target(s) in 1.08s ──────────── Nextest run ID 4d33951a-a859-4a79-80c8-54e32312f29a with nextest profile: default Starting 1 test across 3
cargo nextest run -p boxes steering_off_with_grant_warns_and_injects_no_ca 0 Applying loadouts: default Running task runtime-implement-test-2 in session task-runtime-implement-test-2-8baf... Finished 'test' profile [unoptimized] target(s) in 1.08s ──────────── Nextest run ID a5126081-b116-4012-a4a6-b0207d7b0df7 with nextest profile: default Starting 1 test across 3
cargo nextest run -p boxes steering_off_with_proxy_env_is_refused 0 Applying loadouts: default Running task runtime-implement-test-3 in session task-runtime-implement-test-3-e48a... Finished 'test' profile [unoptimized] target(s) in 0.92s ──────────── Nextest run ID 8ff42c9b-6786-4536-b90b-3ec70ed836c0 with nextest profile: default Starting 1 test across 3
cargo nextest run -p boxes steering_defaults_to_dns 0 Applying loadouts: default Running task runtime-implement-test-4 in session task-runtime-implement-test-4-3c26... Finished 'test' profile [unoptimized] target(s) in 0.89s ──────────── Nextest run ID 17281fc8-eee2-45d9-af54-f6a7d8c16acd with nextest profile: default Starting 1 test across 3
cargo nextest run -p boxes prop_dns_steering_without_resolver_is_exit_3 0 Applying loadouts: default Running task runtime-implement-test-5 in session task-runtime-implement-test-5-f4bb... Finished 'test' profile [unoptimized] target(s) in 1.01s ──────────── Nextest run ID f10025fd-df1a-45a3-b6f7-2928c4f5f168 with nextest profile: default Starting 1 test across 3
cargo nextest run -p boxes prop_installation_mode_unenrolled_is_exit_3 0 Applying loadouts: default Running task runtime-implement-test-6 in session task-runtime-implement-test-6-f5d1... Finished 'test' profile [unoptimized] target(s) in 0.79s ──────────── Nextest run ID aefdbc80-d643-4127-ba60-37bfe3731327 with nextest profile: default Starting 1 test across 3
cargo nextest run -p minimal activation_refuses_grant_before_create_with_exit_3 0 Applying loadouts: default Running task runtime-implement-test-7 in session task-runtime-implement-test-7-dfb3... Compiling ot v0.0.1 (/workbench/crates/ot) Compiling args v0.0.1 (/workbench/crates/args) Compiling paths v0.0.1 (/workbench/crates/paths) Compiling stdlib v0.0.22 (/workbenc

Verify min task run agent-verify exited 101< 10BC8 /strong> under rustc 1.98.1, which the repository does not pin (1.97.0 in rust-toolchain.toml); the PR is not a draft on that alone — CI, which honours the pin, is the gate.

the sandbox ran rustc (1.98.1), the repository pins 1.97.0 in rust-toolchain.toml; a failure here may be the newer toolchain's, not this change's
Applying loadouts: default
Running task runtime-implement-verify in session task-runtime-implement-verify-8154...
    Checking opentelemetry v0.33.0
    Checking args v0.0.1 (/workbench/crates/args)
    Checking ot v0.0.1 (/workbench/crates/ot)
    Checking paths v0.0.1 (/workbench/crates/paths)
   Compiling version v0.8.0 (/workbench/crates/version)
    Checking switch v0.0.1 (/workbench/crates/switch)
    Checking opentelemetry_sdk v0.33.0
    Checking tracing-opentelemetry v0.34.0
    Checking opentelemetry-http v0.33.0
    Checking opentelemetry-appender-tracing v0.33.0
   Compiling minvmd v0.8.0 (/workbench/crates/minvmd)
   Compiling stdlib v0.0.22 (/workbench/crates/stdlib)
    Checking google-cloud-gax-internal v0.7.20
    Checking opentelemetry-proto v0.33.0
   Compiling serial_test_derive v4.0.1
    Checking opentelemetry-otlp v0.33.0
    Checking diagnostics v0.0.1 (/workbench/crates/diagnostics)
    Checking google-cloud-longrunning v1.14.0
    Checking google-cloud-iam-v1 v1.13.0
    Checking mlog v0.0.1 (/workbench/crates/mlog)
    Checking google-cloud-lro v1.11.0
    Checking async-dialog v0.0.1 (/workbench/crates/async-dialog)
    Checking serial_test v4.0.1
    Checking google-cloud-storage v1.20.0
    Checking wait-timeout v0.2.1
    Checking rand_xorshift v0.4.0
    Checking rusty-fork v0.3.1
    Checking bep v0.0.1 (/workbench/crates/bep)
    Checking proptest v1.11.0
    Checking common v0.0.1 (/workbench/crates/common)
    Checking boxes v0.0.1 (/workbench/crates/boxes)
    Checking sandbox v0.0.1 (/workbench/crates/sandbox)
    Checking minimald-rpc v0.0.1 (/workbench/crates/minimald-rpc)
    Checking mfile v0.0.1 (/workbench/crates/mfile)
    Checking decode v0.0.1 (/workbench/crates/decode)
    Checking checkouts v0.0.1 (/workbench/crates/checkouts)
error: using `chunks_exact` with a constant chunk size
   --> crates/minimald-rpc/src/trace.rs:199:46
    |
199 |     for (byte, pair) in out.iter_mut().zip(s.chunks_exact(2)) {
    |                                              ^^^^^^^^^^^^^^^
    |
help: consider using `as_chunks::<2>()` instead
   --> crates/minimald-rpc/src/trace.rs:199:46
    |
199 |     for (byte, pair) in out.iter_mut().zip(s.chunks_exact(2)) {
    |                                              ^^^^^^^^^^^^^^^
    = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.98.0/index.html#chunks_exact_to_as_chunks
    = note: `-D clippy::chunks-exact-to-as-chunks` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::chunks_exact_to_as_chunks)]`

error: could not compile `minimald-rpc` (lib) due to 1 previous error
warning: build failed, waiting for other jobs to finish...

Outside the task's layers::

  • crates/minimal/Cargo.toml
  • crates/minimald/src/net/switch.rs
  • crates/minvmd/src/box_registry.rs

Converted to a draft: something above needs a person before review.

Review threads the coder judged:

  • 👍 valid — crates/boxes/src/core/bep.rs: Added SecretGrant::is_credentialed() (broker only). has_credentialed_upstream, is_github and the BEP-009 arm use it. Commit 5598a5d.
  • 👍 valid — crates/minimal/src/cmd/session.rs: credentialed_upstream_for() now declares the lane only on the flag or a broker grant. Commit 55f38fa.
  • 👍 valid — crates/boxes/src/core/bep.rs: source is now a required GrantSource { Broker, ClientEnv } enum, snake_case, no default. grant_source_is_required_and_known tests it. Commit 5598a5d.
  • 👍 valid — crates/boxes/src/core/bep.rs: has_credentialed_upstream() returns true only for a Broker grant, so BEP-009, BEP-017 and inject_ca ignore client_env. Commit 5598a5d.
  • 👍 valid — crates/boxes/src/core/bep.rs: NoNetworkWithGrant lists and fires on broker grants only. The prop test has a client_env-only case that expects no refusal. Commit 5598a5d.
  • 👍 valid — crates/minimal/src/cmd/session.rs: Lane is flag or any Broker grant. refuse_unhonourable_grants() runs check_activation on the project's bep and secrets with no early return. Commit 55f38fa.
  • 👍 valid — crates/minimal/src/cmd/session.rs: The load failure returns ProjectFileInvalid. failure_exit_code() maps it to 3, and tests assert the type and the code. Commit 55f38fa.

Activating a box whose project declares a broker GitHub grant, with an egress that omits a GitHub host, exits 3 and names each missing host. A client_env grant or a [session.network.bep] setting alone no longer opens the credentialed lane. An unloadable minimal.toml now also exits 3.

Notes from the agent: C1: SecretGrant.source is a required GrantSource enum (broker, client_env). The new SecretGrant::is_credentialed() is true only for broker. has_credentialed_upstream, is_github, github_grants and the BEP-009 grant list use broker grants only. SecretGrant no longer derives Default. C2: project_bep_and_grants() loads the settings, credentialed_upstream_for() declares the lane only on the flag or a broker grant, and refuse_unhonourable_grants() always runs check_activation on the project's bep and secrets. C3: ProjectFileInvalid is a typed error (re-exported as minimal::ProjectFileInvalid) and failure_exit_code() maps it to 3. failure_exit_code lives in the min binary, so the lib test of that name asserts the typed error, and a bin test of the same name asserts the exit code 3, the same split the existing grant test uses. BEP-010 refusal kept as is, per the note. Also ran: cargo nextest run -p minimal for the three new tests (bep_settings_alone_activate_without_credentialed_upstream, only_broker_grants_declare_credentialed_upstream, steering_off_with_proxy_env_is_refused_without_a_grant), all pass. just clippy-strict was not run.

@minimal-foundry
minimal-foundry Bot marked this pull request as draft October 20, 2026 01:06
Copy link
Copy Markdown
Member

/revise minimal-arch ruled CONDITIONS on 9fc1593 (check run 118394712429): the three baseline conditions are met, and two new ones remain. Take both this round and nothing else.

C1, move quic443 out of [network.bep]. In crates/boxes/src/core/bep.rs, remove the quic443 field from BepSettings, its doc and the module doc, and keep the Quic443 enum. In crates/mfile/src/lib.rs, add #[serde(default, skip_serializing_if = "Option::is_none")] pub quic443: Option<boxes::core::bep::Quic443> to SessionNetwork, so [session.network] quic443 parses and [session.network.bep] quic443 is refused as an unknown field, which is where the design puts it. Update the SessionNetwork doc and the CredentialedUpstream doc in crates/boxes/src/lib.rs, which list quic443 among the [network.bep] settings. Add a test in mfile that [session.network] quic443 = "auto" loads. mfile is already in this task's layers.

C2, crates/boxes/src/core/bep.rs module doc (line 14). A grant is a GitHub grant when its source is broker and one of its scopes starts with github:, which is what SecretGrant::is_github() does. The doc still says a github: scope alone is enough.

Reply on the arch threads with the commit. The steering = "off" with proxy_env = true question is with the epic owner; keep the BEP-010 refusal as it is.


Generated by Claude Code

@norrietaylor
norrietaylor marked this pull request as ready for review October 20, 2026 01:14
quic443 is a [network] setting in the design. BepSettings drops the
field and keeps the Quic443 enum. SessionNetwork gains quic443, so
[session.network] quic443 loads and [session.network.bep] refuses it.
The bep module doc now says a GitHub grant needs source = broker.
@minimal-foundry minimal-foundry Bot left a comment
Copy link
Copy Markdown
Contributor Author

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.

Panel: 3 of 3 personas ran (correctness, security, supply-chain).

Comment thread crates/minimal/src/cmd/session.rs Resolved
@minimal-arch minimal-arch 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.

arch-review: PASS · the full ruling

< 10BC8 p dir="auto">The change conforms to Gatehouse §6.10 Validation and networking §5.4. The new head moves quic443 to [session.network], which matches §5.4 line 166. Only broker grants make a credentialed upstream, as §5.4 line 157 requires. Each refusal exits 3 before the daemon starts. The refusal of off with proxy_env follows §5.4 line 172. Ask arch to clarify line 173 for off. The task does not need to change.

Ruled at 19d59f1 against gominimal/arch@3dab1097cda1 by claude-opus-5-5.

@minimal-foundry
Copy link
Copy Markdown
Contributor Author

Round 3 of 10 on a /revise note, pushed as 19d59f1df531.

line exit tail
cargo nextest run -p boxes prop_grant_host_set_outside_egress_is_exit_3 0 Applying loadouts: default Running task runtime-implement-test-0 in session task-runtime-implement-test-0-6485... Compiling args v0.0.1 (/workbench/crates/args) Compiling ot v0.0.1 (/workbench/crates/ot) Compiling paths v0.0.1 (/workbench/crates/paths) Compiling common v0.0.1 (/workbench
cargo nextest run -p boxes prop_none_mode_with_grant_is_exit_3 0 Applying loadouts: default Running task runtime-implement-test-1 in session task-runtime-implement-test-1-5068... Finished 'test' profile [unoptimized] target(s) in 0.48s ──────────── Nextest run ID e94cc9f1-0116-434d-a7b2-64298cbab357 with nextest profile: default Starting 1 test across 3
cargo nextest run -p boxes steering_off_with_grant_warns_and_injects_no_ca 0 Applying loadouts: default Running task runtime-implement-test-2 in session task-runtime-implement-test-2-da16... Finished 'test' profile [unoptimized] target(s) in 0.46s ──────────── Nextest run ID 5b45ba46-e048-437e-9fff-7b4f4518afe5 with nextest profile: default Starting 1 test across 3
cargo nextest run -p boxes steering_off_with_proxy_env_is_refused 0 Applying loadouts: default Running task runtime-implement-test-3 in session task-runtime-implement-test-3-a8c7... Finished 'test' profile [unoptimized] target(s) in 0.47s ──────────── Nextest run ID a988af43-599e-45a5-aeaa-18b47538beb8 with nextest profile: default Starting 1 test across 3
cargo nextest run -p boxes steering_defaults_to_dns 0 Applying loadouts: default Running task runtime-implement-test-4 in session task-runtime-implement-test-4-85fc... Finished 'test' profile [unoptimized] target(s) in 0.47s ──────────── Nextest run ID 21026485-418e-4287-816e-7c33771a4d40 with nextest profile: default Starting 1 test across 3
cargo nextest run -p boxes prop_dns_steering_without_resolver_is_exit_3 0 Applying loadouts: default Running task runtime-implement-test-5 in session task-runtime-implement-test-5-3e26... Finished 'test' profile [unoptimized] target(s) in 0.47s ──────────── Nextest run ID 4bfc21cb-9989-4d62-9485-9914de726e0b with nextest profile: default Starting 1 test across 3
cargo nextest run -p boxes prop_installation_mode_unenrolled_is_exit_3 0 Applying loadouts: default Running task runtime-implement-test-6 in session task-runtime-implement-test-6-1022... Finished 'test' profile [unoptimized] target(s) in 0.49s ──────────── Nextest run ID a30506fd-5b45-45cb-9507-d5d5f302bded with nextest profile: default Starting 1 test across 3
cargo nextest run -p minimal activation_refuses_grant_before_create_with_exit_3 0 Applying loadouts: default Running task runtime-implement-test-7 in session task-runtime-implement-test-7-721a... Compiling args v0.0.1 (/workbench/crates/args) Compiling ot v0.0.1 (/workbench/crates/ot) Compiling paths v0.0.1 (/workbench/crates/paths) Compiling stdlib v0.0.22 (/workbenc

Verify min task run agent-verify exited 101 under rustc 1.98.1, which the repository does not pin (1.97.0 in rust-toolchain.toml); the PR is not a draft on that alone — CI, which honours the pin, is the gate.

32 v0.3.1
    Checking module-lattice v0.2.3
    Checking kem v0.3.0
    Checking sponge-cursor v0.1.0
    Checking data-encoding v2.11.1
    Checking ml-kem v0.3.2
    Checking sha3 v0.12.0
    Checking mlog v0.0.1 (/workbench/crates/mlog)
    Checking heapless v0.9.3
    Checking ssh-key v0.7.0-rc.11
    Checking generic-array v1.4.4
    Checking russh-cryptovec v0.62.0
    Checking num-bigint v0.5.1
    Checking russh-util v0.52.0
    Checking managed v0.8.0
    Checking bitflags v1.3.2
    Checking hex-literal v1.1.0
    Checking tinyvec_macros v0.1.1
    Checking constcat v0.6.1
    Checking russh v0.63.3
    Checking tinyvec v1.12.0
    Checking smoltcp v0.14.0
    Checking is_executable v1.0.6
    Checking switch v0.0.1 (/workbench/crates/switch)
    Checking hickory-proto v0.26.3
    Checking clap_complete v4.6.11
    Checking sysinfo v0.39.6
    Checking hashbrown v0.14.5
    Checking serde_bytes v0.11.19
   Compiling minvmd v0.8.0 (/workbench/crates/minvmd)
    Checking dashmap v6.2.1
    Checking netlink-packet-core v0.8.1
    Checking konst_macro_rules v0.2.19
    Checking russh-sftp v2.4.0
   Compiling stdlib v0.0.22 (/workbench/crates/stdlib)
    Checking konst v0.2.20
    Checking netlink-sys v0.8.8
    Checking const_format v0.2.36
    Checking derive_builder v0.20.2
    Checking nix v0.30.1
    Checking netlink-packet-route v0.25.1
    Checking procfs-core v0.18.0
    Checking hash32 v0.2.1
    Checking itertools v0.15.0
    Checking spin v0.9.9
    Checking generational-arena v0.2.9
    Checking minimald-rpc v0.0.1 (/workbench/crates/minimald-rpc)
    Checking mfile v0.0.1 (/workbench/crates/mfile)
    Checking strum v0.27.2
    Checking pathrs v0.2.5
    Checking oci-spec v0.10.0
    Checking heapless v0.7.17
    Checking netconfig-rs v0.1.6
    Checking procfs v0.18.0
    Checking nix v0.29.0
    Checking netlink-packet-route v0.31.0
    Checking checkouts v0.0.1 (/workbench/crates/checkouts)
    Checking decode v0.0.1 (/workbench/crates/decode)
    Checking getifaddrs v0.6.2
    Checking cobs v0.3.0
    Checking path-dedot v4.0.1
error: using `chunks_exact` with a constant chunk size
   --> crates/minimald-rpc/src/trace.rs:199:46
    |
199 |     for (byte, pair) in out.iter_mut().zip(s.chunks_exact(2)) {
    |                                              ^^^^^^^^^^^^^^^
    |
help: consider using `as_chunks::<2>()` instead
   --> crates/minimald-rpc/src/trace.rs:199:46
    |
199 |     for (byte, pair) in out.iter_mut().zip(s.chunks_exact(2)) {
    |                                              ^^^^^^^^^^^^^^^
    = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.98.0/index.html#chunks_exact_to_as_chunks
    = note: `-D clippy::chunks-exact-to-as-chunks` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::chunks_exact_to_as_chunks)]`

error: could not compile `minimald-rpc` (lib) due to 1 previous error
warning: build failed, waiting for other jobs to finish...

Outside the task's layers::

  • crates/minimal/Cargo.toml
  • crates/minimald/src/net/switch.rs
  • crates/minvmd/src/box_registry.rs

Converted to a draft: something above needs a person before review.

Review threads the coder judged:

  • 👍 valid — crates/boxes/src/core/bep.rs: Removed quic443 from BepSettings and its module doc, and kept the Quic443 enum (commit 19d59f1).
  • 👍 valid — crates/mfile/src/lib.rs:509: Added quic443: Option<Quic443> to SessionNetwork, fixed its doc, and added mfile test session_network_quic443_loads (commit 19d59f1).
  • 👍 valid — crates/boxes/src/core/bep.rs: The module doc now says a GitHub grant needs source = broker and a github: scope, as SecretGrant::is_github checks (commit 19d59f1).

Activating a grant box whose egress omits a GitHub host exits 3 and names each missing host. In this round, [session.network] quic443 = "auto" loads, and [session.network.bep] quic443 is refused as an unknown field.

Notes from the agent: Revise round 3 addresses C1 and C2 only, in commit 19d59f1. C1: BepSettings no longer has quic443, and the Quic443 enum stays. SessionNetwork has quic443: Option<Quic443>. The SessionNetwork, CredentialedUpstream and bep module docs are updated. The new mfile test session_network_quic443_loads also asserts that [session.network.bep] quic443 is refused. C2: the bep module doc now says that a GitHub grant needs source = broker and a github: scope, which is what SecretGrant::is_github checks. The BEP-010 refusal (steering = off with proxy_env = true) does not change. cargo clippy -p boxes -p mfile --all-targets is clean. I did not run just clippy-strict.

@minimal-foundry
minimal-foundry Bot marked this pull request as draft October 20, 2026 01:27
@norrietaylor
norrietaylor marked this pull request as ready for review October 20, 2026 01:40
@norrietaylor norrietaylor 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.

Babysitter review of 19d59f1 (T13: refuse GitHub grants at activation that the box or the un-enrolled host cannot honour). Read as a COMMENT review so it starts no coder round.

What I checked. The settings and the checks live in boxes::core::bep and take the GitHub host set as an argument, so boxes has no edge to bep. GrantSource is a closed, required enum; only a broker grant makes a credentialed upstream, a GitHub grant, a BEP-009 refusal or a CA injection. refusals collects every reason in a fixed order (BEP-009, 008, 010, 017, 056), the host comparison lowercases and strips a trailing dot, and check_activation logs one debug line per refusal with rule and fields. In min activate the project's settings and grants are read with from_dir_recursive, a file that does not load is the typed ProjectFileInvalid mapped to exit 3, the checks run whether or not a lane is declared and before ensure_daemon, and the lane is declared by the flag or a broker grant only. quic443 parses under [session.network] and is refused under [session.network.bep]. CredentialedUpstream keeps its {} wire form when the settings are empty. The four proptests pin each refusal against an oracle, including the client_env-only no-refusal cases. The out-of-layers edits are the two mechanical ::default() lines and the bep path dependency, which the epic owner accepted. No blocking finding from me.

Findings, none blocking

  1. SecretGrant is deny_unknown_fields with a two-variant GrantSource, so a design-valid source = "store" grant (store references, BEP-036) refuses the activation with exit 3 today. That fails closed, and the arch noted it; worth a sentence in the GrantSource doc so the refusal does not read as a bug when BEP-036 lands.

  2. ActivationPlan.inject_ca and SessionNetwork.quic443 have no consumer yet (the arch noted both): the plan's CA bit and the UDP 443 stance are computed and parsed but not carried into BoxPolicy. Those are BEP-018 and §5.4 line 177, outside this task; a doc line on each saying so would stop the next reader looking for the wiring.

  3. The runtime's finding that an unloadable parent minimal.toml now refuses an activation that used to start is correct as a description, and it is what the arch's C3 requires: a file that cannot be read cannot rule out grants. I resolved that thread with the design reason.


Generated by Claude Code

@norrietaylor norrietaylor changed the title T13 — Refuse GitHub grants at activation that the box or the un-enrolled host cannot honour feat(min): refuse GitHub grants at activation that the box or the host cannot honour Oct 20, 2026
@norrietaylor norrietaylor 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.

Babysitter approval of 19d59f1 for the epic owner: every gate item passes on this head (arch PASS, runtime review concluded, every thread resolved and re-verified, all lane aggregators and the CLA status green, squash subject lints as Conventional Commits).


Generated by Claude Code

@norrietaylor
norrietaylor added this pull request to the merge queue Oct 20, 2026
Merged via the queue into main with commit 767c59f Oct 20, 2026
37 checks passed
@norrietaylor
norrietaylor deleted the agent/2264-refuse-github-grants-at-activation-that-the-box branch October 20, 2026 02:52
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.

T13 — Refuse GitHub grants at activation that the box or the un-enrolled host cannot honour

1 participant

0