feat: add worktree cleanup audit integrity (Closes #404)
Reconcile before/after branches/ snapshots so preserved worktrees cannot disappear without removal logs or explained state transitions. - worktree_cleanup_audit.py: snapshot capture, disposition reconciliation - gitea_capture_branches_worktree_snapshot, gitea_assess_worktree_cleanup_integrity - Final-report rule author.worktree_cleanup_audit_proof - worktree-cleanup.md bulk audit section - tests/test_worktree_cleanup_audit.py (11 cases)
This commit is contained in:
@@ -751,6 +751,7 @@ import issue_claim_heartbeat # noqa: E402
|
||||
import issue_work_duplicate_gate # noqa: E402
|
||||
import reviewer_pr_lease # noqa: E402
|
||||
import merged_cleanup_reconcile # noqa: E402
|
||||
import worktree_cleanup_audit # noqa: E402
|
||||
import reconciler_profile # noqa: E402
|
||||
import reconciliation_workflow # noqa: E402
|
||||
import audit_reconciliation_mode # noqa: E402
|
||||
@@ -4326,6 +4327,59 @@ def _remote_branch_exists(h: str, o: str, r: str, auth: str, branch: str) -> boo
|
||||
raise
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
def gitea_capture_branches_worktree_snapshot(
|
||||
open_pr_branches: list[str] | None = None,
|
||||
active_lock_branch: str | None = None,
|
||||
leased_paths: list[str] | None = None,
|
||||
worktree_path: str | None = None,
|
||||
) -> dict:
|
||||
"""Read-only: capture ``branches/`` and worktree audit snapshot (#404)."""
|
||||
read_block = _profile_operation_gate("gitea.read")
|
||||
if read_block:
|
||||
return {
|
||||
"success": False,
|
||||
"reasons": read_block,
|
||||
"permission_report": _permission_block_report("gitea.read"),
|
||||
}
|
||||
root = PROJECT_ROOT
|
||||
if worktree_path:
|
||||
root = os.path.realpath(os.path.abspath(worktree_path))
|
||||
git_root = _get_git_root(root)
|
||||
if git_root:
|
||||
root = git_root
|
||||
snapshot = worktree_cleanup_audit.capture_branches_worktree_snapshot(
|
||||
root,
|
||||
open_pr_branches=open_pr_branches,
|
||||
active_lock_branch=active_lock_branch,
|
||||
leased_paths=leased_paths,
|
||||
)
|
||||
return {"success": True, "snapshot": snapshot}
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
def gitea_assess_worktree_cleanup_integrity(
|
||||
before_snapshot: dict,
|
||||
after_snapshot: dict,
|
||||
removals: list[dict] | None = None,
|
||||
explained_missing: dict[str, str] | None = None,
|
||||
) -> dict:
|
||||
"""Read-only: reconcile cleanup before/after snapshots (#404)."""
|
||||
read_block = _profile_operation_gate("gitea.read")
|
||||
if read_block:
|
||||
return {
|
||||
"integrity_passed": False,
|
||||
"reasons": read_block,
|
||||
"permission_report": _permission_block_report("gitea.read"),
|
||||
}
|
||||
return worktree_cleanup_audit.assess_worktree_cleanup_integrity(
|
||||
before=before_snapshot,
|
||||
after=after_snapshot,
|
||||
removals=removals,
|
||||
explained_missing=explained_missing,
|
||||
)
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
def gitea_reconcile_merged_cleanups(
|
||||
dry_run: bool = True,
|
||||
|
||||
Reference in New Issue
Block a user