Add startup and post-pull task-manager reconcile hooks
Problem
Add a second-stage reconciliation command/hook that runs at manager startup and after git pull to prune stale register entries, archive stale dispatch status files, and refresh root task metadata from durable PR/runtime state instead of relying only on the heartbeat loop.
Context
- Heartbeat is currently the only regular cleanup trigger.
- That means stale state can survive whenever:
- a repo is pulled forward outside the manager loop
- merged PR metadata lands after the last heartbeat cycle
- register/dispatch residue accumulates while no ready task is being picked up
- A separate reconcile command/hook would give the manager a second repair path on startup and after repo sync.
- Relevant files likely include:
scripts/task-manager-startscripts/task-manager-runscripts/task-manager-heartbeat- a new
scripts/task-manager-reconcileorscripts/task-system/reconcile - This task should build on the auto-reconcile logic, not duplicate it.
Possible Solutions
- Option 1: Keep cleanup only inside heartbeat. Simplest, but it leaves startup/pull transitions fragile and allows stale state to persist longer than necessary. Rejected.
- Option 2: Recommended Add a dedicated reconcile command and invoke it:
- once on manager startup
- once after a successful
git pull/repo refresh path - optionally on demand for operators This keeps repair logic reusable and avoids duplicating cleanup behavior across shell scripts.
- Option 3: Fold all reconcile work directly into
task-manager-startandtask-manager-runscripts. Less indirection, but harder to test and reuse.
Plan
- Add a dedicated reconcile entrypoint that reuses task-manager library cleanup logic.
- Call it from startup and post-pull manager paths.
- Ensure it is safe to run repeatedly and produces operator-readable output.
- Add tests around startup/post-pull invocation behavior.
- Document when operators should still run manual reconcile.
Implementation Progress
Files created
scripts/task-manager-reconcile— standalone Python script that runs all four reconcile steps (auto-complete merged PRs, auto-demote orphaned in_progress, prune stale register entries, clear stale dispatch state) in a single idempotent pass. Supports--owner,--idle-seconds,--format text|json.scripts/task-system/reconcile— canonical namespace shim.
Files modified
scripts/task-manager-start— callstask-manager-reconcilesynchronously before launching the heartbeat background process, so stale state from a previous session is cleaned up on startup.scripts/task-manager-run— callstask-manager-reconcileonce before entering the heartbeat loop, covering the case where the run script is invoked directly.scripts/task-system/README.md— addedreconcileto the canonical command list.tests/scripts/test_task_manager_scripts.py— 6 new subprocess-level tests covering merged-PR completion, orphan demotion, register pruning, dispatch cleanup, text output, and idempotency. Addedtask-manager-reconcileto_make_repocopy list.
Key decisions
- Reuses all existing
auto_*andreconcile_register_orphansfunctions fromtask_manager_lib— no duplication. - The reconcile script is safe to run repeatedly (all operations are idempotent).
- Startup integration uses
check=Falseso a reconcile failure doesn't block the manager from starting. - Tests use a fake
ghbinary for PR-state tests andTASK_MANAGER_PR_CI_CHECK=0for non-PR tests.
QA Exploration
- [x] QA exploration completed (or N/A for non-UI tasks)
- N/A: backend/orchestration task
Review Feedback
- [x] Review cleared