Metadata
| Status | done |
|---|---|
| Assigned | agent-49 |
| Agent identity | f51439356729d112a6c404803d88015d5b44832c6c584c62b96732b63c2b0c7e |
| Created | 2026-04-26T16:48:52.047768809+00:00 |
| Started | 2026-04-26T16:49:49.049145164+00:00 |
| Completed | 2026-04-26T17:22:34.727270302+00:00 |
| Tags | eval-scheduled |
| Eval score | 0.82 |
| └ blocking impact | 0.90 |
| └ completeness | 0.82 |
| └ coordination overhead | 0.82 |
| └ correctness | 0.85 |
| └ downstream usability | 0.76 |
| └ efficiency | 0.85 |
| └ intent fidelity | 0.41 |
| └ style adherence | 0.90 |
Description
Description
User's frustration trail: agents 'launch with opus-4-6' — but they don't. Two stacked bugs.
User's clarification on the right behavior
- Pass-through what the user wrote.
claude:opusstaysopus(alias, latest version on claude CLI side);claude:claude-opus-4-6staysclaude-opus-4-6(pinned, user's choice). NO auto-canonicalization either way. - Default: bare alias (
opus/sonnet/haiku) — let claude CLI resolve to current. - Display = the actual string that was passed to the executor. The truth, not a fabricated canonical form.
Bug 1: Display fabricates a dated id
wg show <task> displays Model: claude-opus-4-6 for tasks created with --model claude:opus. The dated string was never typed by the user. Same fabrication shows up in the spawn log:
Spawned by coordinator --executor claude --model claude-opus-4-6 [agent-43]
Fix: in display paths, show what the user wrote (claude:opus), or what actually got passed to the executor after the prefix-strip (opus). NEVER a dated id the user didn't type.
Bug 2: Model is dropped between spawn-task and claude-handler (THE REAL BUG)
claude-handler stderr shows:
claude-handler: spawning claude (model=default, cwd=...)
Claude CLI is invoked with NO --model flag → uses claude CLI's own default (likely sonnet, NOT opus). The configured claude:opus is being dropped between spawn-task argv-construction and claude-handler exec.
Trace:
wg spawn-task .coordinator-1 --dry-runreturns:wg claude-handler --chat coordinator-1— no --model in argvclaude_handler.rs:376-379DOES forward --model when given one, but spawn-task isn't giving it one- Effective model resolution returns
claude:opus, but the spawn-task argv-builder for the claude branch isn't including--model
Fix: in src/commands/spawn_task.rs (around line 354 where the executor branch builds argv), the claude branch must pass --model <effective_model> to the claude-handler exec when the task or daemon config has a non-default model. Strip-provider-prefix already happens inside claude_handler; just pass the spec through.
Verification of fix
After fix, daemon log should show:
[INFO] [coordinator-0 stderr] claude-handler: spawning claude (model=opus, ...)
NOT model=default. And claude CLI then runs actual opus.
wg show shows the user's input string (claude:opus), not claude-opus-4-6.
The 'Spawned by coordinator' log line shows the same string the executor was actually invoked with.
Files likely to touch
src/commands/spawn_task.rs— add --model to claude-handler argv branchsrc/commands/show.rs— display model string as-written / as-passed, no canonicalizationsrc/commands/service/coordinator.rs— 'Spawned by ...' log line uses the actual invocation string- Whatever resolver fabricates
claude-opus-4-6fromclaude:opusfor display — neuter it for the claude executor path
What stays allowed
- User explicitly specifying a dated id (e.g.,
--model claude:claude-opus-4-6or--model claude:opus-4-6) is fine — that's pinning. Pass it through unchanged.
Validation
-
Failing tests first:
- test_spawn_task_passes_model_to_claude_handler — spawn-task --dry-run for task with model='claude:opus' includes
--model opus(after prefix strip) or--model claude:opus - test_show_displays_user_input_not_dated_id —
wg showfor task created with--model claude:opusdisplays the user's spec, NEVER a dated id - test_spawn_log_displays_actual_invocation — 'Spawned by ...' log line matches what was passed to the executor
- test_user_pinned_dated_id_passes_through_unchanged —
wg add 'x' --model claude:opus-4-6displays and runs as opus-4-6
- test_spawn_task_passes_model_to_claude_handler — spawn-task --dry-run for task with model='claude:opus' includes
- Implementation makes tests pass
- cargo build + cargo test pass with no regressions
-
Manual smoke (live, after restart):
- Daemon log:
claude-handler: spawning claude (model=opus, ...)(NOT model=default) wg show .coordinator-1displays Model as user-written (e.g., 'claude:opus', or 'opus' after strip)- 'Spawned by ...' log lines use the same string the executor got
- Daemon log:
Depends on
Required by
Log
- 2026-04-26T16:48:52.046456224+00:00 Task paused
- 2026-04-26T16:49:32.293089428+00:00 Task published
- 2026-04-26T16:49:48.886953304+00:00 Lightweight assignment: agent=Careful Programmer (f5143935), exec_mode=full, context_scope=task, reason=Careful Programmer's precision-focused style is essential for model-passing semantics and display accuracy across spawn_task, show, and coordinator; experienced with 22 similar implementation tasks.
- 2026-04-26T16:49:49.049148741+00:00 Spawned by coordinator --executor claude --model claude-opus-4-6
- 2026-04-26T16:50:01.386315802+00:00 Starting work on model-is-not: fixing model passthrough to claude CLI and display fabrication
- 2026-04-26T16:56:44.321642532+00:00 Traced both bugs. Bug 2: spawn_task.rs resolve_handler uses task.model.clone() which is None for coordinator tasks — config fallback missing. Bug 1: stale-model-alias (6805f9c4e) already changed constants to bare aliases. Implementing fix + tests now.
- 2026-04-26T17:19:56.896819462+00:00 Validated: all 6 new tests pass (spawn_task_passes_model_to_claude_handler, spawn_task_falls_back_to_config_model, user_pinned_dated_id_passes_through_unchanged, task_model_wins_over_config_model, show_displays_user_input_not_dated_id, show_model_field_preserves_user_spec, show_no_dated_id_in_config_constants). cargo build passes. 2785 existing tests pass — 6 pre-existing failures unrelated to changes.
- 2026-04-26T17:19:59.108711920+00:00 Manual smoke: wg spawn-task .coordinator-1 --dry-run shows '-m claude:opus' (was missing before fix). wg show .coordinator-1 displays 'Model: claude:opus' (user's string, no fabricated dated ID). wg show test-model-passthrough with --model claude:opus-4-6 displays 'Model: claude:opus-4-6 (configured)' — pinned IDs pass through unchanged.
- 2026-04-26T17:22:34.727275942+00:00 Task marked as done