Compare commits

..

1 Commits

View File

@@ -6429,91 +6429,4 @@ Original filing (2026-04-18): the session emitted `SessionStart hook (completed)
450. **`prompt` emits `kind:"missing_credentials"` JSON on STDERR (not stdout), leaving stdout at 0 bytes — automation pattern `output=$(claw prompt hello --output-format json)` captures nothing on auth-absent failure; `doctor` correctly surfaces `auth.status:"warn"` with `api_key_present:false` but exposes no `prompt_ready:false` field that automation can check before invoking `prompt`** — dogfooded 2026-05-16 by Jobdori on `a35ee9a0` in response to Clawhip pinpoint nudge at `1505208225321062521`. Exact reproduction (isolated env, no creds, fresh git repo, HEAD `a35ee9a0`): `timeout 5 env -i HOME=$ISOLATED_HOME PATH=$PATH CLAW_CONFIG_HOME=$PROBE/.claw-cfg claw prompt hello --output-format json > stdout.txt 2> stderr.txt` → stdout = **0 bytes**, stderr = 195 bytes containing `{"error":"missing Anthropic credentials…","exit_code":1,"hint":null,"kind":"missing_credentials","type":"error"}`, exit code 1. Confirms Gaebal's `1505208553793781792` pinpoint that `prompt` timeout + zero bytes was the prior state — HEAD `a35ee9a0` now correctly exits 1 with `kind:"missing_credentials"` **but the envelope is still routed to stderr** (issue #447 class, same class as prior entries #422, #435). **Contrast with `doctor`:** `claw doctor --output-format json 2>/dev/null` succeeds to stdout with `checks[auth].status:"warn"`, `api_key_present:false`, `auth_token_present:false` — but the auth check has no `prompt_ready:false` field. Automation that gates on `doctor` before invoking `prompt` must re-derive readiness from `api_key_present && auth_token_present` — there is no single canonical boolean. **Three compound problems:** (a) **stdout-empty on `--output-format json` failure**: same class as #447; `prompt`'s error envelope goes to stderr, not stdout. The canonical automation idiom `if ! result=$(claw prompt "q" --output-format json); then echo "$result" | jq .kind; fi` sees `$result=""` on failure — the jq call gets nothing. All `--output-format json` error paths must route JSON to stdout per #447 contract; (b) **`doctor` missing `prompt_ready` field**: `doctor --output-format json` already knows auth is absent (`api_key_present:false`) but surfaces no derived `prompt_ready:bool` or `prompt_blocked_reason:string` field. Automation must infer readiness from `api_key_present || auth_token_present || legacy_*_present` — a 5-field OR across legacy fields that is fragile as auth mechanisms evolve. A single `prompt_ready:false` (with `prompt_blocked_reason:"auth_missing"`) inside the `auth` check would give downstream a stable contract; (c) **`claw prompt` with no auth does no preflight and fires straight at the API**: the preflight check that `doctor` runs (auth discovery) is not reused by `prompt` to emit a fast typed error before attempting the network call. Both Gaebal's pinpoint (prompt hanging silently on older HEAD) and the current behavior (prompt hitting auth gate after a brief API attempt) stem from the same root: prompt does not short-circuit at the point where `doctor` already knows auth is absent. If `doctor` can emit `kind:"doctor"` with `auth.status:"warn"` in ~20ms without a network call, `prompt` should emit `kind:"missing_credentials"` in the same window and output it to stdout. **Required fix shape:** (a) `prompt --output-format json` must write the `kind:"missing_credentials"` JSON envelope to **stdout**, not stderr — same fix as #447 for all error envelopes; (b) add `prompt_ready:bool` and `prompt_blocked_reason:string|null` to the `auth` check in `doctor --output-format json`; derive it as `api_key_present || auth_token_present || legacy_saved_oauth_present`; (c) `prompt` must run the credential preflight check (same codepath as doctor's auth check) before attempting any API call and emit `{"kind":"missing_credentials","prompt_blocked_reason":"auth_missing"}` on **stdout** with exit 1 if the check fails; (d) `--output-format json` stdout routing fix must cover: `prompt`, `session list` (cross-ref #449), `skills uninstall` (cross-ref #431), `resume` (cross-ref #435), `acp serve` (cross-ref #443) — the full `kind:"missing_credentials"` class; (e) regression test: `claw prompt hello --output-format json` with no creds writes JSON to stdout (0 bytes stderr), exits 1, `kind:"missing_credentials"`, in under 200ms (no network attempt). **Why this matters:** `prompt` is the primary consumer entry point. Auth-absent failure routing to stderr breaks every automation wrapper that captures `$(claw prompt ... --output-format json)`. The `doctor` preflight metadata gap means auth-readiness checks require parsing 5 legacy fields instead of reading one boolean. Cross-references #447 (all JSON error envelopes on stderr), #449 (session list hits auth gate), #431 (skills uninstall hits auth gate), #357 (auth gate on local ops cluster), #422 (exit-code parity). Source: Jobdori live dogfood, `a35ee9a0`, 2026-05-16.
451. **Dogfood automation can silently run probes in the wrong repository/worktree when adjacent checkouts share similarly named binaries and stale build artifacts, so reports may mix evidence from Clawdbot/OMX with claw-code** — dogfooded 2026-05-19 from the `#clawcode-building-in-public` 12:00/12:30 UTC nudge cycle. While following a tmux-hook JSON lifecycle probe, the shell reported `/home/bellman/clawd` as the top-level worktree and executed `node dist/cli/omx.js ...` from Clawdbot/OMX artifacts instead of a claw-code checkout; a later correction found the actual claw-code repos under `/home/bellman/Workspace/claw-code-*`, including one `main` checkout hundreds of commits behind `origin/main`. The transcript therefore briefly contained plausible-looking CLI evidence from the wrong product tree before git provenance checks caught it. **Required fix shape:** (a) before dogfood probes, emit a mandatory machine-readable provenance preflight with repo root, remote URL, branch, HEAD, upstream HEAD, ahead/behind counts, binary path, and embedded build SHA when available; (b) make report templates include this provenance block before any command evidence; (c) warn or block when the requested product name does not match the remote/package/binary identity, or when the checkout is behind the target upstream by a configured threshold; (d) add regression coverage around multi-worktree/multi-product environments proving dogfood harnesses cannot silently attribute evidence from a neighboring repo or stale artifact. **Why this matters:** stale-branch confusion is not just a git annoyance; it corrupts the evidence chain. Claws can land or report fixes against the wrong codebase if the harness does not prove repo and binary identity before probing. Source: gaebal-gajae dogfood response to Clawhip messages `1506265193863446711` and `1506272743895728249` on 2026-05-19.
452. **Validated claw-code checkouts can have no runnable local debug binary, and the failure is a raw shell `No such file or directory` instead of a typed build/provenance preflight result** — dogfooded 2026-05-19 from the `#clawcode-building-in-public` 13:00 UTC nudge after applying the provenance guard from #451. The corrected claw-code checkout was `/home/bellman/Workspace/claw-code-pr2967` with remote `https://github.com/ultraworkers/claw-code.git`, branch `docs/roadmap-workdir-provenance`, HEAD `6183d95`, upstream `origin/main` at `f8e1bb7`, and ahead/behind `1/0`. The first real probe then failed before reaching claw-code logic: `timeout --kill-after=1s 8s ./rust/target/debug/claw plugins list --output-format json` exited `127` with stderr `timeout: failed to run command './rust/target/debug/claw': No such file or directory` and empty stdout. This is distinct from stale-binary mismatch: here the selected checkout is identifiable, but there is no built binary and no canonical instruction/result telling automation whether to build, locate an installed `claw`, or stop. **Required fix shape:** (a) provide a canonical `claw dogfood preflight --output-format json` or equivalent script that checks expected binary paths, installed binary fallback, embedded build SHA, workspace HEAD, and build freshness before any product probe; (b) when the expected local binary is absent, return a typed result such as `kind:"dogfood_preflight"`, `binary_status:"missing"`, `expected_path`, `recommended_build_command`, and `can_use_installed_binary:false|true`; (c) integrate the preflight into dogfood report templates so a missing build artifact is reported as startup friction, not a raw shell 127; (d) add regression/fixture coverage for missing binary, stale binary, matching debug binary, and installed-binary fallback cases. **Why this matters:** after #451 proves the repo is right, claws still need to prove the executable exists and corresponds to that repo. A raw shell missing-file error wastes a nudge cycle and tempts operators to run whatever stale binary happens to be nearby. Source: gaebal-gajae dogfood response to Clawhip message `1506280293831544997` on 2026-05-19.
453. **Plugin list JSON can report bundled plugin `source` paths from a stale user registry in a different checkout, with no stale-source warning or current-bundled-root distinction** — dogfooded 2026-05-19 from the `#clawcode-building-in-public` 13:30 UTC nudge after a successful local build in `/home/bellman/Workspace/claw-code-pr2967` (branch `docs/roadmap-workdir-provenance`, HEAD `25d663d`, binary `./rust/target/debug/claw` reporting `git_sha:"25d663d"`). Running `./rust/target/debug/claw plugins list --output-format json` returned structured `plugins[]`, but both bundled plugin entries reported `source` under `/home/bellman/Workspace/claw-code-parity-worktrees/clawcode-ux-enhance/...` instead of the current checkout. Cleaning and rebuilding the `plugins` crate did not change the output; the stale paths came from `~/.claw/plugins/installed.json`, where bundled plugin records persisted old `source.path` values. The JSON payload gave no `source_stale`, `source_exists`, `current_bundled_root`, `registry_path`, or `source_origin:"registry"` cue, so automation would treat another worktree's bundled plugin path as current truth. **Required fix shape:** (a) for bundled plugins, derive/display source from the current binary/workspace bundled root rather than a persistent user registry path when possible; (b) if registry source is retained, expose `registry_path`, `source_origin`, `source_exists`, `source_matches_current_bundle_root`, and `current_bundled_root` fields; (c) warn in text mode and JSON diagnostics when bundled plugin registry records point outside the current binary/workspace provenance; (d) add regression coverage where `installed.json` contains stale bundled paths from another checkout and `plugins list --output-format json` either self-heals or marks the source stale. **Why this matters:** plugin lifecycle actions rely on source provenance. If a fresh build from checkout A reports bundled plugin sources from checkout B, claws can inspect, enable, update, or debug the wrong plugin tree and misattribute lifecycle failures to current code. Source: gaebal-gajae dogfood response to Clawhip message `1506287843021160500` on 2026-05-19.
454. **`plugins help --output-format json` returns a success-shaped plugin inventory plus `Unknown /plugins action 'help'` prose instead of structured plugin command help or supported lifecycle actions** — dogfooded 2026-05-19 from the `#clawcode-building-in-public` 14:00 UTC nudge on a freshly built binary from `/home/bellman/Workspace/claw-code-pr2967` (`./rust/target/debug/claw version --output-format json` reported `git_sha:"25d663d"`; the worktree had roadmap-only commits ahead of that source build). Running `./rust/target/debug/claw plugins help --output-format json` exited `0` and returned JSON with `kind:"plugin"`, `action:"help"`, `status:"ok"`, a full `plugins[]` inventory, and message `Unknown /plugins action 'help'. Use list, install, enable, disable, uninstall, or update.` It did not return `supported_actions[]`, usage, action metadata, destructive-action markers, target requirements, or a typed `unsupported_action` / `help_unavailable` status. The same probe also confirmed `plugins show example-bundled --output-format json` still returns `status:"ok"` plus an unknown-action message and no selected `plugin` object, matching the existing unsupported-show class, but the new pinpoint is the absence of a plugin lifecycle discovery/help contract. **Required fix shape:** (a) implement `plugins help --output-format json` as a real help/discovery payload with `supported_actions[]`, per-action `requires_target`, `destructive`, `resume_safe`/automation notes, usage, and examples; (b) if `help` is intentionally unsupported, return a non-ok typed JSON envelope with `code:"unsupported_plugin_action"` and structured `supported_actions[]`, not `status:"ok"`; (c) avoid attaching full plugin inventory to unsupported/help responses unless requested, or mark it as incidental; (d) add regression coverage proving plugin lifecycle help is machine-readable and does not require scraping `message` for available actions. **Why this matters:** plugin lifecycle commands include install/enable/disable/update/uninstall; claws need a safe discovery surface before attempting mutations. A success-shaped unknown-help response with only prose action names keeps lifecycle automation brittle and encourages trial-and-error against mutating commands. Source: gaebal-gajae dogfood response to Clawhip message `1506295397285494905` on 2026-05-19.
455. **Plugin help entrypoints hang before producing any help bytes, and with normal user config they emit only a deprecation warning before timeout** — dogfooded 2026-05-19 from the `#clawcode-building-in-public` 14:30 UTC nudge on `/home/bellman/Workspace/claw-code-pr2967` with `./rust/target/debug/claw version --output-format json` reporting `git_sha:"25d663d"`. Bounded probes of `plugins --help --output-format json`, `plugins help --output-format json`, and `plugins list --help --output-format json` each timed out after 8s with `stdout=0`; under the normal user config each had `stderr=121` containing only the repeated config deprecation warning, and under an isolated clean `HOME`/`CLAW_CONFIG_HOME` even `plugins --help` and JSON help forms timed out with both stdout and stderr empty. This is distinct from #454's success-shaped unknown-help JSON observed on the action-dispatch path: the flag-style/local help path can hang before returning any help or typed JSON at all. **Required fix shape:** (a) route `plugins --help`, `plugins help`, and subcommand help forms through static help rendering before config/plugin registry loading; (b) make JSON help return bounded stdout JSON with `kind:"plugin"`, `action:"help"`, `supported_actions[]`, and usage metadata; (c) if dynamic plugin state is intentionally consulted, enforce a short internal timeout and return a typed `plugin_help_unavailable` JSON error instead of zero-byte hangs; (d) add regression coverage with clean home and deprecated-config home proving plugin help emits bytes promptly and does not initialize slow lifecycle/registry paths. **Why this matters:** help must be the safe escape hatch when plugin lifecycle is broken. If every plugin help spelling can hang before bytes, claws cannot discover valid plugin actions, recover from registry issues, or explain how to fix lifecycle state without external docs. Source: gaebal-gajae dogfood response to Clawhip message `1506302942754639892` on 2026-05-19.
456. **Static `--help --output-format json` hangs across multiple local lifecycle namespaces under a clean home, so help discovery is not a reliable no-side-effect escape hatch** — dogfooded 2026-05-19 from the `#clawcode-building-in-public` 15:00 UTC nudge on `/home/bellman/Workspace/claw-code-pr2967` with `./rust/target/debug/claw version --output-format json` reporting `git_sha:"25d663d"`. After pushing the accumulated roadmap branch, clean-environment probes using isolated `HOME` and `CLAW_CONFIG_HOME` showed that `mcp --help --output-format json`, `agents --help --output-format json`, `skills --help --output-format json`, `memory --help --output-format json`, and `session --help --output-format json` each timed out after 8s with `stdout=0` and `stderr=0`. This extends the plugin-specific #455 into a shared parser/help-layer gap: even command namespaces whose help should be static and local can enter a zero-byte hang before any JSON or text help is emitted. **Required fix shape:** (a) centralize `--help`/`help` handling before config, auth, registry, session, MCP, memory, or plugin initialization for all local lifecycle namespaces; (b) make `--output-format json` help return a bounded stdout payload with `kind:"help"`, namespace, usage, supported actions/sections, output formats, and side-effect/auth requirements; (c) add a global deterministic help timeout guard that returns typed JSON such as `kind:"help_unavailable"` instead of allowing zero-byte hangs; (d) add clean-home regression coverage for `mcp`, `agents`, `skills`, `memory`, `session`, and `plugins` help forms proving they emit bytes promptly and do not touch slow lifecycle providers. **Why this matters:** help is the only safe discovery path when lifecycle state is broken. If help itself can hang with no bytes, claws cannot learn how to inspect or recover MCP, agents, skills, memory, sessions, or plugins without external docs or guesswork. Source: gaebal-gajae dogfood response to Clawhip message `1506310493080518767` on 2026-05-19.
457. **Root help is bounded in text mode, but `help --output-format json` and command `--help --output-format json` convert help into a zero-byte hang** — dogfooded 2026-05-19 from the `#clawcode-building-in-public` 15:30 UTC nudge on `/home/bellman/Workspace/claw-code-pr2967` with `./rust/target/debug/claw version --output-format json` reporting `git_sha:"25d663d"`. In an isolated clean `HOME`/`CLAW_CONFIG_HOME`, `./rust/target/debug/claw --help` and `./rust/target/debug/claw help` both exited 0 and printed 7403 bytes of root text help. But `help --output-format json`, `version --help --output-format json`, `doctor --help --output-format json`, and `status --help --output-format json` each timed out after 8s with `stdout=0` and `stderr=0`. This narrows #456: the help renderer itself is capable of returning promptly, but the parser/order path that combines help with JSON output appears to route into a different slow/non-returning path. **Required fix shape:** (a) parse `--help`/`help` before selecting command execution paths, auth, provider, session, or lifecycle initialization, while still preserving requested output format; (b) make root and command help JSON static/bounded with `kind:"help"`, `scope`, `command`, `usage`, `options`, `examples`, and `supported_output_formats`; (c) add regression coverage proving `claw --help`, `claw help`, `claw help --output-format json`, and representative command help forms all return within a small deterministic budget under clean home; (d) ensure JSON help does not silently fall back to text or zero-byte timeout. **Why this matters:** this is a parser-order failure in the safest command surface. Operators can get text help, but the moment automation asks for JSON discovery, help becomes a hang, forcing claws back to prose scraping or external docs. Source: gaebal-gajae dogfood response to Clawhip message `1506318038167847045` on 2026-05-19.
458. **Global output-format flag ordering is parser-hostile, and even `version --output-format json` can hang under clean env despite normal-env success** — dogfooded 2026-05-19 from the `#clawcode-building-in-public` 16:00 UTC nudge on `/home/bellman/Workspace/claw-code-pr2967` with normal-env `./rust/target/debug/claw version --output-format json` reporting `git_sha:"25d663d"`. Clean-environment flag-order probes showed `--output-format json --help`, `--output-format json help`, `--output-format json version`, `--version --output-format json`, and `--output-format json --version` each failed immediately with text-mode stderr only, e.g. `[error-kind: cli_parse] error: unknown option: --output-format json --help`, and `stdout=0`. The parser appears to treat the whole trailing string as one unknown option rather than recognizing a global output-format flag before the command. Separately, in the same clean `HOME`/`CLAW_CONFIG_HOME`, canonical `version --output-format json` timed out after 8s with `stdout=0`/`stderr=0`, even though the same command succeeds in the normal environment. **Required fix shape:** (a) make global flags such as `--output-format json` accepted before or after the subcommand, or return structured JSON `cli_parse` errors on stdout when JSON format is requested anywhere in argv; (b) parse flag values as separate tokens in error reporting instead of echoing combined strings like `--output-format json --help` as one option; (c) ensure `version` is fully local/static and cannot hang under clean env or missing config/auth; (d) add clean-env regression coverage for `version --output-format json`, `--output-format json version`, `--version --output-format json`, and JSON parse errors with stdout envelopes. **Why this matters:** claws often put global flags first for CLI uniformity and run in sanitized envs. If global JSON selection is order-sensitive and local version can hang only under clean env, startup probes become unreliable exactly in CI/sandbox contexts. Source: gaebal-gajae dogfood response to Clawhip message `1506325598245748828` on 2026-05-19.
459. **Dogfood timeout claims lack a required retry/evidence contract, so transient hangs can be recorded as durable product gaps without immediate reproducibility metadata** — dogfooded 2026-05-19 from the `#clawcode-building-in-public` 16:30 UTC nudge while narrowing #458 on `/home/bellman/Workspace/claw-code-pr2967` with `./rust/target/debug/claw version --output-format json` reporting `git_sha:"25d663d"`. The previous 16:00 pass saw clean-env `version --output-format json` time out with zero bytes, but a focused 16:30 retry matrix using isolated `HOME`/`CLAW_CONFIG_HOME` plus minimal env variants (`TERM`, `USER`/`LOGNAME`, `SHELL`, `LANG`/`LC_ALL`, and all combined) returned valid version JSON every time. That means the earlier timeout may have been transient harness load, process scheduling, or invocation interference, while the report format had no mandatory retry count, timing, command log artifact, or “reproduced N/M” field to distinguish flaky evidence from stable behavior. **Required fix shape:** (a) dogfood timeout reports must include retry count, per-attempt exit code/stdout/stderr byte counts, elapsed duration, env summary, binary provenance, and whether the failure reproduced after process isolation; (b) add a standard `timeout_evidence` block to report templates and ROADMAP entries before filing zero-byte hang claims; (c) classify un-reproduced hangs as `flaky_unconfirmed` with follow-up probes instead of stable product bugs; (d) provide a small harness command that runs bounded retries and emits machine-readable evidence JSON. **Why this matters:** zero-byte timeouts are high-severity but easy to misattribute. Without a retry/evidence contract, claws can pollute the backlog with transient scheduler artifacts or miss real nondeterministic hangs because the evidence shape is too thin. Source: gaebal-gajae dogfood response to Clawhip message `1506333141571211314` on 2026-05-19.
460. **Root `help --output-format json` is reproducibly bounded but only wraps 7.4KB of prose in `{kind,message}`, with no structured command or slash-command schema** — dogfooded 2026-05-19 from the `#clawcode-building-in-public` 17:00 UTC nudge on `/home/bellman/Workspace/claw-code-pr2967` with `./rust/target/debug/claw version --output-format json` reporting `git_sha:"25d663d"`. Applying the retry/evidence discipline from #459, three clean-home attempts of `./rust/target/debug/claw help --output-format json` all exited 0 with `stdout=7563`, `stderr=0`, valid JSON keys exactly `kind,message`, `kind:"help"`, and a `message` string of length 7401. There were no `commands[]`, `options[]`, `slash_commands[]`, resume-safety flags, output-format support metadata, side-effect/auth requirements, or examples as structured fields. This supersedes the flaky zero-byte hang framing from #457 for root help: the stable reproducible gap is schema opacity, not timeout. **Required fix shape:** (a) keep `message` for human rendering but add a versioned structured help schema with `schema_version`, `commands[]`, `global_options[]`, `slash_commands[]`, `examples[]`, and `related_docs[]`; (b) include per-command fields such as `name`, `aliases`, `usage`, `description`, `supports_json`, `requires_auth`, `side_effects`, and `resume_safe` where applicable; (c) expose slash-command metadata without requiring prose scraping; (d) add regression coverage proving root help JSON has stable structured fields and that old `message` remains optional/backward-compatible. **Why this matters:** help JSON is the bootstrap discovery surface for claws. Valid JSON that contains only prose still forces automation to scrape text before choosing safe commands or resume paths. Source: gaebal-gajae dogfood response to Clawhip message `1506340691431657472` on 2026-05-19.
461. **Command-specific `--help --output-format json` reproducibly zero-byte hangs even though root JSON help returns bounded prose JSON** — dogfooded 2026-05-19 from the `#clawcode-building-in-public` 17:30 UTC nudge on `/home/bellman/Workspace/claw-code-pr2967` with `./rust/target/debug/claw version --output-format json` reporting `git_sha:"25d663d"`. After #460 confirmed root `help --output-format json` is bounded but schema-opaque, two clean-home attempts each for `status --help --output-format json`, `doctor --help --output-format json`, `version --help --output-format json`, and `sandbox --help --output-format json` all timed out after 8s with `stdout=0` and `stderr=0`. This establishes a split contract: root JSON help reaches the help serializer, while command-specific JSON help falls into a non-returning command execution/parser path. **Required fix shape:** (a) add a command-help dispatch layer that catches `<command> --help` before entering the command's runtime handler; (b) share the same bounded JSON help schema from #460 for command-specific help, with fields `kind:"help"`, `command`, `usage`, `options`, `examples`, `supports_json`, `requires_auth`, and `side_effects`; (c) ensure local/static commands like `version`, `status`, `doctor`, and `sandbox` never initialize slow providers just to render help; (d) add clean-home regression coverage proving command-specific JSON help emits bytes promptly for representative static and lifecycle commands. **Why this matters:** claws often discover command contracts one command at a time. If root help is available but every command's JSON help hangs, automation still cannot inspect option-level semantics safely and must scrape root prose or guess. Source: gaebal-gajae dogfood response to Clawhip message `1506348241128788111` on 2026-05-19.
462. **Text-mode `<command> --help` also zero-byte hangs, proving the bug is command-help dispatch rather than JSON serialization** — dogfooded 2026-05-19 from the `#clawcode-building-in-public` 18:00 UTC nudge on `/home/bellman/Workspace/claw-code-pr2967` with `./rust/target/debug/claw version --output-format json` reporting `git_sha:"25d663d"`. After #461 showed command-specific JSON help hangs, a text-mode retry matrix in isolated clean `HOME`/`CLAW_CONFIG_HOME` showed two attempts each for `status --help`, `doctor --help`, `version --help`, `sandbox --help`, `mcp --help`, `agents --help`, and `skills --help` all timed out after 6s with `stdout=0` and `stderr=0`. Root `--help` and `help` remain bounded, so the split is not help text rendering generally and not JSON formatting specifically; it is the command-specific help dispatch path failing to intercept `<command> --help` before some non-returning runtime path. **Required fix shape:** (a) implement a first-stage argv parser that recognizes `<command> --help` and `<command> help` for every registered command before command runtime initialization; (b) render static text help in text mode and structured JSON help in JSON mode from the same command metadata registry; (c) add regression coverage for both text and JSON help for representative static commands (`version`, `status`, `doctor`, `sandbox`) and lifecycle commands (`mcp`, `agents`, `skills`, `plugins`); (d) ensure every command-help path has a bounded no-provider/no-auth/no-config execution budget. **Why this matters:** users do not only run root `--help`; they naturally ask `claw status --help` or `claw mcp --help`. If that path hangs silently, the product loses the most basic local recovery surface before any real action starts. Source: gaebal-gajae dogfood response to Clawhip message `1506355792582938665` on 2026-05-19.
463. **Root help advertises direct slash examples like `claw /skills`, but direct slash behavior is inconsistent: `/skills` runs a huge local report, `/help` aliases root help, while `/status` is rejected as interactive-only despite being marked resume-safe** — dogfooded 2026-05-19 from the `#clawcode-building-in-public` 18:30 UTC nudge on `/home/bellman/Workspace/claw-code-pr2967` with `./rust/target/debug/claw version --output-format json` reporting `git_sha:"25d663d"`. Root help examples include `claw /skills`, and clean-home probes showed direct `claw /skills` exits 0 and prints a 27KB skill inventory, while direct `claw /help` exits 0 and prints root help. But direct `claw /status` exits 1 with `slash command /status is interactive-only... use claw --resume SESSION.jsonl /status ... when the command is marked [resume] in /help`, even though `/status` is explicitly marked `[resume]` in root help and has a top-level sibling `claw status`. The same surface therefore mixes three semantics for direct slash invocation: accepted alias, accepted local slash report, and rejected interactive-only/resume-only command. **Required fix shape:** (a) define a single direct-slash CLI contract: either reject all slash commands outside REPL/resume with structured guidance, or allow resume-safe/local slash commands consistently; (b) if allowing direct slash commands, route `/status` to the same local/resume-safe status serializer as `claw status` or require `--resume` with a typed `resume_required` code; (c) make help examples distinguish top-level commands from slash commands and avoid advertising `claw /skills` unless direct slash invocation is intentional for the whole supported set; (d) add regression coverage for `/help`, `/skills`, `/status`, `/mcp`, `/agents`, and their top-level equivalents proving consistent direct/resume/text/json behavior. **Why this matters:** claws copy help examples literally. If `claw /skills` works but `claw /status` says interactive-only despite `[resume]`, automation cannot infer which slash commands are safe outside the REPL and will oscillate between direct, top-level, and resume forms. Source: gaebal-gajae dogfood response to Clawhip message `1506363340048564425` on 2026-05-19.
464. **Global `--output-format json` placement is broken for top-level subcommands: post-subcommand placement silently hangs, while pre-subcommand placement is rejected as `cli_parse` despite help documenting `--output-format` as a global flag** — dogfooded 2026-05-19 from the `#clawcode-building-in-public` 19:00/19:30 UTC nudges on `/home/bellman/Workspace/claw-code-pr2967` with `./rust/target/debug/claw version --output-format json` reporting `git_sha:"25d663d"`. Root help lists `--output-format FORMAT` in the global Flags section and examples like `claw [--model MODEL] [--output-format text|json] prompt TEXT`, while top-level commands (`claw status`, `claw doctor`, `claw mcp`, `claw skills`, `claw version`) advertise local diagnostic/report surfaces. Clean-home probes showed two distinct bad paths: `claw version --output-format json`, `claw status --output-format json`, and `claw skills --output-format json` timed out after 5s with `stdout=0`/`stderr=0`; the more canonical GNU-style global placement `claw --output-format json version`, `claw --output-format json status`, and `claw --output-format json skills` exited 1 with `[error-kind: cli_parse] error: unknown option: --output-format json <command>`. The only working form observed for `version` is the special local parser path used by `claw version --output-format json` in a non-clean environment/provenance preflight, which contradicts the clean-home bounded test and suggests the parser/runtime path is environment-sensitive as well as placement-sensitive. **Required fix shape:** (a) make `--output-format` a true global flag accepted before any subcommand and before slash commands; (b) make top-level local commands also accept trailing `--output-format` if the project wants common CLI ergonomics; (c) normalize both placements into one parsed `OutputFormat` before command dispatch; (d) ensure parse errors in JSON-requested mode emit structured JSON rather than prose-on-stderr; (e) add clean-home regression coverage for `claw --output-format json version|status|doctor|mcp|skills` and `claw version|status|doctor|mcp|skills --output-format json`, with bounded no-provider execution. **Why this matters:** claws and shell users routinely place global flags either before or after subcommands. A machine-readable output flag that sometimes hangs and sometimes parse-errors means automation cannot reliably request JSON for the exact local diagnostics it needs during recovery. Source: gaebal-gajae dogfood response to Clawhip messages `1506370889653027012` and `1506378443812765756` on 2026-05-19.
465. **`claw skills` is technically bounded but operationally noisy: the default text output dumps full descriptions for every discovered skill (~27KB / 65 skills in clean-home dogfood), unlike `status`, `doctor`, `mcp`, `sandbox`, and `agents` which stay compact enough for recovery logs** — dogfooded 2026-05-19 from the `#clawcode-building-in-public` 20:00 UTC nudge on `/home/bellman/Workspace/claw-code-pr2967` with `./rust/target/debug/claw version --output-format json` reporting `git_sha:"25d663d"`. Clean-home text probes showed `version`, `status`, `doctor`, `mcp`, `sandbox`, and `agents` all exit promptly with compact diagnostic reports (`version` 136 bytes, `status` 1274 bytes, `doctor` 2519 bytes, `mcp` 117 bytes, `sandbox` 352 bytes, `agents` 17 bytes). `skills` also exits 0, but emits 27,573 bytes by default because it prints every skill name plus full description. This makes `claw skills` a poor first-response diagnostic in clawhip logs, tmux tails, CI failure artifacts, and copied support snippets: the useful inventory count and roots are buried under pages of prose. This is distinct from discovery-scope/security issues (#85/#95): even when the skill set is legitimate, the default report shape is too verbose for a recovery command. **Required fix shape:** (a) make default text `claw skills` compact: counts by source/root plus names only, truncated with an explicit `--verbose` hint; (b) add `claw skills --verbose` or `claw skills list --verbose` for full descriptions; (c) add `--format compact|verbose` or reuse `--compact` if the CLI standardizes it; (d) keep JSON mode complete but add `summary` and `entries[].description` fields so consumers can choose; (e) add regression coverage enforcing that default text output for 50+ skills stays under a small byte/line budget while verbose preserves current detail. **Why this matters:** local diagnostics should be safe to paste and scan during failures. A 27KB default skill dump hides the actual signal and makes every dogfood/support loop noisier than necessary. Source: gaebal-gajae dogfood response to Clawhip message `1506385992368652489` on 2026-05-19.
466. **Syntactically valid MCP config with a nonexistent command is reported as healthy/configured by `doctor`, `mcp`, and `status` instead of surfacing executable reachability as degraded** — dogfooded 2026-05-19 from the `#clawcode-building-in-public` 20:30 UTC nudge on `/home/bellman/Workspace/claw-code-pr2967` with `./rust/target/debug/claw version --output-format json` reporting `git_sha:"25d663d"`. In a temp workspace containing only `.claw.json` with `mcpServers.broken.command:"/definitely/not/a/real/mcp-server"`, clean-home text probes showed `doctor` exits 0 with `Failures 0`, `Config Status ok`, and `Boot preflight ... mcp=true · servers 1`; `mcp` exits 0 and lists `broken stdio project /definitely/not/a/real/mcp-server --serve`; `status` exits 0 and reports `Boot preflight ... mcp=true plugins=true last_failed=none`. None of the three surfaces attempts even a cheap executable existence/PATH reachability check, so a server that cannot possibly launch is indistinguishable from a configured usable MCP server until the first runtime tool call fails. This is distinct from malformed-config degraded-mode items (#143/#144/#440): here the JSON shape is valid and the parser succeeds, but lifecycle readiness is false. **Required fix shape:** (a) add an MCP executable preflight pass that classifies each stdio server as `reachable:true|false|unknown` using absolute-path existence/executable-bit checks and PATH lookup for bare commands, without launching untrusted code; (b) expose per-server fields in `claw mcp` / JSON (`launch_status`, `command_exists`, `command_executable`, `path_resolution`, `error_kind:"mcp_command_not_found"`); (c) make `doctor` add an `mcp_reachability` check with `status:"warn"` or `"fail"` when any configured server command is missing; (d) make `status` distinguish `mcp_configured:true` from `mcp_reachable:false` instead of the current single `mcp=true`; (e) regression test with one valid `/bin/echo` server and one nonexistent absolute path proving partial status is reported. **Fresh mixed-PATH proof (21:00 UTC):** a temp config containing one PATH-resolvable server (`pathEcho.command:"echo"`) and one missing bare command (`missingBare.command:"definitely-not-a-real-mcp-bare-command-xyz"`) still made `mcp` list both as configured, `doctor` report `Failures 0` and `mcp=true · servers 2`, and `status` report `mcp=true` with no degraded marker. So the fix must handle both absolute paths and PATH lookup for bare commands, and it must preserve partial success (`echo` reachable, missingBare not found) instead of collapsing both into `configured`. **Why this matters:** MCP failures are often setup/path mistakes. If doctor says failures 0 and mcp=true while the command path does not exist, claws and users waste turns discovering the break only after a blocked tool call. Source: gaebal-gajae dogfood response to Clawhip messages `1506393539385491598` and `1506401088801083495` on 2026-05-19.
467. **Bare `claw plugins` / `claw plugin` returns the plugin inventory, but the natural explicit action `claw plugins list` / `claw plugin list` zero-byte hangs; singular/plural aliases are wired for the default action but not for the `list` subaction** — dogfooded 2026-05-19 from the `#clawcode-building-in-public` 21:30 UTC nudge on `/home/bellman/Workspace/claw-code-pr2967` with `./rust/target/debug/claw version --output-format json` reporting `git_sha:"25d663d"`. In isolated clean `HOME`/`CLAW_CONFIG_HOME`, `plugins` and `plugin` each exited 0 and printed the two bundled plugins (`example-bundled`, `sample-hooks`) in text mode. But `plugins list` and `plugin list` each timed out after 8s with `stdout=0` and `stderr=0`. `plugins help` and `plugin help` also timed out, while direct `/plugins` and `/plugin` were rejected as interactive-only, showing that there are at least three parser paths for the same lifecycle namespace. This is a narrower current-main follow-up to the historical plugin route/help items (#78/#145/#348/#420/#454/#455): the route now exists for the default inventory, but adding the explicit canonical `list` action drops into a different non-returning path. **Required fix shape:** (a) normalize `plugin` and `plugins` aliases plus omitted action into one parser action before dispatch (`None` and `Some("list")` must be equivalent); (b) route `help` to static plugin help before plugin registry/lifecycle initialization; (c) add a deterministic timeout guard or typed `plugin_action_unavailable` envelope around plugin action dispatch so unsupported/misparsed actions cannot hang silently; (d) add clean-home regression coverage for `plugins`, `plugins list`, `plugin`, `plugin list`, `plugins help`, and `plugin help` in text and JSON modes, proving the first four produce the same inventory and help emits bounded usage. **Why this matters:** `list` is the most obvious plugin lifecycle action and is already the documented/discovery word from other lifecycle namespaces (`mcp list`, `agents list`, `skills list`). If bare inventory works but explicit list hangs, claws cannot safely choose between terse default and explicit action forms, and plugin support remains trial-and-error. Source: gaebal-gajae dogfood response to Clawhip message `1506408638883954768` on 2026-05-19.
468. **Explicit subactions hang across local lifecycle namespaces: bare `agents`, `mcp`, `skills`, `sandbox`, and `doctor` return bounded diagnostics, but natural explicit forms (`agents list`, `mcp list`, `skills list`, `sandbox status`, `doctor check`) zero-byte hang** — dogfooded 2026-05-19 from the `#clawcode-building-in-public` 22:00 UTC nudge on `/home/bellman/Workspace/claw-code-pr2967` with `./rust/target/debug/claw version --output-format json` reporting `git_sha:"25d663d"`. Clean-home text probes showed the bare commands are usable: `agents` exits 0 (`No agents found.`), `mcp` exits 0 with `Configured servers 0`, `skills` exits 0 with inventory, `sandbox` exits 0 with sandbox state, and `doctor` exits 0 with the full health report. But adding the most natural explicit action caused zero-byte timeouts after 8s: `agents list`, `mcp list`, `skills list`, `sandbox status`, and `doctor check` all produced `stdout=0` and `stderr=0`. This broadens #467's plugin-specific `plugins list` hang into a shared parser/action-normalization bug: omitted default action works, but spelling the default action explicitly routes to a non-returning path. **Required fix shape:** (a) define a per-namespace action table where omitted action normalizes to the documented default (`list` for inventory namespaces, `status` for status namespaces, `check`/`run` only if supported); (b) reject unsupported explicit actions with typed bounded errors (`unknown_action`, `supported_actions[]`) instead of falling through to prompt/runtime dispatch; (c) make `agents list`, `mcp list`, and `skills list` equivalent to their bare forms; decide/document whether `sandbox status` and `doctor check` are aliases or unsupported; (d) add clean-home regression coverage for bare/default/unsupported explicit actions in text and JSON across agents, mcp, skills, plugins, sandbox, and doctor. **Why this matters:** users and claws naturally prefer explicit commands in automation (`mcp list`, `agents list`) because they are self-documenting. If explicit defaults hang while bare commands work, every script has to learn undocumented terse forms and cannot safely derive commands from help/usage text. Source: gaebal-gajae dogfood response to Clawhip message `1506416189616947210` on 2026-05-19.
469. **Unexpected positional arguments after local verbs zero-byte hang instead of returning bounded parse errors; even `version extra` hangs, proving the parser does not fail closed once a local subcommand has extra tokens** — dogfooded 2026-05-19 from the `#clawcode-building-in-public` 22:30 UTC nudge on `/home/bellman/Workspace/claw-code-pr2967` with `./rust/target/debug/claw version --output-format json` reporting `git_sha:"25d663d"`. In isolated clean `HOME`/`CLAW_CONFIG_HOME`, bounded 8s probes of `version extra`, `status extra`, `doctor extra`, `sandbox extra`, `agents extra`, `mcp extra`, `skills extra`, and `plugins extra` all timed out with `stdout=0` and `stderr=0`. This is broader than #468's explicit-default-action hang: the extra token does not need to be a plausible action like `list` or `status`; any unexpected positional can route a local, no-auth diagnostic command into a non-returning path. It also refreshes the older extra-arg/fallthrough findings (#127/#147) with current-binary evidence where the failure mode is now a silent hang rather than a visible missing-credentials prompt. **Required fix shape:** (a) every local subcommand parser must declare accepted positional arity and reject extra args before prompt/runtime dispatch; (b) emit a typed bounded error such as `kind:"unexpected_argument"`, `command`, `argument`, `supported_usage`, and `supported_actions[]` where relevant; (c) in JSON-requested mode, route that envelope to the documented JSON stream with nonzero exit; (d) add regression coverage for `version extra`, `status extra`, `doctor extra`, `sandbox extra`, `agents extra`, `mcp extra`, `skills extra`, and `plugins extra` proving they return promptly and do not enter provider/prompt/plugin/session runtime. **Why this matters:** typos and stale wrapper scripts commonly append leftover tokens. A local health command must fail closed with usage guidance, not hang with no bytes; otherwise orchestrators cannot distinguish typo, parser deadlock, provider stall, or lifecycle startup block. Source: gaebal-gajae dogfood response to Clawhip message `1506423740597141665` on 2026-05-19.
470. **Root flag aliases fail closed on extra tokens, but the word alias `help` zero-byte hangs with any trailing token (`help extra`, `help --help`, `help --version`) instead of returning root help or a bounded arity error** — dogfooded 2026-05-19 from the `#clawcode-building-in-public` 23:00/23:30 UTC nudges on `/home/bellman/Workspace/claw-code-pr2967` with `./rust/target/debug/claw version --output-format json` reporting `git_sha:"25d663d"`. Clean-home probes showed the flag aliases are healthy/bounded: `--version` and `-V` exit 0 with version text; `--version extra`, `-V extra`, and `--help extra` exit 1 with `[error-kind: cli_parse]`. But the word help alias is fragile: `help extra`, `help --help`, and `help --version` each timed out after 6s with `stdout=0` and `stderr=0`. This narrows #469: not all root alias extra-token paths hang; the flag parser has a fail-closed path, while the `help` word alias enters the same non-returning command/prompt dispatch when trailing tokens are present. **Required fix shape:** (a) treat `help` as a first-class root command with strict arity: bare `help` renders root help; `help <topic>` either renders a static topic if supported or returns typed `unknown_help_topic`; extra flags like `help --help` and `help --version` must be handled locally; (b) never route `help ...` into provider/prompt/runtime dispatch; (c) make JSON mode preserve the same bounded behavior with `kind:"help"` or `kind:"unknown_help_topic"`; (d) add clean-home regression coverage for `help`, `help extra`, `help --help`, `help --version`, `--help extra`, `--version extra`, and `-V extra`. **Why this matters:** `help` is the recovery primitive users type when every other command is broken. If `--help extra` reports a parse error but `help extra` hangs silently, claws cannot rely on the documented `claw help` alias as a safe discovery surface. Source: gaebal-gajae dogfood response to Clawhip messages `1506431285977940009` and `1506438835775737939` on 2026-05-19.
471. **Root version aliases (`--version`, `-V`) have no JSON form and reject `--output-format json`, while the `version --output-format json` subcommand hangs under clean home — version provenance is not reliably machine-readable from the safest startup path** — dogfooded 2026-05-20 from the `#clawcode-building-in-public` 00:00 UTC nudge on `/home/bellman/Workspace/claw-code-pr2967` with provenance preflight `./rust/target/debug/claw version --output-format json` reporting `git_sha:"25d663d"` in the normal environment. In isolated clean `HOME`/`CLAW_CONFIG_HOME`, `version --output-format json` timed out after 6s with `stdout=0` and `stderr=0`, while `--version --output-format json`, `--output-format json --version`, `-V --output-format json`, and `--output-format json -V` all exited 1 with `[error-kind: cli_parse] unknown option: ...`. Plain `--version`/`-V` work in text mode, but there is no bounded JSON equivalent through the root flag aliases, and the subcommand JSON path is environment/placement-sensitive. This is a focused provenance/startup slice of #464: the one command claws use to prove binary identity has split semantics across root flags and subcommand forms. **Required fix shape:** (a) make `--version --output-format json` and `--output-format json --version` valid aliases for `version --output-format json`; (b) make `-V` support the same formatting contract; (c) ensure `version --output-format json` is config-free/help-free/provider-free and bounded under clean home; (d) emit a typed JSON parse error on stdout/stderr according to the project-wide JSON error-stream contract if an unsupported combination remains; (e) add clean-home regression coverage for all five forms above. **Why this matters:** binary provenance is the first fact every dogfood report and orchestrator needs. If root version flags only produce text and the JSON subcommand can hang, claws cannot safely establish which executable they are testing without relying on a special normal-environment preflight. Source: gaebal-gajae dogfood response to Clawhip message `1506446390212169839` on 2026-05-20.
472. **Malformed project `.claw.json` is silently treated as `loaded 0/N` while `doctor` still says `Config Status ok` and `runtime config loaded successfully`; `status` reports no config error at all** — dogfooded 2026-05-20 from the `#clawcode-building-in-public` 00:30 UTC nudge on `/home/bellman/Workspace/claw-code-pr2967` with `./rust/target/debug/claw version --output-format json` reporting `git_sha:"25d663d"`. In a temp workspace with an invalid `.claw.json` containing truncated JSON (`{"mcpServers":{"bad":{}`), root recovery surfaces correctly stayed config-free: `--help`, `help`, `--version`, `-V`, and `version` all exited 0. But config-aware diagnostics silently downplayed the broken file: `status` exited 0 and reported `Config files loaded 0/5` with no parse error or degraded marker; `doctor` exited 0 with `Failures 0`, `Config Status ok`, `Summary runtime config loaded successfully`, and details `Config files loaded 0/1` plus the discovered malformed file path. This is not the older #143 fatal-status path; it is the opposite failure mode: broken config is detected enough to count as present/discovered, but the parse error is dropped and the health summary remains OK. **Required fix shape:** (a) preserve config parse/load errors per discovered file even when continuing with defaults; (b) make `doctor` config check `status:"fail"` or `"warn"` when any discovered config file fails to parse, never `ok`; (c) make `status` expose `config_load_error` / `config_files[].error` and a degraded marker while still reporting independent workspace fields; (d) distinguish `present_count`, `loaded_count`, and `failed_count`; (e) add regression coverage with malformed/truncated `.claw.json` proving root help/version remain config-free while status/doctor surface the parse error. **Why this matters:** a user with a broken config needs diagnostics to point at the exact file and parse problem. Saying `runtime config loaded successfully` while also saying `loaded 0/1` is contradictory and makes the tool look healthy while silently ignoring the user's intended MCP/plugins/permissions/model settings. Source: gaebal-gajae dogfood response to Clawhip message `1506453939443204247` on 2026-05-20.
473. **Slash-only command guidance is inconsistent: bare `claw compact` fails fast with useful guidance, but `claw compact --help` and `claw compact extra` zero-byte hang instead of returning the same guidance/help or a bounded arity error** — dogfooded 2026-05-20 from the `#clawcode-building-in-public` 01:00 UTC nudge on `/home/bellman/Workspace/claw-code-pr2967` with `./rust/target/debug/claw version --output-format json` reporting `git_sha:"25d663d"`. After confirming the remote `docs/roadmap-workdir-provenance` branch still had HEAD `e9db12d` (Jobdori's claimed `f997a1a8` was not present on origin at probe time), compact-surface probes showed `claw compact` exits 1 with a clear local message: `` `claw compact` is a slash command. Use `claw --resume SESSION.jsonl /compact` or start `claw` and run `/compact`.`` Direct `/compact` also exits 1 with interactive/resume guidance, and `/compact --confirm` returns a bounded unexpected-argument help block. But `compact --help` and `compact extra` each timed out after 6s with `stdout=0` and `stderr=0`. This is a parser/help arity bug distinct from the compaction-internals sentinel issue Jobdori described: the CLI already knows how to explain that `compact` is slash-only, but adding `--help` or any extra token bypasses that safe guidance path. **Required fix shape:** (a) route `compact --help` to static compact help/guidance before prompt/runtime dispatch; (b) route `compact <unexpected>` to a typed bounded `unexpected_argument` or `slash_only_command` error with resume usage; (c) make slash-only top-level shims share one helper so bare/--help/extra forms cannot drift; (d) add clean-home regressions for `compact`, `compact --help`, `compact extra`, `/compact`, `/compact --confirm`, and JSON-mode equivalents. **Why this matters:** users who follow the bare-command guidance and ask for help on the same word hit a silent hang. Recovery commands must converge toward usage, not fall off a different parser cliff as soon as a user adds `--help`. Source: gaebal-gajae dogfood response to Clawhip message `1506461484950093967` on 2026-05-20.
474. **Local diagnostic verbs and slash-only shims hang on `--help`/extra-token forms even when their bare or slash forms already have bounded guidance (`status --help`, `status extra`, `doctor --help`, `doctor extra`, `clear --help`, `clear --confirm`, `clear extra`)** — dogfooded 2026-05-20 from the `#clawcode-building-in-public` 01:30 UTC nudge on `/home/bellman/Workspace/claw-code-pr2967` with `./rust/target/debug/claw version --output-format json` reporting `git_sha:"25d663d"`; branch and origin were both `docs/roadmap-workdir-provenance@1208b9a` before editing. Bounded clean-home probes showed `claw clear` exits 1 with useful slash-only guidance, `/clear` and `/clear --confirm` return bounded interactive/resume guidance, and `/clear extra` returns a bounded usage block. But `clear --help`, `clear --confirm`, and `clear extra` each timed out after 6s with `stdout=0`/`stderr=0`. The same arity/help drift affects bare local diagnostics: `status --help`, `status extra`, `doctor --help`, and `doctor extra` also timed out after 6s with no bytes, despite bare `status`/`doctor` being local, bounded diagnostic commands in other probes. This generalizes #473 from `compact` to the parser layer: after a recognized local verb, trailing tokens are not routed through a command-specific help/arity table and can enter the non-returning prompt/runtime path. **Required fix shape:** (a) define per-command arity/help metadata for every local verb before prompt fallback; (b) `status --help` and `doctor --help` render static help; `status extra` and `doctor extra` return typed `unexpected_argument`; (c) `clear --help` renders slash/resume guidance, while `clear --confirm` either maps to `/clear --confirm` guidance or returns typed `slash_only_command` without dispatch; (d) centralize slash-only top-level shim handling for `compact`, `clear`, and future resume-capable slash commands; (e) add clean-home timeout-guarded regression coverage for all forms above. **Why this matters:** `status` and `doctor` are the commands operators reach for during startup/config breakage. If adding `--help` or a stale wrapper token makes them silently hang, the recovery surface is unreliable and automation cannot distinguish operator typo from runtime deadlock. Source: gaebal-gajae dogfood response to Clawhip message `1506469039562555573` on 2026-05-20.
475. **Local diagnostic commands (`status`, `doctor`, `sandbox`) have no bounded JSON output-form contract: bare text works, suffix `--output-format json` hangs, and prefix `--output-format json <command>` is rejected as a parse error** — dogfooded 2026-05-20 from the `#clawcode-building-in-public` 02:00 UTC nudge on `/home/bellman/Workspace/claw-code-pr2967` with `./rust/target/debug/claw version --output-format json` reporting `git_sha:"25d663d"`; branch and origin were both `docs/roadmap-workdir-provenance@9495dbe` before editing. Clean-home probes showed `status`, `doctor`, and `sandbox` exit 0 with useful human-readable text. But `status --output-format json`, `doctor --output-format json`, and `sandbox --output-format json` each timed out after 6s with `stdout=0` and `stderr=0`. The prefix spelling `--output-format json status|doctor|sandbox` exits 1 with `[error-kind: cli_parse] unknown option`, also with no JSON envelope. This is distinct from #474's help/arity hang: here the option is a documented global formatting concept already used by `version` and prompt mode, but local diagnostics neither honor it nor fail closed consistently. **Required fix shape:** (a) define a project-wide rule for `--output-format` placement and apply it to local diagnostics; (b) support `status --output-format json`, `doctor --output-format json`, and `sandbox --output-format json` with stable `kind:"status"|"doctor"|"sandbox"` envelopes; (c) either support prefix global placement or reject it with a typed JSON-capable parse envelope; (d) ensure these paths are config/provider/prompt-free and bounded under clean home; (e) add timeout-guarded clean-home regressions for bare text, suffix JSON, and prefix JSON forms. **Why this matters:** operators and orchestrators need machine-readable health snapshots during startup failures. If the only working forms are text and JSON requests hang, automation has to scrape prose or misclassify a formatting request as runtime deadlock. Source: gaebal-gajae dogfood response to Clawhip message `1506476585543532596` on 2026-05-20.
476. **Read-only inventory commands (`agents`, `mcp`, `skills`, `plugins`) have no bounded JSON/list contract: bare text works, suffix `--output-format json` hangs, prefix global JSON is rejected, and `skills` dumps a huge prose list with no machine-readable counts/paths** — dogfooded 2026-05-20 from the `#clawcode-building-in-public` 02:30 UTC nudge on `/home/bellman/Workspace/claw-code-pr2967` with `./rust/target/debug/claw version --output-format json` reporting `git_sha:"25d663d"`; branch and origin were both `docs/roadmap-workdir-provenance@bb2cf3f` before editing. Clean-home probes showed bare inventory commands are local and bounded: `agents` prints `No agents found.`, `mcp` prints a short `Configured servers 0` report, `plugins` prints two disabled bundled plugins, and `skills` prints `65 available skills` plus ~27KB of prose descriptions. But `agents --output-format json`, `mcp --output-format json`, `skills --output-format json`, and `plugins --output-format json` each timed out after 6s with `stdout=0`/`stderr=0`. Prefix forms `--output-format json agents|mcp|skills|plugins` exit 1 with `[error-kind: cli_parse] unknown option` and no JSON envelope. This is adjacent to #475 but distinct: these are inventory surfaces that orchestrators need for routing, MCP/plugin lifecycle checks, and skill selection, not just health diagnostics. **Required fix shape:** (a) provide stable JSON envelopes for each command (`kind:"agents"|"mcp"|"skills"|"plugins"`) with counts, source paths, enabled/disabled state, and parse/load errors where relevant; (b) make `--output-format json` suffix bounded and optionally support/predictably reject prefix placement via the global formatting contract; (c) add compact text/list modes for `skills` so default output is not an unbounded prose wall; (d) ensure inventory JSON does not initialize providers or interactive prompt runtime; (e) add clean-home timeout-guarded regressions for bare text, suffix JSON, and prefix JSON forms. **Why this matters:** claws need structured inventories to decide which skills/plugins/MCP servers are available. Scraping 27KB of human prose or hitting a silent hang on JSON makes routing brittle and masks lifecycle breakage. Source: gaebal-gajae dogfood response to Clawhip message `1506484138927067286` on 2026-05-20.
477. **`system-prompt` only works as a bare command; every documented modifier (`--date`, `--cwd`, `--help`, `--output-format json`) and even invalid modifier cases zero-byte hang, making prompt provenance/reproducibility unusable outside the current cwd/date defaults** — dogfooded 2026-05-20 from the `#clawcode-building-in-public` 03:00 UTC nudge on `/home/bellman/Workspace/claw-code-pr2967` with `./rust/target/debug/claw version --output-format json` reporting `git_sha:"25d663d"`; branch and origin were both `docs/roadmap-workdir-provenance@8afdb94` before editing. Bare `system-prompt` exits 0 and prints the expected prompt with dynamic context, including working directory, date, git status, recent commits, and `CLAUDE.md` content. But `system-prompt --date 2026-05-20`, `system-prompt --cwd /tmp --date 2026-05-20`, `system-prompt --help`, `system-prompt extra`, `system-prompt --date nope`, `system-prompt --cwd /definitely/not/here`, and `system-prompt --output-format json` each timed out after 6s with `stdout=0` and `stderr=0`. Prefix global JSON (`--output-format json system-prompt`) exits 1 with `[error-kind: cli_parse] unknown option`. This is worse than a missing JSON parity issue: the help text advertises `claw system-prompt [--cwd PATH] [--date YYYY-MM-DD]`, but the advertised valid modifiers enter the non-returning path. **Required fix shape:** (a) parse `system-prompt` options before prompt/runtime fallback and make `--cwd`/`--date` valid, bounded, and deterministic; (b) validate `--date` format and nonexistent `--cwd` with typed errors; (c) implement `system-prompt --help`; (d) support or typed-reject `--output-format json` with a stable prompt-provenance envelope (`kind:"system_prompt"`, `cwd`, `date`, `project_context_sources`, `git_snapshot`, `text`); (e) add clean-home regression tests for bare, valid modifier, invalid modifier, help, extra arg, and JSON forms. **Why this matters:** `system-prompt` is the main way to debug prompt misdelivery and stale-context complaints. If users cannot pin cwd/date or get structured provenance, they cannot reproduce why a session received the wrong instructions. Source: gaebal-gajae dogfood response to Clawhip message `1506491684064723004` on 2026-05-20.
478. **`export` has a bounded bare no-session error, but every advertised flag/help form (`--help`, `--session`, `--output`, `--output-format json`) zero-byte hangs, so session artifact export cannot be scripted or debugged from the documented CLI surface** — dogfooded 2026-05-20 from the `#clawcode-building-in-public` 03:30 UTC nudge on `/home/bellman/Workspace/claw-code-pr2967` with `./rust/target/debug/claw version --output-format json` reporting `git_sha:"25d663d"`; branch and origin were both `docs/roadmap-workdir-provenance@90a0d38` before editing. Clean-home probes showed bare `export` exits 1 with a good typed error: `[error-kind: no_managed_sessions]`, the partitioned `.claw/sessions/<fingerprint>/` path, and guidance to start `claw` or rerun with `--resume latest`. But `export --help`, `export extra`, `export --session latest`, `export --session definitely-missing`, `export --output /tmp/claw-export-test.md`, and `export --output-format json` each timed out after 6s with `stdout=0`/`stderr=0`. Prefix `--output-format json export` exits 1 with `[error-kind: cli_parse]` and no JSON envelope. The help text advertises `claw export [PATH] [--session SESSION] [--output PATH]`, but those flags are not safely parsed. **Required fix shape:** (a) parse `export` options before prompt/runtime fallback; (b) implement `export --help`; (c) make `--session latest`, missing session IDs, positional PATH, and `--output PATH` return bounded results/errors; (d) support or typed-reject `--output-format json` with an envelope including `kind:"export"`, session fingerprint/path, output path, and skipped/error reason; (e) add clean-home regressions for bare no-session, help, extra arg, missing/latest session, output path, positional path, and JSON forms. **Why this matters:** `export` is the evidence path for stale session, prompt misdelivery, and event/log opacity bugs. If bare no-session works but every real option hangs, operators cannot reliably produce or inspect artifacts when debugging clawability issues. Source: gaebal-gajae dogfood response to Clawhip message `1506499237972545576` on 2026-05-20.
479. **`skills` accepts listing/help surfaces, but unknown skill invocation names zero-byte hang instead of returning a typed `skill_not_found`/usage error, so typoed skill calls look like runtime stalls** — dogfooded 2026-05-20 from the `#clawcode-building-in-public` 04:30 UTC nudge on `/home/bellman/Workspace/claw-code-pr2967` with branch/origin `docs/roadmap-workdir-provenance@4d52703` and binary `./rust/target/debug/claw` built from source SHA `25d663d`. Clean-home probes confirmed healthy bounded surfaces for `skills` (exit 0, `No skills found.`), `skills help`/`skills --help` (usage), and `skills --output-format json` (empty typed inventory). But the actual invocation/error path hangs silently: `skills garbage --output-format json`, `skills missing --output-format json`, `skills help missing --output-format json`, and `skills /nope --output-format json` each timed out after 6s with `stdout=0` and `stderr=0`. In contrast, sibling surfaces are bounded: `agents garbage --output-format json` exits 0 with a typed help envelope including `unexpected:"garbage"`, `mcp garbage --output-format json` does the same, and `skills install /nope --output-format json` exits 1 with a JSON error envelope. **Required fix shape:** (a) resolve the first post-`skills` token against installed skill names before falling into runtime prompt/tool execution; (b) for unknown names return a bounded JSON/text error with `kind:"skill_not_found"`, `name`, `available_count`, and a hint to run `claw skills list`; (c) reject extra args after `skills help` with typed usage instead of trying to invoke `help` as a skill; (d) preserve `skills list <extra>` behavior only if intentionally documented, otherwise reject the extra arg; (e) add clean-home regressions for list/help/json, unknown-name JSON/text, `help extra`, `/pathlike` unknown names, and install missing-path. **Why this matters:** skills are a plugin-like lifecycle surface. A typo or missing local skill should be diagnosable immediately; a zero-byte hang is indistinguishable from MCP startup deadlock or prompt misdelivery and makes automation wrappers unable to classify the failure. Source: gaebal-gajae dogfood response to Clawhip message `1506514333394403409` on 2026-05-20.
480. **`claw session` correctly says it is resume-only when bare, but `session --help` and `session list` zero-byte hang instead of returning bounded guidance, so users trying to discover session management from the advertised slash command get no usable recovery path** — dogfooded 2026-05-20 from the `#clawcode-building-in-public` 05:00 UTC nudge on `/home/bellman/Workspace/claw-code-pr2967` with branch/origin `docs/roadmap-workdir-provenance@93f20df` and binary `./rust/target/debug/claw` built from source SHA `25d663d`. Clean-home probe: bare `claw session` exits 1 with a useful typed stderr error: `[error-kind: unknown] error: \`claw session\` is a slash command. Use \`claw --resume SESSION.jsonl /session\` or start \`claw\` and run \`/session\`.` But the natural discovery and list forms do not share that bounded path: `claw session --help` timed out after 6s with `stdout=0`/`stderr=0`, and `claw session list` timed out after 6s with `stdout=0`/`stderr=0`; a longer wrapper run had to be killed after the `session list` probe stopped producing output. **Required fix shape:** (a) treat `session` as an explicit top-level alias for resume-safe session inspection rather than falling into prompt/runtime dispatch; (b) implement `session --help` with the same usage as `/session [list|exists|switch|fork|delete]` plus the `--resume` requirement where applicable; (c) make `session list` return a bounded empty-list result or a typed `resume_required`/`no_managed_sessions` error rather than hanging; (d) support or typed-reject `--output-format json` for session discovery/list/exists forms; (e) add clean-home regressions for bare `session`, `session --help`, `session list`, `session exists missing`, and the documented `--resume latest /session list` no-session path. **Why this matters:** session management is the recovery surface for stale-session confusion and prompt misdelivery. A user who sees `/session` in help naturally tries `claw session --help` or `claw session list`; hanging there blocks the exact diagnostics needed to find or resume the broken session. Source: gaebal-gajae dogfood response to Clawhip message `1506521887231180986` on 2026-05-20.
481. **Slash-only top-level aliases (`files`, `hooks`, `memory`) emit a useful bare resume-only error, but `--help` hangs with zero output, so users cannot discover the documented resume-safe command shape from the command they just tried** — dogfooded 2026-05-20 from the `#clawcode-building-in-public` 05:30 UTC nudge on `/home/bellman/Workspace/claw-code-pr2967` with branch/origin `docs/roadmap-workdir-provenance@51e6040` and binary `./rust/target/debug/claw` built from source SHA `25d663d`. Clean-home probes show the bare aliases are bounded: `claw files`, `claw hooks`, and `claw memory` each exit 1 with `[error-kind: unknown]` and a helpful message: `Use \`claw --resume SESSION.jsonl /<verb>\` or start \`claw\` and run \`/<verb>\`.` Their JSON forms are also bounded (`files --output-format json`, `hooks --output-format json`, `memory --output-format json`) with the same message in a JSON error envelope. But adding the most natural discovery flag hangs: `claw files --help`, `claw hooks --help`, and `claw memory --help` each timed out after 6s with `stdout=0`/`stderr=0`. In the same clean-home sweep, real top-level local verbs (`config`, `config --help`, `config env --output-format json`) returned immediately, proving this is specific to slash-only alias help fallback. **Required fix shape:** (a) centralize slash-only alias handling so `--help`/`help` never enter prompt/runtime dispatch; (b) return a bounded help page for every slash-only alias, including direct CLI usage (`claw --resume SESSION.jsonl /files`) and whether the command is resume-safe; (c) make JSON help/error envelopes include `kind:"slash_command_alias"`, `slash:"/files"`, `resume_required:true`, and supported resume forms; (d) add clean-home regressions for bare, `--help`, `help`, and JSON forms for `files`, `hooks`, `memory`, plus the already-found `session` sibling (#480). **Why this matters:** these are exactly the diagnostic surfaces users reach for during prompt misdelivery and stale-session debugging. A helpful bare error followed by a zero-byte hang on `--help` is a recovery dead-end. Source: gaebal-gajae dogfood response to Clawhip message `1506529436466675713` on 2026-05-20.
452. **`claw models`, `claw models list`, `claw models help`, and `claw models --help` are not wired as a `CliAction` at all — every spelling falls through to `CliAction::Prompt` and is sent verbatim to the Anthropic API as a user prompt; with credentials the CLI spins on the LLM "Thinking…" spinner forever, without credentials it errors with `missing_credentials` from the provider path. Direct sibling of #78 (`claw plugins` had the same prompt-misdelivery failure mode) for an additional discovery surface that operators and claws naturally try first when they need a model registry/alias/provider list before invoking `--model <alias> prompt …`** — dogfooded 2026-05-24 for the 05:00 Clawhip pinpoint nudge at message `1507971434704797716`, reproduced on local `./rust/target/debug/claw` `git_sha 003b739d` (origin/main `f8e1bb72`; `models` dispatch is grep-clean across `rust/crates/``git grep -nE 'CliAction::Models|"/models"|"models"' rust/` returns 0 hits, while `CliAction::Plugins` is wired at `rust/crates/rusty-claude-cli/src/main.rs:356,891,10153,10158,10167,10180,10193`, so `models` is the analogous unrouted command exactly the way `plugins` was before #78 landed). Repros in a fully clean isolated environment (`HOME=/tmp/iso2/home` with `{"}` settings, fresh `/tmp/iso2/proj` git-init'd workspace, `stdin=/dev/null`): `timeout 8 claw models list` exits `1` with `stderr=490` carrying the **Anthropic provider** `missing_credentials` envelope when `ANTHROPIC_*` env vars are unset, proving the command was dispatched to the LLM rather than handled locally; with `ANTHROPIC_API_KEY` set, every spelling (`models list`, `models`, `models help`, `models --help`) shows the spinner ANSI sequence (`\x1b[38;5;12m⠋ 🦀 Thinking…\x1b[0m`) on stdout and never returns inside the 68s bounded budget. **Why this is distinct from #78 / #145 / the help-JSON cluster:** #78 covered `claw plugins` only; #145 added the regression for `Plugins` parsing; #451 covers `models` in `--output-format json` mode where the failure surface is the silent zero-byte JSON deadlock. This pinpoint is the **plain-text prompt-misdelivery path** for `models`, with three behavioral consequences not covered above: (1) operators get the wrong-shaped error (`missing_credentials` for an Anthropic prompt) when they meant to inspect the model registry; (2) with credentials, expensive token burn on a meaningless `"models list"` LLM completion; (3) no slash-command-vs-direct-command parity — there is also no `/models` REPL command, so claws have no recovery path either. **Required fix shape:** (a) add `CliAction::Models { action: ModelsAction }` with `List`, `Show { name }`, `Help` variants wired in `parse_args` next to the existing `CliAction::Plugins` arm, never falling through to `CliAction::Prompt` for any `models*` spelling; (b) implement `models list` to return the resolved provider registry merged from built-ins (`anthropic`, `openai`, `xai`) plus any `modelProviders.*` profiles in settings, with per-model `name`, `provider`, `aliases[]`, `available`, `requires_credentials`, `source`; (c) implement `models --help` / `models help` as a static bounded help renderer (text + JSON envelopes) that does not touch provider runtime; (d) mirror the slash surface (`/models` REPL command) to match the existing `/agents`, `/mcp`, `/skills`, `/config` pattern; (e) add regression coverage in `parses_models_subcommand`-style tests proving every `models*` spelling resolves to `CliAction::Models` (no LLM dispatch), AND that the action returns within a deterministic budget without provider credentials. **Why this matters:** `models list` is the canonical model-registry discovery spelling across competing CLIs (`gh models list`, `openai api models.list`, `codex models`, the Anthropic Console UI). A claw or operator who reaches for it before deciding `--model <alias>` cannot discover what models exist, cannot validate an alias before paying for a prompt, and — worst case — burns provider tokens sending the string `"models list"` to Claude on a credentialed setup. The cost-of-doing-nothing here is real spend, not just opacity, which is why the prompt-misdelivery class deserves its own surface entry beyond #78/#145's `plugins` precedent. Source: gaebal-gajae dogfood follow-up for the 2026-05-24 05:00 Clawhip pinpoint nudge at message `1507971434704797716`.