ROADMAP #128: claw --model <malformed> (spaces, empty string, invalid syntax) silently accepted at parse time, falls through to cred-error misdirection; joins parser-level trust gap family #108/#117/#119/#122/#127; joins token-burn family #99/#127

This commit is contained in:
YeonGyu-Kim 2026-04-20 12:32:56 +09:00
parent d284ef774e
commit 8122029eba

View File

@ -4690,3 +4690,17 @@ ear], /color [scheme], /effort [low|medium|high], /fast, /summary, /tag [label],
**Blocker.** None. Per-verb post-positional validator + `--json` alias. ~80 lines across `rust/crates/rusty-claude-cli/src/main.rs` and the per-verb dispatch sites.
**Source.** Jobdori dogfood 2026-04-20 against `/tmp/claw-dogfood` (env-cleaned, no git, no config) on main HEAD `7370546` in response to Clawhip pinpoint nudge at `1495620050424434758`. Joins **Silent-flag / documented-but-unenforced** (#96#101, #104, #108, #111, #115, #116, #117, #118, #119, #121, #122, #123, #124, #126) as 18th — `--json` silently swallowed into Prompt dispatch instead of being recognized or rejected. Joins **Parser-level trust gap quintet** (#108, #117, #119, #122, **#127**) as 5th — same `_other => Prompt` fall-through arm, fifth distinct entry case (#108 = typoed verb, #117 = `-p` greedy, #119 = bare slash + arg, #122 = `--base-commit` greedy, **#127 = valid verb + unrecognized suffix arg**). Joins **Cred-error misdirection / failure-classification gaps** as a sibling of #99 (system-prompt unvalidated) — same family of "local diagnostic verb pretends to need API creds." Joins **Truth-audit / diagnostic-integrity** (#80#87, #89, #100, #102, #103, #105, #107, #109, #110, #112, #114, #115, #125) — `claw --help` lies about per-verb accepted flags. Joins **Parallel-entry-point asymmetry** (#91, #101, #104, #105, #108, #114, #117, #122, #123, #124) as 11th — three working forms and one broken form for the same logical intent (`--json` doctor output). Joins **Claude Code migration parity** (#103, #109, #116) as 4th — Claude Code's `--json` convention shorthand is unrecognized in claw-code's verb-suffix position; users migrating get cred errors instead. Cross-cluster with **README/USAGE doc-vs-implementation gap** — README explicitly recommends `claw doctor` as the first health check; the natural JSON form of that exact command is broken. Natural bundle: **#108 + #117 + #119 + #122 + #127** — parser-level trust gap quintet: complete `_other => Prompt` fall-through audit (typoed verb + greedy `-p` + bare slash-verb + greedy `--base-commit` + valid verb + unrecognized suffix). Also **#99 + #127** — local-diagnostic cred-error misdirection pair: `system-prompt` and verb-suffix `--json` both pretend to need creds for pure-local operations. Also **#126 + #127** — diagnostic-verb surface integrity pair: `/config` section args ignored (#126) + verb-suffix args silently mis-dispatched (#127). Session tally: ROADMAP #127.
128. **`claw --model <malformed>` (spaces, empty string, special chars, invalid provider/model syntax) silently falls through to API-layer cred error instead of rejecting at parse time** — dogfooded 2026-04-20 on main HEAD `d284ef7` from a fresh environment (no config, no auth). The `--model` flag accepts any string without syntactic validation: spaces (`claw --model "bad model"`), empty strings (`claw --model ""`), special characters (`claw --model "@invalid"`), non-existent provider/model combinations all parse successfully. The malformed model string then flows into the runtime's provider-detection layer, which silently accepts it as Anthropic fallback or passes it to an API layer that fails with `missing Anthropic credentials` (misdirection) rather than a clear "invalid model syntax" error at parse time. With API credentials configured, a malformed model string gets sent to the API, billing tokens against a request that should have failed client-side.
**Repro (fresh box, no ANTHROPIC_* env vars).** `claw --model "bad model" version` → exit 0, emits version JSON (silent parse). `claw --model "" version` → exit 0, same. `claw --model "foo bar/baz" prompt "test"` → exit 1, `error: missing Anthropic credentials` (malformed model silently routes to Anthropic, then cred error masquerades as root cause instead of "invalid model syntax").
**The gap.** (1) No upfront model syntax validation in parse_args. `--model` accepts any string. (2) Silent fallback to Anthropic when provider detection fails on malformed syntax. (3) Downstream error misdirection — cred error doesn't say "your model string was invalid, I fell back to Anthropic." (4) Token burn on invalid model at API layer — with credentials set, malformed model reaches the API, billing tokens against a 400 response that should have been rejected client-side. (5) Joins #29 (provider routing silent fallback) — both involve Anthropic fallback masking the real intent. (6) Joins truth-audit — status/version JSON report malformed model without validation. (7) Joins cred-error misdirection family (#28, #99, #127).
**Fix shape (~40 lines).** (1) Add `validate_model_syntax(model: &str) -> Result<(), String>` checking: known aliases (claude-opus-4-6, sonnet) or provider/model pattern. Reject empty, spaces, special chars. ~20 lines. (2) Call validation in parse_args right after `--model` flag. Error: `error: invalid model syntax: 'bad model'. Accepted formats: known-alias or provider/model. Run 'claw doctor' to list models.` ~5 lines. (3) No Anthropic fallback in detect_provider_kind for malformed syntax. ~3 lines. (4) Regression tests: (a) `claw --model "bad model" version` exits 1 with clear error. (b) `claw --model "" version` exits 1. (c) `claw --model "@invalid" prompt "test"` exits 1, no API request. (d) `claw --model claude-opus-4-6 version` works (no regression). (e) `claw --model openai/gpt-4 version` works (no regression). ~10 lines.
**Acceptance.** `env -i PATH=$PATH HOME=$HOME claw --model "bad model" version` exits 1 with clear syntax error. With ANTHROPIC_API_KEY set, `claw --model "@@@" prompt "test"` exits 1 at parse time and does NOT make an HTTP request (no token burn). `claw doctor` succeeds (no regression). `claw --model openai/gpt-4 status` works with only OPENAI_API_KEY set (no regression, routing via prefix still works).
**Blocker.** None. Validation fn ~20 lines, parse-time check ~5 lines, tests ~10 lines.
**Source.** Jobdori dogfood 2026-04-20 on main HEAD `d284ef7` in the 10-minute claw-code cycle in response to Clawhip nudge for orthogonal pinpoints. Joins **Parser-level trust gap family** (#108, #117, #119, #122, #127, **#128**) as 6th — different parser surface (model flag validation) but same pattern: silent acceptance of malformed input that should have been rejected at parse time. Joins **Cred-error misdirection** (#28, #99, #127) — malformed model silently routes to Anthropic, then cred error misdirects from the real cause (syntax). Joins **Truth-audit / diagnostic-integrity** — status/version JSON report the malformed model string without validation. Joins **Token burn / unwanted API calls** (#99, #127 via prompt dispatch, **#128** via invalid model at API layer) — malformed input reaches the API instead of being rejected client-side. Natural sibling of #127 (both involve silent acceptance at parse time, both route to cred-error as the surface symptom). Session tally: ROADMAP #128.