8000 fix(minimald): name the range and refuse --public in min net expose (T109) by minimal-foundry[bot] · Pull Request #2718 · gominimal/minimal · GitHub
[go: up one dir, main page]

Skip to content

fix(minimald): name the range and refuse --public in min net expose (T109) - #2718

Merged
norrietaylor merged 5 commits into
mainfrom
agent/2695-min-net-expose-refusals-say-what-happened-and-na
Oct 28, 2026
Merged

norrietaylor merged 5 commits into
mainfrom
agent/2695-min-net-expose-refusals-say-what-happened-and-na

Conversation

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

T109 — min net expose refusals say what happened and name the range

slice: S17
kind: task
covers: NET-145, NET-047
size: M
est: 160 code, 240 tests
executor: agent
difficulty: routine
model: standard
diagnostics: a refused min net expose prints its reason on stderr inside the box and exits 1; the daemon's existing dynamic ingress expose info line names the box, the port as given, the outcome and the reason, in the daemon log min bug already collects
observability: the existing dynamic ingress expose info line, one per request, gains the outcomes refused: public exposure and refused: out of range with the requested port and the box's range
layers:
- in-box-helper:
- crates/minimald/src/env_min_helper.sh: min net expose recognises --public before the port and sends it as its own request, never as the port string; min net expose --public with or without a port reaches the daemon as a public request
- crates/minimald/src/env.rs: the expose channel answers a public request with error: public exposure is not available on this host. Nothing was published. and exits 1, publishing nothing, local or public; printed by the in-box min net expose --public [<port>] on every host this spec binds; replaces today's error: '--public' is not a port number
test: cargo nextest run -p minimald expose_public_refused_without_public_surface
- range-refusal:
- crates/minimald/src/box_actor/ports.rs: an ask-stance request for a port outside the box's range is refused before any prompt is routed, so no prompt is shown; the host-refusal texts stop naming the VM host daemon and the port prompt (the port is outside the --dynamic-range the VM host daemon holds for this box becomes the port is outside this box's --dynamic-range)
- crates/minimald/src/net/policy.rs: the out-of-range refusal reads port 4500 is outside this box's --dynamic-range 3000-3999. Nothing was published. with the requested port and the box's range filled in, for an allow-stance and an ask-stance box alike, printed by the in-box min net expose <port> as error: … with exit 1
- crates/minimald/src/net/listeners.rs: the prompt round's failures read without the VM host daemon's name (the port prompt was refused: … and the deadline and unexpected-reply texts become the request to open the port was refused: …, … did not get an answer in time, … got an answer it could not read)
- crates/minimald/src/box_actor/tests.rs: pins the range refusal text for both stances, that no prompt is routed for an out-of-range ask, and that no mapping is left behind
test: cargo nextest run -p minimald expose_out_of_range_refusal_names_range
test: cargo nextest run -p minimald expose_rejected_leaves_no_partial_mapping
produces: none
consumes: none
proof: Inside a box, min net expose --public 3000 says public exposure is not available on this host, and min net expose 4500 on a box started with --dynamic-range 3000-3999 names that range; neither publishes anything.

Proof

Inside a box, min net expose --public 3000 (or min net expose --public with no port) prints error: public exposure is not available on this host. Nothing was published. and exits 1, and the session is never asked to publish. On a box started with --dynamic-range 3000-3999, min net expose 4500 prints error: port 4500 is outside this box's --dynamic-range 3000-3999. Nothing was published. and exits 1, for an allow box and an ask box alike. An ask box shows no prompt for it, and no mapping is left.

Notes from the agent: Out of scope: crates/minimald/src/box_runtime/tests.rs. Its test vm_ask_host_refusals_are_publish_failures pins two host-refusal texts that the task changes (outside the --dynamic-range and not registered with the VM host daemon). I changed only those two expected strings so the test follows the new texts. Design: the ask-stance range check is in net/policy.rs dynamic_ingress_decision. It returns OutOfRange for an ask box with a range when the port is outside it, so box_actor/ports.rs never calls route_ask for it. An ask box with no range still goes to the prompt as before. The public request travels as a new channel method net-expose-public%<port or empty>. env.rs answers it without asking the session. listeners.rs: the unexpected-reply texts no longer print the Debug form of the reply. It goes to a warn log line. The report_port deadline error is rewritten to the request to open the port did not get an answer in time. The shared report_exchange deadline text, which other verbs use, did not change. I did not change the Usage: min net expose <port> help line, so it does not advertise --public. NET-145 is not in the spec excerpt, so the exact texts come from task.md. Extra runs: 80 related tests passed, and one full cargo nextest run -p minimald passed 1156 tests.

Layer exception

crates/minimald/src/box_runtime/tests.rs is outside T109's layers. Its test vm_ask_host_refusals_are_publish_failures pins the refusal text that the in-layer change rewrote: outside the --dynamic-range becomes outside this box's --dynamic-range, and not registered with the VM host daemon becomes not registered on the host. The hunk updates those two pinned strings only. It changes no behaviour of its own.

Tests

line exit tail
cargo nextest run -p minimald expose_public_refused_without_public_surface 0 Applying loadouts: default Running task runtime-implement-test-0 in session task-runtime-implement-test-0-4df4... Compiling paths v0.0.1 (/workbench/crates/paths) Compiling ot v0.0.1 (/workbench/crates/ot) Compiling args v0.0.1 (/workbench/crates/args) Compiling client-config v0.0.1 (/wo
cargo nextest run -p minimald expose_out_of_range_refusal_names_range 0 Applying loadouts: default Running task runtime-implement-test-1 in session task-runtime-implement-test-1-bcb6... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimald expose_rejected_leaves_no_partial_mapping 0 Applying loadouts: default Running task runtime-implement-test-2 in session task-runtime-implement-test-2-0675... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling graph v0

Verify

min task run agent-verify passed ([tasks.verify]).

Base

The base branch moved while the coder worked; it was merged in before the tests ran.

Out of scope

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

  • crates/minimald/src/box_runtime/tests.rs

Closes #2695


Generated by Claude Code

A port outside the box's --dynamic-range is refused with the range
named, for allow and ask boxes alike, and an ask box refuses it before
any prompt. min net expose --public is its own request and is refused
because this host has no public surface. The host-refusal and port
prompt texts stop naming the VM host daemon.
@coderabbitai
coderabbitai Bot commented Oct 28, 2026 •
Copy link
Copy Markdown
Contributor

Important

Review skipped

Bot user detected.

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

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 45481621-738e-4eba-b1cf-047ff4cd56c7

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.

The native-daemon-e2e lane still matched the old wording, so it failed
on the text this branch ships.
@minimal-foundry
Copy link
Copy Markdown
Contributor Author

Round 1 of 10 on a failed check suite, pushed as 355708a37bed.

line exit tail
cargo nextest run -p minimald expose_public_refused_without_public_surface 0 Applying loadouts: default Running task runtime-implement-test-0 in session task-runtime-implement-test-0-4438... Compiling paths v0.0.1 (/workbench/crates/paths) Compiling args v0.0.1 (/workbench/crates/args) Compiling ot v0.0.1 (/workbench/crates/ot) Compiling client-config v0.0.1 (/wo
cargo nextest run -p minimald expose_out_of_range_refusal_names_range 0 Applying loadouts: default Running task runtime-implement-test-1 in session task-runtime-implement-test-1-0743... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.
cargo nextest run -p minimald expose_rejected_leaves_no_partial_mapping 0 Applying loadouts: default Running task runtime-implement-test-2 in session task-runtime-implement-test-2-d460... Compiling stdlib v0.0.22 (/workbench/crates/stdlib) Compiling version v0.8.0 (/workbench/crates/version) Compiling decode v0.0.1 (/workbench/crates/decode) Compiling mlog v0.

Verify min task run agent-verify passed.

Outside the task's layers::

  • crates/minimald/src/box_runtime/tests.rs
  • scripts/session-e2e.sh

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

Inside a box, min net expose --public 3000 prints error: public exposure is not available on this host. Nothing was published. and exits 1. min net expose 4500 on a box started with --dynamic-range 3000-3999 prints error: port 4500 is outside this box's --dynamic-range 3000-3999. Nothing was published. and exits 1. Neither command publishes anything. The native e2e script now expects this text.

Notes from the agent: Revise round 1. The native-daemon-e2e job failed because scripts/session-e2e.sh line 20960 still matched the old refusal text (declared dynamic range). The binary printed the new text that the task fixes. ci-linux-native-success is the lane aggregator, and it failed only because of that job. I changed the one case pattern so that it expects port <n> is outside this box's --dynamic-range <lo>-<hi>. Nothing was published.. scripts/session-e2e.sh is outside the task's layers. I touched it because it pins the text that this task changes. I found no other pin of the old texts in scripts/, crates/ or docs/. I did not run the e2e script on this box. I checked the new pattern against the exact stderr line from the CI log, and it matches. No Rust code changed in this round.

@norrietaylor
norrietaylor marked this pull request as ready for review October 28, 2026 11:26
@norrietaylor
norrietaylor requested a review from a team as a code owner October 28, 2026 11:26
@minimal-foundry
minimal-foundry Bot commented Oct 28, 2026 •
Copy link
Copy Markdown
Contributor Author

Approved: no findings at 355708a37bed.

Nothing to do.

Verdict APPROVE, posted as a comment: the App cannot review its own pull request; the check and the label carry it.

Clobber: none seen.

@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

The change conforms to §6 and §7.1 of the networking design. The --public refusal is default-deny, and §6 lines 226–227 put public exposure on the roadmap. The out-of-range ask refusal comes before the prompt. The host-side gate in minvmd record_ask still refuses the port, so no check moves across the guest/host boundary. The refusal is audited locally through answer_expose, as §7.1 line 260 requires.

Ruled at 355708a against gominimal/arch@109541a48c31 by claude-opus-5-5.

@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 — approved

Verdict APPROVE — No findings.

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

@minimal-foundry minimal-foundry Bot added the review:approved minimal-review approved the current head label Oct 28, 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 review at 355708a3. I read the helper, channel, ports, policy and listener changes against T109's plan block. min net expose --public [<port>] now reaches the daemon as its own net-expose-public request and is refused with error: public exposure is not available on this host. Nothing was published., without asking the session (NET-145). An ask box with a range refuses a port outside it in dynamic_ingress_decision before any prompt is routed, and the refusal reads port <n> is outside this box's --dynamic-range <a>-<b>. Nothing was published. for both stances (NET-047). The host-refusal and prompt-round texts no longer name the VM host daemon, and an unreadable reply goes to the log rather than to the person. The dynamic ingress expose line gains the refused: public exposure and refused: out of range outcomes. The out-of-layer box_runtime/tests.rs hunk only updates pinned text and is recorded as a layer exception. No findings.


Generated by Claude Code

@norrietaylor norrietaylor changed the title T109 — min net expose refusals say what happened and name the range fix(minimald): name the range and refuse --public in min net expose (T109) Oct 28, 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 at 355708a: every merge gate passes at this head (arch PASS at 355708a, zero open threads, every lane aggregator green). Squash title fix(minimald): name the range and refuse --public in min net expose (T109) and the squashed message pass commitlint. Queued for squash merge.


Generated by Claude Code

@norrietaylor
norrietaylor added this pull request to the merge queue Oct 28, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to no response for status checks Oct 28, 2026
@norrietaylor
norrietaylor added this pull request to the merge queue Oct 28, 2026
Merged via the queue into main with commit 1bbd45c Oct 28, 2026
37 checks passed
@norrietaylor
norrietaylor deleted the agent/2695-min-net-expose-refusals-say-what-happened-and-na branch October 28, 2026 18:24
norrietaylor pushed a commit that referenced this pull request Oct 28, 2026
…T109) (#2718)

* fix(minimald): name the range and refuse --public in min net expose

A port outside the box's --dynamic-range is refused with the range
named, for allow and ask boxes alike, and an ask box refuses it before
any prompt. min net expose --public is its own request and is refused
because this host has no public surface. The host-refusal and port
prompt texts stop naming the VM host daemon.

* test(e2e): pin the new out-of-range expose refusal text

The native-daemon-e2e lane still matched the old wording, so it failed
on the text this branch ships.

---------

Co-authored-by: minimal-foundry[bot] <327719912+minimal-foundry[bot]@users.noreply.github.com>
(cherry picked from commit 1bbd45c)
norrietaylor added a commit that referenced this pull request Oct 28, 2026
…release/0.7.0

The cherry-picked change names main's files, types and helpers. Release/0.7.0
predates the box renames and the helper-request spans, so the change lands in
the release's own code:

- main's box_actor/ports.rs is session.rs here. The ports hunks (the host
  refusal texts, the ask comment, the "refused: out of range" outcome) apply
  to session.rs, in the cherry-pick commit itself.
- The release has no CHANNEL_METHODS list or channel_method span helper, so
  the net-expose-public arm joins handle without a list entry, and
  expose_public_refused_without_public_surface drops its channel_method
  assertion. The refusal text and info line it pins are unchanged.
- expose_out_of_range_refusal_names_range uses sessions:: for boxes:: and
  SessionKeyPredicate for BoxKeyPredicate.

The behaviour is #2718's: a port outside --dynamic-range is refused with the
range named for allow and ask boxes, before any prompt, and min net expose
--public is refused because the host has no public surface.
norrietaylor pushed a commit that referenced this pull request Nov 5, 2026
…2718)

T109. A port outside the box's --dynamic-range is refused with the range named, for
allow and ask boxes alike, and an ask box refuses it before any prompt. min net expose
--public is its own request and is refused because this host has no public surface. The
host-refusal and port prompt texts stop naming the VM host daemon, and the session e2e
script pins the new out-of-range text.

Backport of #2718, folded from #2729.

Adapted to the line:
- main's box_actor/ports.rs hunks land in session.rs.
- The line has no CHANNEL_METHODS list or channel_method helper, so the net-expose-public
  arm joins impl SessionChannel in env.rs without a list entry, and
  expose_public_refused_without_public_surface drops its channel_method assertion. The
  refusal text and log lines it pins are unchanged.
- boxes:: becomes sessions:: and BoxKeyPredicate becomes SessionKeyPredicate.

(cherry picked from commit 1bbd45c)
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.

T109 — min net expose refusals say what happened and name the range

1 participant

0