Dataface Tasks

Make task manager route tasks by role-owner mapping

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

Problem

When a tasks owner is a role slug (e.g. data-viz-designer-engineer), resolve it through the role definition files in tasks/team/roles/ to determine the actual person identity for routing. Use filled_by if present, otherwise fall back to the role's owner field.

Context

  • owner_matches() in scripts/task_manager_lib.py previously used hardcoded identity sets (RJ_IDENTITIES, DAVE_IDENTITIES) to route tasks to managers.
  • Tasks can have owner set to a role slug like data-viz-designer-engineer instead of a person identity like dave.
  • Role definitions live in tasks/team/roles/*.md with frontmatter containing slug, owner (manager), and optionally filled_by (person doing the work).
  • Example: data-viz-designer-engineer has owner: dave and filled_by: rj so tasks owned by this role should route to RJ's manager.
  • Before this fix, role-slug owners did not match either manager identity set, so these tasks were dropped from heartbeat output.

Possible Solutions

Add a resolve_role_owner() function that loads role definitions and maps role slugs to person identities (filled_by if present, else owner). Call it in owner_matches() before comparing identities.

  • Pro: Minimal change surface, role definitions stay the single source of truth.
  • Pro: Caches role map per process because role files rarely change.
  • Con: Adds file I/O on first call, mitigated by caching.

B. Resolve role slugs at task collection time

Resolve in effective_owner() before owner_matches() is called.

  • Pro: owner_matches() stays identity-only.
  • Con: Changes the owner field semantics in TaskInfo, so downstream code would see the resolved identity instead of the original role slug.

Plan

  1. Write failing tests for role-based routing in test_task_manager_scripts.py.
  2. Add load_role_map() returning dict[str, str] that reads tasks/team/roles/*.md and returns {role_slug: filled_by or owner}.
  3. Add resolve_role_owner(task_owner: str) -> str that checks the role map and returns the resolved identity or the original string.
  4. Update owner_matches() to call resolve_role_owner() on task_owner before comparing.
  5. Validate the task file and run focused task-manager tests.

Files to modify: - scripts/task_manager_lib.py - tests/scripts/test_task_manager_scripts.py

Implementation Progress

  • Added load_role_map() to scripts/task_manager_lib.py to read tasks/team/roles/*.md and build a cached {normalized_role_slug: person_identity} map using filled_by first and owner as fallback.
  • Added resolve_role_owner() as a thin lookup wrapper that returns the resolved person for a role slug and otherwise passes the owner through unchanged.
  • Updated owner_matches() to resolve role slugs before applying the existing Dave-versus-RJ manager routing logic.
  • Added test_owner_matches_resolves_role_slugs_via_role_definitions to verify that data-viz-designer-engineer routes to RJ through filled_by, sr-engineer-architect falls back to Dave via owner, and direct identity owners still route as before.

QA Exploration

  • [x] QA exploration completed — N/A, backend-only routing logic change with no UI impact

Review Feedback

  • [ ] Review cleared