{"definition_raw":"---\nid: luci-followup-sweep\ntitle: Sweep overdue ledger rows into orchestrator_inbox\nschedule: \"*/30 * * * *\"\ntimeout: 120\nretry: false\nenabled: true\nnotify_on: failure\nrun_as: shell\ncommand: \"/usr/bin/python3 /home/lucienne/workspace/scripts/luci_followup_sweep.py --timeout 90 --db-timeout 5\"\ntags: [orchestrator, followup, ledger]\nruntime_profile: direct_mixed\n# Script has its own 90s wall timeout and 5s SQLite busy timeout so scheduler\n# logs contain structured phase/error JSON instead of an empty 120s kill.\n---\n\n**OVERRIDES runtime profile:** uses direct Python (no `claude` CLI) because the\nsweep is a pure SQL scan over `mc.db` \u2014 no LLM call, no provider routing.\n\nEvery 30 minutes:\n\n1. Parses any `Expected check-in:` line on open tickets and writes the typed\n   `tickets.expected_check_in_at` column (idempotent backfill).\n2. Lists open tickets and active `runtime_sessions` whose\n   `expected_check_in_at` is in the past.\n3. For each overdue ticket inserts one `pending` row into `orchestrator_inbox`\n   with `source_type='followup_sweep'`, deduped so a single overdue episode\n   produces a single inbox row (matches the `_has_open_row` discipline used by\n   `orchestrator_triage`).\n4. Posts a single `[follow-up] N min past expected check-in` system comment on\n   the ticket when the inbox row is created.\n\nThe orchestrator pickup loop drains `orchestrator_inbox` into the next Luci\ndigest, so overdue check-ins surface in the standard control-plane channel\ninstead of triggering ad-hoc Telegrams.\n\nCloses gap \u00a75 item 2 in `runbooks/luci-delegation-control-plane.md`.\n\nVerification: `python3 /home/lucienne/workspace/scripts/luci_followup_sweep.py --dry-run --timeout 90 --db-timeout 5`\nprints a JSON summary without writing.\n\nThe command uses an internal 90s wall deadline and a 5s SQLite busy timeout,\nboth below the scheduler's 120s kill timeout. Dry-run opens the DB read-only so\nmanual reproduction cannot run schema migrations/backfills.\n\nLogs to the standard scheduler `task_runs.output` field \u2014 one JSON line per\nrun with counts of backfilled, overdue, inserted and deduped rows. Progress is\nemitted as JSON lines on stderr and error JSON includes the active phase so a\nfuture scheduler failure shows where it stalled.\n","id":"luci-followup-sweep","last_run":{"duration_s":0.130979,"log_path":"/home/lucienne/workspace/logs/task-runs/luci-followup-sweep/413836.log","output":"{\"ts\": \"2026-06-13T04:00:44Z\", \"db\": \"/home/lucienne/workspace/mission-control/mc.db\", \"dry_run\": false, \"elapsed_s\": 0.064, \"sqlite_timeout_s\": 5.0, \"backfillable\": 0, \"backfilled\": 0, \"overdue_tickets\": 0, \"overdue_runtimes\": 0, \"inbox_inserted\": 0, \"inbox_skipped_dedupe\": 0, \"status\": \"ok\"}\n","started_at":"2026-06-13T06:00:44.429196+02:00","status":"completed"},"next_run":"2026-06-13 06:30","next_run_iso":"2026-06-13T06:30:00+02:00","runs":[{"duration_s":0.130979,"finished_at":"2026-06-13T06:00:44.562035+02:00","id":413836,"log_path":"/home/lucienne/workspace/logs/task-runs/luci-followup-sweep/413836.log","output":"{\"ts\": \"2026-06-13T04:00:44Z\", \"db\": \"/home/lucienne/workspace/mission-control/mc.db\", \"dry_run\": false, \"elapsed_s\": 0.064, \"sqlite_timeout_s\": 5.0, \"backfillable\": 0, \"backfilled\": 0, \"overdue_tickets\": 0, \"overdue_runtimes\": 0, \"inbox_inserted\": 0, \"inbox_skipped_dedupe\": 0, \"status\": \"ok\"}\n","started_at":"2026-06-13T06:00:44.429196+02:00","status":"completed","task_id":"luci-followup-sweep","task_name":"Sweep overdue ledger rows into orchestrator_inbox"},{"duration_s":0.158569,"finished_at":"2026-06-13T05:30:23.017911+02:00","id":413747,"log_path":"/home/lucienne/workspace/logs/task-runs/luci-followup-sweep/413747.log","output":"{\"ts\": \"2026-06-13T03:30:22Z\", \"db\": \"/home/lucienne/workspace/mission-control/mc.db\", \"dry_run\": false, \"elapsed_s\": 0.064, \"sqlite_timeout_s\": 5.0, \"backfillable\": 0, \"backfilled\": 0, \"overdue_tickets\": 0, \"overdue_runtimes\": 0, \"inbox_inserted\": 0, \"inbox_skipped_dedupe\": 0, \"status\": \"ok\"}\n","started_at":"2026-06-13T05:30:22.856537+02:00","status":"completed","task_id":"luci-followup-sweep","task_name":"Sweep overdue ledger rows into orchestrator_inbox"},{"duration_s":0.159759,"finished_at":"2026-06-13T05:00:55.012480+02:00","id":413667,"log_path":"/home/lucienne/workspace/logs/task-runs/luci-followup-sweep/413667.log","output":"{\"ts\": \"2026-06-13T03:00:54Z\", \"db\": \"/home/lucienne/workspace/mission-control/mc.db\", \"dry_run\": false, \"elapsed_s\": 0.063, \"sqlite_timeout_s\": 5.0, \"backfillable\": 0, \"backfilled\": 0, \"overdue_tickets\": 0, \"overdue_runtimes\": 0, \"inbox_inserted\": 0, \"inbox_skipped_dedupe\": 0, \"status\": \"ok\"}\n","started_at":"2026-06-13T05:00:54.850361+02:00","status":"completed","task_id":"luci-followup-sweep","task_name":"Sweep overdue ledger rows into orchestrator_inbox"},{"duration_s":0.152294,"finished_at":"2026-06-13T04:30:21.941185+02:00","id":413574,"log_path":"/home/lucienne/workspace/logs/task-runs/luci-followup-sweep/413574.log","output":"{\"ts\": \"2026-06-13T02:30:21Z\", \"db\": \"/home/lucienne/workspace/mission-control/mc.db\", \"dry_run\": false, \"elapsed_s\": 0.072, \"sqlite_timeout_s\": 5.0, \"backfillable\": 0, \"backfilled\": 0, \"overdue_tickets\": 0, \"overdue_runtimes\": 0, \"inbox_inserted\": 0, \"inbox_skipped_dedupe\": 0, \"status\": \"ok\"}\n","started_at":"2026-06-13T04:30:21.785134+02:00","status":"completed","task_id":"luci-followup-sweep","task_name":"Sweep overdue ledger rows into orchestrator_inbox"},{"duration_s":0.158847,"finished_at":"2026-06-13T04:04:32.173768+02:00","id":413490,"log_path":"/home/lucienne/workspace/logs/task-runs/luci-followup-sweep/413490.log","output":"{\"ts\": \"2026-06-13T02:04:32Z\", \"db\": \"/home/lucienne/workspace/mission-control/mc.db\", \"dry_run\": false, \"elapsed_s\": 0.062, \"sqlite_timeout_s\": 5.0, \"backfillable\": 0, \"backfilled\": 0, \"overdue_tickets\": 0, \"overdue_runtimes\": 0, \"inbox_inserted\": 0, \"inbox_skipped_dedupe\": 0, \"status\": \"ok\"}\n","started_at":"2026-06-13T04:04:32.011390+02:00","status":"completed","task_id":"luci-followup-sweep","task_name":"Sweep overdue ledger rows into orchestrator_inbox"},{"duration_s":0.163483,"finished_at":"2026-06-13T03:31:20.826662+02:00","id":413400,"log_path":"/home/lucienne/workspace/logs/task-runs/luci-followup-sweep/413400.log","output":"{\"ts\": \"2026-06-13T01:31:20Z\", \"db\": \"/home/lucienne/workspace/mission-control/mc.db\", \"dry_run\": false, \"elapsed_s\": 0.062, \"sqlite_timeout_s\": 5.0, \"backfillable\": 0, \"backfilled\": 0, \"overdue_tickets\": 0, \"overdue_runtimes\": 0, \"inbox_inserted\": 0, \"inbox_skipped_dedupe\": 0, \"status\": \"ok\"}\n","started_at":"2026-06-13T03:31:20.660207+02:00","status":"completed","task_id":"luci-followup-sweep","task_name":"Sweep overdue ledger rows into orchestrator_inbox"},{"duration_s":0.169481,"finished_at":"2026-06-13T03:00:33.881428+02:00","id":413309,"log_path":"/home/lucienne/workspace/logs/task-runs/luci-followup-sweep/413309.log","output":"{\"ts\": \"2026-06-13T01:00:33Z\", \"db\": \"/home/lucienne/workspace/mission-control/mc.db\", \"dry_run\": false, \"elapsed_s\": 0.066, \"sqlite_timeout_s\": 5.0, \"backfillable\": 0, \"backfilled\": 0, \"overdue_tickets\": 0, \"overdue_runtimes\": 0, \"inbox_inserted\": 0, \"inbox_skipped_dedupe\": 0, \"status\": \"ok\"}\n","started_at":"2026-06-13T03:00:33.709471+02:00","status":"completed","task_id":"luci-followup-sweep","task_name":"Sweep overdue ledger rows into orchestrator_inbox"},{"duration_s":0.166657,"finished_at":"2026-06-13T02:30:22.418824+02:00","id":413221,"log_path":"/home/lucienne/workspace/logs/task-runs/luci-followup-sweep/413221.log","output":"{\"ts\": \"2026-06-13T00:30:22Z\", \"db\": \"/home/lucienne/workspace/mission-control/mc.db\", \"dry_run\": false, \"elapsed_s\": 0.066, \"sqlite_timeout_s\": 5.0, \"backfillable\": 0, \"backfilled\": 0, \"overdue_tickets\": 0, \"overdue_runtimes\": 0, \"inbox_inserted\": 0, \"inbox_skipped_dedupe\": 0, \"status\": \"ok\"}\n","started_at":"2026-06-13T02:30:22.249622+02:00","status":"completed","task_id":"luci-followup-sweep","task_name":"Sweep overdue ledger rows into orchestrator_inbox"},{"duration_s":0.135739,"finished_at":"2026-06-13T02:02:20.391698+02:00","id":413136,"log_path":"/home/lucienne/workspace/logs/task-runs/luci-followup-sweep/413136.log","output":"{\"ts\": \"2026-06-13T00:02:20Z\", \"db\": \"/home/lucienne/workspace/mission-control/mc.db\", \"dry_run\": false, \"elapsed_s\": 0.071, \"sqlite_timeout_s\": 5.0, \"backfillable\": 0, \"backfilled\": 0, \"overdue_tickets\": 0, \"overdue_runtimes\": 0, \"inbox_inserted\": 0, \"inbox_skipped_dedupe\": 0, \"status\": \"ok\"}\n","started_at":"2026-06-13T02:02:20.251534+02:00","status":"completed","task_id":"luci-followup-sweep","task_name":"Sweep overdue ledger rows into orchestrator_inbox"},{"duration_s":0.147982,"finished_at":"2026-06-13T01:30:22.211657+02:00","id":413046,"log_path":"/home/lucienne/workspace/logs/task-runs/luci-followup-sweep/413046.log","output":"{\"ts\": \"2026-06-12T23:30:22Z\", \"db\": \"/home/lucienne/workspace/mission-control/mc.db\", \"dry_run\": false, \"elapsed_s\": 0.065, \"sqlite_timeout_s\": 5.0, \"backfillable\": 0, \"backfilled\": 0, \"overdue_tickets\": 0, \"overdue_runtimes\": 0, \"inbox_inserted\": 0, \"inbox_skipped_dedupe\": 0, \"status\": \"ok\"}\n","started_at":"2026-06-13T01:30:22.061290+02:00","status":"completed","task_id":"luci-followup-sweep","task_name":"Sweep overdue ledger rows into orchestrator_inbox"},{"duration_s":0.167256,"finished_at":"2026-06-13T01:00:36.684552+02:00","id":412959,"log_path":"/home/lucienne/workspace/logs/task-runs/luci-followup-sweep/412959.log","output":"{\"ts\": \"2026-06-12T23:00:36Z\", \"db\": \"/home/lucienne/workspace/mission-control/mc.db\", \"dry_run\": false, \"elapsed_s\": 0.068, \"sqlite_timeout_s\": 5.0, \"backfillable\": 0, \"backfilled\": 0, \"overdue_tickets\": 0, \"overdue_runtimes\": 0, \"inbox_inserted\": 0, \"inbox_skipped_dedupe\": 0, \"status\": \"ok\"}\n","started_at":"2026-06-13T01:00:36.515094+02:00","status":"completed","task_id":"luci-followup-sweep","task_name":"Sweep overdue ledger rows into orchestrator_inbox"},{"duration_s":0.163511,"finished_at":"2026-06-13T00:30:21.892745+02:00","id":412870,"log_path":"/home/lucienne/workspace/logs/task-runs/luci-followup-sweep/412870.log","output":"{\"ts\": \"2026-06-12T22:30:21Z\", \"db\": \"/home/lucienne/workspace/mission-control/mc.db\", \"dry_run\": false, \"elapsed_s\": 0.066, \"sqlite_timeout_s\": 5.0, \"backfillable\": 0, \"backfilled\": 0, \"overdue_tickets\": 0, \"overdue_runtimes\": 0, \"inbox_inserted\": 0, \"inbox_skipped_dedupe\": 0, \"status\": \"ok\"}\n","started_at":"2026-06-13T00:30:21.725566+02:00","status":"completed","task_id":"luci-followup-sweep","task_name":"Sweep overdue ledger rows into orchestrator_inbox"},{"duration_s":0.161432,"finished_at":"2026-06-13T00:00:46.167823+02:00","id":412782,"log_path":"/home/lucienne/workspace/logs/task-runs/luci-followup-sweep/412782.log","output":"{\"ts\": \"2026-06-12T22:00:46Z\", \"db\": \"/home/lucienne/workspace/mission-control/mc.db\", \"dry_run\": false, \"elapsed_s\": 0.065, \"sqlite_timeout_s\": 5.0, \"backfillable\": 0, \"backfilled\": 0, \"overdue_tickets\": 0, \"overdue_runtimes\": 0, \"inbox_inserted\": 0, \"inbox_skipped_dedupe\": 0, \"status\": \"ok\"}\n","started_at":"2026-06-13T00:00:46.003350+02:00","status":"completed","task_id":"luci-followup-sweep","task_name":"Sweep overdue ledger rows into orchestrator_inbox"},{"duration_s":0.144952,"finished_at":"2026-06-12T23:30:22.972775+02:00","id":412695,"log_path":"/home/lucienne/workspace/logs/task-runs/luci-followup-sweep/412695.log","output":"{\"ts\": \"2026-06-12T21:30:22Z\", \"db\": \"/home/lucienne/workspace/mission-control/mc.db\", \"dry_run\": false, \"elapsed_s\": 0.065, \"sqlite_timeout_s\": 5.0, \"backfillable\": 0, \"backfilled\": 0, \"overdue_tickets\": 0, \"overdue_runtimes\": 0, \"inbox_inserted\": 0, \"inbox_skipped_dedupe\": 0, \"status\": \"ok\"}\n","started_at":"2026-06-12T23:30:22.825504+02:00","status":"completed","task_id":"luci-followup-sweep","task_name":"Sweep overdue ledger rows into orchestrator_inbox"},{"duration_s":0.168662,"finished_at":"2026-06-12T23:00:35.456679+02:00","id":412608,"log_path":"/home/lucienne/workspace/logs/task-runs/luci-followup-sweep/412608.log","output":"{\"ts\": \"2026-06-12T21:00:35Z\", \"db\": \"/home/lucienne/workspace/mission-control/mc.db\", \"dry_run\": false, \"elapsed_s\": 0.074, \"sqlite_timeout_s\": 5.0, \"backfillable\": 0, \"backfilled\": 0, \"overdue_tickets\": 0, \"overdue_runtimes\": 0, \"inbox_inserted\": 0, \"inbox_skipped_dedupe\": 0, \"status\": \"ok\"}\n","started_at":"2026-06-12T23:00:35.282890+02:00","status":"completed","task_id":"luci-followup-sweep","task_name":"Sweep overdue ledger rows into orchestrator_inbox"},{"duration_s":0.156232,"finished_at":"2026-06-12T22:30:23.445588+02:00","id":412521,"log_path":"/home/lucienne/workspace/logs/task-runs/luci-followup-sweep/412521.log","output":"{\"ts\": \"2026-06-12T20:30:23Z\", \"db\": \"/home/lucienne/workspace/mission-control/mc.db\", \"dry_run\": false, \"elapsed_s\": 0.062, \"sqlite_timeout_s\": 5.0, \"backfillable\": 0, \"backfilled\": 0, \"overdue_tickets\": 0, \"overdue_runtimes\": 0, \"inbox_inserted\": 0, \"inbox_skipped_dedupe\": 0, \"status\": \"ok\"}\n","started_at":"2026-06-12T22:30:23.286691+02:00","status":"completed","task_id":"luci-followup-sweep","task_name":"Sweep overdue ledger rows into orchestrator_inbox"},{"duration_s":0.155628,"finished_at":"2026-06-12T22:00:31.799337+02:00","id":412434,"log_path":"/home/lucienne/workspace/logs/task-runs/luci-followup-sweep/412434.log","output":"{\"ts\": \"2026-06-12T20:00:31Z\", \"db\": \"/home/lucienne/workspace/mission-control/mc.db\", \"dry_run\": false, \"elapsed_s\": 0.071, \"sqlite_timeout_s\": 5.0, \"backfillable\": 0, \"backfilled\": 0, \"overdue_tickets\": 0, \"overdue_runtimes\": 0, \"inbox_inserted\": 0, \"inbox_skipped_dedupe\": 0, \"status\": \"ok\"}\n","started_at":"2026-06-12T22:00:31.641517+02:00","status":"completed","task_id":"luci-followup-sweep","task_name":"Sweep overdue ledger rows into orchestrator_inbox"},{"duration_s":0.159211,"finished_at":"2026-06-12T21:30:23.694074+02:00","id":412347,"log_path":"/home/lucienne/workspace/logs/task-runs/luci-followup-sweep/412347.log","output":"{\"ts\": \"2026-06-12T19:30:23Z\", \"db\": \"/home/lucienne/workspace/mission-control/mc.db\", \"dry_run\": false, \"elapsed_s\": 0.063, \"sqlite_timeout_s\": 5.0, \"backfillable\": 0, \"backfilled\": 0, \"overdue_tickets\": 0, \"overdue_runtimes\": 0, \"inbox_inserted\": 0, \"inbox_skipped_dedupe\": 0, \"status\": \"ok\"}\n","started_at":"2026-06-12T21:30:23.530924+02:00","status":"completed","task_id":"luci-followup-sweep","task_name":"Sweep overdue ledger rows into orchestrator_inbox"},{"duration_s":0.131248,"finished_at":"2026-06-12T21:00:30.244282+02:00","id":412261,"log_path":"/home/lucienne/workspace/logs/task-runs/luci-followup-sweep/412261.log","output":"{\"ts\": \"2026-06-12T19:00:30Z\", \"db\": \"/home/lucienne/workspace/mission-control/mc.db\", \"dry_run\": false, \"elapsed_s\": 0.062, \"sqlite_timeout_s\": 5.0, \"backfillable\": 0, \"backfilled\": 0, \"overdue_tickets\": 0, \"overdue_runtimes\": 0, \"inbox_inserted\": 0, \"inbox_skipped_dedupe\": 0, \"status\": \"ok\"}\n","started_at":"2026-06-12T21:00:30.110516+02:00","status":"completed","task_id":"luci-followup-sweep","task_name":"Sweep overdue ledger rows into orchestrator_inbox"},{"duration_s":0.146235,"finished_at":"2026-06-12T20:30:23.689406+02:00","id":412172,"log_path":"/home/lucienne/workspace/logs/task-runs/luci-followup-sweep/412172.log","output":"{\"ts\": \"2026-06-12T18:30:23Z\", \"db\": \"/home/lucienne/workspace/mission-control/mc.db\", \"dry_run\": false, \"elapsed_s\": 0.063, \"sqlite_timeout_s\": 5.0, \"backfillable\": 0, \"backfilled\": 0, \"overdue_tickets\": 0, \"overdue_runtimes\": 0, \"inbox_inserted\": 0, \"inbox_skipped_dedupe\": 0, \"status\": \"ok\"}\n","started_at":"2026-06-12T20:30:23.540826+02:00","status":"completed","task_id":"luci-followup-sweep","task_name":"Sweep overdue ledger rows into orchestrator_inbox"}],"runs_limit":20,"schedule":"*/30 * * * *","schedule_label":{"description":"Every 30 minutes","is_custom":false,"label":"Every 30 min","sort":1,"sort_time":""},"stats":{"avg_duration":0.5120263667621776,"completed":348,"failed":0,"timeout":1,"total":349},"task":{"_description":"**OVERRIDES runtime profile:** uses direct Python (no `claude` CLI) because the\nsweep is a pure SQL scan over `mc.db` \u2014 no LLM call, no provider routing.\n\nEvery 30 minutes:\n\n1. Parses any `Expected check-in:` line on open tickets and writes the typed\n   `tickets.expected_check_in_at` column (idempotent backfill).\n2. Lists open tickets and active `runtime_sessions` whose\n   `expected_check_in_at` is in the past.\n3. For each overdue ticket inserts one `pending` row into `orchestrator_inbox`\n   with `source_type='followup_sweep'`, deduped so a single overdue episode\n   produces a single inbox row (matches the `_has_open_row` discipline used by\n   `orchestrator_triage`).\n4. Posts a single `[follow-up] N min past expected check-in` system comment on\n   the ticket when the inbox row is created.\n\nThe orchestrator pickup loop drains `orchestrator_inbox` into the next Luci\ndigest, so overdue check-ins surface in the standard control-plane channel\ninstead of triggering ad-hoc Telegrams.\n\nCloses gap \u00a75 item 2 in `runbooks/luci-delegation-control-plane.md`.\n\nVerification: `python3 /home/lucienne/workspace/scripts/luci_followup_sweep.py --dry-run --timeout 90 --db-timeout 5`\nprints a JSON summary without writing.\n\nThe command uses an internal 90s wall deadline and a 5s SQLite busy timeout,\nboth below the scheduler's 120s kill timeout. Dry-run opens the DB read-only so\nmanual reproduction cannot run schema migrations/backfills.\n\nLogs to the standard scheduler `task_runs.output` field \u2014 one JSON line per\nrun with counts of backfilled, overdue, inserted and deduped rows. Progress is\nemitted as JSON lines on stderr and error JSON includes the active phase so a\nfuture scheduler failure shows where it stalled.","_file":"luci-followup-sweep.md","_path":"/home/lucienne/workspace/tasks/luci-followup-sweep.md","command":"/usr/bin/python3 /home/lucienne/workspace/scripts/luci_followup_sweep.py --timeout 90 --db-timeout 5","enabled":true,"id":"luci-followup-sweep","notify_on":"failure","retry":false,"run_as":"shell","runtime_profile":"direct_mixed","schedule":"*/30 * * * *","tags":["orchestrator","followup","ledger"],"timeout":120,"title":"Sweep overdue ledger rows into orchestrator_inbox"}}
