8000 T111 — Host-side commands find a box on any VM, a stopped VM included, and attach errors stay on screen by minimal-foundry[bot] · Pull Request #2811 · gominimal/minimal · GitHub
[go: up one dir, main page]

Skip to content

T111 — Host-side commands find a box on any VM, a stopped VM included, and attach errors stay on screen - #2811

Merged
norrietaylor merged 15 commits into
mainfrom
agent/2705-host-side-commands-find-a-box-on-any-vm-a-stoppe
Nov 1, 2026
Merged

norrietaylor merged 15 commits into
mainfrom
agent/2705-host-side-commands-find-a-box-on-any-vm-a-stoppe

Conversation

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

T111 — Host-side commands find a box on any VM, a stopped VM included, and attach errors stay on screen

slice: S17
kind: task
covers: NET-058, NET-152, NET-148
size: L
est: 380 code, 420 tests
executor: agent
difficulty: needs care
model: strongest
diagnostics: what a person reads is the error itself: a box on no running VM names --vm, a box on a stopped VM names that VM and the command that starts it, and a failed attach leaves its error on screen; min ls shows the stopped VM's boxes as stopped
observability: the existing debug line box name resolved to a VM gains the outcome on a stopped VM with the VM's name, and one debug line per stopped VM read records how many boxes its persisted records hold
depends on:
- blocked by #2696
layers:
- resolution:
- crates/minimal/src/attach.rs: builds on open pull request #2626, which already resolves a box's VM for exec, task run and min net forward; resolve_box_vm also reads each stopped VM's persisted box records, and answers a box found only there as on a stopped VM; the attach path restores the terminal (the unwind and the attach-start termios) before it prints any error that ends min session attach, so the error stays on screen after exit 1
- crates/minimal/src/cmd/session.rs: from #2626, min session exec and min session run resolve the VM from the box name
- crates/minimal/src/cmd/net.rs: from #2626, min net forward resolves the VM from the box name
- crates/minimal/src/cmd/boxes/attach.rs: from #2626; prints the resolution's error only after the terminal is restored
- crates/minimal/src/cmd/boxes/policy.rs: min session policy <box> resolves the VM from the box name
- crates/minimal/src/cmd/boxes/lifecycle.rs: min stop <box> and min session destroy <box> resolve the VM from the box name
- crates/minimal/src/cmd/mod.rs: the not-found error for a box no running VM holds reads error: no running VM has a box named 'beta'. A box on another VM is named with --vm, for example: min --vm <vm> session policy beta, using the command the user ran in place of session policy; a box held only by a stopped VM reads error: box 'beta' is on VM 'alpha', which is stopped. Start it with: min --vm alpha session attach beta; the implementer confirms against crates/minimal/src/autospawn.rs that the named command starts a stopped VM and pins the text in the test
test: cargo nextest run -p minimal box_name_resolves_vm_without_flag
test: cargo nextest run -p minimal unknown_box_names_vm_flag
test: cargo nextest run -p minimal box_on_stopped_vm_names_start_command
test: cargo nextest run -p minimal attach_error_printed_after_terminal_restore
- stopped-vm-records:
- crates/minvmd/src/box_registry.rs: a read-only accessor over a VM state directory's persisted creations file that returns each box's name and id without a running daemon; a file of another version, or one that does not parse, reads as no boxes and is never written
test: cargo nextest run -p minvmd persisted_box_names_read_without_a_daemon
- listing:
- crates/minimal/src/cmd/list.rs: min ls lists the boxes of every VM the user created; a stopped VM's boxes come from its persisted records, each row's STATUS reads stopped and its VM cell reads alpha (stopped); --json carries them with "status": "stopped" and "vm_running": false; the table rule extends under the VM column
- crates/minimal/src/tests.rs: pins both refusal texts, the stopped rows in the table and in --json, and that an attach error prints after the restore sequence
test: cargo nextest run -p minimal ls_lists_boxes_on_stopped_vm
produces: none
consumes: none
proof: With two VMs, min session policy beta, min net forward beta 8080:3000, exec and stop find beta on its VM without --vm; after min --vm alpha stop, min ls lists alpha's boxes as stopped and min session attach beta says which VM to start and how, with the error still on screen.

Proof

On a host with two VMs, min session policy beta, min net forward beta 8080:3000, min session exec beta ..., min session run beta <task>, min session attach beta and min session destroy beta find beta on its VM without --vm. A name that no running VM holds gets: error: no running VM has a box named 'beta'. A box on another VM is named with --vm, for example: min --vm <vm> session policy beta, with the command the user ran in place of session policy. After min --vm alpha stop, min ls lists alpha's boxes with STATUS stopped and the VM cell alpha (stopped), and the rule line now runs under the VM column. min ls --json gives those boxes "status": "stopped" and "vm_running": false. min session attach beta then prints error: box 'beta' is on VM 'alpha', which is stopped. Start it with: min --vm alpha session attach beta. This error comes before the attach touches the terminal, so it stays on screen. min stop <box> is not delivered: see notes.

Notes from the agent: 1. min stop takes no box argument. It stops the selected VM, and StopArgs in crates/minimal/src/cli.rs has no box field. cli.rs is outside the layers, so min stop <box> does not resolve a VM from a box name. min session destroy <box> does. The proof's stop part is true only as min --vm alpha stop, which works already. A follow-up task that adds a box argument to min stop must name cli.rs. Also, cmd_destroy and cmd_session_policy (text) live in cmd/session.rs, not in cmd/boxes/lifecycle.rs or cmd/boxes/policy.rs. So lifecycle.rs needed no change. policy.rs changed only for min session policy -o json.
2. Out of scope: crates/minimal/tests/cli.rs. VmListing is a public struct with a new running field, and that file builds it with struct literals at three sites. The only change there is running: true at each site.
3. Confirmed against autospawn.rs: --vm alpha is published before path resolution (cli.rs publish_vm_name). cmd_attach calls `e…[truncated]

Residuals

  • #2816: exit codes 4 and 2 for the new refusals (failure_exit_code in crates/minimal/src/main.rs). Box CLI work, by the same ruling. This PR keeps exit 1, as main does.
  • #2815: min stop <box>. min stop takes no box name (StopArgs in crates/minimal/src/cli.rs), so the proof's stop leg is not delivered here. By the person's ruling of 2026-10-31, this belongs to the box CLI work, not to NET.

Tests

line exit tail
cargo nextest run -p minimal box_name_resolves_vm_without_flag 0 Applying loadouts: default Running task runtime-implement-test-0 in session task-runtime-implement-test-0-56ca... Compiling paths v0.0.1 (/workbench/crates/paths) Compiling ot v0.0.1 (/workbench/crates/ot) Compiling args v0.0.1 (/workbench/crates/args) Compiling client-config v0.0.1 (/wo
cargo nextest run -p minimal unknown_box_names_vm_flag 0 Applying loadouts: default Running task runtime-implement-test-1 in session task-runtime-implement-test-1-5827... 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.
cargo nextest run -p minimal box_on_stopped_vm_names_start_command 0 Applying loadouts: default Running task runtime-implement-test-2 in session task-runtime-implement-test-2-f21a... 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.
cargo nextest run -p minimal attach_error_printed_after_terminal_restore 0 Applying loadouts: default Running task runtime-implement-test-3 in session task-runtime-implement-test-3-d100... 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.
cargo nextest run -p minvmd persisted_box_names_read_without_a_daemon 0 Applying loadouts: default Running task runtime-implement-test-4 in session task-runtime-implement-test-4-84cb... Compiling paths v0.0.1 (/workbench/crates/paths) Compiling ot v0.0.1 (/workbench/crates/ot) Compiling args v0.0.1 (/workbench/crates/args) Compiling client-config v0.0.1 (/wo
cargo nextest run -p minimal ls_lists_boxes_on_stopped_vm 0 Applying loadouts: default Running task runtime-implement-test-5 in session task-runtime-implement-test-5-8f98... 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 100 under rustc 1.99.0, which the repository does not pin (1.99.1 in rust-toolchain.toml); the PR is not a draft on that alone — CI, which honours the pin, is the gate.

h",
                "parent_span_id": "4453675f089861ae",
                "span_id": "98d4efc7239e3d6c",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "session.message",
            fields: {
                "kind": "GetDenyAllOptOut",
                "parent_span_id": "4453675f089861ae",
                "span_id": "61e5f3b2ffcbf309",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "session.message",
            fields: {
                "kind": "GetPaths",
                "parent_span_id": "4453675f089861ae",
                "span_id": "62bf3d76d29618d6",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "sessions.manager.message",
            fields: {
                "kind": "GetRecord",
                "parent_span_id": "4453675f089861ae",
                "queued_behind": "0",
                "span_id": "463297993fb45d3b",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "sessions.manager.message",
            fields: {
                "kind": "DeleteSession",
                "parent_span_id": "4453675f089861ae",
                "queued_behind": "0",
                "span_id": "2619d5d6e4a08ad5",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "session.message",
            fields: {
                "kind": "Destroy",
                "parent_span_id": "2619d5d6e4a08ad5",
                "span_id": "13b93248126132ff",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
    ]
    note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

  Cancelling due to test failure: 3 tests still running
        PASS [   2.220s] ( 840/1489) minvmd box_registry::tests::a_reattributed_box_keeps_its_row
        PASS [   1.015s] ( 841/1489) minvmd box_registry::tests::a_registry_file_holding_one_loopback_twice_keeps_the_standing_box
        PASS [   5.011s] ( 842/1489) minvmd box_registry::tests::a_registration_refused_for_a_held_address_spends_no_switch_address
────────────
     Summary [  39.182s] 842/1489 tests run: 841 passed, 1 failed, 2 skipped
        FAIL [   3.256s] ( 839/1489) minimal::otel_cli exec_run_attach_and_task_run_share_the_commands_trace
warning: 647/1489 tests were not run due to test failure (run with --no-fail-fast to run all tests, or run with --max-fail)
error: test run failed

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/minimal/src/tests.rs

Out of scope

These files are outside the task's layers:, so this PR is a draft:

  • crates/minimal/tests/cli.rs

Closes #2705

A stopped VM's boxes can now be named and listed by the CLI. The read
never writes or sets aside a file it cannot use.
Policy and destroy resolve the box's VM from its name. A box no running
VM holds names --vm, and a box on a stopped VM names the command that
starts it. min ls lists a stopped VM's boxes as stopped. A relay failure
writes the unwind before the attach error prints.
Record the new connect sites in the daemon connection inventory.
@coderabbitai
coderabbitai Bot commented Oct 31, 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: e8d40bdf-5eed-4396-8748-29150a49c0ca

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

@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 review of 375f68a against T111 (#2705).

  • A box name now picks its VM for attach (resolve_box_on_another_vm), exec, run and min net forward (resolve_box_vm), and min session policy and min session destroy (resolve_box_on_any_vm).
  • Both refusals match the plan text. box_on_stopped_vm documents why min --vm <vm> session attach <box> starts the stopped VM (ensure_daemon → autospawn::ensure_minvmd_running).
  • min ls lists a stopped VM's boxes from its persisted records.
  • Each named test exists.

Notes:

  • The plan names min stop <box>, but min stop takes no box name (StopArgs has only --force), so lifecycle.rs needs no change. That item of the plan is void.
  • The out-of-layer crates/minimal/tests/cli.rs change is three running: true field inits that the new listing field forces.

@norrietaylor
norrietaylor marked this pull request as ready for review October 31, 2026 20:07
@norrietaylor
norrietaylor requested a review from a team as a code owner October 31, 2026 20:07
@minimal-foundry
minimal-foundry Bot commented Oct 31, 2026 •
Copy link
Copy Markdown
Contributor Author

Approved: every review thread resolved at f721ac4f1039.

@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/minimal/src/cmd/boxes/policy.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 change resolves a box's VM from its name for exec, run, net forward, policy, destroy and attach, and min ls lists a stopped VM's boxes. One case does not conform. A non-selected running VM that owns the name silently wins over a stopped VM that also holds it. architecture.md line 389 says a name that matches on more than one host is an error listing the candidates. C1 makes resolve_box_vm return that error. C2 files the undelivered min stop <box> part of NET-058 as an issue.

Ruled at 375f68a against gominimal/arch@8640f85e193d by claude-opus-5-5.

Comment thread crates/minimal/src/attach.rs Resolved
Comment thread crates/minimal/src/attach.rs Resolved
Comment thread crates/minimal/src/tests.rs Resolved
@norrietaylor
Copy link
Copy Markdown
Member

/revise Two items on 375f68a, from the arch-review check and minimal-review.

  1. Arch C1 (crates/minimal/src/attach.rs, resolve_box_vm). When owners has one entry and stopped_holders is not empty, return the ambiguity error the _ => arm returns. It lists the running owner and every stopped holder, marks each stopped VM as stopped, and names --vm. Do not return Ok(Some(..)) in that case. Update the resolve_box_vm doc comment ("a name a running VM owns wins over a stopped VM's record"). In crates/minimal/src/tests.rs, change the last block of box_on_stopped_vm_names_start_command (now assert_eq!(resolved.vm, "default")) to expect that error. When the selected VM owns the name, nothing changes.
  2. JSON failure code (crates/minimal/src/cmd/boxes/policy.rs:956, box_policy_json_inputs). The ambiguity errors from resolve_box_vm are plain anyhow errors, so -o json reports them as DaemonUnreachable. Give them a typed marker in attach.rs and map them here to SessionNotFound, or to a code that says the name is ambiguous if one exists. Add a test.
  3. While there: several comments cite NET-148 for the listing, which is NET-152 (VmListing::running, stopped_vm_listing, the listings_across_vms doc, format_ls_across_vms_on, the ls_lists_boxes_on_stopped_vm doc). Fix the ids.

Arch C2 (min stop <box>) is filed as #2815. Make no code change for it.

@minimal-foundry
Copy link
Copy Markdown
Contributor Author

That /revise is held, not dropped. A coder is already running on #2705. Your note is kept and goes into the next round here, which starts when that coder finishes.

Nothing to type again: the command gets a rocket when its round starts, or a refusal that names the reason. No round was counted for it yet.

A name that more than one VM holds now fails with AmbiguousBoxName.
min session policy -o json maps it to SessionNotFound, not
DaemonUnreachable.
@minimal-foundry minimal-foundry Bot left a comment
Copy link
Copy Markdown
Contributor Author
8BD0

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/minimal/src/cmd/boxes/attach.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 · 3 conditions · the full ruling

The resolution across VMs follows the Addressing rule in most cases, but one new case picks a VM when it must refuse. In resolve_box_vm, a stopped record on a running VM wins over a stopped VM that holds the same name. Line 389 makes that an error that lists the candidates (C3). Because min session destroy uses this path, the wrong pick can destroy the wrong box. The new typed refusals exit 1, but the Exit codes table gives 4 for not found and 2 for ambiguous (C1). The min stop <box> leg is not delivered and the PR body links no issue for it (C2).

Ruled at 87dda39 against gominimal/arch@8640f85e193d by claude-opus-5-5.

Comment thread crates/minimal/src/attach.rs Resolved
Comment thread crates/minimal/src/cmd/mod.rs Resolved
Comment thread crates/minimal/src/cmd/mod.rs Resolved
Comment thread crates/minimal/src/cmd/session.rs Resolved
@minimal-foundry
Copy link
Copy Markdown
Contributor Author

Round 1 of 10 on the runtime's review findings, pushed as 87dda392f38a.

line exit tail
cargo nextest run -p minimal box_name_resolves_vm_without_flag 0 Applying loadouts: default Running task runtime-implement-test-0 in session task-runtime-implement-test-0-6289... Compiling paths v0.0.1 (/workbench/crates/paths) Compiling ot v0.0.1 (/workbench/crates/ot) Compiling args v0.0.1 (/workbench/crates/args) Compiling client-config v0.0.1 (/wo
cargo nextest run -p minimal unknown_box_names_vm_flag 0 Applying loadouts: default Running task runtime-implement-test-1 in session task-runtime-implement-test-1-14ac... 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.
cargo nextest run -p minimal box_on_stopped_vm_names_start_command 0 Applying loadouts: default Running task runtime-implement-test-2 in session task-runtime-implement-test-2-ab44... 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.
cargo nextest run -p minimal attach_error_printed_after_terminal_restore 0 Applying loadouts: default Running task runtime-implement-test-3 in session task-runtime-implement-test-3-fcc1... 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.
cargo nextest run -p minvmd persisted_box_names_read_without_a_daemon 0 Applying loadouts: default Running task runtime-implement-test-4 in session task-runtime-implement-test-4-6a8a... Compiling paths v0.0.1 (/workbench/crates/paths) Compiling ot v0.0.1 (/workbench/crates/ot) Compiling args v0.0.1 (/workbench/crates/args) Compiling client-config v0.0.1 (/wo
cargo nextest run -p minimal ls_lists_boxes_on_stopped_vm 0 Applying loadouts: default Running task runtime-implement-test-5 in session task-runtime-implement-test-5-03e0... 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 100 under rustc 1.99.0, which the repository does not pin (1.99.1 in rust-toolchain.toml); the PR is not a draft on that alone — CI, which honours the pin, is the gate.

h",
                "parent_span_id": "a34ad20ca3fe1bc4",
                "span_id": "69bcdbd25427fa52",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "session.message",
            fields: {
                "kind": "GetDenyAllOptOut",
                "parent_span_id": "a34ad20ca3fe1bc4",
                "span_id": "d50cf65e6446f780",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "session.message",
            fields: {
                "kind": "GetPaths",
                "parent_span_id": "a34ad20ca3fe1bc4",
                "span_id": "ce965fe82ed1eda7",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "sessions.manager.message",
            fields: {
                "kind": "GetRecord",
                "parent_span_id": "a34ad20ca3fe1bc4",
                "queued_behind": "0",
                "span_id": "ff2f1f90b1f4d27a",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "sessions.manager.message",
            fields: {
                "kind": "DeleteSession",
                "parent_span_id": "a34ad20ca3fe1bc4",
                "queued_behind": "0",
                "span_id": "90c3b6767b1b4a92",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "session.message",
            fields: {
                "kind": "Destroy",
                "parent_span_id": "90c3b6767b1b4a92",
                "span_id": "2e1633245f140138",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
    ]
    note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

  Cancelling due to test failure: 3 tests still running
        PASS [   2.223s] ( 840/1489) minvmd box_registry::tests::a_reattributed_box_keeps_its_row
        PASS [   1.024s] ( 841/1489) minvmd box_registry::tests::a_registry_file_holding_one_loopback_twice_keeps_the_standing_box
        PASS [   5.018s] ( 842/1489) minvmd box_registry::tests::a_registration_refused_for_a_held_address_spends_no_switch_address
────────────
     Summary [  47.102s] 842/1489 tests run: 841 passed, 1 failed, 2 skipped
        FAIL [   3.573s] ( 839/1489) minimal::otel_cli exec_run_attach_and_task_run_share_the_commands_trace
warning: 647/1489 tests were not run due to test failure (run with --no-fail-fast to run all tests, or run with --max-fail)
error: test run failed

Outside the task's layers::

  • crates/minimal/tests/cli.rs

Converted to a draft: something above needs a person before review.

Review threads the coder judged:

  • 👍 valid — PRRT_kwDOPdfcxM6yUOag: Both ambiguity errors in resolve_box_vm are now the typed AmbiguousBoxName. The policy JSON path maps it to SessionNotFound. A test pins the type and the text. (not posted on the thread: not an open thread on the pull request)

With two VMs, min session policy beta, min net forward beta 8080:3000, exec and stop find beta on its VM without --vm. After min --vm alpha stop, min ls lists alpha's boxes as stopped, and min session attach beta names the VM to start and the command that starts it, with the error still on screen. This round: a box name that several VMs hold now reports SessionNotFound in min session policy -o json, not DaemonUnreachable.

Notes from the agent: Revise round 1. Added the typed error AmbiguousBoxName in cmd/mod.rs. resolve_box_vm uses it for both ambiguity errors (several running VMs, several stopped VMs). The message text did not change. box_policy_json_inputs maps it to SessionNotFound. box_on_stopped_vm_names_start_command now also pins the stopped-VM ambiguity text and its type. I did not run just clippy-strict.

@minimal-foundry
minimal-foundry Bot marked this pull request as draft October 31, 2026 20:48
A running owner and a stopped VM's record of the same name are now an
ambiguity that lists both VMs and names --vm. The listing comments
cite NET-152.
@minimal-foundry
Copy link
Copy Markdown
Contributor Author

Round 2 of 10 on a /revise note, pushed as 0ca0427448ba.

line exit tail
cargo nextest run -p minimal box_name_resolves_vm_without_flag 0 Applying loadouts: default Running task runtime-implement-test-0 in session task-runtime-implement-test-0-d754... Compiling paths v0.0.1 (/workbench/crates/paths) Compiling ot v0.0.1 (/workbench/crates/ot) Compiling args v0.0.1 (/workbench/crates/args) Compiling client-config v0.0.1 (/wo
cargo nextest run -p minimal unknown_box_names_vm_flag 0 Applying loadouts: default Running task runtime-implement-test-1 in session task-runtime-implement-test-1-c8bd... 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.
cargo nextest run -p minimal box_on_stopped_vm_names_start_command 0 Applying loadouts: default Running task runtime-implement-test-2 in session task-runtime-implement-test-2-452f... 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.
cargo nextest run -p minimal attach_error_printed_after_terminal_restore 0 Applying loadouts: default Running task runtime-implement-test-3 in session task-runtime-implement-test-3-1887... 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.
cargo nextest run -p minvmd persisted_box_names_read_without_a_daemon 0 Applying loadouts: default Running task runtime-implement-test-4 in session task-runtime-implement-test-4-4ee8... Compiling paths v0.0.1 (/workbench/crates/paths) Compiling args v0.0.1 (/workbench/crates/args) Compiling ot v0.0.1 (/workbench/crates/ot) Compiling client-config v0.0.1 (/wo
cargo nextest run -p minimal ls_lists_boxes_on_stopped_vm 0 Applying loadouts: default Running task runtime-implement-test-5 in session task-runtime-implement-test-5-ed3e... 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 100 under rustc 1.99.0, which the repository does not pin (1.99.1 in rust-toolchain.toml); the PR is not a draft on that alone — CI, which honours the pin, is the gate.

kind": "GetNetSwitch",
                "parent_span_id": "df16bfcc5edb8796",
                "span_id": "691ddc80c7af0f44",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "session.message",
            fields: {
                "kind": "GetDenyAllOptOut",
                "parent_span_id": "df16bfcc5edb8796",
                "span_id": "3e6fad085516019b",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "session.message",
            fields: {
                "kind": "GetPaths",
                "parent_span_id": "df16bfcc5edb8796",
                "span_id": "e3126fc08d1ed263",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "sessions.manager.message",
            fields: {
                "kind": "GetRecord",
                "parent_span_id": "df16bfcc5edb8796",
                "queued_behind": "0",
                "span_id": "93339aa59f4d16ce",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "sessions.manager.message",
            fields: {
                "kind": "DeleteSession",
                "parent_span_id": "df16bfcc5edb8796",
                "queued_behind": "0",
                "span_id": "69edea699e1ca966",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "session.message",
            fields: {
                "kind": "Destroy",
                "parent_span_id": "69edea699e1ca966",
                "span_id": "3d6660034fa419b9",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
    ]
    note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

  Cancelling due to test failure: 3 tests still running
        PASS [   3.019s] ( 839/1490) minvmd box_registry::tests::a_closed_shuttle_detaches_rows_until_the_grace
        PASS [   2.218s] ( 840/1490) minvmd box_registry::tests::a_reattributed_box_keeps_its_row
        PASS [   5.011s] ( 841/1490) minvmd box_registry::tests::a_registration_refused_for_a_held_address_spends_no_switch_address
────────────
     Summary [  38.937s] 841/1490 tests run: 840 passed, 1 failed, 2 skipped
        FAIL [   2.973s] ( 838/1490) minimal::otel_cli exec_run_attach_and_task_run_share_the_commands_trace
warning: 649/1490 tests were not run due to test failure (run with --no-fail-fast to run all tests, or run with --max-fail)
error: test run failed

Outside the task's layers::

  • crates/minimal/tests/cli.rs

Converted to a draft: something above needs a person before review.

Review threads the coder judged:

  • 👍 valid — crates/minimal/src/attach.rs: One running owner plus any stopped holder now returns AmbiguousBoxName that lists every VM, marks each stopped one, and names --vm.
  • 👍 valid — crates/minimal/src/attach.rs: The doc comment now says a running owner and a stopped holder of the same name make an ambiguity error that lists both VMs.
  • 👍 valid — crates/minimal/src/tests.rs: The last block now expects the ambiguity error listing default and gamma (stopped), typed AmbiguousBoxName.
  • 👎 invalid — crates/minimal/src/cmd/boxes/attach.rs:480: The premise holds: Relay::start fails before it touches the terminal, so the guard writes an unneeded unwind. The fix is outside this task's layers. It needs crates/minimal-client/src/tty_relay.rs to mark Relay::start failures as not taken, so I left it as a residual.
  • 👍 valid — crates/minimal/src/attach.rs: Same change as C1: a running VM's record (any status) plus a stopped holder now returns AmbiguousBoxName naming every VM and --vm.
  • 👎 invalid — crates/minimal/src/cmd/mod.rs:577: The exit code mapping lives in failure_exit_code in crates/minimal/src/main.rs, which is outside this task's layers. It needs an issue, and I cannot open one from this session.
  • 👎 invalid — crates/minimal/src/cmd/mod.rs:591: Mapping AmbiguousBoxName to exit 2 needs failure_exit_code in crates/minimal/src/main.rs, which is outside this task's layers. It needs an issue.
  • 👎 invalid — crates/minimal/src/cmd/session.rs:513: Already done: the residual for min stop is filed as min stop <box>: stop the VM that owns a named box (box CLI) #2815. The revise note asks for no code change for it.

With two VMs, min session policy beta, min net forward beta 8080:3000, exec and session destroy find beta on its VM without --vm. After min --vm alpha stop, min ls lists alpha's boxes as stopped, and min session attach beta names the VM to start and the command that starts it. The error stays on screen. A name that a running VM and a stopped VM both hold is now refused. The refusal lists both VMs, marks the stopped one, and names --vm.

Notes from the agent: Item 1: resolve_box_vm now returns AmbiguousBoxName when one running VM owns the name and a stopped VM's records hold it. The text is "box name 'api' exists on more than one VM (default, gamma (stopped)); name the one you mean with --vm". The several-owners arm uses the same text and also lists stopped holders. The test also pins that the selected VM's own box still resolves through resolve_box_on_any_vm. Item 2 was already on the branch in 87dda39 (policy.rs maps AmbiguousBoxName to SessionNotFound, and box_on_stopped_vm_names_start_command asserts the typed marker). This round made no further change for it. Item 3: list.rs and the ls_lists_boxes_on_stopped_vm doc now cite NET-152. The NET-148 citations in crates/minvmd/src/box_registry.rs were not in the note and stay. Residuals for a person to file: exit codes 4 (BoxNotFound) and 2 (AmbiguousBoxName) need crates/minimal/src/main.rs failure_exit_code, which is outside the layers. A Relay::start failure needs a not-taken marker in crates/minimal-client/src/tty_relay.rs, which is outside the layers. I have no credential to open issues. just clippy-strict was not run.

@norrietaylor
Copy link
Copy Markdown
Member

/revise One item on 0ca0427, arch C3 from the review of 87dda39.

crates/minimal/src/attach.rs, resolve_box_vm: a running VM that owns the name now always ties with a stopped VM that holds it, and the (_, stopped) arm refuses as ambiguous. Narrow that refusal. When exactly one running VM owns the name and stopped_holders is not empty:

  • if the owner's record.status is boxes::BoxState::Active, return Ok(Some(resolved)), because a running box wins;
  • otherwise return the AmbiguousBoxName error that lists the owner's VM and every stopped holder (each marked stopped) and names --vm.

Update the doc comment to say "a running box wins". In box_on_stopped_vm_names_start_command (crates/minimal/src/tests.rs), cover both cases: an active box on the running VM plus a stopped VM holding the name resolves to the running VM, and a stopped record on the running VM plus a stopped VM holding the name gives AmbiguousBoxName.

Do not edit the PR body. It already lists #2815 and #2816 as box CLI residuals.

A running VM that owns the name with an active box resolves there even
when a stopped VM's records hold the same name. A non-active owner plus a
stopped holder still refuses as ambiguous and names --vm.
@minimal-foundry
Copy link
Copy Markdown
Contributor Author

Round 3 of 10 on a /revise note, pushed as 80adcd99713e.

line exit tail
cargo nextest run -p minimal box_name_resolves_vm_without_flag 0 Applying loadouts: default Running task runtime-implement-test-0 in session task-runtime-implement-test-0-f03e... Compiling paths v0.0.1 (/workbench/crates/paths) Compiling ot v0.0.1 (/workbench/crates/ot) Compiling args v0.0.1 (/workbench/crates/args) Compiling client-config v0.0.1 (/wo
cargo nextest run -p minimal unknown_box_names_vm_flag 0 Applying loadouts: default Running task runtime-implement-test-1 in session task-runtime-implement-test-1-707b... 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.
cargo nextest run -p minimal box_on_stopped_vm_names_start_command 0 Applying loadouts: default Running task runtime-implement-test-2 in session task-runtime-implement-test-2-ca3b... 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.
cargo nextest run -p minimal attach_error_printed_after_terminal_restore 0 Applying loadouts: default Running task runtime-implement-test-3 in session task-runtime-implement-test-3-21ad... 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.
cargo nextest run -p minvmd persisted_box_names_read_without_a_daemon 0 Compiling google-cloud-wkt v1.9.0 Compiling unicode-xid v0.2.6 Compiling http-body v1.1.0 Compiling lalrpop v0.23.1 Compiling http-body-util v0.1.4 Compiling google-cloud-rpc v1.6.0 Compiling malachite-base v0.9.2 Compiling tokio-util v0.7.20 Compiling tokio-rustls v0.26.5
cargo nextest run -p minimal ls_lists_boxes_on_stopped_vm 0 Applying loadouts: default Running task runtime-implement-test-5 in session task-runtime-implement-test-5-140e... 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 100 under rustc 1.99.0, which the repository does not pin (1.99.1 in rust-toolchain.toml); the PR is not a draft on that alone — CI, which honours the pin, is the gate.

kind": "GetNetSwitch",
                "parent_span_id": "aa5732e2ee8a58ff",
                "span_id": "d8b411f8947b4db4",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "session.message",
            fields: {
                "kind": "GetDenyAllOptOut",
                "parent_span_id": "aa5732e2ee8a58ff",
                "span_id": "48cc3d0b1b5f8778",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "session.message",
            fields: {
                "kind": "GetPaths",
                "parent_span_id": "aa5732e2ee8a58ff",
                "span_id": "68b1b40bd8c8756b",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "sessions.manager.message",
            fields: {
                "kind": "GetRecord",
                "parent_span_id": "aa5732e2ee8a58ff",
                "queued_behind": "0",
                "span_id": "73f6924801eec64b",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "sessions.manager.message",
            fields: {
                "kind": "DeleteSession",
                "parent_span_id": "aa5732e2ee8a58ff",
                "queued_behind": "0",
                "span_id": "a6faf00f239d1a5d",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "session.message",
            fields: {
                "kind": "Destroy",
                "parent_span_id": "a6faf00f239d1a5d",
                "span_id": "d274acd95b9a231e",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
    ]
    note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

  Cancelling due to test failure: 3 tests still running
        PASS [   3.017s] ( 839/1490) minvmd box_registry::tests::a_closed_shuttle_detaches_rows_until_the_grace
        PASS [   2.219s] ( 840/1490) minvmd box_registry::tests::a_reattributed_box_keeps_its_row
        PASS [   5.008s] ( 841/1490) minvmd box_registry::tests::a_registration_refused_for_a_held_address_spends_no_switch_address
────────────
     Summary [  37.547s] 841/1490 tests run: 840 passed, 1 failed, 2 skipped
        FAIL [   2.960s] ( 838/1490) minimal::otel_cli exec_run_attach_and_task_run_share_the_commands_trace
warning: 649/1490 tests were not run due to test failure (run with --no-fail-fast to run all tests, or run with --max-fail)
error: test run failed

Outside the task's layers::

  • crates/minimal/tests/cli.rs

Converted to a draft: something above needs a person before review.

With two VMs, min session policy beta, min net forward beta 8080:3000, exec and stop find beta on its VM without --vm. After min --vm alpha stop, min ls lists alpha's boxes as stopped, and min session attach beta says which VM to start and how, with the error still on screen. This round: an active box on a running VM now resolves there, even when a stopped VM's records hold the same name.

Notes from the agent: Round 3 addresses the /revise note (arch C3). In resolve_box_vm, the case with one running owner and stopped holders now returns the owner when its record.status is BoxState::Active. Otherwise it returns the AmbiguousBoxName error, which lists the owner's VM and each stopped holder marked (stopped) and names --vm. The doc comment now says a running box wins. box_on_stopped_vm_names_start_command covers both cases. The active api box on default with gamma holding api resolves to default. A web box stopped through the StopBox RPC on default, with zeta holding web, gives AmbiguousBoxName with (default, zeta (stopped)). I did not re-run the minvmd test line this round, because this round does not change minvmd. cargo clippy -p minimal --all-targets and cargo fmt --check are clean. I did not run just clippy-strict.

A name that more than one VM holds, running or stopped, is now an
ambiguity that lists every VM and names --vm, though the running box
is active. The arm that let an active box win is gone.

An attach whose relay fails before ssh's session reaches the terminal
(the pty, the ssh spawn or raw mode fail) no longer writes the unwind.
The relay calls its suspend hook only once it started, so a failure
before that call is marked and the guard stands down.
@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/minimal/src/cmd/boxes/attach.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 · 1 condition · the full ruling

The compare fixes the cross-VM tie. resolve_box_vm now refuses a name that two VMs hold, as Addressing line 389 requires. One path still picks without an error. resolve_box_on_any_vm and resolve_named_box_version_gated return the selected VM's box on a hit. They never ask the other VMs. So with no --vm, min session destroy shared acts on the default VM's box when alpha also holds shared. Line 389 says an unqualified name on more than one host is an error. C1 sends a hit through resolve_box_vm when several VMs exist, and adds a test on the command path.

Ruled at af11107 against gominimal/arch@8640f85e193d by claude-opus-5-5.

Comment thread crates/minimal/src/cmd/mod.rs Resolved
Comment thread crates/minimal/src/cmd/boxes/attach.rs Resolved
@minimal-foundry
Copy link
Copy Markdown
Con 10BC8 tributor Author

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

line exit tail
cargo nextest run -p minimal box_name_resolves_vm_without_flag 0 Applying loadouts: default Running task runtime-implement-test-0 in session task-runtime-implement-test-0-5473... Compiling paths v0.0.1 (/workbench/crates/paths) Compiling args v0.0.1 (/workbench/crates/args) Compiling ot v0.0.1 (/workbench/crates/ot) Compiling client-config v0.0.1 (/wo
cargo nextest run -p minimal unknown_box_names_vm_flag 0 Applying loadouts: default Running task runtime-implement-test-1 in session task-runtime-implement-test-1-dc5e... 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.
cargo nextest run -p minimal box_on_stopped_vm_names_start_command 0 Applying loadouts: default Running task runtime-implement-test-2 in session task-runtime-implement-test-2-d304... 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.
cargo nextest run -p minimal attach_error_printed_after_terminal_restore 0 Applying loadouts: default Running task runtime-implement-test-3 in session task-runtime-implement-test-3-a645... 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.
cargo nextest run -p minvmd persisted_box_names_read_without_a_daemon 0 Applying loadouts: default Running task runtime-implement-test-4 in session task-runtime-implement-test-4-e85a... Compiling paths v0.0.1 (/workbench/crates/paths) Compiling args v0.0.1 (/workbench/crates/args) Compiling ot v0.0.1 (/workbench/crates/ot) Compiling client-config v0.0.1 (/wo
cargo nextest run -p minimal ls_lists_boxes_on_stopped_vm 0 Applying loadouts: default Running task runtime-implement-test-5 in session task-runtime-implement-test-5-2654... 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 100 under rustc 1.99.0, which the repository does not pin (1.99.1 in rust-toolchain.toml); the PR is not a draft on that alone — CI, which honours the pin, is the gate.

kind": "GetNetSwitch",
                "parent_span_id": "8bfd6da52bc3a227",
                "span_id": "60d292a4dd540804",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "session.message",
            fields: {
                "kind": "GetDenyAllOptOut",
                "parent_span_id": "8bfd6da52bc3a227",
                "span_id": "29b57904321257fd",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "session.message",
            fields: {
                "kind": "GetPaths",
                "parent_span_id": "8bfd6da52bc3a227",
                "span_id": "4042c5f0b00b5e27",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "sessions.manager.message",
            fields: {
                "kind": "GetRecord",
                "parent_span_id": "8bfd6da52bc3a227",
                "queued_behind": "0",
                "span_id": "21508e50553743e9",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "sessions.manager.message",
            fields: {
                "kind": "DeleteSession",
                "parent_span_id": "8bfd6da52bc3a227",
                "queued_behind": "0",
                "span_id": "3cfb02acd4b5515a",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "session.message",
            fields: {
                "kind": "Destroy",
                "parent_span_id": "3cfb02acd4b5515a",
                "span_id": "98887a7376f6150d",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
    ]
    note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

  Cancelling due to test failure: 3 tests still running
        PASS [   3.017s] ( 854/1505) minvmd box_registry::tests::a_closed_shuttle_detaches_rows_until_the_grace
        PASS [   2.208s] ( 855/1505) minvmd box_registry::tests::a_reattributed_box_keeps_its_row
        PASS [   5.010s] ( 856/1505) minvmd box_registry::tests::a_registration_refused_for_a_held_address_spends_no_switch_address
────────────
     Summary [  41.543s] 856/1505 tests run: 855 passed, 1 failed, 2 skipped
        FAIL [   2.810s] ( 853/1505) minimal::otel_cli exec_run_attach_and_task_run_share_the_commands_trace
warning: 649/1505 tests were not run due to test failure (run with --no-fail-fast to run all tests, or run with --max-fail)
error: test run failed

Outside the task's layers::

  • crates/minimal/tests/cli.rs

Converted to a draft: something above needs a person before review.

Review threads the coder judged:

  • 👍 valid — crates/minimal/src/attach.rs: Removed the (1, [, ..]) active-owner arm. One running owner plus a stopped holder now falls to the (, stopped) arm and returns AmbiguousBoxName listing every VM.
  • 👍 valid — crates/minimal/src/attach.rs: Rewrote the doc comment: any name more than one VM holds, running or stopped, is an AmbiguousBoxName that lists every VM, marks each stopped one, and names --vm.
  • 👍 valid — crates/minimal/src/tests.rs: Restored the 385b33c assertion: resolve_box_vm(&global, "api") errors with 'box name 'api' exists on more than one VM (default, gamma (stopped)); name the one you mean with --vm' and downcasts to AmbiguousBoxName. The web case stays.

With two VMs, min session policy beta, min net forward beta 8080:3000, exec and stop find beta on its VM without --vm. After min --vm alpha stop, min ls lists alpha's boxes as stopped, and min session attach beta says which VM to start and how, with the error still on screen. A name that a running VM and a stopped VM both hold is refused with every VM listed and --vm named.

Notes from the agent: Directive items 1 to 3: removed the active-box-wins arm in resolve_box_vm, rewrote its doc comment, and restored the 385b33c 'api' assertion in box_on_stopped_vm_names_start_command. The 'web' case stays. Item 4 is real. Every error that Relay::start returns (pty, ssh spawn, raw mode, pump thread) comes before ssh's session reaches the real terminal, and the relay puts back the termios itself, so the guard wrote a blind unwind. The fix stays inside the layers: a new marker crate::attach::RelayNotStarted wraps the error and prints the same text. The new mark_relay_not_started in cmd/boxes/attach.rs always passes the relay a suspend hook, and the relay calls that hook only after Relay::start returns. A failure before that call gets the marker, and interactive_attach disarms the guard on it. One limit: the hook runs on its own thread. So if Relay::join fails at once (only the wait on ssh's exit can fail), the guard can stand down although the session ran. The termios is still restored in that case. A marker set in minimal-client's Relay::start is the exact fix, but that crate is outside this task's layers. attach_error_printed_after_terminal_restore now pins that an ssh spawn failure writes no unwind and prints 'failed to run ssh: spawning the ssh attach: ...'. just clippy-strict was not run.

@minimal-foundry
minimal-foundry Bot marked this pull request as draft November 1, 2026 00:35
@norrietaylor
Copy link
Copy Markdown
Member

/revise Arch C1 on af11107. This follows from the person's ruling that a name held by more than one VM is ambiguous.

A hit on the selected VM still returns at once, so a second VM that holds the same name is never seen. In crates/minimal/src/cmd/mod.rs resolve_box_on_any_vm and in crates/minimal/src/cmd/boxes/attach.rs resolve_named_box_version_gated:

  • When global.vm is None and several_vms(global) is true, do not return on a hit from the selected VM. Call crate::attach::resolve_box_vm, which walks every VM, the selected one included. Return its AmbiguousBoxName when a second VM, running or stopped, also holds the name.
  • When the selected VM is the only holder, keep its record and client. With one VM, or with --vm, nothing changes and no extra lookup runs.
  • Add a test that drives min session destroy (through resolve_box_on_any_vm) and min session attach (through resolve_named_box_version_gated) with shared on the default VM and on alpha. Assert the AmbiguousBoxName text that names both VMs and --vm.

Do not edit the PR body.

A hit on the selected VM returned at once, so a second VM that holds the
same name was never seen. With several VMs and no --vm, policy, destroy,
attach, exec, run and net forward now check every VM and refuse the name
with the ambiguity error.
@minimal-foundry
Copy link
Copy Markdown
Contributor Author

Round 5 of 10 on a /revise note, pushed as 6d670ccb5eae.

line exit tail
cargo nextest run -p minimal box_name_resolves_vm_without_flag 0 Applying loadouts: default Running task runtime-implement-test-0 in session task-runtime-implement-test-0-254d... Compiling paths v0.0.1 (/workbench/crates/paths) Compiling ot v0.0.1 (/workbench/crates/ot) Compiling args v0.0.1 (/workbench/crates/args) Compiling client-config v0.0.1 (/wo
cargo nextest run -p minimal unknown_box_names_vm_flag 0 Applying loadouts: default Running task runtime-implement-test-1 in session task-runtime-implement-test-1-149d... 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.
cargo nextest run -p minimal box_on_stopped_vm_names_start_command 0 Applying loadouts: default Running task runtime-implement-test-2 in session task-runtime-implement-test-2-8881... 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.
cargo nextest run -p minimal attach_error_printed_after_terminal_restore 0 Applying loadouts: default Running task runtime-implement-test-3 in session task-runtime-implement-test-3-53f2... 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.
cargo nextest run -p minvmd persisted_box_names_read_without_a_daemon 0 Applying loadouts: default Running task runtime-implement-test-4 in session task-runtime-implement-test-4-301a... Compiling paths v0.0.1 (/workbench/crates/paths) Compiling args v0.0.1 (/workbench/crates/args) Compiling ot v0.0.1 (/workbench/crates/ot) Compiling client-config v0.0.1 (/wo
cargo nextest run -p minimal ls_lists_boxes_on_stopped_vm 0 Applying loadouts: default Running task runtime-implement-test-5 in session task-runtime-implement-test-5-c46e... 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 100 under rustc 1.99.0, which the repository does not pin (1.99.1 in rust-toolchain.toml); the PR is not a draft on that alone — CI, which honours the pin, is the gate.

kind": "GetNetSwitch",
                "parent_span_id": "3076d41d173fa192",
                "span_id": "96fa68e9a1d42605",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "session.message",
            fields: {
                "kind": "GetDenyAllOptOut",
                "parent_span_id": "3076d41d173fa192",
                "span_id": "2e24513e10a8982c",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "session.message",
            fields: {
                "kind": "GetPaths",
                "parent_span_id": "3076d41d173fa192",
                "span_id": "06a064a2129cc348",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "sessions.manager.message",
            fields: {
                "kind": "GetRecord",
                "parent_span_id": "3076d41d173fa192",
                "queued_behind": "0",
                "span_id": "af8a33fd607c71fd",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "sessions.manager.message",
            fields: {
                "kind": "DeleteSession",
                "parent_span_id": "3076d41d173fa192",
                "queued_behind": "0",
                "span_id": "192b80e9482267b8",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "session.message",
            fields: {
                "kind": "Destroy",
                "parent_span_id": "192b80e9482267b8",
                "span_id": "ab5a5e9350e61e9e",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
    ]
    note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

  Cancelling due to test failure: 3 tests still running
        PASS [   3.018s] ( 856/1507) minvmd box_registry::tests::a_closed_shuttle_detaches_rows_until_the_grace
        PASS [   2.220s] ( 857/1507) minvmd box_registry::tests::a_reattributed_box_keeps_its_row
        PASS [   5.009s] ( 858/1507) minvmd box_registry::tests::a_registration_refused_for_a_held_address_spends_no_switch_address
────────────
     Summary [  43.580s] 858/1507 tests run: 857 passed, 1 failed, 2 skipped
        FAIL [   2.960s] ( 855/1507) minimal::otel_cli exec_run_attach_and_task_run_share_the_commands_trace
warning: 649/1507 tests were not run due to test failure (run with --no-fail-fast to run all tests, or run with --max-fail)
error: test run failed

Outside the task's layers::

  • crates/minimal/tests/cli.rs

Converted to a draft: something above needs a person before review.

Review threads the coder judged:

  • 👎 invalid — crates/minimal/src/cmd/boxes/attach.rs:478: The race is real, but the fix is outside this task's layers. A race-free signal needs a typed error for the Relay::start failure in crates/minimal-client/src/attach.rs (run_interactive_attach_on). Relay::start and Relay::join are pub(crate) in minimal 10BC8 -client, so crates/minimal cannot separate the st
  • 👍 valid — crates/minimal/src/cmd/mod.rs: resolve_box_on_any_vm now calls ensure_selected_holds_box_alone on a selected-VM hit when there is no --vm and several VMs exist. That runs resolve_box_vm and returns AmbiguousBoxName for a second holder. Pinned with destroy on shared held by default and alpha.
  • 👍 valid — crates/minimal/src/cmd/boxes/attach.rs: resolve_named_box_version_gated (attach, exec, run, net forward) runs the same ensure_selected_holds_box_alone check on a selected-VM hit, before the terminal is touched. A new test attaches to shared on two VMs and asserts the AmbiguousBoxName text.

With two VMs, min session policy beta, min net forward beta 8080:3000, exec and stop find beta on its VM without --vm. A name that two VMs hold, the selected VM included, is refused with an error that names both VMs and --vm. After min --vm alpha stop, min ls lists alpha's boxes as stopped, and min session attach beta says which VM to start and how, with the error still on screen.

Notes from the agent: Round 5 (Arch C1): a new ensure_selected_holds_box_alone in cmd/mod.rs runs after a hit on the selected VM when there is no --vm and the host has several VMs. It calls resolve_box_vm and returns its AmbiguousBoxName. If the walk finds a different record id, the error names both VMs. resolve_box_on_any_vm (policy, destroy) and resolve_named_box_version_gated (attach, exec, run, net forward) call it. With one VM or --vm, no extra lookup runs. The new test box_name_resolves_vm_without_flag_refuses_a_name_two_vms_hold drives destroy and attach with shared on default and alpha. The VM order in the message is enumeration order: (default, alpha). The last block of box_on_stopped_vm_names_start_command pinned the old shortcut (api on default and on stopped gamma resolved to default). It now expects the ambiguity error, and a new solo box shows that the only holder still resolves. The foundry thread on mark_relay_not_started is a real race. Its fix needs a typed error from Relay::start in crates/minimal-client/src/attach.rs, outside this task's layers. Relay::start and Relay::join are pub(crate), so the CLI cannot mark the start failure itself. just clippy-strict was not run.

@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 review of 6d670cc. Arch C1 is closed. With several VMs and no --vm, a hit on the selected VM now runs ensure_selected_holds_box_alone. That walks every VM through resolve_box_vm, which returns AmbiguousBoxName (naming each VM and --vm) when another VM, running or stopped, holds the name. With one VM, or with --vm, no extra lookup runs. Tests cover both destroy and attach. Undrafting: the out-of-layer tests/cli.rs change was accepted earlier.

@norrietaylor
norrietaylor marked this pull request as ready for review November 1, 2026 01:40
@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 · the full ruling

The change now conforms. A hit on the selected VM is checked against every VM before the command uses it. A name that two VMs hold is refused with every candidate listed, as Addressing line 389 requires. All box-naming commands go through the two checked helpers. The exit codes (#2816) and min stop <box> (#2815) stay as filed residuals.

Ruled at 6d670cc against gominimal/arch@8640f85e193d by claude-opus-5-5.

@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/minimal/src/attach.rs Resolved
A daemon matches an exact name before an id prefix. The walk across
VMs now does the same: when any VM holds the name as a name, a VM that
matches only an id prefix is not a candidate.
@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 · the full ruling

The compare conforms. A box name now wins over an id prefix across VMs, the same order the daemon uses in match_id_prefix. A name that two VMs hold as a name is still refused with the list of candidates, as architecture.md line 389 requires. The rest of the change keeps the status of the PASS on 6d670cc. Residuals #2816 and #2815 stay open.

Ruled at f721ac4 against gominimal/arch@8640f85e193d by claude-opus-5-5.

@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: 10 unresolved threads — minimal-arch[bot] crates/minimal/src/attach.rs, minimal-arch[bot] crates/minimal/src/attach.rs, minimal-arch[bot] crates/minimal/src/tests.rs:6007, minimal-arch[bot] crates/minimal/src/attach.rs, minimal-arch[bot] crates/minimal/src/attach.rs, …. No findings.

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

@minimal-foundry
Copy link
Copy Markdown
Contributor Author

Round 6 of 10 on the runtime's review findings, pushed as f721ac4f1039.

line exit tail
cargo nextest run -p minimal box_name_resolves_vm_without_flag 0 Applying loadouts: default Running task runtime-implement-test-0 in session task-runtime-implement-test-0-58a4... Compiling paths v0.0.1 (/workbench/crates/paths) Compiling args v0.0.1 (/workbench/crates/args) Compiling ot v0.0.1 (/workbench/crates/ot) Compiling client-config v0.0.1 (/wo
cargo nextest run -p minimal unknown_box_names_vm_flag 0 Applying loadouts: default Running task runtime-implement-test-1 in session task-runtime-implement-test-1-740c... 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 graph v0
cargo nextest run -p minimal box_on_stopped_vm_names_start_command 0 Applying loadouts: default Running task runtime-implement-test-2 in session task-runtime-implement-test-2-4aad... 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.
cargo nextest run -p minimal attach_error_printed_after_terminal_restore 0 Applying loadouts: default Running task runtime-implement-test-3 in session task-runtime-implement-test-3-47af... 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.
cargo nextest run -p minvmd persisted_box_names_read_without_a_daemon 0 Applying loadouts: default Running task runtime-implement-test-4 in session task-runtime-implement-test-4-a2ef... Compiling paths v0.0.1 (/workbench/crates/paths) Compiling ot v0.0.1 (/workbench/crates/ot) Compiling args v0.0.1 (/workbench/crates/args) Compiling client-config v0.0.1 (/wo
cargo nextest run -p minimal ls_lists_boxes_on_stopped_vm 0 Applying loadouts: default Running task runtime-implement-test-5 in session task-runtime-implement-test-5-f411... 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 100 under rustc 1.99.0, which the repository does not pin (1.99.1 in rust-toolchain.toml); the PR is not a draft on that alone — CI, which honours the pin, is the gate.

kind": "GetNetSwitch",
                "parent_span_id": "8ae610a4305e3a51",
                "span_id": "d770913d9e92f25c",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "session.message",
            fields: {
                "kind": "GetDenyAllOptOut",
                "parent_span_id": "8ae610a4305e3a51",
                "span_id": "ed6d02fd2883c8a4",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "session.message",
            fields: {
                "kind": "GetPaths",
                "parent_span_id": "8ae610a4305e3a51",
                "span_id": "1b039bb2bc01efcf",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "sessions.manager.message",
            fields: {
                "kind": "GetRecord",
                "parent_span_id": "8ae610a4305e3a51",
                "queued_behind": "0",
                "span_id": "37c546e8322b09c2",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "sessions.manager.message",
            fields: {
                "kind": "DeleteSession",
                "parent_span_id": "8ae610a4305e3a51",
                "queued_behind": "0",
                "span_id": "ec6cea5d2a20cf6f",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
        LoggedSpan {
            name: "session.message",
            fields: {
                "kind": "Destroy",
                "parent_span_id": "ec6cea5d2a20cf6f",
                "span_id": "cf367076747b993e",
                "trace_id": "0af7651916cd43dd8448eb211c803111",
            },
            parent: None,
            closed: true,
        },
    ]
    note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

  Cancelling due to test failure: 3 tests still running
        PASS [   3.012s] ( 856/1507) minvmd box_registry::tests::a_closed_shuttle_detaches_rows_until_the_grace
        PASS [   2.220s] ( 857/1507) minvmd box_registry::tests::a_reattributed_box_keeps_its_row
        PASS [   5.010s] ( 858/1507) minvmd box_registry::tests::a_registration_refused_for_a_held_address_spends_no_switch_address
────────────
     Summary [  46.026s] 858/1507 tests run: 857 passed, 1 failed, 2 skipped
        FAIL [   2.993s] ( 855/1507) minimal::otel_cli exec_run_attach_and_task_run_share_the_commands_trace
warning: 649/1507 tests were not run due to test failure (run with --no-fail-fast to run all tests, or run with --max-fail)
error: test run failed

Outside the task's layers::

  • crates/minimal/tests/cli.rs

Converted to a draft: something above needs a person before review.

Review threads the coder judged:

  • 👍 valid — crates/minimal/src/attach.rs: A name match on any VM now wins over an id prefix. resolve_box_vm drops the VMs that match only an id prefix when another VM holds the name, and a test pins 'cafe' against a stopped VM's cafe… id.

With two VMs, min session policy beta, min net forward beta 8080:3000, exec and stop find beta on its VM without --vm. After min --vm alpha stop, min ls lists the boxes of alpha as stopped. min session attach beta then says which VM to start and how, and the error stays on screen. In this round, a box name such as 'cafe' on a running VM also resolves when a stopped VM holds a box whose id starts with 'cafe'.

Notes from the agent: Revise round 6. resolve_box_vm now records how each VM holds the name: as a name or only as an id prefix. When any VM holds it as a name, the id-prefix-only holders are dropped, as match_id_prefix does on one daemon. ensure_selected_holds_box_alone in cmd/mod.rs calls resolve_box_vm, so the selected-VM path gets the same rule. The new case is in box_on_stopped_vm_names_start_command.

@minimal-foundry
minimal-foundry Bot marked this pull request as draft November 1, 2026 02:08
@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 f721ac4f1039 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.

@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 review of f721ac4. Round 6 makes a name match win over an id prefix across VMs, as match_id_prefix does on one daemon. Stopped and running holders are both classified, and id-prefix holders drop out only when some VM holds the name as a name. The cafe test pins it. All 10 threads are answered at this head. Non-blocking: the (0, several) message says "more than one stopped VM" when one holder is a running VM with a stopped box. The ambiguity is right and only the label is loose.

@minimal-foundry minimal-foundry Bot added the review:approved minimal-review approved the current head label Nov 1, 2026
@norrietaylor
norrietaylor marked this pull request as ready for review November 1, 2026 03:10
@norrietaylor
norrietaylor added this pull request to the merge queue Nov 1, 2026
Merged via the queue into main with commit 2e3962f Nov 1, 2026
36 checks passed
@norrietaylor
norrietaylor deleted the agent/2705-host-side-commands-find-a-box-on-any-vm-a-stoppe branch November 1, 2026 04:16
norrietaylor pushed a commit that referenced this pull request Nov 4, 2026
Policy and destroy resolve a box's VM from its name, as attach, exec, run and net forward do.
A box no running VM holds names --vm, a box on a stopped VM names the command that starts it,
and a name any two VMs hold, running or stopped, is refused with every VM listed. A relay
failure writes the unwind before the attach error prints, so the error stays on screen.

Backport of #2811. Adapted to the line: cmd/boxes/attach.rs and policy.rs hunks land in
cmd/session.rs. Dropped, because the line has no stopped session status (#2676) and keeps box
ids apart from session ids (#2485): min ls rows for a stopped VM's boxes, vm_running in its
JSON, and id-prefix matching against a stopped VM's records, which match by name only here.

(cherry picked from commit 2e3962f)
norrietaylor pushed a commit that referenced this pull request Nov 5, 2026
Policy and destroy resolve a box's VM from its name, as attach, exec, run and net forward do.
A box no running VM holds names --vm, a box on a stopped VM names the command that starts it,
and a name any two VMs hold, running or stopped, is refused with every VM listed. A relay
failure writes the unwind before the attach error prints, so the error stays on screen.

Backport of #2811. Adapted to the line: cmd/boxes/attach.rs and policy.rs hunks land in
cmd/session.rs. Dropped, because the line has no stopped session status (#2676) and keeps box
ids apart from session ids (#2485): min ls rows for a stopped VM's boxes, vm_running in its
JSON, and id-prefix matching against a stopped VM's records, which match by name only here.

(cherry picked from commit 2e3962f)
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.

T111 — Host-side commands find a box on any VM, a stopped VM included, and attach errors stay on screen

1 participant

0