fix(gateway): possibilities-matrix fast-path hardening + collision-context guards

The W7 fast path now rejects empty/trivial notes (its sole compensating
control for the skipped journal gates), pushes the branch before the
behind-base check, and pairs the local-gate fallback with the toolchain
guard; the WORK_ALREADY_DONE prompt no longer promises a fast path to
verifying tasks the gate routes elsewhere. build_collision_context now
degrades gracefully at all three call sites instead of breaking the
gate review, PM briefing, or collision-map route.
This commit is contained in:
Renn F
2026-07-15 08:25:06 +02:00
parent 3c1064e7d1
commit 85ac6422ff
8 changed files with 310 additions and 46 deletions
@@ -153,6 +153,42 @@ async def test_collision_map_shows_overlapping_sibling(collision_client: dict) -
assert sib_entry["undeclared"] == []
@pytest.mark.asyncio
async def test_collision_map_degrades_on_builder_failure(
collision_client: dict, monkeypatch: pytest.MonkeyPatch
) -> None:
# build_collision_context is called outside the get_subtasks try/except at
# this site's call site; a raise there must still yield a 200 with no
# siblings, never a 500 — mirrors qa.py's claim_review evidence pattern.
client = collision_client["client"]
parent = _task(collision_client, title="parent", status=TaskStatus.PENDING)
await collision_client["db"].flush()
under = _task(
collision_client,
parent_task_id=parent.id,
title="under review",
intends_to_touch=["roboco/services/git.py"],
)
_task(
collision_client,
parent_task_id=parent.id,
title="colliding sibling",
intends_to_touch=["roboco/services/git.py"],
)
await collision_client["db"].flush()
def _boom(**_kw: Any) -> None:
raise RuntimeError("collision builder exploded")
monkeypatch.setattr("roboco.api.routes.tasks.build_collision_context", _boom)
response = await client.get(f"/api/tasks/{under.id}/collision-map", headers=_HDR)
assert response.status_code == HTTPStatus.OK
body = response.json()
assert body["siblings"] == []
assert body["intends_to_touch"] == ["roboco/services/git.py"]
@pytest.mark.asyncio
async def test_collision_map_omits_non_overlapping_sibling(
collision_client: dict,