Skip to content

feat(minimald): *.localhost hostname registry, startup probe, and registration/deregistration lifecycle #500

Description

@gominimal-aw-bot

Task

Unit 3 is a single-task unit and collapses per ADR 0028. This task parents directly to tracking issue #478.

Re-scoped 2026-06-23 — DNS mechanism realigned to spec B5 (host-side egress proxy), superseding the systemd-resolved narrowing of #485/#500/#546. The sandbox (hakoniwa) and microVM (libkrun) runtimes have no systemd, and the networking spec (03-spec-networking/networking-with-diagrams.md) never required it: R5 "PTask hostnames in host DNS" → B5 "*.localhost + host-side proxy (or one-time /etc/resolver)", tagged "Needs decision (DNS) — zero-root path exists". Resolution + routing are host-side; the runtimes never resolve anything. PR #546 is held (do-not-merge) pending this re-scope; salvage its in-memory registry, drop its systemd-resolved probe.

repo: gominimal/minimal
spec: docs/specs/03-spec-networking/03-spec-networking.md
requirements: R3.1, R3.2, R3.3, R3.5, R3.6 (R3.4 systemd-resolved probe is removed by this re-scope — replaced by an egress-proxy reachability check; see below)

files in scope:

  • crates/minimald/src/net/dns.rs (salvage from feat(minimald): Unit 3 DNS — B5 host-side egress proxy + .min.internal hostname registry #546) — in-memory hostname registry; register(session_name, host_id) / deregister(session_name) with structured tracing events (R3.5); hostname format <session-name>.<host-id>.min.internal (TLD decided 2026-06-23 — Mike's preference; under B5 the TLD is a free label since the proxy routes by Host: header, so .min.internal is semantically honest for internal PTask services and the .localhost loopback-fallback is not relied on); register HostNet PTasks → 127.0.0.1, OwnIp PTasks → the gvproxy switch IP (R3.6). Remove the resolver write path (systemd-resolved D-Bus / resolvectl) — no host resolver is written. OwnIp switch-IP registration depends on the feat(minimald,sandbox2): wire minimald::net switch into the live OwnIp session-launch path (R1.5) #542 live-switch wiring (now merged via feat(minimald,sandbox2): wire net switch into live OwnIp launch path #547).
  • crates/minimald/src/net/proxy.rs (new) — the B5 host-side egress proxy. A forward/CONNECT proxy that routes a request by its Host: header (or CONNECT authority) to the target PTask's address via the registry: HostNet127.0.0.1:<port>, OwnIp → the PTask switch IP through the gvproxy switch (reuse the feat(minvmd): implement DM1 gvproxy tap relay for OwnIp PTasks #540 relay path). The host resolver is never consulted*.min.internal is an opaque label the proxy maps internally, so the no-systemd runtimes and the TLD choice are both irrelevant to correctness. Clients reach the proxy via proxy-env / PAC (HTTP(S)_PROXY), the zero-root cross-platform path the spec asserts ("zero-root path exists"); /etc/resolver is the macOS root-write alternative, not implemented here.
  • crates/minimald/src/lib.rs (or main.rs) — replace the systemd-resolved startup probe with an egress-proxy reachability check: on daemon start, bind the proxy listener; on bind failure → tracing::warn!(component = "dns-proxy", status = "unavailable", remedy = "<port in use / set HTTP_PROXY>"). (Supersedes R3.4's systemd-resolved warn.)
  • crates/minimald/src/session.rs — call dns::register at session launch (HostNet + OwnIp), dns::deregister on exit.
  • (deferred) crates/minimal2/src/client.rs hostname/TCP connect (UC2c, R3.2) — UDS-only client; TCP/hostname transport belongs with the DM5 network-listener work in Unit 4.
  • docs/specs/03-spec-networking/03-spec-networking.md — amend R3.1 hostname format to <session-name>.<host-id>.min.internal; close Open Question 1 with the B5 host-side-egress-proxy decision (proxy routes by Host:/authority; resolution stays host-side; systemd not required), explicitly superseding spike spike: DNS hostname registration works rootlessly on target Linux distributions #485's systemd-resolved finding.

proof artifacts:

  • Test: registry/proxy routing contract. Register a HostNet PTask "myservice"/host-id "dev"; drive a request with Host: myservice.dev.min.internal through the proxy and assert it routes to the registered target. After deregister, assert the proxy returns a not-found (no stale route). No getaddrinfo/host-resolver dependency — asserts the proxy contract directly. Fails on base (no registry/proxy).
  • Test: OwnIp routing — a registered OwnIp PTask routes through the gvproxy switch relay to its switch IP (may reuse / extend the feat(minvmd): implement DM1 gvproxy tap relay for OwnIp PTasks #540 relay test; the privileged netns leg defers to ci-netns.yml). Fails on base.
  • Test: proxy-listener bind-failure emits the component = "dns-proxy" tracing::warn! (supersedes the R3.4 systemd-resolved probe test). Fails on base.

verification:

  • cargo build --locked
  • cargo test -p minimald --locked
  • cargo fmt --all -- --check
  • cargo clippy -p minimald --all-targets -- -D warnings

depends on:

Related to #478

Generated by sdd-triage-materialize for issue #478 ·

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions