Repository navigation
Closed
Labels
kind:taskA task the plan skill rendered; the body carries ## TaskA task the plan skill rendered; the body carries ## Taskmodel:standardA standard model: work that needs care, or routine work that is largeA standard model: work that needs care, or routine work that is largesize:M200 to 500 net lines; one PR200 to 500 net lines; one PR
Description
Task
| slice | size | difficulty | model | who | estimated lines |
|---|---|---|---|---|---|
| Conditions closed | M | needs care | standard | an agent | 360 (200 code, 160 tests) |
A host_ip cohort with one blocked member sends no UDP 443 and gets ICMP port unreachable; when that member stops, the cohort sends UDP 443 again.
Covers:
- BEP-018
Layers:
- ruleset:
- crates/minimald/src/net/classifier.rs:
CohortQuic443learns the path of the cohort's blocked leaf and the daemon's move of ahost_ipbox's processes into and out of it (acgroup.procswrite inside the delegated slice, which needs no CAP_NET_ADMIN and never rewrites the table); its doc stops saying the type is unenforced - scripts/install-host-classifier.sh:
render_rulesetgains one rule keyed on a new delegated leaf under the boxes directory, the cohort's blocked leaf:socket cgroupv2 level <n> "<blocked leaf>" udp dport 443 reject with icmpx port-unreachable; the install step creates that leaf with the rest of the tree, so the privileged step ships the rule and the daemon flips it by membership (widened 2026-10-25: classifier.rs only embeds this script withinclude_str!, so the table is rendered here) - scripts/install_test.sh: the install harness models the blocked leaf
boxes/quic443-blockedbesidedenyandallow(the expected delegation list and bothdrop_cgroup_filesloops before--uninstall), so the un-enrolled and installed trees uninstall again (widened 2026-10-25:common::shell_harnesses all_script_test_harnesses_passruns this harness on the native lane) cargo nextest run -p minimald host_ip_cohort_blocked_stance_rejects_udp_443
- crates/minimald/src/net/classifier.rs:
- lifecycle:
- crates/minimald/src/box_actor/host.rs: the
host_iplaunch path callsCohortQuic443::joinwith the box's resolved stance and moves every residenthost_ipbox into the blocked leaf whenblocked()turns true; the stop path callsleaveand moves them back to their own leaves when the last blocking member goes - crates/minimald/src/box_runtime.rs:
command_in_sessionhands the shim the cohort's blocked leaf instead of the box's own leaf while the cohort is blocked, and records the shim pid under the box id so the injected process goes home when the block lifts (widened 2026-10-25 per arch C1 on feat(minimald): block UDP 443 for a host_ip cohort with a blocked QUIC stance (T53) #2553:min box execand injected hooks must not escape the stance) - crates/minimald/src/box_runtime/tests.rs: the exec-placement tests live here, where
box_runtime.rskeeps its tests (widened 2026-10-25) cargo nextest run -p minimald host_ip_cohort_join_block_leave_drives_the_rule
- crates/minimald/src/box_actor/host.rs: the
Waits on:
Implements the filed residual #2515; those issues close with this task and do not block it.
Plan block
### T53 — Enforce the host_ip cohort's blocked QUIC stance in the host-address ruleset
slice: S9
kind: task
covers: BEP-018
size: M
est: 200 code, 160 tests
executor: agent
difficulty: needs care
model: standard
diagnostics: the bundle's daemon log tail carries one line per cohort stance change naming the box that flipped it
observability: one info log line when the cohort flag turns on or off, with the blocking members
layers:
- ruleset:
- crates/minimald/src/net/classifier.rs: `CohortQuic443` learns the path of the cohort's blocked leaf and the daemon's move of a `host_ip` box's processes into and out of it (a `cgroup.procs` write inside the delegated slice, which needs no CAP_NET_ADMIN and never rewrites the table); its doc stops saying the type is unenforced
- scripts/install-host-classifier.sh: `render_ruleset` gains one rule keyed on a new delegated leaf under the boxes directory, the cohort's blocked leaf: `socket cgroupv2 level <n> "<blocked leaf>" udp dport 443 reject with icmpx port-unreachable`; the install step creates that leaf with the rest of the tree, so the privileged step ships the rule and the daemon flips it by membership (widened 2026-10-25: classifier.rs only embeds this script with `include_str!`, so the table is rendered here)
- scripts/install_test.sh: the install harness models the blocked leaf `boxes/quic443-blocked` beside `deny` and `allow` (the expected delegation list and both `drop_cgroup_files` loops before `--uninstall`), so the un-enrolled and installed trees uninstall again (widened 2026-10-25: `common::shell_harnesses all_script_test_harnesses_pass` runs this harness on the native lane)
test: cargo nextest run -p minimald host_ip_cohort_blocked_stance_rejects_udp_443
- lifecycle:
- crates/minimald/src/box_actor/host.rs: the `host_ip` launch path calls `CohortQuic443::join` with the box's resolved stance and moves every resident `host_ip` box into the blocked leaf when `blocked()` turns true; the stop path calls `leave` and moves them back to their own leaves when the last blocking member goes
- crates/minimald/src/box_runtime.rs: `command_in_session` hands the shim the cohort's blocked leaf instead of the box's own leaf while the cohort is blocked, and records the shim pid under the box id so the injected process goes home when the block lifts (widened 2026-10-25 per arch C1 on #2553: `min box exec` and injected hooks must not escape the stance)
- crates/minimald/src/box_runtime/tests.rs: the exec-placement tests live here, where `box_runtime.rs` keeps its tests (widened 2026-10-25)
test: cargo nextest run -p minimald host_ip_cohort_join_block_leave_drives_the_rule
produces: none
consumes: none
proof: A host_ip cohort with one blocked member sends no UDP 443 and gets ICMP port unreachable; when that member stops, the cohort sends UDP 443 again.
depends on:
- blocked by T31
Generated by Claude Code
Reacted by minimal-foundry
Metadata
Metadata
Assignees
Labels
kind:taskA task the plan skill rendered; the body carries ## TaskA task the plan skill rendered; the body carries ## Taskmodel:standardA standard model: work that needs care, or routine work that is largeA standard model: work that needs care, or routine work that is largesize:M200 to 500 net lines; one PR200 to 500 net lines; one PR
Activity
minimal-foundry commentedon Oct 25, 2026
Done. #2553 merged.
branch
agent/2534-enforce-the-host-ip-cohort-s-blocked-quic-stance· epic #1501 · PR #2553f75fb693Updated 2026-10-25T16:06:05.004Z.
norrietaylor commentedon Oct 25, 2026
Layers amended on 2026-10-25 (babysitter, stale-layers rule): the last run reported that the host-address table is rendered by
render_rulesetinscripts/install-host-classifier.sh, whichclassifier.rsonly embeds, and that the daemon holds no CAP_NET_ADMIN, so the flag cannot be an nft set it updates at runtime. The plan comment on #1501 and this issue now namescripts/install-host-classifier.shas a layer file (oneudp dport 443 rejectrule keyed on a new delegated blocked leaf under the boxes directory), and theclassifier.rsandhost.rsnotes say the daemon flips the stance by moving the cohort'shost_ipbox processes into and out of that leaf.needs-humanis removed so the runtime walks T53 again.Generated by Claude Code