The sandbox guide's dev-container step is unfollowable from a cold start — a command palette it never says how to open, a file a GUI file manager refuses to create, and a command that only exists once the folder is already open
What the page says today
lib/apiDocs/sandbox.ts — step 3 ("Or start it from VS Code instead") has three sub-steps: 1 · install the Dev Containers extension (line 227), 2 · add the file (line 231), 3 · run the palette command (line 255). Nowhere in those three does the reader open the command palette, or open the folder in VS Code. Three defects follow, in the order a reader meets them.
Defect A — the palette it never says how to open (line 227, again at 255)
1 · Install the Dev Containers extension. From the Extensions view, or the command palette's Extensions: Install Extensions.
The command palette is the page's instrument for two of the three sub-steps, and the page never says how to open it. A reader who does not already know the chord is stopped at the first sub-step — before the file, before the container. Every route should be named at FIRST use (line 227), not at the second mention:
- ⇧⌘P (macOS) · Ctrl+Shift+P (Windows/Linux)
- F1 on all three
- View → Command Palette… — the discoverable route, for a reader who would rather not hold a chord
Defect B — the file the reader cannot create (line 231)
2 · Add
.devcontainer/devcontainer.jsonto the folder you are mounting — the same one step 2 would have started from. It pins the published image and passes the mount your profile needs:
…followed by the JSON code block (caption .devcontainer/devcontainer.json, line 235). Between that sentence and sub-step 3 the page gives no way to produce the file. Every other step on the page hands over a runnable command; this one hands over a filename.
That is a wall for anyone not already living in a terminal: macOS Finder — and most GUI file pickers — reject a name beginning with ., so "add .devcontainer/devcontainer.json" is an instruction the reader's file manager refuses to carry out, with no error text that names the reason.
Defect C — the wrong palette command (line 255)
3 · Reopen in Container. Command palette → Dev Containers: Reopen in Container.
"Reopen" presumes the folder is already open in VS Code, and no earlier step opened it. A reader arriving from sub-step 2 — who created the folder in a terminal, or opened VS Code fresh — has either no folder open or a different one, and the command is absent from the palette or reopens the wrong workspace. The command that works from the state this procedure actually leaves the reader in is:
Dev Containers: Open Folder in Container… — it prompts for the folder, then does the same attach.
The one cause
All three are the same omission wearing three hats: the step was written from the memory of someone whose VS Code was already open, already in the right folder, already palette-fluent. The three things that person never has to do are precisely the three the page never says.
What to change
- Sub-step 1 (line 227): name the palette's keystrokes and its menu route at first use.
- Sub-step 2 (line 231): between the existing text block and the JSON code block, a shell snippet that creates the folder and writes the file, plus a short line on the GUI routes that do accept a dot-name.
- Sub-step 3 (line 255): lead with
Dev Containers: Open Folder in Container…, and keepReopen in Containeronly as the named alternative for a reader who already has the folder open — stating that condition, since it is the whole difference between the two.
The shell snippet MUST use a quoted heredoc delimiter — <<'JSON' — so ${localWorkspaceFolder} and ${localEnv:HOME} survive into the file un-expanded. An unquoted heredoc silently writes empty strings for both and produces a devcontainer that mounts the wrong paths, which is a worse failure than any defect above.
Acceptance criteria
- Sub-step 1 names how to open the command palette — both keystrokes (⇧⌘P / Ctrl+Shift+P) and the View → Command Palette… menu route — at the point the page first tells the reader to use it, not at the second mention.
- Step 3 contains a code block whose command creates
.devcontainer/and writesdevcontainer.json, and that command's heredoc delimiter is quoted (<<'JSON'), asserted by a test that greps the shipped content for the quoted form. - The same sub-step names at least one GUI route that accepts a dot-prefixed path — VS Code's Explorer → New File typed as the full path
.devcontainer/devcontainer.json(it creates the intermediate folder), and/or the palette's Dev Containers: Add Dev Container Configuration Files…. - One sentence states why that snippet exists: a GUI file manager will refuse the name. Without the reason the reader does not know the workaround is for them.
- Sub-step 3 names
Dev Containers: Open Folder in Container…as the command to run. IfReopen in Containerstill appears, it appears with its precondition stated ("if the folder is already open in VS Code") — never as the sole instruction. - The JSON the snippet writes is the SAME object the existing code block shows — no second, drifting copy. Derive both from one source in the module, or assert their equality in the truth test.
sandbox-truth.test.tsxstill passes, andlib/apiDocs/sandbox.tsholds its ≥90% per-file coverage floor (this file has been under that gate since MOTIR-2314).- Both the
enandzhcatalogs carry any new reader-facing string.
Out of scope
The published image's obtainability. ghcr.io/moooon-b-v/motir-sandbox:claude was re-probed anonymously on 2026-08-10 and returns HTTP 200 on its manifest — the visibility flip from MOTIR-2009 / MOTIR-2010 holds, so the page needs no docker login caveat and must not grow one.