Summary
Add a scheduled_at column to the Kanban tasks table so tasks can be deferred until a specific time. The dispatcher skips tasks whose scheduled time has not arrived yet.
Motivation
Users want to create tasks that should not start until a future time — e.g. "run this report tomorrow at 9am", "deploy Friday evening", or "revisit this bug after the upstream fix lands next week".
Currently tasks are either ready (dispatched immediately) or blocked by parent dependencies. There is no time-based gating mechanism.
Proposed Design
Schema: Add scheduled_at INTEGER column to tasks table (nullable, NULL = no scheduling constraint).
Dispatcher gate: In dispatch_once(), change the ready-tasks query:
-- Before
SELECT id, assignee FROM tasks
WHERE status = 'ready' AND claim_lock IS NULL
ORDER BY priority DESC, created_at ASC
-- After
SELECT id, assignee FROM tasks
WHERE status = 'ready' AND claim_lock IS NULL
AND (scheduled_at IS NULL OR scheduled_at <= ?)
ORDER BY priority DESC, created_at ASC
The ? parameter is int(time.time()). Same guard in claim_task() to prevent manual claims on not-yet-eligible tasks.
Tool parameter: Add scheduled_at (integer, unix epoch) to kanban_create schema:
"scheduled_at": {
"type": "integer",
"description": "Unix timestamp. Task will not be dispatched until this time."
}
Index: Partial index on scheduled_at for rows where it is not NULL.
Files Changed
hermes_cli/kanban_db.py — schema, dataclass, create_task, dispatch gate, claim gate
tools/kanban_tools.py — kanban_create schema + handler passthrough
Backward Compatibility
- Purely additive: new nullable column, new optional parameter
- NULL
scheduled_at = no scheduling = existing behavior completely unchanged
- No new status in the lifecycle — invisible to consumers that do not use it
Alternatives Considered
New scheduled status — Rejected because it adds a status to the lifecycle requiring changes to every consumer (UI, health checks, recompute logic). The column approach is invisible to non-consumers.
Full Spec
Detailed implementation spec with exact line numbers: SCHEDULED_TASKS_SPEC.md (will be in PR)
Summary
Add a
scheduled_atcolumn to the Kanbantaskstable so tasks can be deferred until a specific time. The dispatcher skips tasks whose scheduled time has not arrived yet.Motivation
Users want to create tasks that should not start until a future time — e.g. "run this report tomorrow at 9am", "deploy Friday evening", or "revisit this bug after the upstream fix lands next week".
Currently tasks are either
ready(dispatched immediately) or blocked by parent dependencies. There is no time-based gating mechanism.Proposed Design
Schema: Add
scheduled_at INTEGERcolumn totaskstable (nullable, NULL = no scheduling constraint).Dispatcher gate: In
dispatch_once(), change the ready-tasks query:The
?parameter isint(time.time()). Same guard inclaim_task()to prevent manual claims on not-yet-eligible tasks.Tool parameter: Add
scheduled_at(integer, unix epoch) tokanban_createschema:Index: Partial index on
scheduled_atfor rows where it is not NULL.Files Changed
hermes_cli/kanban_db.py— schema, dataclass, create_task, dispatch gate, claim gatetools/kanban_tools.py— kanban_create schema + handler passthroughBackward Compatibility
scheduled_at= no scheduling = existing behavior completely unchangedAlternatives Considered
New
scheduledstatus — Rejected because it adds a status to the lifecycle requiring changes to every consumer (UI, health checks, recompute logic). The column approach is invisible to non-consumers.Full Spec
Detailed implementation spec with exact line numbers: SCHEDULED_TASKS_SPEC.md (will be in PR)