10abf8985e
CI / benchmark-publish (pull_request) Has been skipped
CI / lint (pull_request) Successful in 15s
CI / quality (pull_request) Successful in 19s
CI / build (pull_request) Successful in 29s
CI / security (pull_request) Successful in 33s
CI / typecheck (pull_request) Successful in 35s
CI / unit_tests (pull_request) Successful in 2m15s
CI / docker (pull_request) Successful in 39s
CI / integration_tests (pull_request) Successful in 3m4s
CI / coverage (pull_request) Successful in 5m1s
CI / lint (push) Successful in 12s
CI / build (push) Successful in 15s
CI / quality (push) Successful in 16s
CI / security (push) Successful in 31s
CI / typecheck (push) Successful in 33s
CI / benchmark-regression (push) Has been skipped
CI / unit_tests (push) Successful in 3m20s
CI / integration_tests (push) Successful in 4m10s
CI / docker (push) Successful in 1m3s
CI / coverage (push) Successful in 4m20s
CI / benchmark-publish (push) Successful in 16m0s
CI / benchmark-regression (pull_request) Successful in 31m40s
Created ScoredFragment frozen model wrapping ContextFragment with composite_score, score_breakdown, and rank fields. Added pipeline- specific fragment models in domain/contexts/ with proper equality based on uko_uri + detail_depth for deduplication support. ISSUES CLOSED: #538
137 lines
6.9 KiB
Gherkin
137 lines
6.9 KiB
Gherkin
@phase2 @acms @context_fragment_models
|
|
Feature: ScoredFragment and ContextFragment pipeline models
|
|
As a CleverAgents developer
|
|
I want pipeline-specific fragment models with scoring and deduplication
|
|
So that the ACMS context assembly pipeline can rank, deduplicate, and pack fragments
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# ScoredFragment — Construction
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@scored_fragment
|
|
Scenario: Create a ScoredFragment with required fields
|
|
Given a context fragment with uko_node "project://app/main.py" and content "hello" and token_count 10
|
|
When I create a scored fragment with composite_score 0.85
|
|
Then the scored fragment composite_score should be 0.85
|
|
And the scored fragment rank should be 0
|
|
And the scored fragment score_breakdown should be empty
|
|
And the scored fragment uko_node should be "project://app/main.py"
|
|
And the scored fragment detail_depth should be 0
|
|
And the scored fragment token_count should be 10
|
|
|
|
@scored_fragment
|
|
Scenario: Create a ScoredFragment with all fields
|
|
Given a context fragment with uko_node "project://app/io.py" and content "async IO" and token_count 50
|
|
When I create a scored fragment with composite_score 0.92 and rank 1 and breakdown:
|
|
| component | score |
|
|
| relevance | 0.9 |
|
|
| hierarchy | 0.8 |
|
|
| recency | 0.95 |
|
|
Then the scored fragment composite_score should be 0.92
|
|
And the scored fragment rank should be 1
|
|
And the scored fragment breakdown "relevance" should be 0.9
|
|
And the scored fragment breakdown "hierarchy" should be 0.8
|
|
And the scored fragment breakdown "recency" should be 0.95
|
|
|
|
@scored_fragment
|
|
Scenario: Create a ScoredFragment from relevance factory
|
|
Given a context fragment with uko_node "project://app/util.py" and content "utils" and token_count 20 and relevance 0.75
|
|
When I create a scored fragment from relevance
|
|
Then the scored fragment composite_score should be 0.75
|
|
And the scored fragment breakdown "relevance" should be 0.75
|
|
And the scored fragment rank should be 0
|
|
|
|
@scored_fragment
|
|
Scenario: Create a ScoredFragment from fragment factory
|
|
Given a context fragment with uko_node "project://app/core.py" and content "core" and token_count 30
|
|
When I create a scored fragment from factory with score 0.6 and rank 3
|
|
Then the scored fragment composite_score should be 0.6
|
|
And the scored fragment rank should be 3
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# ScoredFragment — Equality and Hashing
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@scored_fragment @equality
|
|
Scenario: ScoredFragments with same uko_node and detail_depth are equal
|
|
Given two scored fragments with uko_node "project://app/main.py" and detail_depth 3
|
|
Then the two scored fragments should be equal
|
|
And the two scored fragments should have the same hash
|
|
|
|
@scored_fragment @equality
|
|
Scenario: ScoredFragments with different uko_node are not equal
|
|
Given a scored fragment with uko_node "project://app/main.py" and detail_depth 3
|
|
And another scored fragment with uko_node "project://app/other.py" and detail_depth 3
|
|
Then the two scored fragments should not be equal
|
|
|
|
@scored_fragment @equality
|
|
Scenario: ScoredFragments with different detail_depth are not equal
|
|
Given a scored fragment with uko_node "project://app/main.py" and detail_depth 3
|
|
And another scored fragment with uko_node "project://app/main.py" and detail_depth 5
|
|
Then the two scored fragments should not be equal
|
|
|
|
@scored_fragment @equality
|
|
Scenario: ScoredFragments can be deduplicated via set
|
|
Given three scored fragments where two share uko_node "project://app/main.py" detail_depth 3
|
|
When I add them to a set
|
|
Then the set should contain 2 unique scored fragments
|
|
|
|
@scored_fragment @equality
|
|
Scenario: ScoredFragments with same identity but different scores are equal
|
|
Given a scored fragment with uko_node "project://app/main.py" and detail_depth 2 and score 0.5
|
|
And another scored fragment with uko_node "project://app/main.py" and detail_depth 2 and score 0.9
|
|
Then the two scored fragments should be equal
|
|
And the two scored fragments should have the same hash
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# ScoredFragment — Immutability
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@scored_fragment @immutability
|
|
Scenario: ScoredFragment is frozen
|
|
Given a context fragment with uko_node "project://app/main.py" and content "hello" and token_count 10
|
|
When I create a scored fragment with composite_score 0.85
|
|
Then modifying the scored fragment composite_score should raise an error
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# ScoredFragment — Validation
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@scored_fragment @validation
|
|
Scenario: Invalid composite_score above 1.0 rejected
|
|
Given a context fragment with uko_node "project://app/main.py" and content "hello" and token_count 10
|
|
When I create a scored fragment with composite_score 1.5
|
|
Then a validation error should be raised
|
|
|
|
@scored_fragment @validation
|
|
Scenario: Invalid composite_score below 0.0 rejected
|
|
Given a context fragment with uko_node "project://app/main.py" and content "hello" and token_count 10
|
|
When I create a scored fragment with composite_score -0.1
|
|
Then a validation error should be raised
|
|
|
|
@scored_fragment @validation
|
|
Scenario: Invalid score_breakdown component rejected
|
|
Given a context fragment with uko_node "project://app/main.py" and content "hello" and token_count 10
|
|
When I create a scored fragment with an invalid breakdown component 1.5
|
|
Then a validation error should be raised
|
|
|
|
@scored_fragment @validation
|
|
Scenario: Negative rank rejected
|
|
Given a context fragment with uko_node "project://app/main.py" and content "hello" and token_count 10
|
|
When I create a scored fragment with composite_score 0.5 and rank -1
|
|
Then a validation error should be raised
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# ContextFragment — strategy_source field
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@context_fragment @strategy_source
|
|
Scenario: ContextFragment has strategy_source field with default
|
|
Given a context fragment with uko_node "project://app/main.py" and content "hello" and token_count 10
|
|
Then the fragment strategy_source should be empty
|
|
|
|
@context_fragment @strategy_source
|
|
Scenario: ContextFragment strategy_source can be set
|
|
Given a context fragment with uko_node "project://app/main.py" and content "hello" and token_count 10 and strategy_source "keyword-search"
|
|
Then the fragment strategy_source should be "keyword-search"
|