fix(operator): answer bare skills and repos in mqlaunch's own words - #171
Merged
Conversation
Both commands, called with no argument, replied about something the operator
had not asked about:
$ mqlaunch skills
usage: mq-skills.py [-h] [--repo REPO] {audit,validate,new} ...
mq-skills.py: error: the following arguments are required: command exit 2
$ mqlaunch repos
GitHub repo picker needs a terminal. exit 1
skills handed over the delegate's file name and argparse's phrasing. repos
named a subject absent from the command line — bare repos routes to the hub,
an interactive picker — and offered no way forward, though six repos
subcommands work headless.
Message, usage and next step only. Exit statuses are deliberately unchanged: 2
for skills, a usage error either way; 1 for repos, because bare repos is valid
on a terminal, so the failure is the environment rather than the command line
and no caller's exit-code handling moves.
Two things left alone on purpose. An invalid skills verb still goes to the
delegate — its error names the word the operator typed, and intercepting it
would mean a second copy of the verb list. And on a terminal bare repos still
opens the hub.
tests/operator-usage-message-smoke.sh checks both halves: the new text, and
that skills audit, skills bogus, repos list and the hub path all still reach
their delegates. A fix that stopped delegating would pass a message-only
check. Run against the unfixed tree it fails at step 2 on the leaked script
name.
ROADMAP: the section still read "Status: Planned" with every box checked. It
now records the measuring pass, its five findings, the two fixed here and in
#169, and the one open decision.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…kout Step 4 ran `mqlaunch skills audit` for real and required it to report skills. That measures the machine: mq-skills.py scans the MQ repos, a CI runner has none, and the step failed there while passing locally. Same exposure in step 8 with mq-repos.py. Both now stub the delegate under a fake BASE_DIR and compare the command line the arm builds — which is what these two steps are actually about. Step 8 also widened from one subcommand to three, including one with an argument, so "forwards verbatim" covers arguments rather than just the verb. Proven able to fail. With the skills guard changed to fire on every invocation, the test stops at step 4 with EXIT=2; with the repos guard changed to never open the hub, it stops at step 7 with EXIT=1. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.
Second fix from the P2 operator inventory. Message, usage and next step only — no underlying functionality changed.
Measured
skillshands the operator the delegate's file name and argparse's phrasing for a command typed asmqlaunch skills.reposnames a subject that never appeared in the command line — barereposroutes to the hub, which is an interactive picker — and offers no way forward, even though sixrepossubcommands work fine headless.After
Both reuse
print_namespace_help, so the verb lists stay in the one place that already held them.Exit statuses are deliberately unchanged
skillsstays 2 — a missing verb is a usage error either way.reposstays 1 — barereposis valid on a terminal, so this is an environment failure, not a usage error. No caller's exit-code handling moves.Left alone on purpose
skillsverb still goes to the delegate. Its error names the word the operator typed, which is the useful part, and intercepting it would mean carrying a second copy of the verb list in bash.reposstill opens the hub. The guard fires only when there is no interactive TTY.Test
tests/operator-usage-message-smoke.sh, 8 steps. It checks the new text and that everything underneath still runs — a "fix" that stopped delegating would pass a message-only check:skillsexits 2, usage on stderr, stdout empty, nomq-skills.py, all three verbs namedskills auditstill runs and reportsskills bogusstill answered by the delegate, naming the typed wordreposexits 1, does not say "GitHub repo picker", namesmqlaunch repos, lists all six headless subcommandsreposstill reaches the hub — stubbed via a fakeBASE_DIR, so it is observable and nothing interactive startsrepos liststill produces the repo tableThe gate was proven able to fail: against the unfixed tree it stops at step 2 with
FAIL: delegate internals reached the operator: mq-skills.py.ROADMAP
The section read
Status: Plannedwith every box checked and its exit gate closed — stale. It now records the measuring pass, its five findings, the two fixed (here and #169), and the one open decision:systemandthemeexit 1 headless whilegit,release,shortcuts,toolsandworkflowsexit 0. That needs a call before anything changes.It also records that the sweep itself made
signal-brainwrite a file into the mqobsidian vault —*-braincommands are writes and belong with the destructive exclusions in any repeat.Full suite green, registry validator green, markdownlint clean.
🤖 Generated with Claude Code