8000 feat(minimald): steer credentialed names to the proxy and fail closed while it is down by minimal-foundry[bot] · Pull Request #2519 · gominimal/minimal · GitHub
[go: up one dir, main page]

Skip to content

feat(minimald): steer credentialed names to the proxy and fail closed while it is down - #2519

Merged
norrietaylor merged 6 commits into
mainfrom
agent/2281-steer-credentialed-names-to-the-proxy-and-fail-c
Oct 25, 2026
Merged

norrietaylor merged 6 commits into
mainfrom
agent/2281-steer-credentialed-names-to-the-proxy-and-fail-c

Conversation

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

T30 — Steer credentialed names to the proxy and fail closed while it is down

slice: S4
kind: task 8000
covers: BEP-062, BEP-078
size: M
est: 280 code, 120 tests
executor: agent
difficulty: needs care
model: standard
diagnostics: the bundle's daemon log tail carries each SERVFAIL answered for a steered name while the proxy was down, with the name and the box
observability: one rate-limited warn log line per steered name answered SERVFAIL, and one info line when the proxy's listener comes back
layers:
- dns:
- crates/minimald/src/net/dns_gate.rs: steered names answer the proxy's address; SERVFAIL while it is down; NODATA for AAAA, HTTPS, SVCB
- crates/minimald/src/net/dns.rs: carries the proxy's listener state to the gate
test: cargo nextest run -p minimald steered_name_servfail_while_proxy_down
test: cargo nextest run -p minimald steered_name_aaaa_https_svcb_are_nodata
produces: none
consumes: none
proof: With the proxy stopped, a dns-steered box resolving github.com gets SERVFAIL, never a real address.
depends on:
- blocked by #2276

Proof

At the gate level, a dns-steered box (steering dns, both, or unset) that resolves github.com while the proxy's listener is down gets SERVFAIL and no address. Its query is never forwarded. When the listener is live, the box gets the proxy's address. AAAA, HTTPS and SVCB lookups of a steered name get NODATA in both states. The two named tests show this. In a running daemon this is not true yet, because nothing builds the gate with steering. See notes.

Notes from the agent: The proof is not delivered end to end. DnsGate::with_steering and net::dns::ProxyListenerState exist and are tested, but no production code calls them. The gate is built in crates/minimald/src/net/switch.rs (BoxGate::for_session, about line 1469), and that file is outside this task's layers, so I did not touch it. To wire it, one call is needed there: .with_steering(policy, <module hosts>, subnet.box_egress_proxy_address(), <shared ProxyListenerState>). Two more things are missing for that. (1) minimald does not depend on the bep crate, so it has no access to bep::module::GITHUB's host set. The caller must pass the hosts in, or minimald/Cargo.toml must add bep. (2) No code in minimald knows whether the proxy's listener is live. The proxy runs in the switch crate's bep_host beside gvproxy (minvmd). Something must call ProxyListenerState::set_live, and that is probably the blocker #2276. Until the wiring lands, both items carry #[cfg_attr(not(test), allow(dead_code))] with a comment that says why. Behaviour: the steering check runs after the existing REFUSED/NXDOMAIN/NODATA rules, so AAAA/HTTPS/SVCB of a steered name keep the NET-136 NODATA (BEP-078). A steered query with only non-A questions (TXT, MX) gets an empty NOERROR while live, so it is never forwarded. The steered A answer has a 30 s TTL. Observability: a SERVFAIL writes one warn line per name per box per minute through the gate's PolicyWarnLimiter, with session_id (the box's switch address) and name. A change from down to live…[truncated]

Tests

line exit tail
cargo nextest run -p minimald steered_name_servfail_while_proxy_down 0 Applying loadouts: default Running task runtime-implement-test-0 in session task-runtime-implement-test-0-199d... 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
cargo nextest run -p minimald steered_name_aaaa_https_svcb_are_nodata 0 Applying loadouts: default Running task runtime-implement-test-1 in session task-runtime-implement-test-1-3583... 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 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-430f...
    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 stdlib v0.0.22 (/workbench/crates/stdlib)
   Compiling version v0.8.0 (/workbench/crates/version)
    Checking diagnostics v0.0.1 (/workbench/crates/diagnostics)
    Checking common v0.0.1 (/workbench/crates/common)
    Checking async-dialog v0.0.1 (/workbench/crates/async-dialog)
    Checking switch v0.0.1 (/workbench/crates/switch)
    Checking boxes v0.0.1 (/workbench/crates/boxes)
    Checking sandbox v0.0.1 (/workbench/crates/sandbox)
    Checking mlog v0.0.1 (/workbench/crates/mlog)
    Checking mfile v0.0.1 (/workbench/crates/mfile)
    Checking minimald-rpc v0.0.1 (/workbench/crates/minimald-rpc)
    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)
    Checking op v0.0.1 (/workbench/crates/op)
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...

Base

The base branch moved while the coder worked and was merged in before the tests ran. These files changed on BOTH sides since the branch point — read them first, because a rewrite from a stale reading can undo a merge without a conflict:

  • crates/minimald/src/net/dns_gate.rs

Residuals

  • T113 — Admit dns and both steering where the host's switch resolves box names #2523 (T58 in slice S9): BoxGate::for_session in crates/minimald/src/net/switch.rs calls DnsGate::with_steering(...) for every dns or both box, and the switch-side bep host calls ProxyListenerState::set_live when the listener goes up or down. Until it lands, the steering in this PR has no production caller and the BEP-062 proof holds in the gate's tests only; both interim comments name the issue.

Closes #2281


Generated by Claude Code

The DNS gate answers a steered box's A lookup of a credentialed name with
the Box Egress Proxy's address while its listener is live, and SERVFAIL
while it is down, so the lookup never falls back to real DNS (BEP-062).
AAAA, HTTPS and SVCB lookups of a steered name stay NODATA (BEP-078).

ProxyListenerState in net::dns carries the listener's state to the gate.
The relay's gate construction does not wire it yet.
The merge from main added BoxPolicy::quic443, so the fixture no
longer compiled.
@coderabbitai
coderabbitai Bot commented Oct 24, 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: a4da676e-ae56-4ed8-bdf3-55092ddacf2e

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

Approved: every review thread resolved at 4e50ffe9c892.

@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 crates/minimald/src/net/dns_gate.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 gate logic conforms to §5.4 line 169 and §5.3 line 148. A steered name is never forwarded, and a new listener state reads down. But no production code calls DnsGate::with_steering or ProxyListenerState::set_live, so a running daemon steers no name. The PR closes #2281 and names no issue for the wiring. C1 changes the PR body to Refs #2281 and records the wiring as a residual with an issue. C2 puts that issue and the flip condition in the two dead_code comments.

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

Comment thread crates/minimald/src/net/dns_gate.rs Resolved
Comment thread crates/minimald/src/net/dns.rs Resolved
A query with a steered and an unsteered question was answered with the
steered addresses only, so the other question got no answer and no
error. Forwarding it would leak the steered name to real DNS, so the
relay now answers the whole query SERVFAIL.
@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, 2 inline.

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

Comment thread crates/minimald/src/net/dns_gate.rs Resolved
Comment thread crates/minimald/src/net/dns_gate.rs Resolved
@minimal-foundry
Copy link
Copy Markdown
Contributor Author

No revise round started on the runtime's review findings, because epic #1501 is stopped. The runtime starts no round on its own while its epic is not walking, and none was counted. A person's /revise <note> still runs; the automatic rounds resume when the epic walks again.

@minimal-foundry
Copy link
Copy Markdown
Contributor Author

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

line exit tail
cargo nextest run -p minimald steered_name_servfail_while_proxy_down 0 Applying loadouts: default Running task runtime-implement-test-0 in session task-runtime-implement-test-0-dd91... 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
cargo nextest run -p minimald steered_name_aaaa_https_svcb_are_nodata 0 Applying loadouts: default Running task runtime- 8000 implement-test-1 in session task-runtime-implement-test-1-3909... 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 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.

ng mlog v0.0.1 (/workbench/crates/mlog)
    Checking bcrypt-pbkdf v0.11.0
    Checking ssh-cipher v0.3.0
    Checking ed25519-dalek v3.0.0
    Checking generic-array v0.14.7
    Checking sha3 v0.11.0
    Checking p256 v0.14.0
    Checking p521 v0.14.0
    Checking p384 v0.14.0
    Checking module-lattice v0.2.3
    Checking mfile v0.0.1 (/workbench/crates/mfile)
    Checking kem v0.3.0
    Checking object v0.40.0
    Checking tinyvec_macros v0.1.1
    Checking hashbrown v0.14.5
    Checking sponge-cursor v0.1.0
    Checking data-encoding v2.11.1
    Checking dashmap v6.2.1
    Checking sha3 v0.12.0
    Checking tinyvec v1.12.0
    Checking ml-kem v0.3.2
    Checking ssh-key v0.7.0-rc.11
    Checking generic-array v1.4.4
    Checking async-compression v0.4.50
    Checking russh-cryptovec v0.62.0
    Checking vsock v0.5.4
    Checking vte v0.15.0
    Checking async-tar v0.6.1
    Checking num-bigint v0.5.1
    Checking russh-util v0.52.0
    Checking decode v0.0.1 (/workbench/crates/decode)
    Checking checkouts v0.0.1 (/workbench/crates/checkouts)
    Checking serde_bytes v0.11.19
    Checking constcat v0.6.1
    Checking hex-literal v1.1.0
    Checking minimald-rpc v0.0.1 (/workbench/crates/minimald-rpc)
    Checking russh v0.64.1
    Checking russh-sftp v2.4.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 hickory-proto v0.26.3
    Checking clap_complete v4.6.11
    Checking async-dialog v0.0.1 (/workbench/crates/async-dialog)
    Checking graph v0.0.1 (/workbench/crates/graph)
    Checking sysinfo v0.39.6
    Checking wait-timeout v0.2.1
    Checking switch v0.0.1 (/workbench/crates/switch)
    Checking bit-vec v0.10.1
    Checking quick-error v1.2.3
    Checking bit-set v0.11.1
    Checking rusty-fork v0.3.1
    Checking rand_xorshift v0.5.0
    Checking unarray v0.1.4
    Checking core_detect v1.0.0
    Checking serial_test v4.0.1
    Checking proptest v1.12.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...

Review threads the coder judged:

  • 👍 valid — crates/minimald/src/net/dns_gate.rs:668: answer_steered now answers SERVFAIL when any question is not steered. Forwarding would leak the steered name to real DNS. The servfail test pins the mixed case.

With the proxy stopped, a dns-steered box that resolves github.com gets SERVFAIL, never a real address. A query that mixes github.com with an unsteered name now also gets SERVFAIL. It is not forwarded and it is not half answered.

Notes from the agent: Revise round 1: one thread. I chose SERVFAIL over forwarding for a mixed query, because forwarding sends the steered name to real DNS and the real resolver can answer it with a real address. The servfail test now covers the mixed case while the listener is live. I did not run just ci or clippy-strict.

Copy link
Copy Markdown
Member

/revise

Round 2 of #2519, on the arch ruling at 9b90b4d and the review findings that stay open. No round is in flight. The epic owner ruled on 2026-10-25 that this PR keeps Closes #2281 and that the wiring is a filed residual: #2523 is now open for it, and the owner has filed it so the task does not have to.

  1. Arch C1 (thread 4368950923, 4368950924): do not change Closes #2281. Add a ## Residuals section to the PR body with one entry for T113 — Admit dns and both steering where the host's switch resolves box names #2523: BoxGate::for_session in crates/minimald/src/net/switch.rs calls DnsGate::with_steering(policy, <credential module hosts>, <proxy address on the switch>, <shared ProxyListenerState>), and the switch-side bep host calls ProxyListenerState::set_live when the listener goes up or down.
  2. Arch C2: in crates/minimald/src/net/dns.rs, the comment above ProxyListenerState becomes // Interim until https://github.com/gominimal/minimal/issues/2523: no production code builds a state yet. Remove the allow when BoxGate::for_session passes one to the gate. In crates/minimald/src/net/dns_gate.rs, the comment above DnsGate::with_steering names the same issue and the same flip condition.
  3. Review finding 4368967909 (intercept_query, mixed-type query): a query that holds a steered A question and an AAAA, HTTPS or SVCB question is answered NODATA by decide before answer_steered runs, so the steered A gets no SERVFAIL while the proxy is down. Check the steered rule first for a query that holds any steered question, or add the mixed-type test that pins the stated rule, whichever keeps the REFUSED, NXDOMAIN and NODATA order of decide for every unsteered question.
  4. Review finding 4368967912 (with_steering has no caller): answer it with the residual T113 — Admit dns and both steering where the host's switch resolves box names #2523 and the interim comments from step 2.
  5. Reply on each thread naming the commit, and resolve the ones the commit fixes.

One commit, Conventional Commits subject, body lines at most 100 characters.


Generated by Claude Code

A query with a steered A question and an AAAA, HTTPS or SVCB question was
answered NODATA by decide, so the steered A got no SERVFAIL while the proxy
was down. Such a query now goes to the steered rule. REFUSED and NXDOMAIN
still come first, and a query of only AAAA, HTTPS or SVCB stays NODATA.

The interim comments on ProxyListenerState and DnsGate::with_steering now
name #2523 and the condition
that removes their dead_code allow.
@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: 5 unresolved threads — minimal-foundry[bot] crates/minimald/src/net/dns_gate.rs:683, minimal-arch[bot] crates/minimald/src/net/dns_gate.rs, minimal-arch[bot] crates/minimald/src/net/dns.rs, minimal-foundry[bot] crates/minimald/src/net/dns_gate.rs:631, minimal-foundry[bot] crates/minimald/src/net/dns_gate.rs:506. 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: PASS_WITH_CONDITIONS · 1 condition · the full ruling

The gate now fails closed for every steered query shape that §5.3 line 151 and line 147 govern, and BEP-078 conforms. No production code calls DnsGate::with_steering or ProxyListenerState::set_live yet. So a running daemon steers no box, and BEP-062 holds only at the gate. C1 wires BoxGate::for_session and removes the dead_code allows. Issue #2523 owns C1 as a filed residual, so the change can merge with C1 open.

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

10000
Comment thread crates/minimald/src/net/dns_gate.rs Resolved
@minimal-foundry
Copy link
Copy Markdown
Contributor Author

Round 2 of 10 on a /revise note, pushed as 4e50ffe9c892.

line exit tail
cargo nextest run -p minimald steered_name_servfail_while_proxy_down 0 Applying loadouts: default Running task runtime-implement-test-0 in session task-runtime-implement-test-0-e9ff... 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
cargo nextest run -p minimald steered_name_aaaa_https_svcb_are_nodata 0 Applying loadouts: default Running task runtime-implement-test-1 in session task-runtime-implement-test-1-0979... 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 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-9be8...
    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 stdlib v0.0.22 (/workbench/crates/stdlib)
   Compiling version v0.8.0 (/workbench/crates/version)
    Checking common v0.0.1 (/workbench/crates/common)
    Checking diagnostics v0.0.1 (/workbench/crates/diagnostics)
    Checking async-dialog v0.0.1 (/workbench/crates/async-dialog)
    Checking boxes v0.0.1 (/workbench/crates/boxes)
    Checking sandbox v0.0.1 (/workbench/crates/sandbox)
    Checking switch v0.0.1 (/workbench/crates/switch)
    Checking mlog v0.0.1 (/workbench/crates/mlog)
    Checking mfile v0.0.1 (/workbench/crates/mfile)
    Checking minimald-rpc v0.0.1 (/workbench/crates/minimald-rpc)
    Checking checkouts v0.0.1 (/workbench/crates/checkouts)
    Checking decode v0.0.1 (/workbench/crates/decode)
    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...

Review threads the coder judged:

In the gate tests, a dns-steered box that resolves github.com while the proxy is stopped gets SERVFAIL and never a real address. This includes a query that holds the A question beside an AAAA, HTTPS or SVCB question. A running daemon does not steer yet. #2523 tracks the wiring in BoxGate::for_session.

Notes from the agent: Commit 4e50ffe addresses directive items 2, 3 and 4. Item 1 (the ## Residuals section) and item 5 (thread replies) are edits to the pull request. I have no credential for them. The runner writes the body, so it must add this residual: #2523 — BoxGate::for_session in crates/minimald/src/net/switch.rs calls DnsGate::with_steering(policy, , , ), and the switch-side bep host calls ProxyListenerState::set_live when the listener goes up or down. Closes #2281 stays as it is. My instructions do not let me resolve threads. For item 3: a query that holds a steered A question now skips the NODATA rule of decide and goes to answer_steered. REFUSED and NXDOMAIN still come first, and a query of only steered AAAA, HTTPS or SVCB questions stays NODATA. A temporary revert of the fix made the new mixed-type assertion fail. The dns.rs comment uses the directive's exact wording on one line, which is longer than 100 characters. rustfmt accepts it. Clippy reports no warnings in the changed files. I did not run just clippy-strict.

@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 4e50ffe9c892 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 T30 — Steer credentialed names to the proxy and fail closed while it is down feat(minimald): steer credentialed names to the proxy and fail closed while it is down 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 4e50ffe: every merge gate passes at this head (arch PASS with its condition held on the filed residual #2523, zero open threads, every lane aggregator green, bot resolutions re-verified). Squash title feat(minimald): steer credentialed names to the proxy and fail closed while it is down 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 33b984a Oct 25, 2026
37 checks passed
@norrietaylor
norrietaylor deleted the agent/2281-steer-credentialed-names-to-the-proxy-and-fail-c branch October 25, 2026 03:54
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.

T30 — Steer credentialed names to the proxy and fail closed while it is down

1 participant

0