Metadata
| Status | done |
|---|---|
| Assigned | agent-687 |
| Agent identity | f51439356729d112a6c404803d88015d5b44832c6c584c62b96732b63c2b0c7e |
| Created | 2026-04-27T14:15:39.175623226+00:00 |
| Started | 2026-04-27T14:16:03.021433250+00:00 |
| Completed | 2026-04-27T15:29:17.126893421+00:00 |
| Tags | eval-scheduled |
Description
Description
The executor taxonomy has 6 overlapping user-facing concepts (executor, provider, endpoint, route, handler, model) that reduce to TWO real axes (delegate-vs-in-process, wire protocol). The proliferation causes constant confusion and config bugs (model-routes-to-wrong-executor, claude+local-model = 404, etc — see agency-picks-claude, agency-still-picks, local-providers-fix history this session).
User decision (verbatim): 'lets simplify executor taxonomy. deeply problematic.'
Target model
User picks ONE thing: a (model, endpoint) pair. wg derives everything else.
- model —
claude:opus,openrouter:anthropic/claude-opus-4-6,local:qwen3-coder,oai-compat:gpt-5, etc. Carries provider prefix. - endpoint — defaults from provider (claude → claude CLI's own auth; openrouter → openrouter.ai; local → user-supplied URL). Optional.
From these two, wg internally decides:
- Which handler subprocess to spawn (claude-handler / codex-handler / nex)
- Which wire protocol to use (Anthropic vs OAI-compat)
- Whether it's delegate-to-CLI (claude, codex, aider/llm if added) or in-process (nex/native)
The user never types --executor again. Never sees [agent].executor in config. Never has to pick -x claude vs -x native — the model spec implies it.
What changes (user-facing)
| Today | New |
|---|---|
wg init -x claude -m claude:opus | wg init -m claude:opus (executor implied) |
wg init -x nex -m qwen3-coder -e https://lambda01... | wg init -m local:qwen3-coder -e https://lambda01... (or just -m if endpoint isn't local-style) |
wg add 'task' --executor claude --model opus | wg add 'task' --model claude:opus |
[agent] executor = 'claude' in config | DEPRECATED. Just [agent] model = 'claude:opus'. |
[dispatcher] executor = 'native' | DEPRECATED. [dispatcher] model = 'local:qwen3-coder' is the only knob. |
wg setup --route claude-cli | UNCHANGED (routes were already the right idea — make them the canonical setup path) |
What changes (internals — not user-facing)
The wg codebase still has all the executor implementations (claude-handler, codex-handler, nex/native). They become internal handler types keyed off model-prefix → handler-kind:
claude:*→ claude-handler subprocesscodex:*oroai-compat:gpt-*→ codex-handlerlocal:*,openrouter:*,oai-compat:*→ nex (in-process)- Future: aider/llm/etc each get their own internal handler
This mapping lives in ONE place (e.g., src/dispatch/handler_for_model.rs) and is the single source of truth for 'given this model, what binary do I spawn'.
Deprecation surfaces
For one release:
-x <executor>flag accepted with deprecation warning, mapped to corresponding model spec[agent].executorfield accepted with deprecation warning, ignored if model has provider prefix--executoronwg addaccepted with deprecation warningwg config --coordinator-executoraccepted with deprecation warning
After one release: drop them entirely.
Documentation rewrite
CLAUDE.md, AGENT-GUIDE.md, README.md, docs/AGENT-SERVICE.md — all references to 'executor' as a user concept get rewritten:
- 'pick an executor' → 'pick a model'
- 'executor types: claude, native, codex, ...' → 'wg picks the right handler based on your model and endpoint'
- Examples use only model + endpoint
Files likely to touch
src/cli.rs— drop / deprecate-xand--executorflags on init / add / spawn / setupsrc/commands/init.rs— implied-executor logic from-msrc/commands/add.rs— samesrc/commands/setup.rs— routes are the canonical entry; drop the duplicate executor-question pathssrc/config.rs— markexecutorfield deprecated; warn on load if setsrc/dispatch/plan.rs—plan_spawnalready does most of this work; just remove theagent_executorparameter and infer from model- New:
src/dispatch/handler_for_model.rs(or similar) — single source of truth for model → handler-kind mapping - Docs: CLAUDE.md, AGENT-GUIDE.md, README.md, docs/AGENT-SERVICE.md, docs/COMMANDS.md
- Migration tests: legacy configs with
executor=Xstill load with deprecation warning, behavior matches
What stays
- Routes (
wg setup --route claude-cli) — they were always the right user-facing abstraction; keep them - Handlers themselves (claude-handler, codex-handler, nex) — internal implementation, unchanged
shellexec-mode (genuinely doesn't involve an LLM) — stays as an exec_mode flag, not an executor- Per-task model override (
wg add 'X' --model Y) — stays
Migration plan
- Add deprecation warnings on every
executor=surface (config, CLI, IPC) — don't break anyone. - Update docs + examples to use model+endpoint only.
- Implement handler-for-model resolver as single source of truth.
- After one release: hard-remove the deprecated surfaces.
Out of scope
- Rewriting the handler implementations themselves (claude-handler, nex) — those are fine, just become internal
- The chat-as-first-class refactor (
wg-chat-asalready done, separate concern) - The route default-model splits (
wg-setup-routesalready filed, separate concern)
Validation
-
Failing tests first:
- test_init_without_executor_flag_uses_model_prefix —
wg init -m claude:opusproduces config with handler=claude (no --executor needed) - test_init_with_local_model_routes_to_nex —
wg init -m local:qwen3-coder -e https://...produces config that uses nex handler (no --executor needed) - test_legacy_executor_flag_warns_and_works —
wg init -x claude -m claude:opusstill produces same config + emits one deprecation warning - test_legacy_executor_field_warns_on_load — config with
[agent] executor = 'claude'loads, emits warning, model spec wins - test_handler_for_model_is_single_source_of_truth — grep src/ for executor-decision logic outside the handler-for-model resolver returns zero hits
- test_no_executor_in_user_facing_help —
wg --help,wg init --help,wg add --helpmention model + endpoint, NOT executor
- test_init_without_executor_flag_uses_model_prefix —
- Implementation makes tests pass
- cargo build + cargo test pass with no regressions
-
Manual smoke (HARD GATE):
- Fresh dir:
wg init -m claude:opusworks, config has no executor field, dispatch produces claude-handler spawn - Fresh dir:
wg init -m local:qwen3-coder -e https://lambda01...works, dispatch produces nex spawn against the endpoint - Legacy config with
executor=claudeloads, emits one warning, behaves identically wg setup --route claude-cli --yesproduces a no-executor-field config that works- All docs read coherently with no mention of 'executor' as a user concept (only routes + models)
- Fresh dir:
Depends on
Required by
- (none)
Log
- 2026-04-27T14:15:39.169482554+00:00 Task paused
- 2026-04-27T14:15:39.229286862+00:00 Task published
- 2026-04-27T14:16:01.777485427+00:00 Lightweight assignment: agent=Careful Programmer (f5143935), exec_mode=full, context_scope=task, reason=Careful Programmer is ideal for this large architectural refactor: careful deprecation paths, multi-file implementation, TDD validation, and regression prevention are all core strengths of the Careful tradeoff.
- 2026-04-27T14:16:03.021440143+00:00 Spawned by coordinator --executor claude --model opus
- 2026-04-27T14:16:20.987651005+00:00 Starting: investigating current executor taxonomy in src/cli.rs, src/config.rs, src/dispatch/plan.rs
- 2026-04-27T15:28:04.877782432+00:00 All 6 validation tests pass + 4 init tests pass + manual smoke A/B/C/D verified. No new test regressions vs main.
- 2026-04-27T15:28:48.286063301+00:00 Committed: d0ccd8313 — pushed to remote
- 2026-04-27T15:29:17.126912929+00:00 Task pending eval (agent reported done; awaiting `.evaluate-*` to score)
- 2026-04-27T15:29:30.079874400+00:00 PendingEval → Done (evaluator passed; downstream unblocks)