diff --git a/roboco/services/self_heal_engine.py b/roboco/services/self_heal_engine.py index 83638f6d..6f5f5254 100644 --- a/roboco/services/self_heal_engine.py +++ b/roboco/services/self_heal_engine.py @@ -176,22 +176,25 @@ class SelfHealEngine(BaseService): description=( f"RoboCo's own CI regressed.\n\n{obs.detail}\n\n" f"Evidence: {obs.raw_ref}\n\n" - "Investigate and fix the regression at its root so CI " - "returns to green. This task was opened automatically by " - "the self-heal loop and is HELD for the CEO's " - "Approve-&-Start — it will not dispatch until the CEO " - "approves it. Once approved, it ships through the normal " - "gates (QA, PR review, and the CEO's merge)." + "This is a Main-PM coordination root: decompose the fix " + "and delegate the code work to a cell dev — the Main PM " + "does not write the fix itself. This task was opened " + "automatically by the self-heal loop and is HELD for the " + "CEO's Approve-&-Start — it will not dispatch until the " + "CEO approves it. Once approved, the delegated fix ships " + "through the normal gates (QA, PR review, and the CEO's " + "merge)." ), acceptance_criteria=[ - f"CI on {obs.repo_hint}'s default branch is green again", - "The cause of the failing run is fixed at its root, not " - "masked or skipped", + "The CI regression is decomposed into a code-fix " + "subtask delegated to a cell developer", + f"CI on {obs.repo_hint}'s default branch is green again " + "and the fix merged through the normal gates", ], team=Team.MAIN_PM, assigned_to=_foundation.AGENTS["main-pm"].uuid, created_by=_foundation.AGENTS["system"].uuid, - task_type=TaskType.CODE, + task_type=TaskType.PLANNING, nature=TaskNature.TECHNICAL, estimated_complexity=Complexity.MEDIUM, project_id=cast("UUID", project.id), diff --git a/tests/conftest.py b/tests/conftest.py index 4a9dc2b3..46d43c4e 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -67,12 +67,24 @@ if TYPE_CHECKING: # --------------------------------------------------------------------------- -# Test DB endpoint discovery — env-overridable, default to localhost:5432. +# Test DB endpoint discovery — env-overridable. +# +# Defaults match the project's own running postgres (`roboco-postgres` in +# `docker-compose.yml`): superuser `roboco`/`roboco`, host-exposed on +# `localhost:15432` (the container's 5432). `roboco` has CREATEDB, which the +# session fixture needs to provision/drop an ephemeral per-run test DB. +# +# Previously these defaulted to the OS `$USER` with an empty password on +# `localhost:5432`, which hit a bare system postgres that has no such role — +# every `db_session` test failed with `InvalidPasswordError: password +# authentication failed for user "renzof"` instead of running. Defaulting to +# the project's actual DB makes the integration suite run out of the box; any +# of these can still be overridden with `ROBOCO_TEST_DB_*`. # --------------------------------------------------------------------------- _TEST_DB_HOST = os.environ.get("ROBOCO_TEST_DB_HOST", "localhost") -_TEST_DB_PORT = int(os.environ.get("ROBOCO_TEST_DB_PORT", "5432")) -_TEST_DB_USER = os.environ.get("ROBOCO_TEST_DB_USER", os.environ.get("USER", "renzof")) -_TEST_DB_PASSWORD = os.environ.get("ROBOCO_TEST_DB_PASSWORD", "") +_TEST_DB_PORT = int(os.environ.get("ROBOCO_TEST_DB_PORT", "15432")) +_TEST_DB_USER = os.environ.get("ROBOCO_TEST_DB_USER", "roboco") +_TEST_DB_PASSWORD = os.environ.get("ROBOCO_TEST_DB_PASSWORD", "roboco") _TEST_DB_ADMIN_DB = os.environ.get("ROBOCO_TEST_DB_ADMIN_DB", "postgres") diff --git a/tests/unit/runtime/test_self_heal_ceo_gate.py b/tests/unit/runtime/test_self_heal_ceo_gate.py index e76fb45c..1a6c9ad3 100644 --- a/tests/unit/runtime/test_self_heal_ceo_gate.py +++ b/tests/unit/runtime/test_self_heal_ceo_gate.py @@ -179,7 +179,10 @@ async def test_originate_opens_task_held_for_ceo( assert req.confirmed_by_human is False # held for the CEO — the F059 fix assert req.status == TaskStatus.PENDING assert req.source == SELF_HEAL_SOURCE - assert req.task_type == TaskType.CODE + # A Main-PM-owned coordination root (not code — the Main PM delegates the + # fix to a cell dev). `code` + `main_pm` is rejected by the + # main_pm_cannot_own_code guard, so the self-heal root must be `planning`. + assert req.task_type == TaskType.PLANNING # ---------------------------------------------------------------------------