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
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
248 lines
11 KiB
Gherkin
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
|