Fix what a clean-room reconstruction of the spec found - #539
Merged
Conversation
added 3 commits
August 30, 2026 16:56
README said `dl blooop/devlaunch` names the pane `devlaunch-main-3j1t`, "the workspace id, the same string `dl --ls` prints and the container's hostname carries". docs/workspace-tools.md:511 says the opposite about the same command: the pane is `devlaunch@main`, the id read for a person with the hashed suffix off, *where* `dl --ls` and the hostname say `devlaunch-main-3j1t`. The docs page is right. `titled()` in flows/launch.rs:2850 answers `workspace.label()` whenever the devpod id is the derived one, which is every launch that does not name a recorded id, and `an_id_metadata_recorded_is_titled_ by_that_id_and_not_by_the_triples_label` pins the one arm that differs. The README sentence is the pre-change behaviour that workspace-tools.md:530 already describes as what it "used to be". Nothing caught it: the README's guard (test_readme_cli_doc.py) holds flags to being mentioned, not claims to being true, so the most read sentence about this feature was the least checked one. Found by a clean-room reconstruction of the spec from the CLI surface, the docs and the test names alone, with the implementation withheld.
docs/cli.md writes `dl <ws> rm --force` a dozen times and never says that the position is load-bearing. It is: `--force` has to follow both the workspace and the verb. In the verb slot it is read as the verb (`Unknown command '--force'`) and in the workspace slot as the workspace (`Unknown workspace '--force'`), both exit 1 with nothing deleted. A global command has no slot for it to fall into, so `dl --force --prune` and `dl --prune --force` are one line. Two rules for one spelling, discoverable only by being refused, and written down until now only in the names of the tests that pin them. This says it once beside the docker paragraph that already explains which `--force` is which, and cites those tests so the rule and its guard are one lookup apart.
The terminal title is stated on two pages: the README's feature list, where a reader meets it, and docs/workspace-tools.md, where the reasoning for the spelling lives. That is a second hand-maintained copy of one fact, which this repository allows only with a test beside it that diffs the copies. The rule earned the test rather than being applied on principle. The two pages had already drifted apart on this exact sentence, in opposite directions, about the same example command, and nothing failed: the README's guard holds a flag to being mentioned, not a claim to being true. The instrument is the sentence both pages already write, "names the pane `<x>`", so neither carries a marker for this test's benefit and a page that drops the claim fails here rather than passing quietly. Reverting the README to its old wording reproduces the failure.
Reviewer's GuideThis documentation-focused PR fixes an incorrect README terminal-title example, specifies positional Flow diagram for positional force flag handlingflowchart TD
A[Parse CLI arguments] --> B{Command is global?}
B -->|Yes| C[Accept --force in either position]
B -->|No| D{--force follows workspace and verb?}
D -->|Yes| E[Execute workspace verb]
D -->|No| F[Return argument error and delete nothing]
Flow diagram for synchronized terminal-title documentationflowchart LR
A[README title claim] --> C[Title consistency regression test]
B[workspace-tools title claim] --> C
C -->|Claims agree| D[Documentation passes]
C -->|Claims differ or missing| E[Test fails]
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
A fresh-context review of this branch found the `--force` paragraph asserting a
rule the grammar does not implement, and the title guard pinning something
weaker than it claimed. Both are fixed here.
**The paragraph generalised two cases into a law.** It said a misplaced `--force`
"refuses rather than being dropped". True of the workspace and verb slots; false
of everything past the verb, where only `rm` and `rme` read the flag and
`up`, `stop`, `kill`, `code`, `restart`, `recreate`, `reset` and `dotfiles` take
it and discard it in silence. cli.rs says so twice already ("the flag is the
no-op it is on `up` and `stop`"; "every other verb drops it on the floor") and
README says there is no `dl <ws> kill --force` to type, which in fact parses.
Verified against the built binary rather than inferred. The section now states
both halves, names `kill` as the one worth remembering, and adds the selector
form, which cannot be forced at all: `dl rm --force` is the verb-slot refusal and
its suggested `dl rm -- --force` would run the flag as a shell command.
It also moved. Sitting inside `### --rm: the throwaway workspace` it separated
"It stops at work that is nowhere else" from the `--rm` that sentence's "It"
refers to, and handed the reader `--force` as the antecedent: the exact thing
that goes past that check. It is its own section now, beside the other
grammar sections, and cites the 259-ordering matrix test that is its thesis.
**The guard pinned agreement, not truth.** It diffed two prose pages, so the
inverted repair, editing the docs page down to the README's wrong string, would
have passed it while reporting that `titled()` had been consulted. It had not.
`flows/launch.rs` carries the same sentence verbatim and is the one copy that
cannot be wrong without the behaviour being wrong, so the prose is now held
against it. Both drift directions are checked, including that inverted one.
Anchoring the regex on the example command fixes two more: it no longer matches
inside "every prompt *renames* the pane", which the docs and provision.rs both
say of the prompt's own later write, and set equality no longer forbids `docs/`
from documenting the examples that are titled differently, which it does.
Also: the README named one of the title's two transformations, and dropping the
suffix alone gives `devlaunch-main`, not `devlaunch@main`. Both are named now,
with the id-named case the docs page already covers. And all three copies cite
the guard, so whoever edits one learns the other two exist.
The guard added in 25cb71c and rebuilt in f0d2e4d claimed to hold the prose against the module that computes the title. It did not. What it read out of `flows/launch.rs` is a `///` comment, matched by the same regex it runs over the two Markdown pages, so all three sources were prose and the third only looked different. The commit message and the PR description both rest on the sentence "the one copy that cannot be wrong without the behaviour being wrong", and that was the copy the compiler never reads. Reproduced rather than argued. Change the separator in `WorkspaceId::label`, update the one assertion that pins it so `cargo test` goes green again, leave the prose alone: the old guard passes on three pages that are now all wrong. That is the same blind spot the two-page version had, needing one more simultaneous edit. The answer now comes from that assertion. `a_label_is_the_id_with_the_suffix_off_ and_an_at_where_the_dash_was` gains the example every page writes about, and the guard reads the literal out of it. It is the only copy that cannot be wrong without a test failing, because it is compared against what `label()` returns every time the suite runs. Rerunning the mutation now fails the guard, as do drifts in each of the four prose copies taken one at a time. Three smaller defects in the same six lines, fixed here because the rewrite lands on top of them: - `docs/workspaces.md` states the same name twice, in the table of the three renderings and the sentence under it, and nothing read it. Its table row is now a source, so the count is four. - The one-answer check said "states more than one pane name" when it had found none, which is the reachable case: reword the assertion and the message names a number it is not. It now reports the count it saw. - `truth` was a second hand-written spelling of a path already in `SOURCES`. If they drifted the guard raised `FileNotFoundError` instead of failing by name. One literal now, and a missing file fails with a sentence. The prose moves in the same commit because it describes the guard: `launch.rs` said the pages are diffed "against this one", the README and `docs/workspace-tools.md` said "the three", and all three said the guard diffs the *sentence* when it diffs one backticked name. Splitting those out would leave a commit whose tree states something false. The README also cited `rust/.../flows/launch.rs`, a path that greps to nothing, which the standing rule on citations forbids and `test_citations_resolve.py` does not reach. Claude-Session: https://claude.ai/code/session_01Lxs53nxfvou4SiPeFx4TZv
The formatter's own output on the previous commit. Kept separate rather than amended so the branch history stays append-only. Claude-Session: https://claude.ai/code/session_01Lxs53nxfvou4SiPeFx4TZv
The `--force` section added in ee0119a writes both refusals into a code block: dl <ws> --force rm -> Unknown command '--force'. dl --force <ws> rm -> Unknown workspace '--force'. Those are the only diagnostics quoted verbatim anywhere in `docs/cli.md`, and this diff introduced both. They are a second hand-maintained copy of strings `render.rs` and `lib.rs` own, which this repository allows only with a test beside them that diffs them against the first, and the same rule this branch exists to apply to the terminal title. The section already cites three tests, but citing is not diffing: every one of them pins the *behaviour*, so all three stay green with the message reworded and the page left quoting the old one. Reword `Unknown command` to `Unknown verb` in the binary and nothing fails. `the_force_placement_section_quotes_the_refusals_it_says_it_does` reads the section back and asserts each quoted refusal is a prefix of what the binary actually prints, alongside the exit code and the clone still being there. A prefix because the block drops the `Use '...'` suggestion deliberately: it is quoting the refusal, not transcribing the session. Confirmed red by making that reword in the doc and green with it restored. It reads the page the way `provision::lending_contract` reads `docs/workspace-tools.md`, matching on the heading rather than on any phrase under it, so the prose stays free to be rewritten. A renamed heading panics with the name it looked for instead of yielding an empty section every assertion passes over. Claude-Session: https://claude.ai/code/session_01Lxs53nxfvou4SiPeFx4TZv
The branch's answer to "the README and the docs page disagree about the terminal
title" was a guard that held the copies to each other. Reviewing it turned up the
same defect twice: the copy it called authoritative was a doc comment nothing
checks, and the count kept being wrong. A guard whose own correctness argument has
needed fixing twice is the wrong instrument for four sentences.
So there is one place that writes the tab's spelling now: the renderings table in
`docs/workspaces.md`, beside the id and the selector row it is meant to be matched
against. That table is the reason the fact wants to be written down at all, and it
is the only page that publishes all three side by side.
Everything else states the rule and links:
- `README.md` says the suffix comes off and the dash before the branch is spelled
`@`, and links to the table. It loses the worked example, which is the real cost
of this shape and the reason it was worth asking about.
- `docs/workspace-tools.md` keeps the whole explanation of *why* the spelling is
what it is, and points at the table for the value. It still shows the name inside
the escape sequence and the `PS1` line, which are illustrations of the mechanism
rather than statements of the answer, and the prose now says so.
- `flows/launch.rs` names `docs/workspaces.md` and stops writing the string. A doc
comment is exactly the copy that goes stale, which is what the deleted guard got
wrong about itself.
`test_title_claim_agrees.py` is deleted, 114 lines. The standing rule it was
answering only bites on a second hand-maintained copy, and there is no longer one.
What survives is the assertion the guard was eventually anchored to.
`a_label_is_the_id_with_the_suffix_off_and_an_at_where_the_dash_was` still pins
`("blooop", "devlaunch", "main")` to `devlaunch@main`, which is the cell the table
publishes, and `docs/workspaces.md` names it. That is one test checking one
published string against what `label()` returns, rather than a regex reading three
pages and a doc comment.
The `--force` guard added in the previous commit stays. A page quoting a
program's diagnostics is a copy no amount of single-sourcing removes.
Claude-Session: https://claude.ai/code/session_01Lxs53nxfvou4SiPeFx4TZv
`the_force_placement_section_quotes_the_refusals_it_says_it_does`, added two
commits ago, compared the doc's quote to the binary's stderr with
`run.err.starts_with("ed)`. `quoted` is a `String` built by splitting the doc
line at `->`, so "the refusal the page quotes" and "the page quoted nothing" are
the same value, and `starts_with("")` is true of every string.
Reachable from an ordinary edit. Reflow the code block so the message wraps below
the arrow:
dl <ws> --force rm ->
Unknown command '--force'. (exit 1, nothing deleted)
`split_once("->")` returns an empty tail, and the assertion carrying the test's
whole claim asserts nothing. I applied exactly that to `docs/cli.md` and the test
reported 1 passed. The two remaining assertions in the loop cannot catch it: the
exit code is 1 for both spellings by construction and neither line deletes a
clone, so they hold no matter what the binary says. From that point the message
could be reworded freely while `docs/cli.md` went on citing this test by name as
what diffs the quote against what the binary prints.
Nothing bounded the prefix below, either: quoting `Unknown` and nothing else
passed too.
Both close the same way. The quote is now compared for equality against the
message's first sentence, which is the span the page actually writes, so a quote
that is empty or truncated fails on the same assertion as a quote that is stale.
Six mutations now fail where two of them passed before: the empty capture, the
truncation to `Unknown`, a reworded quote, a reworded binary message, a renamed
spelling and a renamed heading.
Claude-Session: https://claude.ai/code/session_01Lxs53nxfvou4SiPeFx4TZv
018277d deleted the title guard on the grounds that the fact now had one copy, and said so in three places. It had four. `docs/workspace-tools.md` went on stating the answer for a named command twice, outside the two exemptions that commit's own prose enumerated: line 549 a workspace opened from the selector is titled `devlaunch@main`, the same as one opened as `dl blooop/devlaunch@main` line 599 `dl blooop/devlaunch@main` installs `devlaunch@main`, a later `dl devlaunch-main-3j1t` installs the id `rust/dl/src/select.rs` carried a third. Neither doc sentence is showing a mechanism the way the escape sequence and the `PS1` line are; each tells the reader what a specific command produces, which is exactly what the README was doing wrong when 1e2a24b opened this branch. Apply the branch's own test: move the separator in `WorkspaceId::label`, fix the one assertion, and all three sentences are wrong with nothing failing. Deleting the guard while they stood left the fact less protected than the commit claimed, on the page that explains the feature. None of the three needed the literal. The selector sentence is about the title being the *same* as a spec launch, so it now says that and nothing else. The profile sentence is drawing the contrast between the readable name and the id, so it names them rather than spelling one. `select.rs` points at the table. The claims are corrected to what is true rather than widened to fit: the table is where the tab's spelling is *decided*, and no other page states it as the answer to a command. What survives elsewhere is inside an example of the mechanism, which the prose now says and a reader can check: the OSC line, the `PS1` line and the contrast that explains why the character is `@`. Found by the Spec and Defects axes independently, which is the second time on this branch that a commit message's claim about its own guarantee has been the defect rather than the code. Claude-Session: https://claude.ai/code/session_01Lxs53nxfvou4SiPeFx4TZv
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.
Three fixes, all of them defects found by reconstructing this tool's specification from its observable surface alone, with the implementation withheld.
How they were found
Five agents were each given a sealed corpus and asked to write the implementation spec they would hand to an engineer:
README.md, the six user-facingdocs/pages, verbatimdl --helpandaid --help, and an index of all 2,496 test names with no bodies. No source, noCLAUDE.md, nodevelopment.md, and neither archival planning document, sincerust-rewrite-plan.mdstates the layer decision outright and would have given the answer away.The primary result is not in this diff and is worth recording: three of the five reconstructed the real architecture (four layers,
runnertoclientstodomaintoflows, dependencies strictly downward, the crate split withdevlaunch-runneras a leaf,render.rsowning every user-facing byte). One inferred that a fitness test must exist asserting only one type spawns processes, which isrust/devlaunch-runner/tests/one_seam.rs. The architecture is legible from outside the implementation. What the exercise actually produced was a list of places where the documented behaviour is wrong, underspecified, or self-contradictory, which is what is fixed here.Every claim was verified against the tree before being acted on. One in the same batch was verified and rejected: that the delete guard inspects a recorded clone while the delete removes a derived one. Both route through the same
resolve_clone_path, so it is not a defect and nothing here changes it.1. The README said the wrong thing about the terminal title
README.mdsaiddl blooop/devlaunchnames the panedevlaunch-main-3j1t, "the workspace id, the same stringdl --lsprints and the container's hostname carries".docs/workspace-tools.mdsays the opposite about the same command: the pane isdevlaunch@main, and it contrasts that against exactly the string the README asserted.The docs page is right.
titled()inrust/devlaunch-core/src/flows/launch.rsanswersworkspace.label()whenever the devpod id is the derived one, which is every launch that does not name a recorded id, andan_id_metadata_recorded_is_titled_by_that_id_and_not_by_the_triples_labelpins the single arm that differs. The README was describing behaviour thatworkspace-tools.mdalready calls what it "used to be".2. Where
--forcemay sit was undocumented, and the first attempt got the rule wrongdocs/cli.mdwrites the flag in the trailing position a dozen times without saying the position is load-bearing. The rule has two halves, and the first version of this PR documented only the first and generalised it into a law:Unknown command '--force'); in the workspace slot as the workspace (Unknown workspace '--force'). Both exit 1, nothing deleted.rmandrmedo anything with it.up,stop,kill,code,restart,recreate,resetanddotfilestake the flag and drop it silently. That is the one place this grammar discards a word rather than refusing it, andkillis the case worth remembering, since the README says there is nodl WORKSPACE kill --forceto type and in fact it parses.dl rm --forceis the verb-slot refusal, and its suggesteddl rm -- --forcewould run the flag as a shell command.dl --force --pruneanddl --prune --forceare one line.The original text claimed "a flag that has landed somewhere it cannot mean what you meant refuses rather than being dropped", which is true of the first bullet and false of the second.
cli.rssays so twice already ("the flag is the no-op it is onupandstop"; "every other verb drops it on the floor"). Verified against the built binary rather than inferred.It is now its own section beside the other grammar sections rather than inside
### --rm: the throwaway workspace, where it had separated "It stops at work that is nowhere else" from the--rmthat sentence's "It" refers to, handing the reader--forceas the antecedent: the exact thing that goes past that check.The section quotes both refusals, which makes them a second copy of strings
render.rsandlib.rsown.the_force_placement_section_quotes_the_refusals_it_says_it_doesreads the section back and diffs each quoted refusal against what the binary prints. The three tests the section already cited all pin the behaviour, so every one of them stays green with the message reworded and the page left quoting the old one.3. One fact was written in four places, and is now written in one
The terminal title was stated in the README's feature list, in
docs/workspaces.md, indocs/workspace-tools.mdand inflows/launch.rs. The standing rule permits copies only with a test beside them that diffs them, so the first two attempts here added one.Both were wrong in the same way, and the second one's commit message asserted the opposite. It claimed
flows/launch.rswas "the one copy that cannot be wrong without the behaviour being wrong" and held the prose against it. What the guard could read there was a///comment, which the compiler never checks: move the separator inWorkspaceId::label, update the one assertion that pins it, leave the prose alone, and the guard passes on four pages that are all now wrong. Reproduced rather than argued.So the copies are gone instead. The renderings table in
docs/workspaces.mdis where the tab's spelling is decided, beside the id and the selector row it exists to be matched against, and no other page states it as the answer to a command. Getting that true took one more commit: the first attempt at it said "one place" whiledocs/workspace-tools.mdwas still telling the reader what two named commands produce, andselect.rsa third. Those now name the readable name rather than spelling it. What survives elsewhere is inside an example of the mechanism, which the prose says and a reader can check.README.mdstates the rule and links to it, losing its worked example, which is the real cost of this shape.docs/workspace-tools.mdkeeps the whole explanation of why the spelling is what it is and points at the table for the value; it still shows the name inside the escape sequence and thePS1line, and now says those illustrate the mechanism rather than settle it.flows/launch.rsnames the page and stops writing the string, a doc comment being exactly the copy that goes stale.test_title_claim_agrees.pyis deleted. What survives is the assertion it was eventually anchored to:a_label_is_the_id_with_the_suffix_off_and_an_at_where_the_dash_waspins("blooop", "devlaunch", "main")todevlaunch@main, which is the cell the table publishes, anddocs/workspaces.mdnames it. One test checking one published string against whatlabel()returns.Deliberately not fixed here
dl --lsis serial, onedevpod statusper workspace. Now #540.reconcile.rsjoins by path and never by id, plus a resumable two-phase migration. Already in flight in recent commits.every_row_carries_its_own_index_or_marking_cannot_accumulateshows indices already exist.Worth a separate look: roughly thirty tests pin behaviour byte-for-byte against the retired Python build, an oracle nothing can run any more, while
names_python_refuses_for_exotic_unicode_are_accepted_hererecords where the parity is deliberately partial.Testing
test/minuse2e: 663 pass.cargo test --workspacepasses exceptflows::provision::tests::the_probe_reports_the_config_facts_when_it_actually_runs, which fails identically on an unmodifiedorigin/HEADworktree in this container and passes in CI.cargo clippy --locked --all-targets -- -D warningsandcargo fmt --checkclean. The only behaviouralrust/change is the new grammar test;workspace_id.rsgains one assertion andlaunch.rsone doc comment edit.Summary by Sourcery
Correct workspace terminal naming documentation and formalize
--forcegrammar behavior while consolidating the title specification and its verification.Bug Fixes:
--force, including rejected placements, silently ignored non-removal uses, and global-command handling.Enhancements:
--forcerefusal messages remain synchronized with the CLI output.Documentation:
--forcein the CLI and workspace documentation.Tests:
--forceplacement and documentation tests that verify quoted diagnostics match the binary.Chores: