diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index f47ef02b3..47216a66f 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -3,6 +3,12 @@ One `## YYYY-MM-DD` heading per merge day, newest first; one bullet of at most two lines per entry. See the CHANGELOG rule in [AGENTS.md](../AGENTS.md). +## 2026-09-05 + +- Worker refusals now use the typed human-review story transition, and mega-brief telemetry ignores polling-only timestamps while retaining them in bounded evidence. +- Product Brief deploy observation now stops at a story no-deploy state with retained cause evidence, instead of spending the full deploy-Run wait. +- Production scaffolds now pin service-template `40b54d8`, whose generated CI verifies its exact uv release without consulting a mutable version manifest. + ## 2026-09-04 - Worker success reports now stop their agent process group before exact-commit verification, preventing a late local commit from invalidating durable provenance; mega-brief logs bounded engineering transitions and terminal diagnostics. diff --git a/scripts/check-ci-gate.py b/scripts/check-ci-gate.py index d01b55ce9..598af3fd4 100644 --- a/scripts/check-ci-gate.py +++ b/scripts/check-ci-gate.py @@ -122,7 +122,7 @@ # Trees whose image references are not this repository's to pin. Reason per line, same # rule as the exclusions above: an unpinned image is a decision on the record. UNPINNED_IMAGE_DIRS = { - "shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3": ( + "shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c": ( "a vendored copy of a service-template release, read by the template " "compatibility tests; its compose files belong to that repository, and " "editing them here would make the fixture stop matching the release it " diff --git a/scripts/system_configs.yaml b/scripts/system_configs.yaml index b0eec3b76..7b2a96944 100644 --- a/scripts/system_configs.yaml +++ b/scripts/system_configs.yaml @@ -76,7 +76,7 @@ description: "Production Copier template source" - key: scheduler.service_template_ref - value: "91e582180b4295bce45155759bdad0dfa43b75f3" + value: "40b54d87dbfe64a9fa6ec379820e43137aaba04c" category: scheduler description: "Pinned service-template commit with the core settings and core jobs contracts" diff --git a/services/langgraph/src/consumers/engineering_result_handler.py b/services/langgraph/src/consumers/engineering_result_handler.py index 46935260e..ab441fcb7 100644 --- a/services/langgraph/src/consumers/engineering_result_handler.py +++ b/services/langgraph/src/consumers/engineering_result_handler.py @@ -11,7 +11,6 @@ from shared.contracts.dto.project import ProjectDTO from shared.contracts.dto.run import RunStatus, RunType from shared.contracts.dto.run_result import EngineeringRunResult -from shared.contracts.dto.story import StoryStatus from shared.contracts.dto.task import TaskStatus from shared.contracts.queues.deploy import DeployMessage, DeployTrigger from shared.contracts.queues.worker_result import WorkerStopReason @@ -314,10 +313,7 @@ async def handle_worker_gave_up( if story_id: try: - await api_client.patch( - f"stories/{story_id}", - json={"status": StoryStatus.WAITING_HUMAN_REVIEW.value}, - ) + await api_client.transition_story(story_id, "human-review") except Exception: logger.warning("story_whr_on_gave_up_failed", story_id=story_id, exc_info=True) diff --git a/services/langgraph/tests/unit/consumers/test_engineering_blocked.py b/services/langgraph/tests/unit/consumers/test_engineering_blocked.py index dae156102..1d9da51f3 100644 --- a/services/langgraph/tests/unit/consumers/test_engineering_blocked.py +++ b/services/langgraph/tests/unit/consumers/test_engineering_blocked.py @@ -30,6 +30,7 @@ def mock_api(): api.patch = AsyncMock() api.post = AsyncMock() api.get = AsyncMock(return_value={"created_by": "user"}) + api.transition_story = AsyncMock() yield api @@ -151,10 +152,8 @@ async def test_gave_up_transitions_story_to_whr( redis=mock_redis, ) - story_patch_calls = [c for c in mock_api.patch.call_args_list if "stories" in str(c)] - assert len(story_patch_calls) >= 1 - call_json = story_patch_calls[0][1].get("json", {}) - assert call_json.get("status") == "waiting_human_review" + mock_api.transition_story.assert_awaited_once_with("story-1", "human-review") + assert not any("stories/" in str(call) for call in mock_api.patch.call_args_list) @pytest.mark.asyncio @patch( @@ -265,5 +264,4 @@ async def test_gave_up_without_story_skips_story_transition( redis=mock_redis, ) - story_patch_calls = [c for c in mock_api.patch.call_args_list if "stories" in str(c)] - assert len(story_patch_calls) == 0 + mock_api.transition_story.assert_not_awaited() diff --git a/services/langgraph/tests/unit/consumers/test_engineering_reject.py b/services/langgraph/tests/unit/consumers/test_engineering_reject.py index 181282f14..8b97f7ecd 100644 --- a/services/langgraph/tests/unit/consumers/test_engineering_reject.py +++ b/services/langgraph/tests/unit/consumers/test_engineering_reject.py @@ -19,6 +19,7 @@ def mock_api(): with patch("src.consumers.engineering_result_handler.api_client") as api: api.patch = AsyncMock() api.post = AsyncMock() + api.transition_story = AsyncMock() api.get = AsyncMock(return_value={"created_by": "system"}) yield api @@ -86,7 +87,5 @@ async def test_reject_transitions_story_to_whr( redis=mock_redis, ) - story_patch_calls = [c for c in mock_api.patch.call_args_list if "stories" in str(c)] - assert len(story_patch_calls) >= 1 - call_json = story_patch_calls[0][1].get("json", {}) - assert call_json.get("status") == "waiting_human_review" + mock_api.transition_story.assert_awaited_once_with("story-1", "human-review") + assert not any("stories/" in str(call) for call in mock_api.patch.call_args_list) diff --git a/services/langgraph/tests/unit/test_blocked_flow_e2e.py b/services/langgraph/tests/unit/test_blocked_flow_e2e.py index 230fa4449..385b38cae 100644 --- a/services/langgraph/tests/unit/test_blocked_flow_e2e.py +++ b/services/langgraph/tests/unit/test_blocked_flow_e2e.py @@ -89,6 +89,7 @@ async def test_handle_worker_gave_up_full_chain(self, mock_api, mock_po_event, m mock_api.patch = AsyncMock() mock_api.post = AsyncMock() + mock_api.transition_story = AsyncMock() mock_api.get = AsyncMock(return_value={"created_by": "user"}) mock_notify.return_value = 1 @@ -128,10 +129,9 @@ async def test_handle_worker_gave_up_full_chain(self, mock_api, mock_po_event, m metadata = task_patches[0][1]["json"]["failure_metadata"] assert "56/78" in metadata["reason"] - # Story transitioned to WHR - story_patches = [c for c in mock_api.patch.call_args_list if "stories" in str(c)] - assert len(story_patches) >= 1 - assert story_patches[0][1]["json"]["status"] == "waiting_human_review" + # Story transitioned to WHR through the lifecycle action, never PATCH. + mock_api.transition_story.assert_awaited_once_with("story-1", "human-review") + assert not any("stories/" in str(call) for call in mock_api.patch.call_args_list) # Admin notified at warning level mock_notify.assert_awaited_once() diff --git a/services/worker-manager/tests/unit/test_compose_runner.py b/services/worker-manager/tests/unit/test_compose_runner.py index b78ba9754..b81a72b76 100644 --- a/services/worker-manager/tests/unit/test_compose_runner.py +++ b/services/worker-manager/tests/unit/test_compose_runner.py @@ -326,7 +326,7 @@ async def test_limits_override_is_in_the_inspected_and_executed_invocation(self, @pytest.mark.asyncio async def test_real_service_template_resolution_passes_the_production_validator(self, tmp_path): fixture = Path(__file__).parents[4] / ( - "shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3" + "shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c" ) workspace = tmp_path / "workspace" shutil.copytree(fixture, workspace) @@ -342,7 +342,7 @@ async def test_real_service_template_resolution_passes_the_production_validator( def test_service_template_has_no_label_file_compatibility_consumer(self): fixture = Path(__file__).parents[4] / ( - "shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3" + "shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c" ) assert all("label_file" not in source.read_text() for source in (fixture / "infra").glob("compose*.yml")) @@ -350,7 +350,7 @@ def test_service_template_has_no_label_file_compatibility_consumer(self): @pytest.mark.asyncio async def test_real_documented_integration_resolution_passes_the_production_validator(self, tmp_path): fixture = Path(__file__).parents[4] / ( - "shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3" + "shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c" ) workspace = tmp_path / "workspace" shutil.copytree(fixture, workspace) @@ -370,7 +370,7 @@ async def test_real_documented_integration_resolution_passes_the_production_vali @pytest.mark.asyncio async def test_documented_integration_source_flow_is_compiled(self, tmp_path): fixture = Path(__file__).parents[4] / ( - "shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3" + "shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c" ) workspace = tmp_path / "workspace" shutil.copytree(fixture, workspace) diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.copier-answers.yml b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.copier-answers.yml similarity index 93% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.copier-answers.yml rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.copier-answers.yml index c1c796cef..bbbb5d35a 100644 --- a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.copier-answers.yml +++ b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.copier-answers.yml @@ -1,5 +1,5 @@ # Changes here will be overwritten by Copier; NEVER EDIT MANUALLY -_commit: 0.4.0-19-g91e5821 +_commit: 0.4.0-20-g40b54d8 _src_path: gh:vladmesh/service-template author_email: dev@example.com author_name: Developer diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.coveragerc b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.coveragerc similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.coveragerc rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.coveragerc diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.dockerignore b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.dockerignore similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.dockerignore rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.dockerignore diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.env.example b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.env.example similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.env.example rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.env.example diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/__init__.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/__init__.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/__init__.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/__init__.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/contracts/__init__.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/contracts/__init__.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/contracts/__init__.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/contracts/__init__.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/contracts/env_contract.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/contracts/env_contract.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/contracts/env_contract.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/contracts/env_contract.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/contracts/env_usage.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/contracts/env_usage.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/contracts/env_usage.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/contracts/env_usage.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/enforce_spec_compliance.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/enforce_spec_compliance.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/enforce_spec_compliance.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/enforce_spec_compliance.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/frontend/__init__.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/frontend/__init__.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/frontend/__init__.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/frontend/__init__.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/frontend/generator.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/frontend/generator.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/frontend/generator.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/frontend/generator.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/generate.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/generate.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/generate.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/generate.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/generators/__init__.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/generators/__init__.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/generators/__init__.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/generators/__init__.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/generators/base.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/generators/base.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/generators/base.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/generators/base.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/generators/context.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/generators/context.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/generators/context.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/generators/context.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/generators/controllers.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/generators/controllers.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/generators/controllers.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/generators/controllers.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/generators/event_adapter.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/generators/event_adapter.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/generators/event_adapter.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/generators/event_adapter.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/generators/events.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/generators/events.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/generators/events.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/generators/events.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/generators/jobs_manifest.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/generators/jobs_manifest.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/generators/jobs_manifest.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/generators/jobs_manifest.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/generators/protocols.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/generators/protocols.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/generators/protocols.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/generators/protocols.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/generators/routers.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/generators/routers.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/generators/routers.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/generators/routers.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/generators/schemas.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/generators/schemas.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/generators/schemas.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/generators/schemas.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/generators/settings_manifest.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/generators/settings_manifest.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/generators/settings_manifest.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/generators/settings_manifest.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/lib/env.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/lib/env.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/lib/env.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/lib/env.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/lib/fs.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/lib/fs.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/lib/fs.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/lib/fs.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/lint/__init__.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/lint/__init__.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/lint/__init__.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/lint/__init__.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/lint/controller_sync.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/lint/controller_sync.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/lint/controller_sync.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/lint/controller_sync.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/openapi/__init__.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/openapi/__init__.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/openapi/__init__.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/openapi/__init__.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/openapi/generator.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/openapi/generator.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/openapi/generator.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/openapi/generator.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/spec/__init__.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/spec/__init__.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/spec/__init__.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/spec/__init__.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/spec/events.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/spec/events.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/spec/events.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/spec/events.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/spec/loader.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/spec/loader.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/spec/loader.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/spec/loader.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/spec/manifests.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/spec/manifests.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/spec/manifests.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/spec/manifests.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/spec/models.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/spec/models.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/spec/models.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/spec/models.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/spec/operations.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/spec/operations.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/spec/operations.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/spec/operations.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/spec/types.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/spec/types.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/spec/types.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/spec/types.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/templates/codegen/controller.py.j2 b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/templates/codegen/controller.py.j2 similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/templates/codegen/controller.py.j2 rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/templates/codegen/controller.py.j2 diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/templates/codegen/event_adapter.py.j2 b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/templates/codegen/event_adapter.py.j2 similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/templates/codegen/event_adapter.py.j2 rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/templates/codegen/event_adapter.py.j2 diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/templates/codegen/events.py.j2 b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/templates/codegen/events.py.j2 similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/templates/codegen/events.py.j2 rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/templates/codegen/events.py.j2 diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/templates/codegen/protocols.py.j2 b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/templates/codegen/protocols.py.j2 similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/templates/codegen/protocols.py.j2 rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/templates/codegen/protocols.py.j2 diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/templates/codegen/registry.py.j2 b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/templates/codegen/registry.py.j2 similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/templates/codegen/registry.py.j2 rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/templates/codegen/registry.py.j2 diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/templates/codegen/router.py.j2 b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/templates/codegen/router.py.j2 similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/templates/codegen/router.py.j2 rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/templates/codegen/router.py.j2 diff --git a/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/toolchain.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/toolchain.py new file mode 100644 index 000000000..90d2aec6f --- /dev/null +++ b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/framework/toolchain.py @@ -0,0 +1,10 @@ +"""Pinned toolchain versions for framework and generated-project CI.""" + +# Workflows repeat these literals; tooling tests enforce the exact pins. +# setup-uv v7.4.0 reads its bundled manifest, then falls back to this exact +# release URL for 0.11.29 instead of querying the mutable remote manifest. +SETUP_UV_ACTION = "astral-sh/setup-uv@6ee6290f1cbc4156c0bdd66691b2c144ef8df19a" + +# Keep uv pinned exactly. +UV_VERSION = "0.11.29" +UV_LINUX_X86_64_CHECKSUM = "04f8b82f5d47f0512dcd32c67a4a6f16a0ea27c81537c338fd0ad6b23cebe829" diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/pyproject.toml b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/pyproject.toml similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/pyproject.toml rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.framework/pyproject.toml diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.githooks/pre-commit b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.githooks/pre-commit similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.githooks/pre-commit rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.githooks/pre-commit diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.githooks/pre-push b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.githooks/pre-push similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.githooks/pre-push rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.githooks/pre-push diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.github/workflows/ci.yml b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.github/workflows/ci.yml similarity index 93% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.github/workflows/ci.yml rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.github/workflows/ci.yml index 6bbe48045..5a55c5abd 100644 --- a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.github/workflows/ci.yml +++ b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.github/workflows/ci.yml @@ -26,9 +26,10 @@ jobs: python-version: "3.12" - name: Set up uv - uses: astral-sh/setup-uv@v7 + uses: astral-sh/setup-uv@6ee6290f1cbc4156c0bdd66691b2c144ef8df19a with: version: "0.11.29" + checksum: "04f8b82f5d47f0512dcd32c67a4a6f16a0ea27c81537c338fd0ad6b23cebe829" - name: Set up project run: make setup @@ -127,9 +128,10 @@ jobs: python-version: "3.12" - name: Set up uv - uses: astral-sh/setup-uv@v7 + uses: astral-sh/setup-uv@6ee6290f1cbc4156c0bdd66691b2c144ef8df19a with: version: "0.11.29" + checksum: "04f8b82f5d47f0512dcd32c67a4a6f16a0ea27c81537c338fd0ad6b23cebe829" - name: Generate code from specs run: | diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.github/workflows/deploy.yml b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.github/workflows/deploy.yml similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.github/workflows/deploy.yml rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.github/workflows/deploy.yml diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.gitignore b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.gitignore similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.gitignore rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/.gitignore diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/AGENTS.md b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/AGENTS.md similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/AGENTS.md rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/AGENTS.md diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/ARCHITECTURE.md b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/ARCHITECTURE.md similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/ARCHITECTURE.md rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/ARCHITECTURE.md diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/CONTRIBUTING.md b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/CONTRIBUTING.md similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/CONTRIBUTING.md rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/CONTRIBUTING.md diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/Makefile b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/Makefile similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/Makefile rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/Makefile diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/README.md b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/README.md similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/README.md rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/README.md diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/TASK.md b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/TASK.md similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/TASK.md rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/TASK.md diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/infra/.env.test b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/infra/.env.test similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/infra/.env.test rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/infra/.env.test diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/infra/README.md b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/infra/README.md similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/infra/README.md rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/infra/README.md diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/infra/compose.base.yml b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/infra/compose.base.yml similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/infra/compose.base.yml rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/infra/compose.base.yml diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/infra/compose.dev.yml b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/infra/compose.dev.yml similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/infra/compose.dev.yml rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/infra/compose.dev.yml diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/infra/compose.local.yml b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/infra/compose.local.yml similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/infra/compose.local.yml rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/infra/compose.local.yml diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/infra/compose.prod.yml b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/infra/compose.prod.yml similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/infra/compose.prod.yml rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/infra/compose.prod.yml diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/infra/compose.tests.integration.yml b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/infra/compose.tests.integration.yml similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/infra/compose.tests.integration.yml rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/infra/compose.tests.integration.yml diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/infra/env.contract.yaml b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/infra/env.contract.yaml similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/infra/env.contract.yaml rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/infra/env.contract.yaml diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/mypy.ini b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/mypy.ini similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/mypy.ini rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/mypy.ini diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/pyproject.toml b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/pyproject.toml similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/pyproject.toml rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/pyproject.toml diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/pytest.ini b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/pytest.ini similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/pytest.ini rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/pytest.ini diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/ruff.toml b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/ruff.toml similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/ruff.toml rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/ruff.toml diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services.yml b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services.yml similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services.yml rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services.yml diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/__init__.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/__init__.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/__init__.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/__init__.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/AGENTS.md b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/AGENTS.md similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/AGENTS.md rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/AGENTS.md diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/Dockerfile b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/Dockerfile similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/Dockerfile rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/Dockerfile diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/README.md b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/README.md similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/README.md rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/README.md diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/docs/openapi.json b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/docs/openapi.json similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/docs/openapi.json rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/docs/openapi.json diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/env.contract.yaml b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/env.contract.yaml similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/env.contract.yaml rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/env.contract.yaml diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/manifest.yaml b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/manifest.yaml similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/manifest.yaml rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/manifest.yaml diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/migrations/alembic.ini b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/migrations/alembic.ini similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/migrations/alembic.ini rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/migrations/alembic.ini diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/migrations/env.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/migrations/env.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/migrations/env.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/migrations/env.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/migrations/script.py.mako b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/migrations/script.py.mako similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/migrations/script.py.mako rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/migrations/script.py.mako diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/migrations/versions/0001_initial.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/migrations/versions/0001_initial.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/migrations/versions/0001_initial.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/migrations/versions/0001_initial.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/migrations/versions/118f8b3895d8_create_user.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/migrations/versions/118f8b3895d8_create_user.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/migrations/versions/118f8b3895d8_create_user.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/migrations/versions/118f8b3895d8_create_user.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/migrations/versions/4d8c1f9a2b7e_create_settings.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/migrations/versions/4d8c1f9a2b7e_create_settings.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/migrations/versions/4d8c1f9a2b7e_create_settings.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/migrations/versions/4d8c1f9a2b7e_create_settings.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/migrations/versions/9c2e5a71d4f3_create_job_commands.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/migrations/versions/9c2e5a71d4f3_create_job_commands.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/migrations/versions/9c2e5a71d4f3_create_job_commands.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/migrations/versions/9c2e5a71d4f3_create_job_commands.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/pyproject.toml b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/pyproject.toml similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/pyproject.toml rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/pyproject.toml diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/scripts/migrate.sh b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/scripts/migrate.sh similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/scripts/migrate.sh rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/scripts/migrate.sh diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/scripts/start.sh b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/scripts/start.sh similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/scripts/start.sh rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/scripts/start.sh diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/spec/jobs.yaml b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/spec/jobs.yaml similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/spec/jobs.yaml rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/spec/jobs.yaml diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/spec/settings.yaml b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/spec/settings.yaml similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/spec/settings.yaml rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/spec/settings.yaml diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/spec/users.yaml b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/spec/users.yaml similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/spec/users.yaml rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/spec/users.yaml diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/__init__.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/__init__.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/__init__.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/__init__.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/app/__init__.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/app/__init__.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/app/__init__.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/app/__init__.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/app/api/__init__.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/app/api/__init__.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/app/api/__init__.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/app/api/__init__.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/app/api/router.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/app/api/router.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/app/api/router.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/app/api/router.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/app/api/routers/__init__.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/app/api/routers/__init__.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/app/api/routers/__init__.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/app/api/routers/__init__.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/app/api/v1/__init__.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/app/api/v1/__init__.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/app/api/v1/__init__.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/app/api/v1/__init__.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/app/api/v1/health.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/app/api/v1/health.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/app/api/v1/health.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/app/api/v1/health.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/app/factory.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/app/factory.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/app/factory.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/app/factory.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/app/grant_capability.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/app/grant_capability.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/app/grant_capability.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/app/grant_capability.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/app/jobs_capability.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/app/jobs_capability.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/app/jobs_capability.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/app/jobs_capability.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/app/lifespan.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/app/lifespan.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/app/lifespan.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/app/lifespan.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/app/middleware.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/app/middleware.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/app/middleware.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/app/middleware.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/app/models/__init__.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/app/models/__init__.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/app/models/__init__.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/app/models/__init__.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/app/models/job_command.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/app/models/job_command.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/app/models/job_command.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/app/models/job_command.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/app/models/registry.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/app/models/registry.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/app/models/registry.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/app/models/registry.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/app/models/setting.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/app/models/setting.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/app/models/setting.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/app/models/setting.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/app/models/user.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/app/models/user.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/app/models/user.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/app/models/user.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/app/repositories/__init__.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/app/repositories/__init__.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/app/repositories/__init__.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/app/repositories/__init__.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/app/repositories/job_command.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/app/repositories/job_command.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/app/repositories/job_command.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/app/repositories/job_command.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/app/repositories/setting.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/app/repositories/setting.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/app/repositories/setting.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/app/repositories/setting.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/app/repositories/user.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/app/repositories/user.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/app/repositories/user.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/app/repositories/user.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/app/services/__init__.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/app/services/__init__.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/app/services/__init__.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/app/services/__init__.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/app/settings_capability.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/app/settings_capability.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/app/settings_capability.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/app/settings_capability.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/controllers/jobs.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/controllers/jobs.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/controllers/jobs.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/controllers/jobs.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/controllers/settings.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/controllers/settings.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/controllers/settings.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/controllers/settings.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/controllers/users.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/controllers/users.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/controllers/users.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/controllers/users.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/core/__init__.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/core/__init__.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/core/__init__.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/core/__init__.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/core/db.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/core/db.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/core/db.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/core/db.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/core/logging.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/core/logging.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/core/logging.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/core/logging.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/core/orm.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/core/orm.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/core/orm.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/core/orm.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/core/settings.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/core/settings.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/core/settings.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/core/settings.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/generated/__init__.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/generated/__init__.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/generated/__init__.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/generated/__init__.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/generated/jobs_schemas.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/generated/jobs_schemas.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/generated/jobs_schemas.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/generated/jobs_schemas.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/generated/protocols.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/generated/protocols.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/generated/protocols.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/generated/protocols.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/generated/registry.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/generated/registry.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/generated/registry.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/generated/registry.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/generated/routers/__init__.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/generated/routers/__init__.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/generated/routers/__init__.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/generated/routers/__init__.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/generated/routers/jobs.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/generated/routers/jobs.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/generated/routers/jobs.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/generated/routers/jobs.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/generated/routers/settings.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/generated/routers/settings.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/generated/routers/settings.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/generated/routers/settings.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/generated/routers/users.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/generated/routers/users.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/generated/routers/users.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/generated/routers/users.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/generated/settings_schemas.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/generated/settings_schemas.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/generated/settings_schemas.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/generated/settings_schemas.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/main.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/main.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/src/main.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/src/main.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/tests/__init__.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/tests/__init__.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/tests/__init__.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/tests/__init__.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/tests/conftest.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/tests/conftest.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/tests/conftest.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/tests/conftest.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/tests/unit/test_events.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/tests/unit/test_events.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/tests/unit/test_events.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/tests/unit/test_events.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/tests/unit/test_health.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/tests/unit/test_health.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/tests/unit/test_health.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/tests/unit/test_health.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/tests/unit/test_import_boundaries.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/tests/unit/test_import_boundaries.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/tests/unit/test_import_boundaries.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/tests/unit/test_import_boundaries.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/tests/unit/test_jobs.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/tests/unit/test_jobs.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/tests/unit/test_jobs.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/tests/unit/test_jobs.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/tests/unit/test_middleware.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/tests/unit/test_middleware.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/tests/unit/test_middleware.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/tests/unit/test_middleware.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/tests/unit/test_product_settings.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/tests/unit/test_product_settings.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/tests/unit/test_product_settings.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/tests/unit/test_product_settings.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/tests/unit/test_settings.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/tests/unit/test_settings.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/tests/unit/test_settings.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/tests/unit/test_settings.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/tests/unit/test_users.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/tests/unit/test_users.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/tests/unit/test_users.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/tests/unit/test_users.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/uv.lock b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/uv.lock similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/backend/uv.lock rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/backend/uv.lock diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/frontend/AGENTS.md b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/frontend/AGENTS.md similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/frontend/AGENTS.md rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/frontend/AGENTS.md diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/frontend/Dockerfile b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/frontend/Dockerfile similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/frontend/Dockerfile rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/frontend/Dockerfile diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/frontend/README.md b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/frontend/README.md similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/frontend/README.md rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/frontend/README.md diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/frontend/env.contract.yaml b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/frontend/env.contract.yaml similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/frontend/env.contract.yaml rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/frontend/env.contract.yaml diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/frontend/package.json b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/frontend/package.json similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/frontend/package.json rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/frontend/package.json diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/frontend/src/.gitkeep b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/frontend/src/.gitkeep similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/frontend/src/.gitkeep rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/frontend/src/.gitkeep diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/notifications_worker/AGENTS.md b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/notifications_worker/AGENTS.md similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/notifications_worker/AGENTS.md rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/notifications_worker/AGENTS.md diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/notifications_worker/Dockerfile b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/notifications_worker/Dockerfile similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/notifications_worker/Dockerfile rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/notifications_worker/Dockerfile diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/notifications_worker/README.md b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/notifications_worker/README.md similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/notifications_worker/README.md rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/notifications_worker/README.md diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/notifications_worker/__init__.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/notifications_worker/__init__.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/notifications_worker/__init__.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/notifications_worker/__init__.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/notifications_worker/env.contract.yaml b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/notifications_worker/env.contract.yaml similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/notifications_worker/env.contract.yaml rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/notifications_worker/env.contract.yaml diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/notifications_worker/pyproject.toml b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/notifications_worker/pyproject.toml similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/notifications_worker/pyproject.toml rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/notifications_worker/pyproject.toml diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/notifications_worker/spec/notifications.yaml b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/notifications_worker/spec/notifications.yaml similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/notifications_worker/spec/notifications.yaml rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/notifications_worker/spec/notifications.yaml diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/notifications_worker/src/__init__.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/notifications_worker/src/__init__.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/notifications_worker/src/__init__.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/notifications_worker/src/__init__.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/notifications_worker/src/controllers/__init__.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/notifications_worker/src/controllers/__init__.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/notifications_worker/src/controllers/__init__.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/notifications_worker/src/controllers/__init__.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/notifications_worker/src/controllers/notifications.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/notifications_worker/src/controllers/notifications.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/notifications_worker/src/controllers/notifications.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/notifications_worker/src/controllers/notifications.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/notifications_worker/src/main.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/notifications_worker/src/main.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/notifications_worker/src/main.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/notifications_worker/src/main.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/notifications_worker/tests/test_smoke.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/notifications_worker/tests/test_smoke.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/notifications_worker/tests/test_smoke.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/notifications_worker/tests/test_smoke.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/notifications_worker/uv.lock b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/notifications_worker/uv.lock similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/notifications_worker/uv.lock rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/notifications_worker/uv.lock diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/tg_bot/AGENTS.md b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/tg_bot/AGENTS.md similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/tg_bot/AGENTS.md rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/tg_bot/AGENTS.md diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/tg_bot/Dockerfile b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/tg_bot/Dockerfile similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/tg_bot/Dockerfile rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/tg_bot/Dockerfile diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/tg_bot/README.md b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/tg_bot/README.md similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/tg_bot/README.md rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/tg_bot/README.md diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/tg_bot/__init__.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/tg_bot/__init__.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/tg_bot/__init__.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/tg_bot/__init__.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/tg_bot/env.contract.yaml b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/tg_bot/env.contract.yaml similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/tg_bot/env.contract.yaml rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/tg_bot/env.contract.yaml diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/tg_bot/pyproject.toml b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/tg_bot/pyproject.toml similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/tg_bot/pyproject.toml rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/tg_bot/pyproject.toml diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/tg_bot/src/__init__.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/tg_bot/src/__init__.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/tg_bot/src/__init__.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/tg_bot/src/__init__.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/tg_bot/src/access.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/tg_bot/src/access.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/tg_bot/src/access.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/tg_bot/src/access.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/tg_bot/src/main.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/tg_bot/src/main.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/tg_bot/src/main.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/tg_bot/src/main.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/tg_bot/src/middleware.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/tg_bot/src/middleware.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/tg_bot/src/middleware.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/tg_bot/src/middleware.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/tg_bot/tests/__init__.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/tg_bot/tests/__init__.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/tg_bot/tests/__init__.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/tg_bot/tests/__init__.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/tg_bot/tests/unit/__init__.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/tg_bot/tests/unit/__init__.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/tg_bot/tests/unit/__init__.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/tg_bot/tests/unit/__init__.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/tg_bot/tests/unit/test_access.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/tg_bot/tests/unit/test_access.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/tg_bot/tests/unit/test_access.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/tg_bot/tests/unit/test_access.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/tg_bot/tests/unit/test_command_handler.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/tg_bot/tests/unit/test_command_handler.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/tg_bot/tests/unit/test_command_handler.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/tg_bot/tests/unit/test_command_handler.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/tg_bot/tests/unit/test_middleware.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/tg_bot/tests/unit/test_middleware.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/tg_bot/tests/unit/test_middleware.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/tg_bot/tests/unit/test_middleware.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/tg_bot/tests/unit/test_smoke.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/tg_bot/tests/unit/test_smoke.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/tg_bot/tests/unit/test_smoke.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/tg_bot/tests/unit/test_smoke.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/tg_bot/uv.lock b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/tg_bot/uv.lock similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/services/tg_bot/uv.lock rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/services/tg_bot/uv.lock diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/shared/pyproject.toml b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/shared/pyproject.toml similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/shared/pyproject.toml rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/shared/pyproject.toml diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/shared/shared/__init__.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/shared/shared/__init__.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/shared/shared/__init__.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/shared/shared/__init__.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/shared/shared/generated/__init__.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/shared/shared/generated/__init__.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/shared/shared/generated/__init__.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/shared/shared/generated/__init__.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/shared/shared/generated/events.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/shared/shared/generated/events.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/shared/shared/generated/events.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/shared/shared/generated/events.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/shared/shared/generated/schemas.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/shared/shared/generated/schemas.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/shared/shared/generated/schemas.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/shared/shared/generated/schemas.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/shared/shared/generated/types.ts b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/shared/shared/generated/types.ts similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/shared/shared/generated/types.ts rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/shared/shared/generated/types.ts diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/shared/shared/http_client.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/shared/shared/http_client.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/shared/shared/http_client.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/shared/shared/http_client.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/shared/shared/logging.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/shared/shared/logging.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/shared/shared/logging.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/shared/shared/logging.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/shared/shared/py.typed b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/shared/shared/py.typed similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/shared/shared/py.typed rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/shared/shared/py.typed diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/shared/spec/events.yaml b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/shared/spec/events.yaml similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/shared/spec/events.yaml rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/shared/spec/events.yaml diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/shared/spec/models.yaml b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/shared/spec/models.yaml similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/shared/spec/models.yaml rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/shared/spec/models.yaml diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/tests/conftest.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/tests/conftest.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/tests/conftest.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/tests/conftest.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/tests/integration/.gitkeep b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/tests/integration/.gitkeep similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/tests/integration/.gitkeep rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/tests/integration/.gitkeep diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/tests/integration/test_example.py b/shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/tests/integration/test_example.py similarity index 100% rename from shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/tests/integration/test_example.py rename to shared/tests/fixtures/service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c/tests/integration/test_example.py diff --git a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/toolchain.py b/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/toolchain.py deleted file mode 100644 index 4c18dbe31..000000000 --- a/shared/tests/fixtures/service-template-91e582180b4295bce45155759bdad0dfa43b75f3/.framework/framework/toolchain.py +++ /dev/null @@ -1,7 +0,0 @@ -"""Pinned toolchain versions for framework and generated-project CI.""" - -# Workflows repeat these literals; tooling tests enforce the exact pins. -SETUP_UV_ACTION = "astral-sh/setup-uv@v7" - -# Keep uv pinned exactly. -UV_VERSION = "0.11.29" diff --git a/shared/tests/unit/test_env_usage.py b/shared/tests/unit/test_env_usage.py index 2df4b6025..bac3071c4 100644 --- a/shared/tests/unit/test_env_usage.py +++ b/shared/tests/unit/test_env_usage.py @@ -349,13 +349,30 @@ def test_template_fixture_tracks_the_pinned_template_ref(): assert answers["_commit"].endswith(f"g{pinned_template_ref()[:7]}") +def test_template_fixture_pins_verified_uv_bootstrap(): + """The production render must not retain setup-uv's mutable manifest lookup.""" + action = "astral-sh/setup-uv@6ee6290f1cbc4156c0bdd66691b2c144ef8df19a" + version = "0.11.29" + checksum = "04f8b82f5d47f0512dcd32c67a4a6f16a0ea27c81537c338fd0ad6b23cebe829" + fixture = template_fixture() + workflow = (fixture / ".github" / "workflows" / "ci.yml").read_text() + embedded_toolchain = (fixture / ".framework" / "framework" / "toolchain.py").read_text() + + assert f"uses: {action}" in workflow + assert f'version: "{version}"' in workflow + assert f'checksum: "{checksum}"' in workflow + assert f'SETUP_UV_ACTION = "{action}"' in embedded_toolchain + assert f'UV_VERSION = "{version}"' in embedded_toolchain + assert f'UV_LINUX_X86_64_CHECKSUM = "{checksum}"' in embedded_toolchain + + def test_template_fixture_content_matches_its_pinned_render(): """A renamed fixture must not be able to pass provenance with stale rendered files.""" fixture = template_fixture() answers = yaml.safe_load((fixture / ".copier-answers.yml").read_text()) assert answers == { - "_commit": "0.4.0-19-g91e5821", + "_commit": "0.4.0-20-g40b54d8", "_src_path": "gh:vladmesh/service-template", "author_email": "dev@example.com", "author_name": "Developer", @@ -368,7 +385,7 @@ def test_template_fixture_content_matches_its_pinned_render(): } assert ( fixture_tree_digest(fixture) - == "38856e1a130cc792f201baa878bfc523bfbc1b256a15d714dd6b663407c42bea" + == "9dfa3bbd628c91c1deb54352bc4306e9df52b444be143de4406dc59bfdaa4f24" ) diff --git a/shared/tests/unit/test_settings_seed_contract.py b/shared/tests/unit/test_settings_seed_contract.py index 4b13d2589..76010f88f 100644 --- a/shared/tests/unit/test_settings_seed_contract.py +++ b/shared/tests/unit/test_settings_seed_contract.py @@ -12,7 +12,7 @@ def test_core_v1_refusal_discriminators_match_the_pinned_template(): controller = ( Path(__file__).parents[1] / "fixtures" - / "service-template-91e582180b4295bce45155759bdad0dfa43b75f3" + / "service-template-40b54d87dbfe64a9fa6ec379820e43137aaba04c" / "services/backend/src/controllers/settings.py" ) diff --git a/tests/integration/template/test_stage5_mock_smoke.py b/tests/integration/template/test_stage5_mock_smoke.py index 7bdc3af67..958e1524d 100644 --- a/tests/integration/template/test_stage5_mock_smoke.py +++ b/tests/integration/template/test_stage5_mock_smoke.py @@ -16,7 +16,7 @@ def test_production_template_is_loaded_from_system_config() -> None: template = load_production_template() assert template.source == "gh:vladmesh/service-template" - assert template.ref == "91e582180b4295bce45155759bdad0dfa43b75f3" + assert template.ref == "40b54d87dbfe64a9fa6ec379820e43137aaba04c" def test_stage5_smoke_uses_an_isolated_workspace_and_project_name(tmp_path: Path) -> None: diff --git a/tests/live/brief_telemetry.py b/tests/live/brief_telemetry.py index 5e94255de..0acad3ce0 100644 --- a/tests/live/brief_telemetry.py +++ b/tests/live/brief_telemetry.py @@ -135,6 +135,23 @@ def _engineering_run_line(run: dict, budget: int) -> str: return f"{line}{details}"[:budget] +def _semantic_engineering_snapshot( + tasks: list[dict], runs: list[dict], runs_error: str | None +) -> dict[str, object]: + """Return progress facts that should cause a transition event. + + ``updated_at`` changes on every control-plane poll. It remains in the + rendered snapshot for timing evidence, but cannot itself be progress. + """ + return { + "tasks": [ + {key: value for key, value in task.items() if key != "updated_at"} for task in tasks + ], + "runs": [{key: value for key, value in run.items() if key != "updated_at"} for run in runs], + "runs_error": runs_error, + } + + def engineering_observation( ctx: dict, *, @@ -150,7 +167,7 @@ def engineering_observation( """ _check_deadline(ctx, time.monotonic()) raw = json.dumps( - {"tasks": tasks, "runs": runs, "runs_error": runs_error}, + _semantic_engineering_snapshot(tasks, runs, runs_error), sort_keys=True, default=str, separators=(",", ":"), diff --git a/tests/live/pipeline_helpers.py b/tests/live/pipeline_helpers.py index 860caeff7..d76676a43 100644 --- a/tests/live/pipeline_helpers.py +++ b/tests/live/pipeline_helpers.py @@ -96,7 +96,7 @@ GITHUB_ORG = "project-factory-organization" TEMPLATE_REPO = "gh:vladmesh/service-template" -TEMPLATE_REF = "91e582180b4295bce45155759bdad0dfa43b75f3" +TEMPLATE_REF = "40b54d87dbfe64a9fa6ec379820e43137aaba04c" ORCHESTRATOR_ROOT = resolve_repo_root(Path(__file__)) # Timeouts (seconds) @@ -2287,6 +2287,55 @@ async def wait_deploy_run( return None +_BRIEF_NO_DEPLOY_STORY_STATUSES = frozenset( + { + StoryStatus.WAITING_HUMAN_REVIEW.value, + StoryStatus.WAITING_USER_SECRET.value, + StoryStatus.COMPLETED.value, + StoryStatus.FAILED.value, + StoryStatus.ARCHIVED.value, + } +) + + +async def wait_brief_deploy_run( + api_internal: httpx.AsyncClient, + ctx: dict, + *, + timeout: float = DEPLOY_RUN_TIMEOUT, + poll_interval: float = DEPLOY_RUN_POLL_INTERVAL, + on_poll: Callable[[], None] | None = None, +) -> dict | None: + """Wait for a Product Brief deploy, stopping when its story cannot create one. + + A deploy Run appears only after the generated repository CI succeeds. If + CI or a worker refusal instead parks the story, waiting through the full + deploy budget obscures the terminal cause and spends paid time needlessly. + """ + + async def story_alive() -> bool: + story_id = ctx["story_id"] + response = await api_internal.get(f"/api/stories/{story_id}") + response.raise_for_status() + status = response.json().get("status") + ctx["brief_deploy_story_status"] = status + if status not in _BRIEF_NO_DEPLOY_STORY_STATUSES: + return True + ctx["deploy_run_error"] = ( + f"story {story_id} reached no-deploy state {status} before a deploy Run appeared" + ) + return False + + return await wait_deploy_run( + api_internal, + ctx, + timeout=timeout, + poll_interval=poll_interval, + on_poll=on_poll, + story_alive=story_alive, + ) + + async def _wait_for_followup_deploy_result( api_internal: httpx.AsyncClient, ctx: dict, diff --git a/tests/live/test_harness_contract.py b/tests/live/test_harness_contract.py index 5d164485e..d52479499 100644 --- a/tests/live/test_harness_contract.py +++ b/tests/live/test_harness_contract.py @@ -180,6 +180,66 @@ def test_brief_engineering_telemetry_emits_changed_task_run_facts_once(monkeypat ) == 1 +def test_brief_engineering_telemetry_ignores_updated_at_only_changes(monkeypatch): + clock = [100.0] + monkeypatch.setattr(pipeline_helpers.time, "monotonic", lambda: clock[0]) + ctx: dict = {} + pipeline_helpers.begin_brief_productive_window(ctx) + pipeline_helpers.report_brief_stage(ctx, "engineering", observed_state="tasks_released") + + pipeline_helpers.report_brief_engineering_observation( + ctx, + tasks=[{"id": "task-1", "status": "in_progress", "updated_at": "first"}], + runs=[{"id": "eng-1", "status": "running", "updated_at": "first"}], + ) + first_transition = ctx["brief_telemetry"][-1] + assert "first" in first_transition["observed_state"] + + clock[0] += pipeline_helpers.BRIEF_HEARTBEAT_SECONDS + pipeline_helpers.report_brief_engineering_observation( + ctx, + tasks=[{"id": "task-1", "status": "in_progress", "updated_at": "second"}], + runs=[{"id": "eng-1", "status": "running", "updated_at": "second"}], + ) + + assert ctx["brief_telemetry"][-1]["event"] == "brief_heartbeat" + assert [event["event"] for event in ctx["brief_telemetry"]].count( + "brief_engineering_transition" + ) == 1 + + +def test_brief_engineering_telemetry_records_status_change_after_timestamp_only_poll(monkeypatch): + clock = [100.0] + monkeypatch.setattr(pipeline_helpers.time, "monotonic", lambda: clock[0]) + ctx: dict = {} + pipeline_helpers.begin_brief_productive_window(ctx) + pipeline_helpers.report_brief_stage(ctx, "engineering", observed_state="tasks_released") + + pipeline_helpers.report_brief_engineering_observation( + ctx, + tasks=[{"id": "task-1", "status": "in_progress", "updated_at": "first"}], + runs=[], + ) + clock[0] += pipeline_helpers.BRIEF_HEARTBEAT_SECONDS + pipeline_helpers.report_brief_engineering_observation( + ctx, + tasks=[{"id": "task-1", "status": "in_progress", "updated_at": "second"}], + runs=[], + ) + clock[0] += 1 + pipeline_helpers.report_brief_engineering_observation( + ctx, + tasks=[{"id": "task-1", "status": "done", "updated_at": "third"}], + runs=[], + ) + + assert ctx["brief_telemetry"][-1]["event"] == "brief_engineering_transition" + assert "done" in ctx["brief_telemetry"][-1]["observed_state"] + assert [event["event"] for event in ctx["brief_telemetry"]].count( + "brief_engineering_transition" + ) == 2 + + def test_brief_engineering_changed_snapshot_stops_at_productive_deadline(monkeypatch): clock = [100.0] monkeypatch.setattr(pipeline_helpers.time, "monotonic", lambda: clock[0]) @@ -3292,6 +3352,65 @@ async def test_wait_deploy_run_selects_the_run_carrying_the_merged_sha(monkeypat assert ctx["deploy_run_id"] == "deploy-poll-1" +@pytest.mark.asyncio +@pytest.mark.parametrize( + "status", + [ + pytest.param("waiting_human_review", id="human-review"), + pytest.param("waiting_user_secret", id="user-secret"), + pytest.param("failed", id="failed"), + ], +) +async def test_wait_brief_deploy_run_stops_at_a_story_no_deploy_state(monkeypatch, status): + monkeypatch.setenv("INTERNAL_API_KEY", "test-internal-key") + calls: list[str] = [] + + def handler(request: httpx.Request) -> httpx.Response: + calls.append(request.url.path) + if request.url.path == "/api/stories/story-1": + return httpx.Response(200, json={"id": "story-1", "status": status}, request=request) + raise AssertionError(f"unexpected request: {request.method} {request.url}") + + ctx = {"project_id": "project-1", "story_id": "story-1"} + async with pipeline_helpers.api_client_as_internal_service( + base_url="http://test", transport=httpx.MockTransport(handler) + ) as api_internal: + run = await pipeline_helpers.wait_brief_deploy_run(api_internal, ctx, timeout=1) + + assert run is None + assert calls == ["/api/stories/story-1"] + assert ctx["brief_deploy_story_status"] == status + assert ctx["deploy_run_error"] == ( + f"story story-1 reached no-deploy state {status} before a deploy Run appeared" + ) + + +@pytest.mark.asyncio +async def test_wait_brief_deploy_run_keeps_waiting_while_story_can_deploy(monkeypatch): + monkeypatch.setenv("INTERNAL_API_KEY", "test-internal-key") + expected = _deploy_run("deploy-poll-1", head_sha="abc123") + + def handler(request: httpx.Request) -> httpx.Response: + if request.url.path == "/api/stories/story-1": + return httpx.Response( + 200, json={"id": "story-1", "status": "pr_review"}, request=request + ) + if request.url.path == "/api/runs/": + return httpx.Response(200, json=[expected], request=request) + raise AssertionError(f"unexpected request: {request.method} {request.url}") + + ctx = {"project_id": "project-1", "story_id": "story-1"} + async with pipeline_helpers.api_client_as_internal_service( + base_url="http://test", transport=httpx.MockTransport(handler) + ) as api_internal: + run = await pipeline_helpers.wait_brief_deploy_run(api_internal, ctx, timeout=1) + + assert run == expected + assert ctx["deploy_run_id"] == "deploy-poll-1" + assert ctx["brief_deploy_story_status"] == "pr_review" + assert "deploy_run_error" not in ctx + + @pytest.mark.asyncio async def test_wait_deploy_run_selects_the_earliest_qualifying_merged_run(monkeypatch): """Initial deploy observation is chronological, independent of API ordering.""" diff --git a/tests/live/test_product_brief_pipeline.py b/tests/live/test_product_brief_pipeline.py index 71b27a453..fd0cab4d4 100644 --- a/tests/live/test_product_brief_pipeline.py +++ b/tests/live/test_product_brief_pipeline.py @@ -51,10 +51,10 @@ trigger_scaffold, verify_undeploy_residue, wait_application_not_deployed, + wait_brief_deploy_run, wait_brief_engineering, wait_deploy, wait_deploy_outcome, - wait_deploy_run, wait_product_brief_admission, wait_scaffold, wait_settings_seed_followup, @@ -289,7 +289,7 @@ async def product_brief_pipeline(): # noqa: PLR0911, PLR0915 - terminal phase e report_brief_stage(ctx, "generated_ci_deploy", observed_state="engineering_done") if ( - await wait_deploy_run( + await wait_brief_deploy_run( api_internal, ctx, timeout=DEPLOY_RUN_TIMEOUT, @@ -455,7 +455,7 @@ async def test_engineering_deploy_and_settings_seed_succeeded(self, product_brie assert ctx.get("story_branch_error") is None, ctx.get("story_branch_error") assert ctx.get("deploy_outcome") == DeployOutcome.SUCCESS.value, ctx.get( "deploy_error_details" - ) + ) or ctx.get("deploy_run_error") assert ctx.get("final_app_status") == ApplicationStatus.RUNNING.value assert ctx.get("deployed_image_error") is None, ctx.get("deployed_image_error") assert ctx["brief_settings_seed"] == [