Repository navigation
fix(deps): bump pulldown-cmark to 0.13.6 for RUSTSEC-2026-0433 - #2846
Merged
Merged
Conversation
Co-Authored-By: Claude Opus 5.5 & 8000 lt;noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NSAwDroXL6KqsSxUzdbZGw
Contributor
|
Important Review skippedReview was skipped due to path filters ⛔ Files ignored due to path filters: 1
CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including
|
Contributor
|
Approved: no findings at Nothing to do. Clobber: none. |
This was referenced Nov 2, 2026
bryan-minimal
approved these changes
Nov 2, 2026
norrietaylor
added a commit
that referenced
this pull request
Nov 3, 2026
* fix(deps): bump pulldown-cmark to 0.13.6 for RUSTSEC-2026-0433 (#2846) Claude-Session: https://claude.ai/code/session_01NSAwDroXL6KqsSxUzdbZGw Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(minimald): hand a reaped name over in one manager step (#2842) A reap read the records and then sent the handover as a second message. A removal that began between the two left the name with no row while another retained box still had it. The manager now releases the reaped box's row, picks the successor among boxes not being removed, and registers it in one message. The reap and the prune return after both. The daemon log names the release (name-released) before the handover (name-handed-over), both with box ids. Co-authored-by: minimal-foundry[bot] <327719912+minimal-foundry[bot]@users.noreply.github.com> * T126 — A host-address box's port that collides on the host is shown at session start and in `min ls` (#2830) * feat(minvmd): answer a node's collided mirror ports over control The host control socket answers a read-only mirror_collisions verb with the node's mirrored ports that collided with a holder on the host. The node mirror keeps the time each port first collided. * feat(minimal): show collided mirror ports in min ls and activate min ls prints a MIRROR PORTS row per VM whose host_ip box ports are held by another program on the host, and --json carries mirror_collisions per VM. min session activate of a host_ip box on a VM host prints the same sentence per port when it does not attach. * fix(minimal): show an unread VM's mirror ports as null in min ls Read each VM's collided mirror ports concurrently, and keep a failed read apart from an empty one: --json writes null for a VM with no answer and [] only for an answered empty read. * fix(minimal): name a VM host whose mirror ports were not read min ls printed nothing for a running VM host that gave no answer, so it looked the same as one with no collisions. It now prints one MIRROR PORTS row that says the VM did not report its ports. * fix(minimal): skip the mirror-port read on a native host A native host has no VM host daemon. The fallback listing's control socket there is minimald's, which does not serve the collided-port read, so min ls printed a false MIRROR PORTS row on every native host. * fix(minimal): name an unread VM host at activate, enter the span min session activate now prints the unread sentence that min ls prints when the VM host daemon gives no answer. The ListSessions span wraps the collided-port reads, and a native host's --json carries no mirror_collisions field. --------- Co-authored-by: minimal-foundry[bot] <327719912+minimal-foundry[bot]@users.noreply.github.com> * T42 — Start every box's entrypoint from its spec through one launcher (#2841) * feat(mfile): carry entrypoint and lifetime in the box spec The spec gains an [execution] table with the box's lifetime and, for a box that does not run its login shell, its entrypoint argv. A v0 spec stored before the table existed reads with the entrypoint its type implies. * feat(minimald): start each box's entrypoint from its spec One launcher decision, LaunchSpec::entrypoint, reads the first process from the box's stored spec: the login shell, or the spec's argv. The actor reads the stored spec once, keeps its hold, and hands it to every launcher. A launch minted for an exec keeps the shell, because the exec runs the box's command. Each launch logs its entrypoint in a box.launch span. * fix(minimald): keep the shell on every launch of an exec-run box A task's run arrives over the exec channel. A hook launch or an attach can come before or after that exec, and a hook launch's gated first process starts at the next attach. Only the exec-minted launch held the shell, so a task box could run its task twice, and an attach got the task, not a shell. Every launch now says an exec carries the run, and the launcher starts the shell for it. * refactor(mfile): write box.lifetime and execution.exec in the spec Rename Lifetime::Persistent to UntilStopped, move the lifetime to [box] with a until_complete default for v0 specs, and serialize the entrypoint as execution.exec. List the argv shape as a v0 exception. * fix(minimald): refuse a launch whose stored spec cannot be read held_spec returns an error for unreadable spec bytes or a failed store read, and launch_host refuses with SpawnFailed instead of starting the shell. Mark run_by_exec as an interim that T43 (#2405) removes. * test(minimald): store a readable spec in the stopped-box record test A launch now refuses a stored spec it cannot read, so the test's placeholder bytes failed its ensure_host. Store a session spec instead. * docs(mfile): say that no launch reads the spec's lifetime yet A box ends when its entrypoint returns, whatever box.lifetime says. * fix(minimald): keep entrypoint arguments out of the launch log The box.launch span and its info event printed every argument of an argv entrypoint. An argument can carry a secret, so they now name the program (or the login shell) and the argument count only. A test pins that a secret-looking argument does not reach the log. --------- Co-authored-by: minimal-foundry[bot] <327719912+minimal-foundry[bot]@users.noreply.github.com> Co-authored-by: Karl Godard <karl@minimal.dev> * T30 — Run a command in a box with a terminal or detached, under an exec id (#2843) * feat(minimald-rpc): carry exec mode, timeout and exec id on the wire min://exec carries an argv with its mode (attached, tty or detached) and an optional timeout. min://exec/attach, min://exec/output and min://exec/wait name an exec by its UUIDv7 id. The box store places each exec's transcript beside the record and appends events by path. * feat(minimald): run box execs under an id, with a terminal or detached Every command for a box gets a UUIDv7 exec id, and a box that is not running refuses it with exit 2 naming its state. min://exec runs an argv with no shell: attached, on a daemon terminal, or detached with stdin closed. Tty and detached execs answer with their id at once, capture their output beside the box record, and keep their exit for min://exec/wait. An exec's own timeout stops it and records an exec_exited event with reason timeout, and the box keeps running. * style(minimald-rpc): format the exec id parse and its tests * fix(minimald): bound the wait after an exec timeout; drop reaped execs A command that survives the stop at its timeout no longer holds its wait open: the wait after the stop is bounded, then SIGKILLed and recorded as a timeout. Ended execs of a reaped box leave the exec map. * fix(minimald): exit 124 on exec timeout; wait reads stored exit An exec that its own timeout ends now exits 124, attached or detached. A wait on an exec that this daemon holds no entry for reads the box's stored exec_exited event, so a detached exec's exit code outlives a daemon restart. * fix(minimald): cap exec transcripts at 8 MiB and stream reads A detached exec now writes through a pipe and a pump, as a tty exec does, so the daemon can cap its transcript. Past the cap the transcript keeps a mark and the newest half of the cap, and the command keeps running. The output read and the attach replay copy the transcript in 64 KiB chunks, up to its length at the open, and the attach takes the terminal lock only to open the file and subscribe. * fix(minimald): bound tty exec input; no deadline past the clock A tty exec's terminal input went through an unbounded channel, so a program that never reads stdin let the daemon queue grow without limit. The terminal now holds typed input in a HeldInput with the attached path's bounds (EXEC_INPUT_HELD_MAX per exec, EXEC_INPUT_HELD_DAEMON_MAX for the daemon). Past either bound the chunk is dropped and the log says so once per exec. The exec's end releases what it held. An attached exec's timeout too large for the clock panicked after the spawn. timeout_deadline now uses checked_add and gives no deadline. Tests: unread tty input stays within the cap, a timeout of u64::MAX seconds runs the exec to its end, and an exec id from one box finds no exec, output or exit in another. * fix(minimald): wait on exec terminals in the runtime, not a thread The tty feed wrote to the terminal from a blocking thread. When the program never read its input, that write never returned, and each such exec left a blocking thread behind for good. The terminal and the detached pipe are now non-blocking and watched through AsyncFd, so the supervisor can stop the pump and the feed at the exec's end. Both stop on a closed state too, because tokio never clears it and a wait for it returns at once. --------- Co-authored-by: minimal-foundry[bot] <327719912+minimal-foundry[bot]@users.noreply.github.com> Co-authored-by: Karl Godard <karl@minimal.dev> * fix(minimald): hand a destroyed box's name to the next holder (#2849) A destroy removed the box that held a name's row and left the name with no row, while another retained box still had that name. The destroy now runs the same handover as a reap: the row goes to the running box with the name, else to the most recent creation. The destroy answers after the handover. The daemon log names the destroyed box and the successor, and the destroy span records the successor id or "none". Co-authored-by: minimal-foundry[bot] <327719912+minimal-foundry[bot]@users.noreply.github.com> * T114 — `min ls` and the box commands tell the truth, end to end (#2839) * test(e2e): prove min ls and the box commands across two VMs Adds the ls_and_box_commands_tell_the_truth case: a stopped VM's boxes in min ls, the ADDRESS and EGRESS cells against min session policy, policy and forward without --vm, the unknown-box and stopped-VM refusals, both proxy ports after the preferred port frees, and the --public and out-of-range expose refusals. * test(e2e): record ls_and_box gates as NOT RUN, check declared rules The four gates of ls_and_box_commands_tell_the_truth now call not_run, so the lane summary names the case. A 'declared rules' EGRESS cell is now checked against the subnets rule row that min session policy prints, not only against an egress heading. * test(e2e): read the expose address past a trailing carriage return The ls_and_box case read the box's address from the in-box expose reply with an end-of-line anchor. A reply over the exec channel can end in a carriage return, which left the address empty. * test(e2e): brace lt_port before a bracket class in the expose read shellcheck reads $lt_port[[:space:]] as an array index (SC1087). The braces keep the same match and make the script lint-clean again. * fix(minimal): poll the owning VM in min net forward A forward to a box on another VM polled the selected VM for its session. That VM does not hold the box, so the forward closed on the first tick. Reconnect the poll to the owning VM, version-gated. --------- Co-authored-by: minimal-foundry[bot] <327719912+minimal-foundry[bot]@users.noreply.github.com> Co-authored-by: Norrie Taylor <91171431+norrietaylor@users.noreply.github.com> * docs(spec): specify dns steering and the host_ip lane for spec 24 (#2851) * docs(spec): specify dns steering and the host_ip lane for spec 24 Add BEP-080 to BEP-087 so the default `dns` steering works for own_ip and host_ip boxes on a VM host, as architecture D6 and networking §5.4 require. - BEP-080, BEP-081: direct TLS to the proxy on port 443, routed by SNI, and admitting dns and both on a VM host (#2805). - BEP-082 to BEP-087: the host_ip lane: a host-side box id, the cohort proxy lane, cohort-attributed delivery with the named box's egress and audit subject, the in-effect rule, per-box steering, and the live proof. - BEP-015 gains a host_ip proxy_env case. - Security considerations states the cohort lane and per-box steering. * docs(spec): keep the first slice paragraph unchanged and move the host_ip e2e checks to BEP-087 * docs(spec): address review on the host_ip lane requirements - BEP-083: the cohort lane also admits TCP 443 at the proxy's address, the direct TLS path dns steering uses. - BEP-084: refuse and audit a cohort-attributed value that names no live host_ip box of this host. - BEP-086: cite NET-003's VM-backed resolver requirement, not NET-079. - BEP-087: the proxy_env case is its own sub-requirement. - Security considerations: BEP-083 and BEP-084 join the redemption invariant, and BEP-084 the egress invariant. * T10 — Log a box's output from its start, out of the box's reach (#2852) * feat(boxes): name a box's output log beside its record Adds LOG_FILE and BoxDir, the box's directory as code outside the store sees it: the log path, a lookup by id through the index, a log read by offset, and an event append for a writer that holds no DiskBox. * feat(minimald-rpc): add a streamed read of a box's output log * feat(minimald): log a box's output from its start The host appends every read from the box's terminal to its output log before it hands the bytes to an attached client, so the client is a second reader. A binding whose client closes its channel, drops its connection or is shed records a detached event, and the box runs on. * feat(minimald): serve a box's output log by its id ReadLog streams the log from a byte offset, and with follow sends new output until the box is reaped. A test shows that files written into the box's own directories reach neither the log nor the record. * fix(minimald): read a box's log on the blocking pool The followed log read polled the store with blocking std::fs calls on an async task. The find, the chunk reads and the retained check now run through spawn_blocking, so a slow disk does not hold a runtime worker. * fix(boxes): cap a box's output log and read it across a drop The log keeps a drop mark and the newest half past 8 MiB. A reader keeps its file open and moves to the replaced file with no byte sent twice. The read refuses a link or a file that is not regular. * fix(minimald): start no store box without its output log BoxOutputLog::open returns the open's error for a box in the store, and Host::build stops before the launch. The log writes through the capped store writer, and ReadLog keeps one reader for the whole stream. * fix(minimald): run detach hooks when a PTY client is lost A lost client already records a detached event. Its on_detach hooks now run too, so the event and the hooks agree. A test drives a box past the log cap. * style: format the log cap tests * docs(boxes): mark the 8 MiB log cap as not yet in the design The cap drops the start of a box's output past 8 MiB. That departs from architecture.md line 473. gominimal/arch#159 decides the bound. * docs(specs): record the interim 8 MiB box log cap in BOX The decision that logs a box's output from its start now states the 8 MiB cap, what the log keeps past it, and the arch#159 decision that removes the cap or changes BOX-155. --------- Co-authored-by: minimal-foundry[bot] <327719912+minimal-foundry[bot]@users.noreply.github.com> * T9 — End a box when its entrypoint returns, never for idleness or client loss (#2850) * feat(minimald): end an until_complete box when its entrypoint returns The host loop now says whether a kill ended it. The actor watches each launch's loop and, when the entrypoint returned on its own and the spec sets lifetime = "until_complete", sets the record to exited with the exit code and records an exited event with reason "exit". The daemon does this whether or not a client is attached. Such a box raises no shell-exit prompt (BOX-038). A client that goes away never stops a box (BOX-015). * test(minimald): pin box ends on entrypoint return, not client loss Adds the actor tests for BOX-038 and BOX-015. The shell round trip now expects no prompt and an exited record. Tests about a box kept after its shell exits now create an until_stopped box. The rpc shutdown test no longer answers a prompt. * fix(minimald): retry the exited-record write when an entrypoint ends The host and the watch are gone by the time the write runs, so a single failed write left the box running with nothing in it. Retry it with a short backoff, and pin the retry with a test seam. * test(e2e): expect an exited box, not a prompt, when a shell exits The session-exit prompt is gone: exiting the shell ends the box, which stays listed as exited. The pty driver no longer answers a prompt. Each leg that exited a shell now checks the box is exited with code 0, and destroys it where it used to answer Delete. * docs(minimald): put the launch-record seam doc back on its module * test(e2e): resume the exited kept box before the exec into it An exec runs only in a running box. After the shell exits and the row is withdrawn, the leg now resumes the box with a pty 'min session attach', checks that it runs under the same id and that its row is back, and then runs the exec as before. * test(minimald): fail when the channel stays open after shell exit The wait loop ended on a timeout as well as on close, so the test passed even if the channel never closed. Panic on the timeout. * fix(minimald): end an exited box before a queued attach or exec A message queued beside a returned entrypoint ran first and launched a new host, so the entrypoint ran again and its exit was lost. Now only a stop or a destroy goes ahead of the exit, and ensure_host refuses a stopped or exited box. --------- Co-authored-by: minimal-foundry[bot] <327719912+minimal-foundry[bot]@users.noreply.github.com> * build(deps): bump sysinfo to 0.40 sysinfo 0.40 makes System construction fallible (System::new returns Result<System, sysinfo::Error>). The three callers keep their 0.39 behaviour on an unsupported platform: minvmd's metrics sample and minimald's resource-pool probe return None, and minvmd's host capacity probe reports zero memory. Unblocks the dependabot cargo group (#2844), which bumped sysinfo without migrating the callers. --------- Co-authored-by: Karl Godard <karl@minimal.dev> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: minimal-foundry[bot] <327719912+minimal-foundry[bot]@users.noreply.github.com>
norrietaylor
pushed a commit
that referenced
this pull request
Nov 4, 2026
Merged
norrietaylor
pushed a commit
that referenced
this pull request
Nov 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Cargo.lock only: pulldown-cmark 0.13.5 → 0.13.6. RUSTSEC-2026-0433 fails cargo-deny in every merge group until this lands.
🤖 Generated with Claude Code
https://claude.ai/code/session_01NSAwDroXL6KqsSxUzdbZGw