Dataface Tasks

Fix tasks server /status task lists to match heartbeat groups

IDINFRA_TOOLING-FIX_TASKS_SERVER_STATUS_TASK_LISTS_TO_MATCH_HEARTBEAT_GROUPS
Statuscompleted
Priorityp2
Milestonem1-ft-analytics-analyst-pilot
Ownersr-engineer-architect
Completed bydave
Completed2026-03-24

Problem

/status shows summary cards whose numbers come from classify_tasks() in scripts/task_manager_lib.py (snapshot_payloadcounts). The HTML body uses _classify_task_sections() in tasks/tools/tasks_server.py, which does not mirror that logic. In particular, any task with registered or dispatch_state is sent to Other before status is considered, so in-progress / dispatched work does not appear under an “Active” heading even when the Active card is non-zero. There is also no “Active tasks” list section in _render_task_sections — only Needs Attention, Ready, Blocked, Other. Operators see 13 Active in the cards but a single “Other tasks (422)” list, which feels broken.

Context

  • Prior task tasks/workstreams/infra-tooling/tasks/improve-tasks-serve-status-ui-for-operator-triage.md (completed) described “Active sections” but the shipped _render_task_sections never added an Active bucket; classification diverged from the heartbeat library.
  • Heartbeat text summary (render_summary) already lists Active and Needs attention in sync with classify_tasks.
  • Snapshot JSON (/status.json) is consumed by tooling; any new fields should be additive and backward-compatible.
  • Files: scripts/task_manager_lib.py (snapshot_payload, classify_tasks), tasks/tools/tasks_server.py (_render_task_sections, _classify_task_sections, CSS), tests/core/test_tasks_server.py.

Possible Solutions

  • Recommended: Extend snapshot_payload with explicit group membership (e.g. per-task display_group or slug lists per group) derived from the same groups dict used for counts, then render /status sections from that so cards and lists cannot drift. Render Needs attention and Active tasks as <table> rows (columns: task link, status, dispatch, PR/CI, age, first attention reason) above Ready, Blocked, and Other (list or table for consistency).
  • Reimplement classify_tasks logic in Python inside tasks_server.py from task dicts — high drift risk, duplicate bugs.
  • Have tasks server shell out to heartbeat script — too heavy.

Plan

  1. Add structured group data to the snapshot in snapshot_payload (minimal additive schema; document in a short comment).
  2. Replace _classify_task_sections usage with snapshot-driven grouping; add Active tasks section and keep Needs attention prominent; use tables for operator scanability.
  3. Update/extend test_tasks_server.py so a fixture with mixed tasks asserts correct section headings, row counts matching counts, and that an in_progress + registered task appears under Active, not only under Other.
  4. Manual or Playwright smoke: /status shows separate tables when counts > 0.
  5. just task validate after task file edits.

Implementation Progress

  • 2026-03-24: in_progress. Manager dispatch.
  • 2026-03-24: Added display_group field to each task in snapshot_payload (scripts/task_manager_lib.py) via _build_display_group_lookup() — maps each task slug to its classify_tasks group (needs_attention wins over other groups). This is the single source of truth so cards and lists cannot drift.
  • 2026-03-24: Replaced _classify_task_sections in tasks/tools/tasks_server.py — now reads display_group from the snapshot instead of re-classifying. Returns a dict with 5 groups: needs_attention, active_tasks, ready_to_pick_up, waiting_on_dependencies, other.
  • 2026-03-24: Added "Active tasks" section to _render_task_sections, rendered between Needs Attention and Ready to pick up.
  • 2026-03-24: Updated tests in tests/core/test_tasks_server.py (new: test_classify_task_sections_uses_display_group, test_classify_task_sections_missing_display_group_falls_back, test_status_page_active_tasks_section; updated: test_classify_task_sections_completed_goes_to_other_bucket, RICH_SNAPSHOT fixture, all snapshot fixtures with display_group).
  • 2026-03-24: Added test_snapshot_payload_includes_display_group in tests/scripts/test_task_manager_scripts.py.
  • 2026-03-24: just ci passes (85 affected tests pass; 2 pre-existing flaky timeout failures unrelated).

QA Exploration

  • [x] QA exploration completed
  • Launched tasks server on port 8585, navigated to /status with Playwright.
  • With a test snapshot containing all 5 groups, verified:
  • Cards show correct counts: Ready=2, Blocked=1, Active=2, Attention=1, Escalation=1.
  • Sections render in order: Needs Attention (1), Active tasks (2), Ready to pick up (2), Waiting on dependencies (1), Other tasks (1).
  • List counts match card numbers exactly — the core bug is fixed.
  • Active tasks (registered + running dispatch) no longer appear under Other.
  • PR links, CI badges, dispatch badges, blocker text all render correctly.

Review Feedback

  • 2026-03-24: Review requested an explicit regression test for dual-membership tasks (ready_to_pick_up + needs_attention) and clearer precedence around snapshot grouping.
  • 2026-03-24: Added test_snapshot_payload_attention_overrides_ready_display_group; no production-code change was needed because the snapshot logic was already correct once the test forced the overdue path explicitly.
  • 2026-03-24: Fresh just review rerun returned APPROVED; no blocking findings remain.
  • [x] Review cleared