You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
ROADMAP ultraworkers#111: /providers documented as 'List available model providers' but dispatches to Doctor
Dogfooded 2026-04-18 on main HEAD b2366d1 from /tmp/cdHH.
Specification mismatch at the command-dispatch layer:
commands/src/lib.rs:716-720 SlashCommandSpec registry:
name: 'providers', summary: 'List available model providers'
commands/src/lib.rs:1386 parser:
'doctor' | 'providers' => SlashCommand::Doctor
So /providers dispatches to SlashCommand::Doctor. A claw calling
/providers expecting {kind: 'providers', providers: [...]} gets
{kind: 'doctor', checks: [auth, config, install_source, workspace,
sandbox, system]} instead. Same top-level kind field name,
completely different payload.
Help text lies twice:
--help slash listing: '/providers List available model providers'
--help Resume-safe summary: includes /providers
Unlike STUB_COMMANDS (ultraworkers#96) which fail noisily, /providers fails
QUIETLY — returns wrong subsystem output.
Runtime has provider data:
ProviderKind::{Anthropic, Xai, OpenAi, ...} at main.rs:1143-1147
resolve_repl_model with provider-prefix routing
pricing_for_model with per-provider costs
provider_fallbacks config field
Scaffolding is present; /providers just doesn't use it.
By contrast /tokens → Stats and /cache → Stats are semantically
reasonable (Stats has the requested data). /providers → Doctor
is genuinely bizarre.
Fix shape:
A. Implement: SlashCommand::Providers variant + render helper
using ProviderKind + provider_fallbacks + env-var check (~60)
B. Remove: delete 'providers' from registry + parser (~3 lines)
then /providers becomes 'unknown, did you mean /doctor?'
Either way: fix --help to match.
Parallel to ultraworkers#78 (claw plugins CLI variant never constructed,
falls through to prompt). Both are 'declared in spec, not
implemented as declared.' ultraworkers#78 fails noisy, ultraworkers#111 fails quiet.
Joins silent-flag cluster (ultraworkers#96-ultraworkers#101, ultraworkers#104, ultraworkers#108) — 8th
doc-vs-impl mismatch. Joins unplumbed-subsystem (ultraworkers#78, ultraworkers#96,
ultraworkers#100, ultraworkers#102, ultraworkers#103, ultraworkers#107, ultraworkers#109) as 8th declared-but-not-
delivered surface. Joins truth-audit.
Natural bundles:
ultraworkers#78 + ultraworkers#96 + ultraworkers#111 — declared-but-not-as-declared triangle
ultraworkers#96 + ultraworkers#108 + ultraworkers#111 — full --help/dispatch hygiene quartet
(help-filter-leaks + subcommand typo fallthrough + slash
mis-dispatch)
Filed in response to Clawhip pinpoint nudge 1494872623782301817
in #clawcode-building-in-public.
**Blocker.** None. `project_root_for` helper trivially reusable from the git-root walker. Discovery list is additive — adding ancestor entries doesn't break existing cwd-anchored configs. Most invasive piece is the architectural decision: walk-to-project-root + cwd-overlay (this proposal), or walk-every-ancestor-like-CLAUDE.md (#85's current over-broad policy), or unify both under a single policy.
3179
3179
3180
3180
**Source.** Jobdori dogfood 2026-04-18 against `/tmp/cdGG/nested/deep/dir` on main HEAD `16244ce` in response to Clawhip pinpoint nudge at `1494865079567519834`. Joins **truth-audit / diagnostic-integrity** (#80–#87, #89, #100, #102, #103, #105, #107, #109) — doctor reports "ok, defaults active" when the operator actually has a config. Joins **discovery-overreach / security-shape** (#85, #88) as the opposite-direction sibling: #85 over-discovers instruction files; #110 under-discovers config files. Cross-cluster with **Reporting-surface / config-hygiene** (#90, #91, #92) — this is the canonical config-discovery policy bug. Natural bundle: **#85 + #110** — unify ancestor-discovery policy across CLAUDE.md + config. Also **#85 + #88 + #110** as the three-way "ancestor-walk policy audit" covering skills over-discovery, CLAUDE.md prompt injection via ancestors, and config under-discovery from subdirectories. Session tally: ROADMAP #110.
3181
+
3182
+
111. **`/providers` slash command is documented as "List available model providers" in both `--help` and the shared command-spec registry, but its parser at `commands/src/lib.rs:1386` maps it to `SlashCommand::Doctor` — so invoking `/providers` runs the six-check health report (auth/config/install_source/workspace/sandbox/system) and returns `{kind: "doctor", checks: [...]}`. A claw expecting a structured list of `{providers: [{name, models, base_url, reachable}]}` gets workspace-health JSON instead** — dogfooded 2026-04-18 on main HEAD `b2366d1` from `/tmp/cdHH`. The command-spec registry at `commands/src/lib.rs:716-718` declares `name: "providers", summary: "List available model providers"`. `--help` echoes that summary in the slash-command listing and in the Resume-safe line. Actual dispatch routes to doctor. Declared contract and implementation diverge completely; this is a specification mismatch rather than a stub — `/providers` has documented semantics claw does not implement and silently delivers the wrong subsystem.
3183
+
3184
+
**Concrete repro.**
3185
+
```
3186
+
$ cd /tmp/cdHH && git init -q .
3187
+
$ # set up a minimal session
3188
+
$ claw --resume s --output-format json /providers | jq '.kind'
3189
+
"doctor"
3190
+
$ # A /providers call returns kind=doctor with six health checks
3191
+
$ claw --resume s --output-format json /providers | jq '.checks[].name'
3192
+
"auth"
3193
+
"config"
3194
+
"install source"
3195
+
"workspace"
3196
+
"sandbox"
3197
+
"system"
3198
+
# No `providers` array. No provider list. Auth/config/etc health checks.
3199
+
3200
+
$ # Compare help documentation:
3201
+
$ claw --help | grep '/providers'
3202
+
/providers List available model providers [resume]
3203
+
# Help advertises provider listing. Implementation delivers doctor.
3204
+
3205
+
# Also compare: /tokens and /cache alias to SlashCommand::Stats, which IS
3206
+
# reasonable — Stats contains token + cache counts. Those aliases are
3207
+
# semantically close. /providers → Doctor is not.
3208
+
$ claw --resume s --output-format json /tokens | jq '.kind'
3209
+
"stats"
3210
+
# Reasonable: Stats has token counts.
3211
+
$ claw --resume s --output-format json /cache | jq '.kind'
Both `/doctor` and `/providers` collapse to `SlashCommand::Doctor`. The registry-declared semantics for `/providers` ("list available model providers") is never honored.
3235
+
- `rust/crates/rusty-claude-cli/src/main.rs` — `render_providers_report` / `render_providers_json` / any provider-listing code: **does not exist**. Verified via `grep -rn "fn render_providers\|fn list_providers\|pub fn providers" rust/crates/ | head` — zero matches.
3236
+
- Runtime DOES know about providers conceptually — `rust/crates/rusty-claude-cli/src/main.rs:1143-1147` enumerates `ProviderKind::Anthropic`, `Xai`, etc. for prefix-routing model names. `resolve_repl_model` + provider-prefix logic has provider awareness. None of it is surfaced through a command.
3237
+
3238
+
**Why this is specifically a clawability gap.**
3239
+
1. *Declared-but-not-implemented contract mismatch.* Unlike #96's `STUB_COMMANDS` entries (where the infrastructure says "not yet implemented"), `/providers` silently succeeds with the WRONG output. A claw parsing `{kind: "providers", providers: [...]}` from the documented spec gets `{kind: "doctor", checks: [...]}` instead — same top-level `kind` field name, completely different payload shape.
3240
+
2. *Help text lies twice.* The standalone slash-command line in `--help` says "List available model providers." The Resume-safe summary also includes `/providers` (passes the #96 filter because it IS implemented — just as the wrong handler). A claw reading either surface cannot know the command is mis-wired without running it.
3241
+
3. *Runtime has provider data.* `ProviderKind::{Anthropic,Xai,OpenAi,...}`, `resolve_repl_model`, provider-prefix routing, and `pricing_for_model` all know about providers. A real `/providers` implementation would have input from `ProviderKind` + any configured `providerFallbacks` array + env vars. ~20 lines. The scaffolding is present.
3242
+
4. *Parallel to #78 (CLI route never constructed).* #78 says `claw plugins` CLI route is wired as a `CliAction` variant but falls through to Prompt. #111 says `/providers` slash command is wired as a `SlashCommandSpec` entry but dispatches to the wrong handler. Both are "declared in the spec, not actually implemented as declared." #78 fails noisily (prompt-fallthrough error); #111 fails quietly (returns a different subsystem's output).
3243
+
5. *Joins the Silent-flag / documented-but-unenforced cluster* on a new axis: documentation-vs-implementation mismatch at the command-dispatch layer.
3244
+
6. *Test coverage blind spot.* A unit test that asserts `claw --resume s /providers` returns `kind: "doctor"` would PASS today — which means the current test suite (if any covers /providers) is locking in the bug.
3245
+
3246
+
**Fix shape — either implement /providers properly or remove it from the spec + help.**
3247
+
1. *Option A — implement.* Add a `SlashCommand::Providers` variant. Build a `render_providers_json(runtime_config) -> json!({ kind: "providers", providers: [{name, base_url_env, active, has_credentials, ...}] })` helper from the existing `ProviderKind` enum + `provider_fallbacks` config + env-var inspection. Add to the `run_resume_command` match. ~60 lines.
3248
+
2. *Option B — remove.* Delete the `"providers"` name from the command-spec registry. Remove `"providers"` from the parser arm. `/providers` becomes an unknown slash command and gets the "Did you mean /doctor?" suggestion. ~3 lines of deletion.
3249
+
3. *Either way, fix `--help`.* If implemented (Option A), the current help text is correct. If removed (Option B), delete the help line.
3250
+
4. *Regression test.* Assert `/providers` returns `kind: "providers"` (Option A) or returns "unknown slash command" error (Option B). Either way, prevent the current silent-wrong-subsystem behavior.
3251
+
5. *Cross-check.* Audit the rest of the registry for other mismatches. `/tokens → Stats` and `/cache → Stats` are semantically defensible (stats contains what the user asked for). Any other parser arms that collapse disparate commands into a single handler are candidates for the same audit.
3252
+
3253
+
**Acceptance.** `claw --resume s /providers` returns either `{kind: "providers", providers: [...]}` (Option A) or exits with structured error `unknown slash command: /providers. Did you mean /doctor?` (Option B). The `--help` line for `/providers` matches actual behavior. Test suite locks in the chosen semantic.
3254
+
3255
+
**Blocker.** None. The choice (implement vs remove) is the only architectural decision. Runtime has enough scaffolding that implementing is ~60 lines. Removing is ~3 lines.
3256
+
3257
+
**Source.** Jobdori dogfood 2026-04-18 against `/tmp/cdHH` on main HEAD `b2366d1` in response to Clawhip pinpoint nudge at `1494872623782301817`. Joins **silent-flag / documented-but-unenforced** (#96–#101, #104, #108) on the command-dispatch-semantics axis — eighth instance of "documented behavior differs from actual." Joins **unplumbed-subsystem / CLI-advertised-but-unreachable** (#78, #96, #100, #102, #103, #107, #109) as the eighth surface where the spec advertises a capability the implementation doesn't deliver. Joins **truth-audit / diagnostic-integrity** (#80–#87, #89, #100, #102, #103, #105, #107, #109, #110) — `/providers` silently returns doctor output under the wrong kind label; help lies about capability. Natural bundle: **#78 + #96 + #111** — three-way "declared but not implemented as declared" triangle (CLI route never constructed + help resume-safe leaks stubs + slash command dispatches to wrong handler). Also **#96 + #108 + #111** — full `--help`/dispatch surface hygiene quartet covering help-filter-leaks + subcommand typo fallthrough + slash-command mis-dispatch. Session tally: ROADMAP #111.
0 commit comments