mirror of
https://github.com/rennf93/roboco.git
synced 2026-08-03 07:23:24 +02:00
fix(workspace): role-aware worktree refresh at every spawn (#692)
* fix(workspace): refresh a present per-task worktree at every respawn ensure_worktree_self_heal treated an already-present worktree as a pure no-op (venv-link + chown only), so a worktree created once at first claim or first claim_review stayed frozen at that commit across every later respawn even as new commits landed on origin — the root mechanism behind a live multi-round QA/PR-gate bounce loop, where the reviewer kept re-examining its own stale round-1 checkout. _ensure_worktree_before_spawn now classifies the caller's role (WORKTREE_AUTHOR_ROLES: developer/documenter, mirroring the gateway commit tool's RBAC) and _refresh_present_worktree compares local HEAD against origin/<branch>: behind-or-equal fast-forwards for every role (never discarding an author's uncommitted edits to do it); strictly ahead is always left alone; diverged only resets for a pure reader, whose local history can never be anything but a stale prior-round checkout. conventions_check_for_task's list-vs-content gap (list from git objects, content from the physical worktree) is closed as a side effect: the reviewer's worktree is now current as of spawn, and the branch under review gains no further commits while it sits in awaiting_pr_review. * fix(workspace): refresh re-added worktrees; fail the dirty guard toward preservation - A pruned worktree re-added from a surviving local ref now runs the same fetch-and-classify refresh as a present one, so an evicted reviewer worktree cannot resurrect a stale checkout. - A failing git status reads as dirty, never clean: the guard that protects an author's uncommitted edits fails toward preservation. - The hard reset verifies the worktree is actually on the task branch first; a detached or drifted worktree is left alone with a warning. - The conventions-check docstring states the remaining second-claim ceiling instead of claiming full closure. --------- Co-authored-by: Renn F <rennf93@users.noreply.github.com>
This commit is contained in:
@@ -69,13 +69,40 @@ async def test_ensures_worktree_when_task_short_id_set() -> None:
|
||||
# Healthy clone -> no re-clone, just the worktree self-heal.
|
||||
ws.ensure_workspace.assert_not_awaited()
|
||||
ws.ensure_worktree_self_heal.assert_awaited_once()
|
||||
args = ws.ensure_worktree_self_heal.call_args.args
|
||||
assert args[0] == Path("/data/workspaces/roboco-api/backend/be-dev-1")
|
||||
assert args[1] == Path(
|
||||
call = ws.ensure_worktree_self_heal.call_args
|
||||
assert call.args[0] == Path("/data/workspaces/roboco-api/backend/be-dev-1")
|
||||
assert call.args[1] == Path(
|
||||
"/data/workspaces/roboco-api/backend/be-dev-1/.worktrees/a3c40fe7"
|
||||
)
|
||||
assert args[2] == "feature/backend/abc12345"
|
||||
assert args[3] == "roboco-api"
|
||||
assert call.args[2] == "feature/backend/abc12345"
|
||||
assert call.args[3] == "roboco-api"
|
||||
# be-dev-1 is a developer — an author-capable role.
|
||||
assert call.kwargs["can_author"] is True
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_reader_role_classified_as_non_author_for_refresh() -> None:
|
||||
# A QA/PR-reviewer/PM respawn onto the SAME task-branch worktree must be
|
||||
# classified as a pure reader so ensure_worktree_self_heal knows a stale
|
||||
# checkout there is always safe to reset to origin.
|
||||
orch = _make_orchestrator()
|
||||
ws = MagicMock()
|
||||
ws.ensure_worktree_self_heal = AsyncMock()
|
||||
ws.ensure_workspace = AsyncMock()
|
||||
|
||||
with (
|
||||
patch("roboco.db.base.get_db_context", return_value=_fake_db_ctx(MagicMock())),
|
||||
patch("roboco.services.workspace.WorkspaceService", return_value=ws),
|
||||
patch(
|
||||
"roboco.services.workspace.WorkspaceService._is_workspace_healthy",
|
||||
return_value=True,
|
||||
),
|
||||
):
|
||||
await orch._ensure_worktree_before_spawn(
|
||||
_ctx(), "roboco-api", "backend", "be-qa", "task-1"
|
||||
)
|
||||
|
||||
assert ws.ensure_worktree_self_heal.call_args.kwargs["can_author"] is False
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
|
||||
Reference in New Issue
Block a user