Tasks: remove the process runner — tmux-only dispatch (issue-156)
Phase 3 of 3. Derived from
bugfix.md+design.md(both locked). TDD per task; each task names the ACs it delivers.
Task list
- [x] T1 — registry: drop
Session.runner(AC2.2). Remove the field from the dataclass,to_dict,from_dict(legacy key ignored on read) and thesession.registeredevent. Updatetest_tmux_runner.py::TestSessionRunnerFields(round-trip without the field; a legacy record carrying"runner": "process"still parses and is not branched on). - [x] T2 — runner module: tmux always required, empty target is missing (AC1.3, AC2.4).
check_dependencies(web_enabled)— tmux unconditional, ttyd when the web terminal is on;TmuxRunner.deliverreportssession_missingfor an empty target. UpdateTestCheckDependencies. - [x] T3 — harness adapters: remove the headless dispatch surface (AC2.1). Delete
HarnessAdapter.resume/spawn/_run/_resume_argv,DispatchResult,_session_id_from_output; rename_spawn_argv→_oneshot_argv(base + claude + cursor); trimharness/__init__exports. KeepUsage/usage_from_output/parse_json_object/oneshot_argv(critics) and theinteractive_*surface. Updatetest_routing.pyadapter tests; keeptest_critics.pygreen. - [x] T4 — interaction config: drop the runner coupling. Remove the
runnerparameter and the cli-under-process warning fromInteractionConfig.from_mapping; updatetest_interaction.py. - [x] T5 — dispatcher: one dispatch plane (AC1.1, AC1.2, AC2.3).
RoutingConfiglosesrunner(leftover key ⇒ warning);_dispatch_oneis tmux-only (headless else-branch,no-adapterdrop and_log_usageremoved);_spawn_foralways_spawn_tmux; constructor/reload comments updated. - [x] T6 — commands + announcer sweep.
gh_webhook/pollstartup and reload log lines;sessions attachempty-target message;sessions listdrops the Runner column;sessions startprints the tmux target;SessionAnnouncer.announceguard becomesnot session.tmux_target; poller comment updated. - [x] T7 — re-host the dispatcher test fleet on the tmux contract. The
FakeAdapterdispatch block intest_routing.pyand the end-to-end suites (test_webhook_routing_integration.py,test_poller_integration.py,test_control_cli.py,test_announce.py,test_graph_drive*.py) run on the tmux path with the stateful stub tmux; delete tests that pinned the removed behaviour (process defaults, attach-refusal, cli-under-process warning,check_dependencies("process")). - [x] T8 — new pins (AC2.3, AC2.4, AC4.1). Integration test (Gherkin, linked to AC2.4): an event for a legacy record without
tmuxTargetrespawns a tmux session resuming the recorded conversation. Unit tests:routing.runnerleftover warns and is ignored; spawn needs no runner config to be tmux. - [x] T9 — config schema + shipped configs (AC2.3, AC3.1). Delete
routing.runnerfromcli-config.schema.json; scrub process-runner prose from neighbouring descriptions (interaction,tmux,webTerminal,announce,defaultHarness); update.the-loop/cli-config.yamlandskills/the-loop/templates/cli-config.yaml. - [x] T10 — CLI docs (AC3.1).
docs/config/cli/routing-options.md(delete### runner, fix interaction/webTerminal/announce prose — in the same commit as T9:test_docs_parityP3/P4 pin schema↔docs),docs/cli/concepts.md,getting-started.md,installation.md(tmux is now required),index.md,commands/{poll,gh-webhook,sessions}.md,docs/config/cli/{index,polling-options}.md,docs/config/index.md,docs/cli/state.md(registry schema dropsrunner). - [x] T11 — capability docs (AC3.2).
interactive-sessions.md(tmux is the capability, not an option; mixed-fleet requirement removed),webhook-triggers.md(cli-under-process requirement removed),token-economy.md(cost model no longer a runner tradeoff),process-graph.md,cli.md; history rows added, existing rows untouched. - [x] T12 — skill references (AC3.1).
skills/the-loop/reference/token-economy.md(rewrite the runner-tradeoff framing),automation.md,context.md. - [x] T13 — decision record.
decision-056(tmux is the only runner; supersedes the runner choice of 021 and the headless dispatch of 016); index row added; 021's index status flipped tosuperseded (by 056). - [x] T14 — full gate + evidence (AC4.2). pytest, ruff check+format, pyright, markdownlint,
validate_config.py; evidence in the execution log. - [x] T15 — ship. Self-reviews, push
claude/github-issue-156-w0x1bz, PR with reviewer briefing, phase label →loop:needs-review, paper-trail comment on the ticket (with the agent marker).
Dependency graph (DAG)
mermaid
flowchart TD
T1[T1 registry] --> T5[T5 dispatcher]
T2[T2 runner module] --> T5
T3[T3 adapters] --> T5
T4[T4 interaction] --> T5
T5 --> T6[T6 commands sweep]
T5 --> T7[T7 re-host test fleet]
T6 --> T7
T7 --> T8[T8 new pins]
T9[T9 schema+configs] --> T10[T10 CLI docs]
T10 --> T11[T11 capability docs]
T11 --> T12[T12 skill references]
T12 --> T13[T13 decision record]
T8 --> T14[T14 full gate]
T13 --> T14
T14 --> T15[T15 ship]Checkpoints
- After T6: package imports clean; unit suites for the touched modules green.
- After T8: full pytest green.
- After T13: markdownlint +
validate_config.py+ docs-parity tests green. - After T14: evidence recorded in
execution-log.md.
Review comments
- (populated via PR review)