8000 Merge remote-tracking branch 'origin/main' into agent/2937-a-native-own-address-box-reaches-a-host-exposure · gominimal/minimal@c061bc6 · GitHub
[go: up one dir, main page]

Skip to content

Merge remote-tracking branch 'origin/main' into agent/2937-a-native-o…

Minimal Arch / arch-review failed Nov 4, 2026 in 0s

CONDITIONS

3963

Baseline. This re-reviews c061bc63 against the CONDITIONS on 582b5323 (this PR), on arch 7a86ec7b. since.diff equals git diff 582b5323 c061bc63, and pr.diff equals git diff a4a7c523 c061bc63. The merge c061bc63 brings #2987 from main. git diff-tree --cc is empty, so it is clean, and I do not rule on its hunks here. The one branch commit is 43dcaf98.

Governs: specs/networking/deployment-and-egress-gateway.md §7.1. Line 249: reach needs both halves. Line 251: CIDR coverage of the alias is the fall-through, and an allow-all box reaches exposures as it reaches siblings. Line 252: Minimal's own listeners are never exposures, decided at each flow, from the moment a listener binds.

Ruling. The forward hold conforms to line 252. Each PortForwarder at 127.0.0.1 holds its port for its protocol in the daemon registry, from the bind until an unbind succeeds. The per-attach hold in gvproxy_network.rs is removed. The names_host_alias() change deviates from line 251. A compiled allow_subnets of None means the dimension allows all (EgressRules::allow_subnets() doc, and classify admits on it). The gate gets that shape only for EffectiveEgress::AllowAll (box_actor/setup.rs effective_egress_section()). The shipped phase is InForce, so that happens only behind the NET-077 opt-out. Under the in-force default, effective_egress already resolves an absent section or list to an empty one, so the NET-074 reasoning in the new comment never decides a flow. The change only refuses an opt-out allow-all box that reaches every sibling. The new test asserts that refusal, so it proves the opposite of line 251 (rubric rule 3). C1 and C2 revert the arm and fix the proof.

Not checked. The ledger entry for 582b5323 is cut off before its conditions. I cannot read their full text, so I took them from the 43dcaf98 commit message. If a condition on 582b5323 asked for the is_some_and arm, this ruling departs from it on line 251, for the reason above. I did not build. The tests are read, not run.

Conditions

  • C1: crates/minimald/src/net/switch.rs names_host_alias(): the covered test goes back to rules.allow_subnets().is_none_or(|allow| allow.iter().any(|cidr| cidr.contains(alias))). A compiled allow_subnets of None is the allow-all dimension (egress.rs allow_subnets() doc). The gate gets it only from effective_egress_section() mapping EffectiveEgress::AllowAll to egress: None, behind the NET-077 opt-out. That box reaches siblings through classify (egress.rs line 1244), so it reaches an exposure as well. Under the in-force default an own-address box with no section is already EgressPolicy::deny_all(), and an absent list in a declared section is already Some(vec![]), so the NET-074 refusal stays. Replace the comment at lines 1772-1774 with that reason.
  • C2: crates/minimald/src/net/switch.rs native_own_ip_host_exposure_needs_the_box_to_name_the_host: the no_egress case (egress: None, line 5223) and the no_subnets case (allow_subnets = None, line 5233) assert that the frame reaches the switch. Their messages say that an allow-all box reaches the exposure as it reaches a sibling. Add a case with egress: Some(boxes::EgressPolicy::deny_all()) that asserts refusal. That policy is what the gate gets for an own-address box with no section under the in-force default (NET-074).

Ruled at c061bc6 against gominimal/arch@7a86ec7bb3c0 by claude-opus-5-5; arch_rulings 913, job d1393fea-9317-4c04-877f-27fe4f4ed0ac.

0