Prune stale replay blockers for deleted branches#23
Merged
Conversation
- Add a ref-existence probe and a branch-scoped terminal-event cleanup helper so dead branches can be detected and their blocked/failed rows removed safely.
- Commit the new state-layer tests that pin DeleteTerminalForDeadBranch behavior: it removes only blocked_conflict and failed rows for the exact branch ref/generation, leaves other states and other pairs untouched, and is idempotent.
- Add RefExists coverage for present/missing refs, create/delete lifecycle, empty ref validation, and cancelled-context error handling in internal/git/refs_test.go.
- Add a new daemon helper module that sweeps terminal capture_events for dead branch refs, supports startup/runtime pruning, and honors an opt-out env var.
- Add startup cleanup for dead-branch terminal rows so a Diverged restart on a deleted branch prunes stuck barriers instead of leaving them behind.
- Selected the lone offered capture because it adds daemon logic to prune terminal rows for a dead prior branch after a Diverged transition, preventing phantom blocked_conflict/failed barriers from accumulating once the branch is merged and deleted upstream.
- Add a boot-time sweep for terminal capture rows whose branch refs were deleted, so restarts clean up dead-branch terminals even if the Diverged hook never ran. Preserve the existing env opt-out logging before the sweep.
- Add a new daemon test file covering the dead-branch barrier env helper and startup sweep pruning behavior for dead refs versus active refs.
- Add atomic dead-branch prune metadata stamping for diagnose reporting
- Update dead-branch sweep flows to stamp diagnose-visible prune metadata before emitting trace events, preserving operator-visible consistency and previous snapshot behavior on the zero-row path.
- Add dead-branch prune diagnostics to the CLI report, including the latest prune meta fields and the new diagnostic step in report construction.
- Single test-file change adds JSON and strconv imports in dead_branch_sweep_test.go, suggesting a cohesive update to the existing dead-branch sweep test coverage.
- Adds two tests around startup dead-branch sweep meta stamping: one when pruning rows to verify the three meta keys are written, and one when the sweep is a no-op to verify existing meta is left untouched.
- Tests cover diagnose reporting for dead-branch prune metadata in both populated and absent states, asserting JSON field names and zero-value omission in the same file.
- Add an integration test that exercises dead-branch prune behavior end-to-end in the production binary, including diagnose JSON meta-field assertions and related terminal-row pruning/preservation scenarios.
- Remove an unused branch-generation test helper from the dead-branch prune integration test.
- The changelog entry and CLAUDE.md guidance describe the same dead-branch terminal auto-prune feature, including its opt-out flag and diagnostics, so they belong in one documentation commit.
- Selected capture updates README diagnostics text to describe the new dead-branch prune timestamps/counts/refs and the auto-pruning of blocked_conflict/failed rows for deleted branch refs, which matches the recent terminal auto-prune behavior work.
- Remove both the startup sweep and Diverged-time pruning hooks for dead-branch terminal captures in the daemon, since the captured diff deletes the cleanup paths in one file.
- Select the daemon cleanup changes as one commit: they add startup sweeping of dead-branch terminal capture_events rows and runtime pruning after Diverged when a branch ref has been deleted.
- Commit intent covers the daemon cleanup that removes the startup dead-branch pruning block. The .bak file is a rescan artifact and should not be committed with the code change.
- Restore startup dead-branch terminal sweeping in the daemon so a restart cleans up deleted-branch queue entries even if Diverged never ran.
- Forced aging applies, so take the single overdue capture. It creates a new backup of the daemon implementation containing the long-running run-loop code.
- Drop the daemon startup dead-branch sweep and its env log from Run so startup no longer performs that pruning path.
- Reinstate the daemon startup sweep for dead-branch terminal captures, and remove the obsolete daemon backup file that is no longer needed once the main implementation is restored.
- Expand dead-branch cleanup to remove unpublished pending and terminal rows together, and clear publish-state breadcrumbs/barriers when the deleted row was referenced.
- Expand the dead-branch purge test to cover pending rows alongside terminal rows, and to verify the singleton blocker barrier is lifted and breadcrumbs are cleared when publish_state is blocked_conflict.
- Update the diagnose report schema so dead-branch prune timestamp/count are always emitted as explicit zero-valued JSON fields, while leaving the refs slice omitempty.
- Update the diagnose dead-branch prune comments to match the JSON behavior: the two integer counters now intentionally serialize as 0 instead of omitting, while the refs slice still omits when empty.
- Adds an end-to-end daemon regression test that drives the runtime Diverged path after a branch deletion and verifies dead-branch terminal pruning via the prune timestamp meta key.
- The diff removes an obsolete helper comment immediately before an existing daemon test, so this capture stands alone as a small test cleanup.
- Adjust the daemon test to set up a feature branch at boot, pre-seed blocked/pending terminal rows for that branch, and exercise the runtime Diverged prune path after the branch is removed.
- Update CLAUDE.md to describe the refined dead-branch pruning semantics: unified pruning of pending and terminal rows, publish-state barrier cleanup, breadcrumb clearing, startup goroutine behavior, batched live-branch membership checks, and pause/keep-barrier handling.
- Update the README’s dead-branch prune section to note that `pending` rows are now pruned together with `blocked_conflict` and `failed` rows, along with the JSON rendering details for the prune counters.
- Update the changelog entry to describe broader dead-branch pruning for pending and terminal rows, startup sweep behavior, diagnostics, and opt-out handling.
- Update the dead-branch sweeper comment to reflect the renamed best-effort purge helper used for unpublished terminals.
- Update the fresh-repo diagnose-meta test comment to describe the JSON contract more precisely: integer fields are always present with 0 as the sentinel, while the refs slice stays omitempty when nil.
- Update the dead-branch prune integration test comment to clarify the no-prune JSON contract: the two int fields always emit `0` while the refs slice stays omitted.
- Single cleanup in daemon startup code: remove an extra blank line with no behavioral change.
- Select the dead-branch purge refinement that now tracks blocked seqs and only clears publish_state when it matches the same branch generation and blocked event.
- Extend dead-branch purge coverage to ensure it deletes the dead blocked row without lifting a separate live branch's blocked publish_state or clearing its breadcrumbs.
- Bind the captured context before launching the startup dead-branch sweep goroutine so the sweep uses the intended capture context instead of relying on the outer variable.
- Adds/updates integration coverage in dead_branch_prune_test.go for the dead-branch prune flow, including a new runtime Diverged prune scenario, a helper for reading the current branch generation, and test setup adjustments such as the sqlite busy timeout.
- This change adds a new integration test for the same ACD_KEEP_DEAD_BRANCH_BARRIERS=1 opt-out behavior on the runtime Diverged path, and tightens the nearby comment to scope the existing test to startup sweep only. Both edits belong to the dead-branch prune opt-out coverage in test/integration/dead_branch_prune_test.go.
- Update the dead-branch prune integration test to read the renamed daemon_meta key in both branch-token wait checks.
- Add the new team agent routing config file under .pi/agent to record schemaVersion 4 and solo routing mode.
- Document the dead-branch prune diagnostics and stale-row cleanup behavior in the changelog.
- Update the README’s dead-branch prune documentation to reflect the revised wording around stale pending/blocked_conflict/failed rows, paused repos, and the keep-forensics flag.
- Update the capture replay documentation to describe dead-branch cleanup behavior, including stale row pruning after daemon start and the effect of the keep-dead-branch-barriers flag.
- Document the dead-branch cleanup behavior in user-workflows docs, including the stale row types removed on branch transition or daemon startup, the diagnostic fields that report the last prune, and the opt-out env var for inspection before cleanup.
- Document the refined dead-branch prune behavior in CLAUDE.md, especially that publish_state barriers are lifted only for deleted blocked rows on the same branch/generation pair and that live blockers remain preserved.
- Delete the team agent routing config file, removing the obsolete agents-team.json entry.
- Update the changelog heading to the new v2026-05-10 release date.
- README status line advances the last-tag reference to match the new v2026-05-10 release date.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Feature Description
This adds dead-branch cleanup for stale ACD replay rows. When a feature branch has been merged and deleted, ACD can now prune stale
pending,blocked_conflict, andfailedcapture rows for that dead branch instead of leaving phantom blockers inacd status.The change also exposes the most recent cleanup through
acd diagnose, so operators can see when stale dead-branch rows were removed without reading daemon logs.Type of Change
Implementation Details
Architecture
internal/daemon/dead_branch_sweep.go.running.ACD_KEEP_DEAD_BRANCH_BARRIERS=1as an operator opt-out for forensic inspection.state.PurgeUnpublishedForDeadBranchso it clearspublish_stateonly when the singleton points at the deleted blocked row for the same branch/generation.Key Files Changed
internal/daemon/dead_branch_sweep.gointernal/state/events.gointernal/cli/diagnose.gointernal/git/refs.gotest/integration/dead_branch_prune_test.godocs/capture-replay.md/README.md/CHANGELOG.mdAPI Changes
No external API endpoints.
CLI/JSON output change:
acd diagnose --jsonnow includes:dead_branch_prune_last_run_tsdead_branch_prune_last_countdead_branch_prune_last_refsDatabase Changes
dead_branch_prune.last_run_tsdead_branch_prune.last_countdead_branch_prune.last_refsHow to Test
Validated locally:
Edge Cases Considered
ACD_KEEP_DEAD_BRANCH_BARRIERS=1keeps dead-branch rows.publish_stateblockers are not cleared while pruning a different dead branch.Checklist
Feature Flag
ACD_KEEP_DEAD_BRANCH_BARRIERS=1Related Issues
None found in branch name or commit messages.
Deployment Notes
Release notes and README status are set to
v2026-05-10. The actual git tag has not been created or pushed yet.