Dataface Tasks

Move task ready queue intent out of frontmatter and add kickoff flow

IDINFRA_TOOLING-MOVE_TASK_READY_QUEUE_INTENT_OUT_OF_FRONTMATTER_AND_ADD_KICKOFF_FLOW
Statusnot_started
Priorityp0
Milestonem1-ft-analytics-analyst-pilot
Ownersr-engineer-architect

Problem

Eliminate merge-conflict churn caused by using task frontmatter status=ready as the queue signal. Design and implement a better kickoff model that keeps planning state durable, keeps runtime queue/claim state in task-manager-owned data, and gives operators an explicit command such as task kickoff or equivalent to enqueue work without rewriting the root task file.

Context

Current completed infra tasks intentionally moved started_at/in_progress runtime churn out of task frontmatter, but they explicitly kept ready in frontmatter as queue intent. That avoided part of the conflict pattern, not the whole thing. We still get confusing drift because the root task file is used to express queue state on main while the worktree later updates the same file to completed/PR metadata. The existing model also makes task authoring feel slippery: writing a task often immediately becomes a queue mutation. We need to reconsider whether ready belongs in root task markdown at all. Relevant prior tasks and docs: move-task-manager-claim-and-start-state-out-of-task-frontmatter-into-manager-registry; route-manager-updates-for-active-tasks-into-the-running-worktree-or-a-follow-up-task; implement-two-tier-task-manager-escalation; AGENTS.md and .codex/skills/task-manager/SKILL.md. Any new model must preserve one-task-per-worktree isolation, keep heartbeat as the pickup mechanism, and avoid regressions in tasks serve status visibility.

Possible Solutions

Option 1: Keep ready in frontmatter and rely on reconciliation/diff warnings. Lowest change, but it preserves the root problem and keeps queue intent coupled to merge-prone task markdown. Rejected unless we accept ongoing drift. Option 2: Recommended: move queue intent into the manager registry and introduce an explicit kickoff command such as plans task kickoff --path (or scripts/task-system/kickoff ). The task file stays in planning states like not_started/completed while the registry records queued, claimed, started, and dispatch metadata. Heartbeat picks up queued registry entries instead of scanning for status=ready in task frontmatter. Option 3: Use a separate queue manifest or append-only kickoff log in tasks/logs/ while leaving task files untouched until completion. Simpler mental model than status=ready, but adds a second durable artifact to reconcile and may be less operator-friendly than a registry-backed command. Option 4: Make the tasks server POST action create kickoff registry entries instead of editing frontmatter. This pairs well with Option 2 but should be treated as UI on top of the canonical kickoff API, not the first implementation step.

Plan

  1. Reconstruct the current lifecycle precisely: task authoring, queue intent, heartbeat pickup, dispatch registration, worktree execution, PR creation, reconciliation, and completion. Identify every place where ready/frontmatter still creates drift or merge conflicts. 2. Decide the canonical state model. Recommended target: root task files keep durable planning/completion records only; manager registry owns queued/claimed/started runtime state; kickoff is an explicit operator action, not a frontmatter edit. 3. Design the operator surface: plans task kickoff --path and/or scripts/task-system/kickoff , plus optional tasks-server UI action that calls the same underlying implementation. 4. Update heartbeat, tasks server, and status views to read queued state from registry/snapshot instead of status=ready in frontmatter. Preserve backward-compatible reading of existing ready tasks during migration, but bias all new flows to kickoff. 5. Add migration/reconciliation rules for old ready tasks and document the new semantics in AGENTS.md, CLAUDE.md, and .codex/skills/task-manager/SKILL.md. 6. Only after the new path is proven, deprecate or sharply narrow the meaning of frontmatter ready so queue intent no longer depends on editing the root task file on main.

Implementation Progress

Core changes (task_manager_lib.py)

  • Added queued_at field to TaskInfo dataclass
  • Added kickoff_task(owner, task_path) function: writes registry entry with queued_at timestamp, no frontmatter mutation, rejects completed tasks
  • Updated collect_tasks() to populate queued_at from registry entries
  • Updated classify_tasks(): primary queue signal is queued_at in registry; status=ready in frontmatter is preserved as backward-compatible fallback. A task with queued_at but no started_at is classified as ready_to_pick_up even if registered
  • Added queued_at to snapshot payload for status visibility

CLI (task_cli.py)

  • Added task kickoff subcommand: just task kickoff --path <task> [--owner <owner>]
  • Validates path, delegates to kickoff_task() from task_manager_lib

Shell script

  • Added scripts/task-system/kickoff as operator entry point

Tasks server

  • tasks_server_chat.py: register_task_for_manager with status=ready now calls kickoff instead of editing frontmatter
  • tasks_server.py: status badges show "queued" (green) for tasks with queued_at but non-ready frontmatter status

Documentation

  • Updated AGENTS.md, CLAUDE.md, .codex/skills/task-manager/SKILL.md, .codex/commands/task-new.md to reference kickoff as the canonical queue mechanism

Tests

  • 7 new tests in tests/scripts/test_task_manager_scripts.py: kickoff registry entry creation, classify_tasks pickup, dependency blocking, frontmatter fallback, no-frontmatter-mutation invariant, completed-task rejection, queued_at population
  • All 69 tests pass (62 existing + 7 new)

QA Exploration

  • [x] QA exploration completed (or N/A for non-UI tasks)

N/A — non-UI infrastructure task. Changes to tasks server status badges are cosmetic and covered by existing snapshot tests.

Review Feedback

  • [ ] Review cleared