Files
cleveragents-core/features/execute_phase_context_assembler_coverage.feature
HAL9000 9da9c1b1c6 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
2026-06-14 08:18:13 -04:00

288 lines
13 KiB
Gherkin

@mock_only
Feature: Execute-phase context assembler coverage
Comprehensive tests for ACMSExecutePhaseContextAssembler covering
_resolve_execute_view, _path_matches, _resource_matches,
_to_context_fragment, and the full assemble() method with all
filtering branches.
# ---- Protocol ----
Scenario: epcov protocol assemble method is abstract
Given epcov a class implementing the ExecutePhaseContextAssembler protocol
When epcov I call assemble on the protocol stub
Then epcov the result should be None
# ---- _resolve_execute_view ----
Scenario: epcov resolve execute view success
Given epcov an assembler with a project repository returning a custom policy
When epcov I resolve the execute view for "proj-alpha"
Then epcov the resolved view should have the custom include_resources
Scenario: epcov resolve execute view falls back on exception
Given epcov an assembler with a project repository that raises an exception
When epcov I resolve the execute view for "proj-broken"
Then epcov the resolved view should be the default empty ContextView
# ---- _path_matches static method ----
Scenario: epcov path matches with no rules passes all
When epcov I check path matching for "src/foo.py" with no include or exclude
Then epcov the path should match
Scenario: epcov path matches with include rule matching
When epcov I check path matching for "src/foo.py" with include "src/**/*.py"
Then epcov the path should match
Scenario: epcov path matches with include rule not matching
When epcov I check path matching for "docs/readme.md" with include "src/**/*.py"
Then epcov the path should not match
Scenario: epcov path matches with exclude rule matching
When epcov I check path matching for "src/secret.py" with exclude "src/secret*"
Then epcov the path should not match
Scenario: epcov path matches with exclude rule not matching
When epcov I check path matching for "src/foo.py" with exclude "src/secret*"
Then epcov the path should match
# ---- Absolute path matching with relative globs (issue #10972) ----
@tdd_issue @tdd_issue_10972
Scenario: epcov path matches absolute path against relative include glob
When epcov I check path matching for "/app/.opencode/skills/SKILL.md" with include ".opencode/**"
Then epcov the path should match
@tdd_issue @tdd_issue_10972
Scenario: epcov path matches absolute path against relative exclude glob
When epcov I check path matching for "/app/.opencode/skills/SKILL.md" with exclude ".opencode/**"
Then epcov the path should not match
@tdd_issue @tdd_issue_10972
Scenario: epcov path matches absolute path against relative include glob with wildcard
When epcov I check path matching for "/app/docs/readme.md" with include "docs/*"
Then epcov the path should match
@tdd_issue @tdd_issue_10972
Scenario: epcov path matches absolute path not matching relative include glob
When epcov I check path matching for "/app/src/main.py" with include "docs/*"
Then epcov the path should not match
@tdd_issue @tdd_issue_10972
Scenario: epcov relative path is excluded by trailing ** glob
When epcov I check path matching for "build/debug/output.log" with exclude "build/**"
Then epcov the path should not match
@tdd_issue @tdd_issue_10972
Scenario: epcov absolute path matched against relative exclude glob
When epcov I check path matching for "/app/.opencode/skills/secret.md" with exclude ".opencode/**"
Then epcov the path should not match
@tdd_issue @tdd_issue_10972
Scenario: epcov absolute path deep subdirectory matches relative glob
When epcov I check path matching for "/app/docs/api/endpoint.md" with include "docs/**"
Then epcov the path should match
@tdd_issue @tdd_issue_10972
Scenario: epcov absolute path excluded by nested relative glob
When epcov I check path matching for "/app/vendor/lib/external.py" with exclude "vendor/**"
Then epcov the path should not match
@tdd_issue @tdd_issue_10972
Scenario: epcov absolute pattern (anchored with /) passed through unchanged
When epcov I check path matching for "/src/main.py" with include "/src/**"
Then epcov the path should match
# ---- _resource_matches static method ----
Scenario: epcov resource matches with no rules passes all
When epcov I check resource matching for "res:abc" with no include or exclude
Then epcov the resource should match
Scenario: epcov resource matches with include rule matching
When epcov I check resource matching for "res:abc" with include "res:*"
Then epcov the resource should match
Scenario: epcov resource matches with include rule not matching
When epcov I check resource matching for "other:xyz" with include "res:*"
Then epcov the resource should not match
Scenario: epcov resource matches with exclude rule matching
When epcov I check resource matching for "res:secret" with exclude "res:secret"
Then epcov the resource should not match
Scenario: epcov resource matches with exclude rule not matching
When epcov I check resource matching for "res:abc" with exclude "res:secret"
Then epcov the resource should match
# ---- _to_context_fragment ----
Scenario: epcov converts tiered fragment with full metadata
Given epcov an assembler instance
When epcov I convert a tiered fragment with detail_depth 3 and relevance 0.8
Then epcov the core fragment should have detail_depth 3 and relevance 0.8
Scenario: epcov converts tiered fragment with missing metadata defaults
Given epcov an assembler instance
When epcov I convert a tiered fragment with no detail_depth or relevance
Then epcov the core fragment should have detail_depth 1 and relevance 0.5
Scenario: epcov converts tiered fragment with non-int detail_depth
Given epcov an assembler instance
When epcov I convert a tiered fragment with detail_depth "high" and relevance "bad"
Then epcov the core fragment should have detail_depth 1 and relevance 0.5
Scenario: epcov converts tiered fragment clamps relevance to bounds
Given epcov an assembler instance
When epcov I convert a tiered fragment with relevance 1.5
Then epcov the core fragment should have clamped relevance 1.0
Scenario: epcov converts tiered fragment with negative relevance
Given epcov an assembler instance
When epcov I convert a tiered fragment with relevance -0.3
Then epcov the core fragment should have clamped relevance 0.0
Scenario: epcov converts tiered fragment with no resource_id uses uko fallback
Given epcov an assembler instance
When epcov I convert a tiered fragment with empty resource_id
Then epcov the core fragment uko_node should start with "uko:"
Scenario: epcov converts tiered fragment with path metadata
Given epcov an assembler instance
When epcov I convert a tiered fragment with path "src/main.py" in metadata
Then epcov the core fragment provenance location should be "src/main.py"
Scenario: epcov converts tiered fragment with non-string path metadata
Given epcov an assembler instance
When epcov I convert a tiered fragment with non-string path in metadata
Then epcov the core fragment provenance location should be empty
# ---- assemble: no project links ----
Scenario: epcov assemble returns None when plan has no project links
Given epcov an assembler instance
And epcov a plan with no project links
When epcov I call assemble on the plan
Then epcov the assembled result should be None
# ---- assemble: empty scoped view ----
Scenario: epcov assemble returns None when scoped view is empty
Given epcov an assembler with scoped view returning empty list
And epcov a plan with project links
When epcov I call assemble on the plan
Then epcov the assembled result should be None
# ---- assemble: fragment excluded by missing view ----
Scenario: epcov assemble excludes fragment whose project has no view
Given epcov an assembler with views only for "proj-alpha"
And epcov a plan with project links for "proj-alpha" and "proj-beta"
And epcov scoped fragments for "proj-alpha" and "proj-beta"
When epcov I call assemble on the plan
Then epcov the assembled result should include only proj-alpha fragments
# ---- assemble: resource filtering ----
Scenario: epcov assemble excludes fragment by resource include rules
Given epcov an assembler with resource include rule "allowed:*"
And epcov a plan with project links
And epcov scoped fragments with resource ids "allowed:file" and "denied:file"
When epcov I call assemble on the plan
Then epcov the assembled result should include only the allowed resource fragment
Scenario: epcov assemble excludes fragment by resource exclude rules
Given epcov an assembler with resource exclude rule "secret:*"
And epcov a plan with project links
And epcov scoped fragments with resource ids "public:file" and "secret:file"
When epcov I call assemble on the plan
Then epcov the assembled result should include only the public resource fragment
# ---- assemble: path filtering ----
Scenario: epcov assemble excludes fragment by path include rules
Given epcov an assembler with path include rule "src/**"
And epcov a plan with project links
And epcov scoped fragments with paths "src/main.py" and "docs/readme.md"
When epcov I call assemble on the plan
Then epcov the assembled result should include only the src fragment
Scenario: epcov assemble excludes fragment by path exclude rules
Given epcov an assembler with path exclude rule "vendor/**"
And epcov a plan with project links
And epcov scoped fragments with paths "src/main.py" and "vendor/lib.py"
When epcov I call assemble on the plan
Then epcov the assembled result should include only the non-vendor fragment
Scenario: epcov assemble excludes fragment with no path when include_paths set
Given epcov an assembler with path include rule "src/**"
And epcov a plan with project links
And epcov a scoped fragment with no path metadata
When epcov I call assemble on the plan
Then epcov the assembled result should be None
# ---- assemble: max_file_size filtering ----
Scenario: epcov assemble excludes fragment exceeding max_file_size
Given epcov an assembler with max_file_size of 10 bytes
And epcov a plan with project links
And epcov a scoped fragment with content exceeding 10 bytes
When epcov I call assemble on the plan
Then epcov the assembled result should be None
# ---- assemble: max_total_size filtering ----
Scenario: epcov assemble excludes fragment exceeding max_total_size
Given epcov an assembler with max_total_size of 20 bytes
And epcov a plan with project links
And epcov two scoped fragments each with 15 byte content
When epcov I call assemble on the plan
Then epcov the assembled result should include only the first fragment
# ---- assemble: all filtered out ----
Scenario: epcov assemble returns None when all fragments are filtered out
Given epcov an assembler with resource include rule "nonexistent:*"
And epcov a plan with project links
And epcov scoped fragments with resource ids "other:a" and "other:b"
When epcov I call assemble on the plan
Then epcov the assembled result should be None
# ---- assemble: successful full pipeline ----
Scenario: epcov assemble returns full AssembledContext on success
Given epcov an assembler with default policy and pipeline
And epcov a plan with project links
And epcov scoped fragments that pass all filters
When epcov I call assemble on the plan
Then epcov the assembled result should be an AssembledContext
And epcov the assembled result should have fragments and metadata
# ---- _resolve_hot_max_tokens: reads context_policy_json from DB ----
@tdd_issue @tdd_issue_11035
Scenario: epcov assemble uses project-level hot_max_tokens from context_policy_json
Given epcov an assembler with context_policy_json hot_max_tokens 32000
And epcov a plan with project links
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 32000
@tdd_issue @tdd_issue_11035
Scenario: epcov assemble falls back to global hot_max_tokens when context_policy_json has no override
Given epcov an assembler with no hot_max_tokens in context_policy_json
And epcov a plan with project links
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