8000 test(minimald): prove DNS steering fails closed end to end (T32) by minimal-foundry[bot] · Pull Request #2550 · gominimal/minimal · GitHub
[go: up one dir, main page]

Skip to content

test(minimald): prove DNS steering fails closed end to end (T32) - #2550

Merged
norrietaylor merged 2 commits into
mainfrom
agent/2289-dns-steering-fails-closed-end-to-end
Oct 25, 2026
Merged

norrietaylor merged 2 commits into
mainfrom
agent/2289-dns-steering-fails-closed-end-to-end

Conversation

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

T32 — DNS steering fails closed, end to end

slice: S4
kind: integration
covers: none
size: M
est: 80 code, 120 tes 8000 ts
executor: agent
difficulty: needs care
model: standard
diagnostics: the bundle's daemon log tail carries the SERVFAIL answers and the rejected datagrams of the run
observability: the warn and debug lines both tasks emit, in one run
layers:
- e2e:
- scripts/session-e2e.sh: one case: stop the proxy, resolve a steered name, query its HTTPS record, send QUIC to 443
test: ./scripts/session-e2e.sh bep_dns_steering_fails_closed_end_to_end
produces: none
consumes: none
proof: A steered name answers SERVFAIL while the proxy is down, AAAA, HTTPS and SVCB answer NODATA, and UDP 443 from a blocked box is rejected at once.
depends on:
- blocked by #2281
- blocked by #2282

Proof

Partly delivered. On a VM lane with the gvproxy switch, ./scripts/session-e2e.sh bep_dns_steering_fails_closed_end_to_end starts a credentialed-lane box with the default dns steering and quic443 = "block", then stops bep serve. It asserts that AAAA, HTTPS and SVCB lookups of api.github.com are NODATA, and that UDP to 192.0.2.1:443 is refused with 'Connection refused' in under 2 s. The proof's first clause, a steered name that answers SERVFAIL while the proxy is down, is not true at this branch. The case reports that leg as KNOWN GAP on issue #2523 and does not count it as passed.

Notes from the agent: 1. The SERVFAIL leg cannot pass at this branch head. DnsGate::with_steering and ProxyListenerState exist (#2519), but no production code calls them. Their own comments say this and name #2523. A steered A lookup is forwarded to real DNS. The case passes this leg when it gets rcode 2. Otherwise it calls known_gap with the rcode it got. When #2523 lands, change that known_gap to a fail.
2. Activation refuses a box that has a broker secret and dns steering on every host. crates/minimal/src/cmd/boxes/create.rs uses HostFacts::LOCAL, which sets box_zone_resolver: false (BEP-017). So the case gets its credentialed lane from --credentialed-upstream with no secret. quic443 = "auto" blocks only with a credentialed secret, so the case declares quic443 = "block". Once a box with a secret can use dns steering, a box with a GitHub grant is the closer match to the task.
3. Nothing in the case ran on this box. The test line exits 0 with NOT RUN because there is no E2E_VM and no MINVMD_GVPROXY_BIN. The NODATA and UDP 443 legs are hard assertions, but they are not yet exercised. They need a run on a VM lane (macOS HVF, or Linux KVM with gvproxy). On macOS the case kills 'bep serve --listener /minimal/providers/local-minvmd0/gvproxy-bep.sock'. On other VM lanes no proxy runs, so the proxy is down from the start.
4. Observabi…[truncated]

Tests

line exit tail
./scripts/session-e2e.sh bep_dns_steering_fails_closed_end_to_end 0 ::group::DNS steering fails closed while the Box Egress Proxy is down bep_dns_steering_fails_closed_end_to_end: NOT RUN (no MINVMD_GVPROXY_BIN: the steered lookups and the UDP 443 rejection run on the VM host's switch, and this target has none) ::endgroup:: session e2e: 1 case(s) NOT RUN: bep_dns_st

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.

0.11.19
    Checking path-dedot v4.0.1
    Checking route_manager v0.2.13
    Checking russh-sftp v2.4.0
    Checking path-absolutize v4.0.1
    Checking libcgroups v0.7.0
    Checking tun-rs v2.8.8
    Checking postcard v1.1.3
    Checking sendfd v0.4.4
    Checking close_fds v0.3.2
    Checking caps v0.5.6
   Compiling minvmd v0.8.0 (/workbench/crates/minvmd)
    Checking size v0.5.0
    Checking hakoniwa v1.7.2 (https://github.com/souk4711/hakoniwa.git?rev=0810ffa37620ef5c57de263c8eaa1f4d7633c14a#0810ffa3)
    Checking tagptr v0.2.0
    Checking object v0.40.0
    Checking moka v0.12.16
    Checking sandbox v0.0.1 (/workbench/crates/sandbox)
   Compiling serial_test_derive v4.0.1
    Checking compression-core v0.4.33
    Checking async-tar v0.6.1
    Checking compression-codecs v0.4.45
    Checking async-compression v0.4.50
    Checking serial_test v4.0.1
    Checking vsock v0.5.4
    Checking vte v0.15.0
    Checking diagnostics v0.0.1 (/workbench/crates/diagnostics)
    Checking tokio-vsock v0.7.2
    Checking vt100 v0.16.2 (https://github.com/gominimal/vt100-rust.git?rev=9b8cce5a6798daf061948259ebcb073bb1ea54a6#9b8cce5a)
    Checking async-dialog v0.0.1 (/workbench/crates/async-dialog)
    Checking minimald-rpc v0.0.1 (/workbench/crates/minimald-rpc)
    Checking mfile v0.0.1 (/workbench/crates/mfile)
    Checking castaway v0.2.4
    Checking strum v0.28.0
    Checking compact_str v0.9.1
    Checking signal-hook v0.3.18
    Checking unicode-truncate v2.0.1
    Checking kasuari v0.4.12
    Checking pem v4.0.0
    Checking yasna v0.6.0
    Checking lru v0.18.2
    Checking ratatui-core v0.1.2
    Checking rcgen v0.14.10
    Checking signal-hook-mio v0.2.5
    Checking derive_more v2.1.1
    Checking wait-timeout v0.2.1
    Checking decode v0.0.1 (/workbench/crates/decode)
    Checking checkouts v0.0.1 (/workbench/crates/checkouts)
    Checking bit-vec v0.10.1
    Checking quick-error v1.2.3
    Checking rusty-fork v0.3.1
    Checking bit-set v0.11.1
    Checking crossterm v0.29.0
    Checking line-clipping v0.3.8
    Checking rand_xorshift v0.5.0
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...

Residuals

Closes #2289


Generated by Claude Code

One case, bep_dns_steering_fails_closed_end_to_end, on a VM lane with
the gvproxy switch. It starts a credentialed-lane box with the default
dns steering and quic443 = "block", stops `bep serve`, and from inside
the box asserts that AAAA, HTTPS and SVCB lookups of api.github.com are
NODATA and that UDP to port 443 is refused within 2 s.

The steered A lookup is a known gap until #2523 wires the steering into
the relay's DNS gate: the case passes it on SERVFAIL and otherwise
counts it as KNOWN GAP with the rcode it got.
@coderabbitai
coderabbitai Bot commented Oct 25, 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: aef3f584-3848-421c-a6dc-680932bf4125

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 25, 2026 •
Copy link
Copy Markdown
Contributor Author

Approved: every review thread resolved at b2198c2c15ff.

@norrietaylor resolved the last thread, which releases the approval this review had withheld.

Nothing to do.

@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 scripts/session-e2e.sh 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_WITH_CONDITIONS · 1 condition · the full ruling

The case tests the §5.3 line 151 NODATA rule and the §5.7 line 218 UDP 443 active reject with hard assertions. It reports the steered SERVFAIL leg as a known gap on #2523. That follows the #2519 ruling. The PR body still says Closes #2289, but the proof's first clause is still open. Make the edit in C1, and keep #2289 open until the known_gap becomes a failure.

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

Comment thread scripts/session-e2e.sh Resolved
When the steered A lookup gets no SERVFAIL, the case records a known
gap. The closing line now says so, and does not read as a full pass.
@minimal-foundry
Copy link
Copy Markdown
Contributor Author

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

line exit tail
./scripts/session-e2e.sh bep_dns_steering_fails_closed_end_to_end 0 ::group::DNS steering fails closed while the Box Egress Proxy is down bep_dns_steering_fails_closed_end_to_end: NOT RUN (no MINVMD_GVPROXY_BIN: the steered lookups and the UDP 443 rejection run on the VM host's switch, and this target has none) ::endgroup:: session e2e: 1 case(s) NOT RUN: bep_dns_st

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.

  Checking ed25519 v3.0.0
    Checking poly1305 v0.9.1
    Checking blowfish v0.10.0
    Checking blake2 v0.11.0-rc.6
    Checking bcrypt-pbkdf v0.11.0
    Checking argon2 v0.6.0-rc.8
    Checking ssh-cipher v0.3.0
    Checking ed25519-dalek v3.0.0
    Checking generic-array v0.14.7
    Checking sha3 v0.11.0
    Checking p521 v0.14.0
    Checking p384 v0.14.0
    Checking hash32 v0.3.1
    Checking module-lattice v0.2.3
    Checking kem v0.3.0
    Checking constcat v0.6.1
    Checking sponge-cursor v0.1.0
    Checking data-encoding v2.11.1
    Checking ml-kem v0.3.2
    Checking ssh-key v0.7.0-rc.11
    Checking sha3 v0.12.0
    Checking heapless v0.9.3
    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 is_executable v1.0.6
    Checking hex-literal v1.1.0
    Checking managed v0.8.0
    Checking bitflags v1.3.2
    Checking clap_complete v4.6.11
    Checking russh v0.64.1
    Checking minimald-rpc v0.0.1 (/workbench/crates/minimald-rpc)
    Checking smoltcp v0.14.0
    Checking tinyvec_macros v0.1.1
    Checking tinyvec v1.12.0
    Checking switch v0.0.1 (/workbench/crates/switch)
    Checking hickory-proto v0.26.3
    Checking sysinfo v0.39.6
   Compiling stdlib v0.0.22 (/workbench/crates/stdlib)
    Checking mfile v0.0.1 (/workbench/crates/mfile)
    Checking netlink-packet-core v0.8.1
    Checking generational-arena v0.2.9
    Checking konst_macro_rules v0.2.19
    Checking netlink-sys v0.8.8
    Checking konst v0.2.20
    Checking derive_builder v0.20.2
    Checking checkouts v0.0.1 (/workbench/crates/checkouts)
    Checking const_format v0.2.36
    Checking decode v0.0.1 (/workbench/crates/decode)
    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 hashbrown v0.14.5
    Checking fixedbitset v0.5.7
    Checking strum v0.27.2
    Checking dashmap v6.2.1
    Checking oci-spec v0.10.0
    Checking heapless v0.7.17
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...

Review threads the coder judged:

  • 👍 valid — scripts/session-e2e.sh: Leg 1 now sets ds_a_gap on the known gap. The closing line then says the steered A lookup did not fail closed, and does not report a full pass.

With the proxy down, the e2e case checks that the steered A lookup answers SERVFAIL, that AAAA, HTTPS and SVCB answer NODATA, and that UDP 443 from a quic443 = "block" box is refused within 2000 ms. The closing line now claims a full pass only when the A lookup got SERVFAIL. When it did not, the line names the known gap (#2523).

Notes from the agent: This round changes only the closing line of proof_bep_dns_steering_fails_closed_end_to_end. The case did not execute here because there is no KVM and no gvproxy, so the e2e lane still owes the evidence. bash -n and shellcheck -S warning are clean.

@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_WITH_CONDITIONS · 1 condition · the full ruling

The compare fixes the closing line. It no longer claims a full pass when the steered A lookup is a known gap. Legs 2 and 3 are hard assertions of §5.3 lines 150 and 151. Leg 1 is still a known gap on #2523, and §5.3 line 147 requires fail-closed. That leg is open, and C1 makes it a hard failure when #2523 lands. No leg ran in this sandbox, so the ci-macos just e2e run is the first proof of legs 2 and 3.

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

Comment thread scripts/session-e2e.sh Resolved
@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: 3 unresolved threads — minimal-foundry[bot] scripts/session-e2e.sh, minimal-arch[bot] scripts/session-e2e.sh:12290, minimal-arch[bot] scripts/session-e2e.sh:12290. No findings.

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

@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 — every review thread is resolved; @norrietaylor closed the last one. The review of b2198c2c15ff withheld this approval on the threads open then. Posted as a comment: the App cannot approve its own pull request; the check and the label carry it.

@minimal-foundry minimal-foundry Bot added the review:approved minimal-review approved the current head label Oct 25, 2026
@norrietaylor norrietaylor changed the title T32 — DNS steering fails closed, end to end test(minimald): prove DNS steering fails closed end to end (T32) Oct 25, 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 b2198c2: every merge gate passes at this head (arch PASS_WITH_CONDITIONS at b2198c2 whose condition is a filed residual owned by #2523 and T58 #2538, zero open threads, every lane aggregator green including ci-macos-success). The PR keeps Closes #2289 by the epic owner's ruling. Squash title test(minimald): prove DNS steering fails closed end to end (T32) 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 25, 2026
Merged via the queue into main with commit e40e028 Oct 25, 2026
37 checks passed
@norrietaylor
norrietaylor deleted the agent/2289-dns-steering-fails-closed-end-to-end branch October 25, 2026 16:11
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.

T32 — DNS steering fails closed, end to end

1 participant

0