Files
cleveragents-core/features/execute_phase_context_assembler_coverage.feature
T
hamza.khyari 1baa888659
CI / lint (pull_request) Successful in 57s
CI / typecheck (pull_request) Successful in 1m24s
CI / quality (pull_request) Successful in 1m16s
CI / build (pull_request) Successful in 40s
CI / security (pull_request) Successful in 1m28s
CI / integration_tests (pull_request) Successful in 6m2s
CI / helm (pull_request) Successful in 24s
CI / push-validation (pull_request) Successful in 28s
CI / unit_tests (pull_request) Successful in 7m13s
CI / docker (pull_request) Successful in 1m29s
CI / coverage (pull_request) Successful in 11m50s
CI / status-check (pull_request) Successful in 7s
fix(acms): use project-level hot_max_tokens in execute phase context assembly
Added _resolve_effective_budget() method to
ACMSExecutePhaseContextAssembler that reads each linked project's
settings.hot_max_tokens and uses the maximum override value as the
pipeline budget instead of the hardcoded global default.

Updated assemble() to use the resolved effective budget for both
CoreContextBudget and ContextRequest.

Added Behave regression scenario with @tdd_issue @tdd_issue_11035 tags
verifying the pipeline receives the project-level budget.

Removed test artifact ANALYSIS.md left over from scenario 20.

Fixes: #11035
Fixes: #11215
2026-05-15 10:27:57 +00:00

248 lines
11 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
@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
# ---- _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
# ---- assemble: project-level hot_max_tokens budget override ----
@tdd_issue @tdd_issue_11035
Scenario: epcov assemble uses project-level hot_max_tokens when set
Given epcov an assembler with project hot_max_tokens set to 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 assembled budget should be 32000