chore(plan): T-5, T-6 — minute-loop stall and POST /tasks doc drift

Found while planning the workspace Office (workspace T-163): long jobs
stall the minute loop for their whole duration, and the POST /tasks
docs show an executor name and config keys the code does not accept.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-19 10:34:58 +02:00
co-authored by Claude Opus 5.5
parent 613ecb9fb1
commit 0a5d7f1067
2 changed files with 16 additions and 0 deletions
+2
View File
@@ -0,0 +1,2 @@
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06GN6K3C1NQ7WDPM3YXD6BSTZM', 'T-5', '2026-10-19 08:34:39.758', '2026-10-19 08:34:39.758', NULL, 'c01351dc67e02131a9927ff1f0318979', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06GN6K3CM8S6RJDH27S0W8G3WW', 'T-6', '2026-10-19 08:34:39.906', '2026-10-19 08:34:39.906', NULL, 'f11bc08d305977cc16c9dd4628165c16', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
+14
View File
@@ -0,0 +1,14 @@
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06GN6K3C1NQ7WDPM3YXD6BSTZM', 'bug', NULL, 'Long jobs stall the minute loop for their whole duration', '`process_minute` waits for every task in its batch to finish (`src/tasks/executor.py:388-389`), and the minute job runs with APScheduler `max_instances: 1` (`src/main.py:77-81`). So a long task blocks every later minute for its whole duration: the 03:05 UTC config backup (~17 minutes) skips about seventeen ticks each night — the log carries "maximum number of running instances" warnings, 16 of them in the 24 hours to 2026-10-19.
Every-minute jobs slip by that much. The workspace''s new reminder dispatch (workspace T-177) is built to catch up, so this degrades it rather than breaks it — but reminders due in that window arrive late.
Fix: run long tasks fire-and-forget (or as their own APScheduler jobs) so the minute loop only dispatches and returns.
Done when: a task that runs 20 minutes produces no skipped-instance warnings, and an every-minute task keeps firing alongside it.', 'backlog', 'medium', NULL, NULL, NULL, '2026-10-19 08:34:39.757', '2026-10-19 08:34:39.757', NULL, '4d2303e4c2a4c412b15024d0f34d4796', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= tickets.updated_at;
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06GN6K3CM8S6RJDH27S0W8G3WW', 'task', NULL, 'POST /tasks docs show the wrong executor name and config keys', 'Three places describe the API wrongly, found while planning the workspace''s Office (workspace T-163):
- The `POST /tasks` docstring (`src/main.py:207-270`) and `TASK_REGISTRATION.md` show `"executor": "rest_api"`, `${VAR}` inside `headers`, and a `body` key. The code requires `rest_api_executor`, substitutes `${VAR}` only in `url`, `payload` and `auth` (`src/executors/rest_api_executor.py:99-107`, `_substitute_env_vars` :203-218), and reads `payload`. Anyone copying the example gets a job that sends the literal string `${VAR}`.
- `CLAUDE.md` cites the executor loader at `executor.py:202`; it is now :279.
- `CLAUDE.md` says an unauthenticated call gets a "200-shape" reply; it is a 401 (`main.py:120-131`, confirmed live).
Done when: the docstring and `TASK_REGISTRATION.md` show a working example taken from a real job, and the two `CLAUDE.md` statements match the code.', 'backlog', 'low', NULL, NULL, NULL, '2026-10-19 08:34:39.906', '2026-10-19 08:34:39.906', NULL, 'f2ae9e8f61920cfef5f3662694236132', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= tickets.updated_at;