8000 T84 — Record a box's runtime-admitted ports in the VM host daemon's table on the in-VM daemon's report, within the host-held grant · Issue #1897 · gominimal/minimal · GitHub
[go: up one dir, main page]

Skip to content
  • T84 — Record a box's runtime-admitted ports in the VM host daemon's table on the in-VM daemon's report, within the host-held grant #1897

    Closed

    Description

    @norrietaylor

    Task

    slice size difficulty model who estimated lines
    Expose a port from inside the box M needs care strongest an agent 660 (300 code, 360 tests)

    The VM host daemon holds each box's dynamic-ingress grant from the host-side registration and records a runtime port only inside it: an admit report outside the stance or range, past the per-row cap or over the per-row admit rate is refused, an ask-stance admit from the guest is refused until a host-recorded yes exists, a withdraw report is never refused by the cap or rate, a row's withdrawal clears its runtime ports, and each recorded admission has an owner-only host-side audit copy; the gate admits a runtime port only under the protocol it was recorded for. A host-side read of a box's row shows its switch address, egress allow-list and ports while the newest live box of that name lives, and no row once it is destroyed. The guest report door is inert until T94 binds and bridges it.

    Covers:

    • NET-138

    Layers:

    • schema:
      • crates/minimald-rpc/src/lib.rs: the box control protocol gains admit-port and withdraw-port verbs as a fixed, size-bounded message carrying only the row key, the port and the protocol, and a read-only row verb keyed by the box's name that returns the row's switch address, its derived egress allow-list and its declared and runtime-admitted ports, or says no row is held
      • cargo nextest run -p minimald-rpc box_control_admit_and_withdraw_round_trip
      • cargo nextest run -p minimald-rpc box_control_read_row_round_trip
    • vmhost:
      • crates/minvmd/src/box_registry.rs: a row holds the box's dynamic_ingress stance and allowed range from the host-side registration and its runtime-admitted ports keyed by port and protocol; an admit report is recorded only when the row exists, its stance is allow and the port is inside its range, and is refused otherwise; under ask, an admit report from the guest is refused with the typed reason that the ask yes must be host-recorded, until the host records it (T96); an admit report is also refused once the row holds the per-row cap of runtime ports (256) or exceeds the per-row admit rate (10 per second); a withdraw report is never refused by the cap or rate; a withdraw report removes the port; a row's withdrawal clears its runtime ports; a name resolves to the newest live box under it
      • crates/minvmd/src/control.rs: carries the admit-port and withdraw-port verbs' handler for the guest report door, enforced per door and driven directly in tests, but binds no guest report door at runtime — T94 binds it with the vsock bridge; writes an owner-only (0600) host-side audit copy for each recorded admission; serves the read-only row verb on the host control socket only, whose owner-only file mode is its access control, and refuses it on the guest report door; the verb changes no state; when no box under the name is live the read reports no row, never a destroyed box's last row
      • crates/minvmd/src/cmd/status.rs: minvmd status --row <name> --json prints the read-only row verb's reply
      • crates/minvmd/src/main.rs: minvmd status gains the --row <name> flag
      • crates/minvmd/src/net/egress_gate.rs: the gate's admitted set for a box is its declared ports plus the runtime ports recorded under the request's protocol, so a port admitted for udp never admits tcp
      • cargo nextest run -p minvmd admit_report_recorded_within_host_grant
      • cargo nextest run -p minvmd admit_report_refused_outside_range_or_under_deny
      • cargo nextest run -p minvmd ask_admit_from_guest_refused_without_host_record
      • cargo nextest run -p minvmd admit_report_refused_past_row_cap_or_rate
      • cargo nextest run -p minvmd runtime_port_withdrawn_on_report_and_on_row_withdrawal
      • cargo nextest run -p minvmd admitted_runtime_port_reaches_the_box_through_the_gate
      • cargo nextest run -p minvmd admitted_runtime_udp_port_does_not_admit_tcp
      • cargo nextest run -p minvmd read_row_reports_switch_address_allow_list_and_ports
      • cargo nextest run -p minvmd read_row_refused_on_guest_channel
      • cargo nextest run -p minvmd read_row_absent_for_destroyed_name
      • cargo nextest run -p minvmd row_by_name_resolves_newest_live_creation
      • cargo nextest run -p minvmd audit_copy_created_owner_only
    • cli:
      • crates/minimal/src/cmd/session.rs: the host-side registration carries the box's dynamic_ingress stance and allowed range, from the same create inputs the session record holds
      • cargo nextest run -p minimal registration_carries_dynamic_ingress_grant

    Waits on:

    Plan block
    ### T84 — Record a box's runtime-admitted ports in the VM host daemon's table on the in-VM daemon's report, within the host-held grant
      slice: S13
      kind: task
      covers: NET-138
      size: M
      est: 300 code, 360 tests
      executor: agent
      difficulty: needs care
      model: strongest
      diagnostics: the VM host daemon's log carries one line per admit or withdraw report with the box, the port, the protocol, the reporting source (expose, ask or listen) and the outcome, including each refusal against the host-held grant
      observability: one info line per recorded admission or withdrawal and one warn line per report refused against the host-held grant; minvmd appends an owner-only host-side copy of each recorded admission to its own audit log
      layers:
        - schema:
          - crates/minimald-rpc/src/lib.rs: the box control protocol gains admit-port and withdraw-port verbs as a fixed, size-bounded message carrying only the row key, the port and the protocol, and a read-only row verb keyed by the box's name that returns the row's switch address, its derived egress allow-list and its declared and runtime-admitted ports, or says no row is held
          test: cargo nextest run -p minimald-rpc box_control_admit_and_withdraw_round_trip
          test: cargo nextest run -p minimald-rpc box_control_read_row_round_trip
        - vmhost:
          - crates/minvmd/src/box_registry.rs: a row holds the box's dynamic_ingress stance and allowed range from the host-side registration and its runtime-admitted ports keyed by port and protocol; an admit report is recorded only when the row exists, its stance is allow and the port is inside its range, and is refused otherwise; under ask, an admit report from the guest is refused with the typed reason that the ask yes must be host-recorded, until the host records it (T96); an admit report is also refused once the row holds the per-row cap of runtime ports (256) or exceeds the per-row admit rate (10 per second); a withdraw report is never refused by the cap or rate; a withdraw report removes the port; a row's withdrawal clears its runtime ports; a name resolves to the newest live box under it
          - crates/minvmd/src/control.rs: carries the admit-port and withdraw-port verbs' handler for the guest report door, enforced per door and driven directly in tests, but binds no guest report door at runtime — T94 binds it with the vsock bridge; writes an owner-only (0600) host-side audit copy for each recorded admission; serves the read-only row verb on the host control socket only, whose owner-only file mode is its access control, and refuses it on the guest report door; the verb changes no state; when no box under the name is live the read reports no row, never a destroyed box's last row
          - crates/minvmd/src/cmd/status.rs: `minvmd status --row <name> --json` prints the read-only row verb's reply
          - crates/minvmd/src/main.rs: `minvmd status` gains the `--row <name>` flag
          - crates/minvmd/src/net/egress_gate.rs: the gate's admitted set for a box is its declared ports plus the runtime ports recorded under the request's protocol, so a port admitted for udp never admits tcp
          test: cargo nextest run -p minvmd admit_report_recorded_within_host_grant
          test: cargo nextest run -p minvmd admit_report_refused_outside_range_or_under_deny
          test: cargo nextest run -p minvmd ask_admit_from_guest_refused_without_host_record
          test: cargo nextest run -p minvmd admit_report_refused_past_row_cap_or_rate
          test: cargo nextest run -p minvmd runtime_port_withdrawn_on_report_and_on_row_withdrawal
          test: cargo nextest run -p minvmd admitted_runtime_port_reaches_the_box_through_the_gate
          test: cargo nextest run -p minvmd admitted_runtime_udp_port_does_not_admit_tcp
          test: cargo nextest run -p minvmd read_row_reports_switch_address_allow_list_and_ports
          test: cargo nextest run -p minvmd read_row_refused_on_guest_channel
          test: cargo nextest run -p minvmd read_row_absent_for_destroyed_name
          test: cargo nextest run -p minvmd row_by_name_resolves_newest_live_creation
          test: cargo nextest run -p minvmd audit_copy_created_owner_only
        - cli:
          - crates/minimal/src/cmd/session.rs: the host-side registration carries the box's dynamic_ingress stance and allowed range, from the same create inputs the session record holds
          test: cargo nextest run -p minimal registration_carries_dynamic_ingress_grant
      produces: none
      consumes:
        - crates/minvmd/src/box_registry.rs
        - crates/minvmd/src/control.rs
      proof: The VM host daemon holds each box's dynamic-ingress grant from the host-side registration and records a runtime port only inside it: an admit report outside the stance or range, past the per-row cap or over the per-row admit rate is refused, an ask-stance admit from the guest is refused until a host-recorded yes exists, a withdraw report is never refused by the cap or rate, a row's withdrawal clears its runtime ports, and each recorded admission has an owner-only host-side audit copy; the gate admits a runtime port only under the protocol it was recorded for. A host-side read of a box's row shows its switch address, egress allow-list and ports while the newest live box of that name lives, and no row once it is destroyed. The guest report door is inert until T94 binds and bridges it.
      depends on:
        - blocked by #1669
        - blocked by #1663
        - blocked by #1896
    

    Activity

    1. added
      kind:taskA task the plan skill rendered; the body carries ## Task
      size:L500 to 900 net lines; one PR, and the ceiling
      model:strongestThe strongest model available: unknown ground, or large work that needs care
      on Oct 3, 2026
    2. norrietaylor commented on Oct 3, 2026

      @norrietaylor
      MemberAuthor

      The spec text this task implements is in draft #1898, which amends NET-138: runtime ports are recorded only inside the host-held dynamic_ingress grant, and admit reports are bounded by a per-row cap and rate. Implement against the plan block. The spec amendment merges after this run, so it doesn't block dispatch. This task still waits on its task blockers: #1669, #1663 and #1896.

    3. norrietaylor commented on Oct 3, 2026

      @norrietaylor
      MemberAuthor

      Scope added from the T65 #1813 review: the gate-table half of the live-table requirement (after create, read the box's row and assert its switch address and derived egress allow-list; after destroy, the row is gone). T65's control protocol has no row read, so this task now adds a read-only row verb (host control socket only), minvmd status --row, and the e2e case vm_host_row_read_tracks_create_and_destroy.

    4. minimal-foundry commented on Oct 4, 2026

      @minimal-foundry
      Contributor

      Done. #1960 merged.

      branch agent/1897-record-a-box-s-runtime-admitted-ports-in-the-vm · epic #1437 · PR #1960

      Updated 2026-10-28T06:17:32.453Z.

    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

    Metadata

    Metadata

    Assignees

    No one assigned

      Labels

      kind:taskA task the plan skill rendered; the body carries ## Taskmodel:strongestThe strongest model available: unknown ground, or large work that needs caresize:L500 to 900 net lines; one PR, and the ceiling

      Type

      No type

      Projects

      No projects

        Milestone

        No milestone

        Relationships

        None yet

        Development

        No branches or pull requests

        Issue actions

      • 0