the launcher opens a session instead of refusing one - #13
Merged
Conversation
The channel flag is variadic, so the prompt written after it was read as a channel entry and claude refused the launch outright — the first real use of this script died on "entries must be tagged: /oss:tick" without opening anything. The prompt goes first now and the flag last, the ordering the launcher this borrows from already proved. That flag also resolves configured MCP servers only, so naming one that is not registered refuses the launch the same way. The consumer is registered here at local scope, its path read from installed_plugins.json rather than globbed out of the plugin cache, which answers with whichever version sorts last. When there is no consumer to register the flag is dropped and the missing half is named: a session with no board beats no session. Tests pin HOME for the same reason they already pin PATH — the consumer is looked up under ~/.claude, so an unpinned HOME decides the assertion by whether the developer running the suite happens to have supertool installed. Co-Authored-By: Max <noreply>
`python3` by name is a POSIX assumption: Windows ships `python` and no `python3`, and its App Execution Alias supplies a `python` that exists and opens a store page rather than running. The launcher now proves each candidate by running it, the route scripts/doctor.sh already takes, so the channel name and the consumer path stop being silently unreadable there. The same assumption sat in the config tests, where it did more damage: with `python3` absent, the timeout and not-found cases both ran a command that does not exist, so both reported `failed` and the states they exist to tell apart were never exercised on that platform. They build the command from sys.executable now. And verify_test_command read only 127 as "command not found" -- the POSIX shell's code. cmd.exe answers 9009, so every missing runner on Windows was reported as a failing suite, which sends somebody to debug a suite that was never installed. The changelog entries move into fragments now that a real issue number exists to key them on, which is what changelog.d/README.md said it was waiting for. Co-Authored-By: Max <noreply>
`[ -n "$x" ] && cmd <<HEREDOC ... || true` inside a command substitution is a syntax error under bash -- `syntax error near unexpected token ||` -- and every local run stayed green because macOS ships bash 3.2 as /bin/sh and it parses that shape. The guard is a plain `if` now, which both parse. The changelog job never installed markdown-it-py. The checker refuses to fall back to text scanning without it and exits non-zero saying so, which is the right refusal -- three text-scanning fallbacks shipped upstream and all three were bypassed within one audit -- so the gate failed on its parser rather than on a fragment the first time it ran for real. Co-Authored-By: Max <noreply>
Both python lookups in the launcher had their stderr sent to /dev/null, so an absent registry, a supertool that is not installed and an install path that no longer holds the consumer all arrived as one "not found" — which is the shape that reports a confident wrong answer and sends whoever reads it to the wrong remedy. Each dead end says which one it is now, and the diagnostics are no longer swallowed. verify_test_command resolves the runner with which() before running anything. The shell's own "command not found" code is not portable — POSIX answers 127, cmd.exe answers 9009, and a GitHub Windows runner answered neither, so a runner that was never installed reported as a suite that ran and failed. That is the one confusion the four states exist to prevent. The precheck is skipped when the command carries a shell operator, where the first word is not the whole story. Co-Authored-By: Max <noreply>
The pinned PATH was the stub directory plus /usr/bin and /bin. Those are Git Bash's on Windows and hold no python, so the launcher had none to read the channel name or find the consumer with — it said so correctly, and three channel tests failed against a fixture problem wearing a product bug's clothes. The interpreter running the suite is on the PATH now; the pin still keeps the real claude out of reach, which is what it was for. Co-Authored-By: Max <noreply>
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.
oss-workspacefailed the first time it was run for real:The flag is variadic, so the prompt written after it was read as one of its values and
clauderefused the launch rather than degrading. The prompt goes first now and the flag last — the orderingclaude-supertool's launcher already proved and this one dropped when it was extracted.Two things behind that, both measured rather than assumed:
installed_plugins.jsonrather than globbed out of the plugin cache — a glob answers with whichever version sorts last, which is a version the session is not running. That exact bug already shipped once inscripts/doctor.py.bunis missing, the session opens without the channel and stderr names the half that is missing. Refusing to launch over a board nobody asked for is worse than launching without it.Tests pin
HOMEfor the same reason they already pinPATH: the consumer is looked up under~/.claude, so an unpinned HOME decides the channel assertions by whether whoever runs the suite happens to have supertool installed — green here, red on a contributor's machine. Four new cases cover the argv ordering, the registered path, the unregistered path, and the fact that editing someone's MCP config is said out loud with the removal command.The bashism guard moved from substring to statement-position matching:
-s localand prose about local scope both tripped it. A test that is wrong in the direction of stopping you still gets edited around rather than heeded.258 tests, 92%, shellcheck clean.