fix-codex-init

Fix: codex-init should produce working full config (and codex profile overlay is failing)

Metadata

Statusdone
Assignedagent-2620
Agent identity02e879681e52e0a384106169be043416c4d946e850ab26b2269c57681b52a6e7
Created2026-05-11T18:38:51.835886715+00:00
Started2026-05-11T18:40:06.883494961+00:00
Completed2026-05-11T19:29:52.075179040+00:00
Tagsbug,config,init,profile,codex, eval-scheduled
Eval score0.70
└ blocking impact0.75
└ completeness0.70
└ coordination overhead0.80
└ correctness0.65
└ downstream usability0.72
└ efficiency0.75
└ intent fidelity0.61
└ style adherence0.72

Description

Problem

The profile overlay system is broken in a particularly bad way: it half-applies. ~/.wg/profiles/codex.toml correctly defines [agent].model = "codex:gpt-5.5", but wg profile show after wg profile use codex reports effective agent.model = claude:opus. Tier mappings get through; [agent].model is silently dropped. So users on codex profile get a config that says codex everywhere but actually runs claude. Silent, contradictory, undebuggable.

Compounding it: wg config init --route codex-cli doesn't produce a working codex config either, so users can't escape the broken profile by initializing locally.

Design (user-directed): profile = symlink target

Replace the overlay/merge system with symlink-based profile snapshots.

  • Each profile is a complete config snapshot living at ~/.wg/config.toml.<name> (e.g., config.toml.claude, config.toml.codex, config.toml.nex).
  • ~/.wg/config.toml is a symlink pointing at the active profile file.
  • wg profile use codex = atomic symlink swap: ln -sfn config.toml.codex ~/.wg/config.toml.
  • No merge logic. What's in the target file is exactly what runs. readlink ~/.wg/config.toml tells you the active profile at a glance.
  • Editing ~/.wg/config.toml (the symlink) writes through to the underlying config.toml.<name> — so existing wg config -m flows keep working without changes.

Windows fallback

Windows symlinks require admin or developer mode. Detect and fall back to:

  • Copy config.toml.<active>config.toml on profile switch
  • Maintain a tiny ~/.wg/active-profile pointer file naming the active profile
  • Same wg profile show UX, different mechanism underneath

Implement symlink path first; Windows fallback is a feature-flagged branch in the swap logic.

Versioning (future, NOT in scope here)

The naming scheme leaves room for snapshot/versioning (config.toml.codex.2026-05-11, wg profile snapshot, rollback). That's a follow-up task — v1 just uses bare profile names.

What to do

  1. Make codex profile a complete, working config snapshot. Use /home/erik/impg/.wg/config.toml as the reference (see Annex A). Move/rename ~/.wg/profiles/codex.toml~/.wg/config.toml.codex, expand to a full standalone working config.

  2. Same for claude and nex. ~/.wg/profiles/claude.toml~/.wg/config.toml.claude, similarly expanded. ~/.wg/profiles/nex.toml~/.wg/config.toml.nex. Each must be a complete working config on its own.

  3. Replace profile-merge logic with symlink-swap. Find the config resolver (likely src/config/ or src/profile/). Remove overlay/merge code. wg profile use <name>:

    • On Unix: atomic symlink(config.toml.<name>, config.toml) (use renameat2-style atomic replace, or write to temp + rename)
    • On Windows: copy config.toml.<name>config.toml and update ~/.wg/active-profile
    • Hot-reload the daemon (same as today's profile switch)
  4. Fix wg config init --route codex-cli (and legacy -x codex) to set up profile files + symlink in one go. wg config init --route codex-cli = ensure ~/.wg/config.toml.codex exists from the codex template, symlink ~/.wg/config.toml → it. Same logic for other routes.

  5. wg profile show cleanup. Drop the now-meaningless 'Effective settings (base config + profile overlay)' line. Replace with: active profile name, readlink target (or copy-source on Windows), and a short grep 'model' excerpt so users can verify at a glance.

  6. Migrate existing installs. First run after upgrade: if ~/.wg/profiles/<name>.toml exists and ~/.wg/config.toml.<name> doesn't, move the file. If ~/.wg/config.toml is a real file (not a symlink) and an active-profile is set, rename it to config.toml.<active> and create the symlink. Single migration pass, no deprecation window.

  7. Add regression tests:

    • After wg profile use codex (Unix): ~/.wg/config.toml is a symlink whose target is config.toml.codex
    • After wg profile use codex: grep 'model = ' "/home/erik/.wg/config.toml" shows codex models, NOT claude:opus
    • After wg profile use codex, wg status reports codex-derived executor
    • wg config init --route codex-cli creates both config.toml.codex and the symlink in a fresh ~/.wg
    • Windows-fallback path (gate on #[cfg(windows)] or feature flag): same UX, copy-based

Migration / back-compat

Per recurring guidance: single active user, skip back-compat ceremony. Single in-place migration on upgrade, no migrate subcommand, no .bak, no deprecation windows.

Out of scope (file as separate tasks if wanted)

  • Profile versioning / snapshotting (wg profile snapshot, wg profile rollback)
  • Per-section override syntax (intentionally removed)
  • TUI changes
  • Profile diff / merge UI

Validation

  • ~/.wg/config.toml.codex exists as a complete working config matching Annex A (claude / nex similarly complete)
  • Profile-merge / overlay code path removed
  • On Unix: wg profile use codex makes ~/.wg/config.toml a symlink to config.toml.codex, atomically
  • On Windows (or behind #[cfg(windows)] test): same command copies file + updates ~/.wg/active-profile
  • Editing ~/.wg/config.toml (the symlink) on Unix writes through to the underlying config.toml.<name> (i.e., wg config -m still works)
  • After wg profile use codex: wg status shows codex executor, NOT claude
  • wg config init --route codex-cli produces equivalent codex setup from the codex template
  • Migration: existing install with ~/.wg/profiles/codex.toml and a real-file ~/.wg/config.toml upgrades cleanly on first run
  • Regression tests pass: profile-swap correctness, write-through edit, init route correctness
  • cargo build clean, cargo test clean
  • cargo install --path . after, so fix is live in global wg
  • Manual smoke (fresh tmp $HOME or container): wg profile use codex, cd /tmp/x && wg init && wg add 'test' && wg service start, confirm dispatched agent uses codex executor

Annex A: reference working codex config

(From /home/erik/impg/.wg/config.toml — user's hand-built config that actually works.)

[agent]
model = "codex:gpt-5.5"

[dispatcher]
model = "codex:gpt-5.5"
max_agents = 8

[models.default]
model = "codex:gpt-5.5"

[models.task_agent]
model = "codex:gpt-5.5"

[models.evaluator]
model = "codex:gpt-5.4-mini"

[models.flip_inference]
model = "codex:gpt-5.4-mini"

[models.flip_comparison]
model = "codex:gpt-5.4-mini"

[models.assigner]
model = "codex:gpt-5.4-mini"

[tiers]
fast     = "codex:gpt-5.4-mini"
standard = "codex:gpt-5.4"
premium  = "codex:gpt-5.5"

(Other sections — [agency], [chat], [tui], [checkpoint], [guardrails], etc — should match the claude profile's defaults except where there's a codex-specific reason to diverge. Full file at /home/erik/impg/.wg/config.toml for reference.)

Depends on

Required by

Log