Route manager updates for active tasks into the running worktree or a follow-up task
Problem
Prevent manager-side edits to already-running root task files on main. Detect when a task already has an active worktree/worker, provide a safe path to send updates to that same task context or create a follow-up task instead, and document/encode the rule so active tasks do not accumulate merge-conflict churn from main-branch task edits.
Context
- We keep seeing the same conflict pattern:
- a task is already running in its own worktree/branch/PR
- manager-side edits on
mainmutate that same task markdown file - the task branch later rebases and conflicts on task text,
started_at, PR metadata, or checklists - The desired behavior is not just “be more careful.” The system should make the safe path obvious:
- if the task is already active, send updates into that same task context
- if the change is materially new scope, create a follow-up task
- do not silently fork the task story by editing the root task file on
main - Relevant surfaces:
scripts/task_manager_lib.py— core classification/detection functionsscripts/task-manager-heartbeat— heartbeat cycle that runs detection.codex/skills/task-manager/SKILL.md— operator-facing docs- Manager registry (
.tasks/task_manager/task-manager-{owner}.register.json) tracks which tasks are active withregistered_attimestamps
Possible Solutions
- Chosen: add
is_task_active()query +detect_root_edits_to_active_tasks()escalation signal. The heartbeat warns when a root task file was edited after dispatch started (root_task_editedsignal, tier1). An operator-facingscripts/task-system/is-active <slug>command tells the operator whether a task is active and suggests the correct path (work in the worktree or create a follow-up task). - Docs-only approach: already present in SKILL.md “Do Not Edit Running Tasks On Main” section, but insufficient under pressure.
- Hard-block: too blunt; some reconciliation edits are valid after PR lands.
Plan
- [x] Add
is_task_active(slug, owner)totask_manager_lib.py— returns structured dict with active status, worktree path, dispatch state. - [x] Add
detect_root_edits_to_active_tasks(tasks)totask_manager_lib.py— compares root task file mtime againstregistered_attimestamp, flags tasks edited after dispatch withroot_task_editedescalation signal (tier1). - [x] Create
scripts/task-manager-is-active+scripts/task-system/is-activeCLI wrapper for operator queries. - [x] Hook
detect_root_edits_to_active_tasksinto heartbeat cycle alongside existingdetect_metadata_driftanddetect_dispatch_completed_unreconciled. - [x] Add
root_task_editedto SKILL.md watchdog signal codes. - [x] Write 7 tests (TDD): 4 for
is_task_active, 3 fordetect_root_edits_to_active_tasks.
Implementation Progress
- 2026-03-24: Task created from repeated merge conflicts caused by manager-side edits to active root task files after work had already started in a dedicated worktree.
- 2026-03-24: Implemented
is_task_active()anddetect_root_edits_to_active_tasks()intask_manager_lib.py. Createdscripts/task-system/is-activeCLI. Hooked root-edit detection into heartbeat. Addedroot_task_editedsignal to SKILL.md. All 7 new tests pass. - 2026-03-25: Rebases onto current
origin/main, resolved the task-file conflict by keeping the completed worksheet, hardeneddetect_metadata_drift()against vanishing files, tightenedis_task_active()to require a real registration timestamp, madetask-manager-is-activereturn exit code1for inactive tasks, and added regression tests for those review-driven fixes.
QA Exploration
- [x] N/A — non-UI task (pure library + CLI + heartbeat changes)
Review Feedback
- [x] Review cleared
- 2026-03-25:
just reviewapproved after follow-up fixes for inactive CLI exit codes,detect_metadata_drift()OSError handling, andis_task_active()registration semantics. Review artifact:.tmp/pr-review-branch-20260325-083224.md