Tasks: one the-loop start for every service the config enables
Phase 3 of 3. A DAG, not a list. Each
_Test:_names a row oftesting-plan.md.
mermaid
graph LR
T1["1 · enabled flags (schema + config code)"] --> T2["2 · MCP flag in create_app"]
T1 --> T3["3 · poller/daemon.py + daemon_entry"]
T3 --> T4["4 · delete poll cmd, shrink daemonize"]
T1 --> T5["5 · core/lifecycle.py"]
T4 --> T5
T5 --> T6["6 · lifecycle commands"]
T5 --> T7["7 · POST /api/v1/restart + contract"]
T1 --> T8["8 · ensure_service fail-closed"]
T4 --> T9["9 · re-point poller tests"]
T6 --> T10["10 · new tests"]
T7 --> T10
T8 --> T10
T6 --> T11["11 · docs + capability docs + decision-084"]
T10 --> T12["12 · verification"]
T9 --> T12
T11 --> T12Tasks
- [x] 1. The
enabledflags. Addservice.enabled,service.mcp.enabled,webhooks.ghWebhook.enabled,polling.enabledto both schema copies (byte-identical) and toskills/the-loop/templates/cli-config.yaml; resolve them inapi/config.service_configand wherever the daemon blocks are read. Requirements: R1.1, R5.3, NFR4 · Test: T6 - [x] 2. MCP is mountable-off.
create_appskips building/mounting the MCP app and its lifespan whenservice.mcp.enabledis false;/mcpanswers 404. Requirements: R1.6 · Test: T4 - [x] 3. The poller run loop moves. New
poller/daemon.py(options from config, run, status, stop — logic fromcommands/poll.py, messages renamed tothe-loop stop/status);daemon_entry poller [--once]drives it directly. Requirements: R2.2, R2.3, NFR1 · Test: T3 - [x] 4. Remove the poll command. Delete
commands/poll.pyand its registration;cli.py's_refresh_cli_config_pathsdrops the import;daemonize.pyshrinks toopen_logfile(the double-fork existed forpoll start --daemononly). Requirements: R2.1 · Test: T3, T12 - [x] 5.
core/lifecycle.py.plan,start_all,stop_all,status_all,schedule_restartas designed (D3); service spawn/health logic moved here fromservice_cmd, which now delegates. Requirements: R1.1–R1.5, R3.1–R3.4, R4.4, R4.5 · Test: T1 - [x] 6. The lifecycle commands.
commands/lifecycle_cmd.py:start,stop,status --format,restart --with-upgrade(planner from issue-152,components=["cli"], upgrade failure does not abort the start half). Requirements: R1, R3, R4.1–R4.3 · Test: T2 - [x] 7. The restart API.
POST /api/v1/restart→schedule_restart; add the route todocs/api-specs/openapi/the-loop.v1.yaml; state the MCP exclusion inapi/mcp.py. Requirements: R4.4, R4.5 · Test: T4, T5 - [x] 8. Fail-closed auto-start.
client.ensure_servicerefuses whenservice.enabledis false, naming the key. Requirements: R5.2 · Test: T1 - [x] 9. Re-point the poller tests. The scenarios of
test_poll_command,test_poll_daemon_integration,test_poll_status(and any otherpoll startdriver) keep their Gherkin and assert via the new entry points; runlock/tmux/interaction tests updated where they shelledthe-loop poll. Requirements: R2.2, R2.4 · Test: T3 - [x] 10. New tests.
test_core_lifecycle.py,test_lifecycle_cmd.py, restart-API and MCP-flag cases in the existing integration suites; contract parity. Requirements: all · Test: T1, T2, T4, T5 - [x] 11. Docs. Command pages (delete
poll.md; addstart.md,stop.md,status.md,restart.md; updateindex.md,service.md,gh-webhook.md), config option pages (polling,webhook,service), getting-started / installation / state, README + cli/README, capability docs (cli.md,control-plane.md,webhook-triggers.md,interactive-sessions.md),reference/observability.md+reference/automation.md, decision-084 + index row. Requirements: NFR3 · Test: T6, T9(docs), T12 - [x] 12. Verification. Execute the plan, fill its Results column, commit evidence. Requirements: all · Test: T7–T12
Added on owner review (PR #229)
- [x] 13. Fold
gh-webhookandserviceaway. Receiver run loop →webhook/daemon.py; both command modules deleted;daemon_entrydrives both daemons directly; hints, docs (pages relocated to/cli/serviceand/cli/receiver), capability docs and tests re-pointed. Requirements: R5.1 (superseded form) · Test: T3, T7, T13 - [x] 14. Dashboard restart.
restart()on the API client (live + demo), the Settings Service card, the config editor's "Restart now" onrestartRequired; UI tests, lint, typecheck, build. Requirements: R4.6 · Test: T13 - [x] 15. Single-process mode (review round 2, issue-231).
service.hostIngresses(default true) inservice_config+ both schema copies + template;api/ingress.pyhosting the poller (_run_lockedwithstop_event, no signal handlers) and the receiver (build_receiversplit) as locked threads increate_app's lifespan;core.lifecycledetecting hosted-ness from the lock instart_all/stop_all/status_all;RESTART_REQUIRED+ new event types; docs (config/command/service/receiver pages, capability docs, decision-084 §8, requirements R6 / design D6). Requirements: R6.1–R6.6 · Test: T14