From 9da9c1b1c6356ff0cd4f3c029c4862ffc6c4a134 Mon Sep 17 00:00:00 2001 From: HAL9000 Date: Sat, 9 May 2026 12:46:59 +0000 Subject: [PATCH 1/2] fix(acms): wire ContextAssemblyPipeline as default in ACMSExecutePhaseContextAssembler ACMSExecutePhaseContextAssembler previously instantiated the plain ACMSPipeline when no pipeline was explicitly provided, missing production Phase 1 optimizations including confidence-weighted strategy selection, proportional budget allocation with min-budget enforcement, parallel strategy execution with circuit breaking, and per-stage timing instrumentation. The default is now ContextAssemblyPipeline which provides all of these capabilities while remaining a drop-in replacement for ACMSPipeline. ISSUES CLOSED: #10027 --- CONTRIBUTORS.md | 1 + ...e_phase_context_assembler_coverage.feature | 10 ++++ ..._phase_context_assembler_coverage_steps.py | 59 +++++++++++++++++++ .../execute_phase_context_assembler.py | 5 +- 4 files changed, 74 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index ca832487b..eeadc112c 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -109,3 +109,4 @@ Below are some specific details of individual PR contributions. * HAL 9000 has contributed the CleanupService sandbox cache invalidation fix (PR #8257 / issue #7527): `_purge_sandboxes()` now invalidates the internal `_sandbox_dirs_cache` after deleting stale directories so that a subsequent `scan()` call on the same instance re-reads the filesystem instead of returning already-deleted paths as stale items. * HAL 9000 has contributed the LSP subprocess cleanup fix (#10597): added a defensive ``_process = None`` reset before ``subprocess.Popen()`` in ``StdioTransport.start()`` to prevent orphaned child processes and file descriptor leaks when ``subprocess.Popen()`` fails during initialization. * HAL 9000 has contributed the Invariant Data Model and Database Schema (PR #8701 / issue #8524): SQLAlchemy ORM model with fields id (UUID), description (text), created_at (timestamp), and is_active (bool); Alembic migration creating the invariants table with index on is_active for efficient active-query filtering; BDD Behave unit tests and Robot Framework integration tests. +* HAL 9000 has contributed the ACMS execute phase ContextAssemblyPipeline wiring (PR #10027): replaces the base ``ACMSPipeline`` default with ``ContextAssemblyPipeline`` in ``ACMSExecutePhaseContextAssembler``, enabling production Phase 1 components (confidence-weighted strategy selection, proportional budget allocation, parallel execution with circuit breaking) and per-stage timing instrumentation by default. Includes Behave test coverage verifying the default pipeline type. diff --git a/features/execute_phase_context_assembler_coverage.feature b/features/execute_phase_context_assembler_coverage.feature index 660a79392..3e9ad7ec0 100644 --- a/features/execute_phase_context_assembler_coverage.feature +++ b/features/execute_phase_context_assembler_coverage.feature @@ -275,3 +275,13 @@ Feature: Execute-phase context assembler coverage And epcov scoped fragments that pass all filters When epcov I call assemble on the plan Then epcov the pipeline received budget max_tokens of 4096 + + # ---- Default pipeline type ---- + + Scenario: epcov default pipeline is ContextAssemblyPipeline when none provided + Given epcov an assembler with no explicit pipeline argument + Then epcov the internal pipeline should be a ContextAssemblyPipeline + + Scenario: epcov explicit pipeline overrides default ContextAssemblyPipeline + Given epcov an assembler with an explicitly passed ACMSPipeline mock + Then epcov the internal pipeline should be the explicitly passed mock diff --git a/features/steps/execute_phase_context_assembler_coverage_steps.py b/features/steps/execute_phase_context_assembler_coverage_steps.py index 53a0ddf2d..ffb899842 100644 --- a/features/steps/execute_phase_context_assembler_coverage_steps.py +++ b/features/steps/execute_phase_context_assembler_coverage_steps.py @@ -124,6 +124,65 @@ def _make_assembler( return assembler +@given("epcov an assembler with no explicit pipeline argument") +def step_epcov_no_explicit_pipeline(context: Context) -> None: + + tier_service = MagicMock() + tier_service.get_scoped_view.return_value = [] + + repo = MagicMock() + repo.get_context_policy.return_value = ProjectContextPolicy() + + context.epcov_assembler = ACMSExecutePhaseContextAssembler( + context_tier_service=tier_service, + project_repository=repo, + hot_max_tokens=4096, + ) + + +@given("epcov an assembler with an explicitly passed ACMSPipeline mock") +def step_epcov_explicit_pipeline(context: Context) -> None: + + tier_service = MagicMock() + tier_service.get_scoped_view.return_value = [] + + repo = MagicMock() + repo.get_context_policy.return_value = ProjectContextPolicy() + + mock_pipeline = MagicMock() + context.epcov_explicit_pipeline_mock = mock_pipeline + context.epcov_assembler = ACMSExecutePhaseContextAssembler( + context_tier_service=tier_service, + project_repository=repo, + acms_pipeline=mock_pipeline, + hot_max_tokens=4096, + ) + + +@then("epcov the internal pipeline should be a ContextAssemblyPipeline") +def step_epcov_default_pipeline_is_context_assembly(context: Context) -> None: + + from cleveragents.application.services.acms_pipeline import ( + ContextAssemblyPipeline, + ) + + assert isinstance( + context.epcov_assembler._pipeline, + ContextAssemblyPipeline, + ), ( + f"Expected ContextAssemblyPipeline but got " + f"{type(context.epcov_assembler._pipeline).__name__}" + ) + + +@then("epcov the internal pipeline should be the explicitly passed mock") +def step_epcov_explicit_pipeline_kept(context: Context) -> None: + + assert context.epcov_assembler._pipeline is context.epcov_explicit_pipeline_mock, ( + "Expected the explicitly passed mock pipeline to be used" + ) + + # --------------------------------------------------------------------------- # Protocol (line 36) # --------------------------------------------------------------------------- diff --git a/src/cleveragents/application/services/execute_phase_context_assembler.py b/src/cleveragents/application/services/execute_phase_context_assembler.py index da2af9895..17f5fdbb9 100644 --- a/src/cleveragents/application/services/execute_phase_context_assembler.py +++ b/src/cleveragents/application/services/execute_phase_context_assembler.py @@ -9,6 +9,9 @@ from typing import Any, Protocol import structlog +from cleveragents.application.services.acms_pipeline import ( + ContextAssemblyPipeline, +) from cleveragents.application.services.acms_service import ACMSPipeline from cleveragents.domain.models.acms.crp import AssembledContext, ContextRequest from cleveragents.domain.models.acms.tiers import TieredFragment @@ -49,7 +52,7 @@ class ACMSExecutePhaseContextAssembler(ExecutePhaseContextAssembler): ) -> None: self._tier = context_tier_service self._project_repository = project_repository - self._pipeline = acms_pipeline or ACMSPipeline() + self._pipeline = acms_pipeline or ContextAssemblyPipeline() self._hot_max_tokens = hot_max_tokens self._logger = logger.bind(component="execute_phase_context_assembler") -- 2.52.0 From bedd1ec0c500c11e6b032cc129b9fb57ef55bd8a Mon Sep 17 00:00:00 2001 From: CleverThis Date: Sun, 14 Jun 2026 07:29:32 -0400 Subject: [PATCH 2/2] fix(acms): move ContextAssemblyPipeline import to module level in step defs Per project import rules, all imports must appear at the top of the file. The ContextAssemblyPipeline import was inside the @then step function body; moved it to the module-level imports section alongside other production-code imports. ISSUES CLOSED: #10027 --- .../execute_phase_context_assembler_coverage_steps.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/features/steps/execute_phase_context_assembler_coverage_steps.py b/features/steps/execute_phase_context_assembler_coverage_steps.py index ffb899842..68ac3e0d3 100644 --- a/features/steps/execute_phase_context_assembler_coverage_steps.py +++ b/features/steps/execute_phase_context_assembler_coverage_steps.py @@ -19,6 +19,9 @@ from unittest.mock import MagicMock, patch from behave import given, then, when from behave.runner import Context +from cleveragents.application.services.acms_pipeline import ( + ContextAssemblyPipeline, +) from cleveragents.application.services.execute_phase_context_assembler import ( ACMSExecutePhaseContextAssembler, ) @@ -162,10 +165,6 @@ def step_epcov_explicit_pipeline(context: Context) -> None: @then("epcov the internal pipeline should be a ContextAssemblyPipeline") def step_epcov_default_pipeline_is_context_assembly(context: Context) -> None: - from cleveragents.application.services.acms_pipeline import ( - ContextAssemblyPipeline, - ) - assert isinstance( context.epcov_assembler._pipeline, ContextAssemblyPipeline, -- 2.52.0