You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix: name the agent binary devpod picked from a hostname
Section 3 of #560, as far as dl can honestly reach it.
devpod chooses which agent binary to inject by globbing `uname -a` for `arm`,
and `uname -a` prints the nodename beside the machine. So a container whose
hostname holds `arm` reads as an ARM machine, devpod downloads the arm64 agent,
the version check cannot execute it, and the launch dies with `exit status
126` -- "not executable", which names neither the architecture nor the word
that chose it. dl is one of the ways the word gets there: its setup pass sets
the container's hostname to the workspace id, and a workspace id is derived
from the branch, so `feature/armature` is enough.
A refused `devpod up` of a workspace whose id contains `arm` now carries one
line of dl's own, beside devpod's sentence and without changing the exit code.
The line is a conditional, and that is the honest limit rather than hedging.
dl runs the `up` as a passthrough, because an image build's progress belongs on
the user's terminal rather than through a pipe, so dl never reads devpod's
message: what it holds is a nonzero exit and a name. That is enough to know the
trap is set and not enough to know it fired, so the sentence says what to look
for in devpod's own output above it. Reading that output instead would mean
piping the build through dl -- changing what devpod renders, and dropping the
process group that lets a Ctrl-C tear a build down rather than orphan it
holding the launch lock, since `Runner::session` starts its child with
`OwnGroup::No` where the `up` needs `Yes` (#304).
`clients::devpod::reads_as_arm` transcribes devpod's four globs, uncase-folded
because a shell `case` is, and answers for a machine name as readily as for a
hostname -- which is what the exemption reads: a host that is itself ARM gets
no line, because there devpod's guess is right.
The upstream fix is one line (glob `uname -m`) and is not here.
Claude-Session: https://claude.ai/code/session_01Dn4qJGhkW4KdwQnMuNSXsN
Copy file name to clipboardExpand all lines: docs/rust-rewrite-plan.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -198,6 +198,7 @@ Nothing diverges silently.
198
198
| 32 | **`--rm` is docker's `--rm`, and the flag-spelled verbs are retired.** `dl <ws> --rm` and `dl <ws> --rm -- <cmd>` now hand over a session and delete the workspace once it ends — what row 30's `--autorm` did, under the name docker gives it. The word `rm` is unchanged and is the only way to delete one *now*, so `docker rm` / `docker run --rm` is the whole of the grammar and no spelling has to be read twice. Three withdrawals pay for it, each refused at exit 1 rather than reinterpreted: `--autorm` (`--autorm is now spelled --rm: …`); `--stop`, whose only reason to exist was being a flag (rows 15 and 30) and which cannot stay a *cancelling* suffix beside a `--rm` that runs the line; and row 30's suffix override itself, so `aid <ws> 'review this pr' --rm` now runs the review and deletes afterwards where it used to delete instead, and `dl prune <ws> --rm` is row 31's refusal rather than a removal (with `--force` also on the line it is the `--force`-beside-`--rm` refusal instead, named first because the pair is the more confused half). `--force` still does not compose with `--rm` — docker keeps `-f` on `rm` too — and `dl <ws> rm --rm` is refused as the two requests it is. Retired flags are answered *before* anything else the line got wrong, since both moved on account of `--rm`'s new meaning. aid peels the retired spellings so dl refuses them by name instead of joining them into a prompt, and builds no agent command for such a line, so nothing is booted on the way to exit 1. `Overridden`, `pick_target` and the `--rm overrode the rest of the line` notice are gone with the override. | Row 30 bought "and now delete it" as a suffix and paid for it with a flag whose meaning was unguessable from its spelling: `--rm` cancelled the line, `--autorm` ran it, and the two looked like a pair. docker had already split the same problem the other way — a verb for now, a `run` flag for after — and taking that split makes the common line (`aid <ws> <prompt> --rm`: send the agent in, get the disk back) the one the short spelling names, at the cost of the rarer one, which `dl rm` and a pick does in fewer keystrokes than recalling a long prompt to append to it. The withdrawals are recognised rather than deleted, for row 31's reason: a flag dropped from `Cli` is clap's `unexpected argument` at exit 2, naming the spelling and not the replacement — and the spelling is exactly what cannot explain a line that stopped working because a *different* flag changed meaning. Pinned by the `retired_flag` / `rm_` tests in `dl/src/cli.rs`, `the_retired_flag_spellings_name_the_words_that_replaced_them` and `autorm_is_refused_with_the_spelling_that_replaced_it` in `dl/tests/lifecycle.rs`, the `rm_on_exit_` tests in `dl/tests/launch.rs`, and `a_retired_spelling_starts_no_agent_and_is_handed_to_dl_to_refuse` in `aid/src/rewrite.rs`. |
199
199
| 33 | **A warm launch of a triple says how far behind its checkout is.** `dl owner/repo@branch` against a workspace devpod already knows prints one line before the attach banner when the clone's `HEAD` is behind the `refs/remotes/origin/<branch>` that clone last fetched, naming the count both ways (`its checkout is 37 commits behind origin/main … (and 3 of its own it has not pushed)`). Python printed nothing, and neither did earlier Rust. The launch still runs no fetch: the report is one `rev-list` against a local repository, so it says how the checkout stands against a ref of whatever age and never claims to know the remote. Silent when the counts agree, when the checkout is only ahead, when there is no clone on disk, for a bare workspace name (no triple, so no branch to name and no clone path to derive), and for a warm resolution addressed by an id `metadata.json` recorded rather than the one the triple derives (devlaunch#88's arm, where the derived clone path is not this container's source). `reset`'s help line and the README table stopped saying "Clean slate: remove everything, recreate" in the same change, because that promise reads as one about the checkout and `reset` cannot keep it. | The warm arm makes no git call and never will (devlaunch#144, built by #149 and #150), and a launch that looks like it verified new work when it verified neither the commit nor the image invalidates whatever was concluded inside the container. A fetch on attach was the tempting fix and is the wrong trade; the fact was available locally the whole time. Pinned by the `checkout`/`warm_triple` tests in `flows::launch` and by `a_warm_triple_whose_checkout_is_behind_says_how_far_and_still_runs_no_git_fetch` plus `a_bare_workspace_name_reports_no_checkout_however_stale_it_is` in `dl/tests/launch.rs`, whose world is `launch_scenario.py`'s `--stale-checkout`. blooop/devlaunch#560 §1. |
200
200
| 34 | **Every `devpod up` says whether it forwarded dotfiles.** One line per `up`: the repository and script it passed, or that devpod's context options name none and where to set one. Python read `devpod context options`, silently forwarded `--dotfiles`/`--dotfiles-script` or silently omitted them, and left no way from the terminal to tell which had happened. An attach that runs no `up` prints neither line. | Three plausible causes and no observation to cut between them is what turned "the dotfiles never landed" into a fortnight: `DOTFILES_URL` is read out of `devpod context options` and out of nothing else, not the process environment and not `~/.devpod/config.yaml`, and `context-options.json` is dl's *cache* of that answer rather than an input. The line costs nothing on a path that is already spawning a container build, and it makes a silent policy checkable. Pinned by `an_up_says_which_dotfiles_it_asked_devpod_for_and_the_argv_agrees` in `dl/tests/launch.rs`, which asserts the sentence and the argv together so the two cannot drift. blooop/devlaunch#560 §2. |
201
+
| 35 | **A refused `devpod up` of a workspace whose id contains `arm` gains one line of dl's own.** The refusal still renders nothing else and still exits with devpod's status; this is a second line beside it, phrased as a conditional (`If devpod said 'inject agent' and 'exit status 126' above, this is why: …`) naming the workspace id, the `*arm*` glob, the hostname `uname -a` carries, and the `docker cp` that unblocks a container already in that state. Python printed nothing. Silent for every other refusal, for an id with no `arm` in it, and on a host whose own architecture reads as ARM, where devpod's guess is correct. | devpod's `is_arm` globs `uname -a`, which prints the nodename beside the machine, so a branch named `armature` or `alarm` gets the arm64 agent on an x86 host and a launch that dies saying only "not executable" -- and dl is one of the ways the name gets there, since its setup pass sets the container's hostname to the workspace id. **The conditional is not hedging, it is the honest limit**: `devpod up` runs as a passthrough so its progress reaches the terminal directly, dl therefore never reads devpod's message, and what it holds is an exit code and a name. Matching devpod's stderr instead would mean piping the build through dl -- changing what devpod renders and, since `Runner::session` starts its child with `OwnGroup::No`, dropping the process group that lets a Ctrl-C `killpg` a build instead of orphaning it holding the launch lock (row 27, #304). One conditional sentence on a failed launch is the cheaper trade. `clients::devpod::reads_as_arm` is the transcription of devpod's four globs and answers for a machine name as readily as for a hostname, which is what the ARM-host exemption reads. Pinned by the `reads_as_arm` tests in `clients/devpod.rs`, the `arm_agent_hint` tests in `dl/src/render.rs`, and `a_failed_up_of_an_arm_named_workspace_names_the_agent_binary_devpod_picked` plus `an_ordinary_workspace_whose_up_failed_gets_no_arm_explanation` in `dl/tests/launch.rs`, whose world is `launch_scenario.py`'s `--arm-branch`. blooop/devlaunch#560 §3, whose upstream half (glob `uname -m`) is not fixed here. |
201
202
202
203
Additions require a PR that updates this table; the row number is cited by any
0 commit comments