A reusable abstraction for running implementation work in an isolated
workspace, independent of which agent host (Claude Code, Codex) or which
mechanism is available. Lifecycle skills speak one vocabulary of operations;
this skill maps each operation to a concrete recipe per mode. It is consumed as
a library by /aep-launch, /aep-build, and /aep-autopilot, and can be
invoked standalone to dry-run detection (see Standalone Usage).
Native-first: Claude Code launches use a native in-process background subagent
(native-bg-subagent, the default) or — where the claude --bg flag exists —
native background sessions (claude-bg); Codex launches use native subagents
(codex-subagent) or headless exec workers (codex-exec). tmux+cmux is the
legacy mode — selected only by explicit pin
(git config aep.executor-backend tmux) or on generic hosts. Every mode runs its
worker in an AEP-created git worktree at .feature-workspaces/<ws>.
How Other Skills Use This
| Skill | What it uses | Operations |
|---|---|---|
/aep-launch |
Start the implementation agent + expose it for review | detect, spawn, present |
/aep-build Phase 5 |
Spawn the evaluator in the right execution context | detect, spawn_evaluator |
/aep-build |
Raise a human decision mid-build | gate |
/aep-autopilot |
Run the periodic tick check cheaply; steer workspaces | detect, check, nudge, liveness, gate |
/aep-wrap |
Tear down the worker + worktree after merge | teardown |
/aep-dispatch |
Resolve the handoff mode; route "…with workflow" runs | detect |
The Operation Contract
Every consumer speaks these verbs. The recipe files supply the implementation per mode.
| Op | Purpose |
|---|---|
detect() |
Resolve host + native capabilities + pin, select a mode |
spawn(ws, branch, prompt) |
Start an implementation agent bound to the AEP worktree |
spawn_evaluator(ws, role) |
Start an evaluator agent (worktree-bound) in the mode's eval context; accepts an optional tier-derived effort hint (see backends.md) |
nudge(ws, msg) |
Send a mid-flight instruction (steerable modes; pull-based under claude-bg) |
liveness(ws) |
Is the agent actively working? (mode-specific signal + git-diff corroboration) |
gate(ws) |
Surface a worker's human decision: needs-human.md + the mode's transport, answered hub-and-spoke through the main agent (block-in-place or gate-and-park) |
check(prompt, schema) |
Run a read-only analysis prompt in a cheap, context-isolated agent; return its JSON result — keeps a long-lived orchestrator session's context small |
monitor(ws) |
Read .dev-workflow/signals/status.json — host-independent, never changes |
present(ws) |
Human review surface (TaskOutput / claude attach / Codex thread / cmux tab / signals) |
teardown(ws) |
Worker + worktree cleanup |
monitor()is already abstract. Progress is reported through signal files at phase boundaries regardless of the executor. Native push channels (SendMessage, send_input) are an acceleration layer — the signal files remain the durable, host-agnostic source of truth.
The Modes (summary)
| Mode | Lifetime | Selected when |
|---|---|---|
| native-bg-subagent | session-bound | Claude Code default + long-lived orchestrator |
| claude-bg | OS-bound | Claude Code, claude --bg present (cron driver / OS-bound need) |
| codex-subagent | session-bound | Codex with a living main thread (desktop app or interactive CLI) |
| codex-exec | OS-bound | Codex + cron driver, or hard isolation demanded |
| legacy | OS-bound | explicit pin (aep.executor-backend tmux), or generic host w/ tmux |
| workflow | session-bound | explicit opt-in ("…with workflow") + Claude Code (see /aep-workflow) |
| headless | session-bound | last resort |
Read references/backends.md for each mode's mechanism, the detection recipe,
the full selection order, the driver × backend compatibility matrix, the
human-gate protocol, and orphan re-adoption.
Reference Files
| File | Contents | When to read |
|---|---|---|
references/backends.md |
Mode matrix, detection, selection order, driver compatibility, gate protocol, orphan re-adoption, check() |
Always, before spawning or steering |
references/claude-native.md |
native-bg-subagent (default) + claude-bg recipes, --bg availability note |
When the selected mode is a Claude native one |
references/codex-native.md |
codex-subagent + codex-exec recipes, aep-builder/aep-evaluator role TOMLs, desktop app mapping |
When the selected mode is a Codex one |
references/tmux-session.md |
legacy recipes (tmux spawn/nudge/liveness, cmux tab ladder) |
When legacy is pinned or selected |
references/dogfood-validation.md |
dogfood_method() host × mode detection, e2e_tool(), target_url() resolution |
When running dogfood validation (consumed by /aep-build, /aep-launch, /aep-watch, the autopilot post-merge guard) |
The skill also ships two probes, so the exact bash lives in one place instead of being retyped from a reference:
scripts/detect-backend.sh [--lifetime long|ephemeral] [--opt-in workflow|tmux] [--json]— host, executor commands, native capabilities, pin, presentation surface, and the selectedMODE.eval "$(bash scripts/detect-backend.sh)"to use it.scripts/spawn-liveness-probe.sh <name> <agent_id>— the post-spawn liveness probe every spawner runs (references/backends.md§ Post-Spawn Liveness Probe).
Standalone Usage
Invoked directly, this skill reports what would happen:
- Run
bash scripts/detect-backend.sh(add--lifetime ephemeralwhen this invocation is a cron/launchd one-shot — the script cannot probe that). - Report each field it prints, and say why that
MODEwon: which earlier rule in the selection order did not match. - If the user asked "why not workflow / why not tmux", explain the opt-in/pin gates.
This does not spawn anything — it is a dry-run of detect().
Rationale
Why native modes come first and tmux is a pinned legacy mode, why AEP owns the
worktree, why session-bound vs OS-bound is a first-class axis, why human gates are
hub-and-spoke, and why autopilot drives only steerable modes are recorded in
docs/decisions/native-first-executor.md,
docs/decisions/host-agnostic-executor.md, and
docs/decisions/remove-claude-team.md.
Next Step
After detecting/spawning, control returns to the calling skill:
/aep-launch→ the bootstrap was the spawn prompt (native modes) or sent over tmux (legacy), then/aep-buildruns in the workspace/aep-autopilot→ resumes its tick loop/aep-dispatch→ completes the handoff