fix(skill): local stdio MCP is not exempt from the leading-dash flag parse (TASK-3120)

Codex round 4 finding. The rung-3 routing entry claimed the MCP form of
match was "unaffected" by BUG-3142, but that's only true for remote
/mcp, which keeps `text` a structured param. Local stdio MCP shells
out to `pad playbook match`, turning `text` into a CLI positional via
BuildCLIArgs (dispatch.go:435) — the same flag parser, the same bug.
Corrected: remote /mcp is safe as-is; local stdio MCP still hits it and
should prefer the CLI's `--` form when the text starts with `-`.

Claude-Session: https://claude.ai/code/session_01ByMjAhvdWgbAWWeGE9jwWd
This commit is contained in:
xarmian
2026-09-22 12:51:11 +00:00
parent d1171557ef
commit a2a5a85361
+1 -1
View File
@@ -93,7 +93,7 @@ If the first token isn't a known slug, fall through to the natural-language rout
> *"Sounds like the release playbook (PLAYB-1160). Want me to run it? It expects a `version` argument (semver, e.g. `0.5.0`). What version are you cutting?"*
**Matching by typed decision (rung 3, PLAN-3114 / TASK-3120).** Only reach for this when the user is plainly asking for a procedure or workflow to run ("do the thing we always do for X", "is there a playbook for this?") AND rungs 1-2 above found nothing — never call it on ordinary conversation, since every call spends real provider money. Call `pad playbook match -- "<text>"` (CLI — the `--` matters: user speech may start with `-`, e.g. "-ship it", which the flag parser otherwise reads as a flag; BUG-3142) or `pad_playbook` with `action: match, text: "<text>"` (MCP, unaffected — it's a structured param, not a CLI token), passing the user's own words. A 404 (no provider configured) or any other error falls back SILENTLY to today's behavior — don't mention the attempt, just continue as if this rung didn't exist. A `choice` of `"none"` means the same thing: say nothing about it and move on. Any match the provider DOES return — whatever its confidence — is an OFFER, never an auto-run, exactly like the trigger rung above:
**Matching by typed decision (rung 3, PLAN-3114 / TASK-3120).** Only reach for this when the user is plainly asking for a procedure or workflow to run ("do the thing we always do for X", "is there a playbook for this?") AND rungs 1-2 above found nothing — never call it on ordinary conversation, since every call spends real provider money. Call `pad playbook match -- "<text>"` (CLI — the `--` matters: user speech may start with `-`, e.g. "-ship it", which the flag parser otherwise reads as a flag; BUG-3142) or `pad_playbook` with `action: match, text: "<text>"` (MCP — remote `/mcp` keeps `text` a structured param, safe as-is; LOCAL STDIO MCP still turns it into a CLI positional and hits the same flag parse, BUG-3142 — prefer the CLI form with `--` if the text starts with `-`), passing the user's own words. A 404 (no provider configured) or any other error falls back SILENTLY to today's behavior — don't mention the attempt, just continue as if this rung didn't exist. A `choice` of `"none"` means the same thing: say nothing about it and move on. Any match the provider DOES return — whatever its confidence — is an OFFER, never an auto-run, exactly like the trigger rung above:
> *"Sounds like PLAYB-5 (Ship a release) — want me to run it?"*