Feature: Skeleton compressor As an ACMS subsystem I want to compress context fragments for subplan inheritance So that child plans receive relevant context within a token budget Background: Given a skeleton compressor service # --- budget validation ------------------------------------------------- Scenario: Reject negative skeleton_budget Given context fragments with total tokens 1000 When I compress with skeleton_budget -1 Then the compressor should raise a ValueError for invalid budget Scenario: Accept budget 0 returns empty Given context fragments with total tokens 1000 When I compress with skeleton_budget 0 Then the result should contain zero fragments Scenario: Accept large budget returns all fragments Given context fragments with total tokens 1000 When I compress with skeleton_budget 1000 Then all fragments should be returned unchanged Scenario: Accept budget at boundary 500 Given context fragments with total tokens 1000 When I compress with skeleton_budget 500 Then compressed tokens should be at most 500 # --- stable ordering -------------------------------------------------- Scenario: Fragments with equal relevance are ordered by id Given three fragments with equal relevance 0.5 When I compress with skeleton_budget 10000 Then fragments should be ordered by fragment_id ascending Scenario: Fragments are ordered by relevance descending Given fragments with relevances 0.9, 0.3, and 0.7 When I compress with skeleton_budget 10000 Then the first fragment should have relevance 0.9 And the last fragment should have relevance 0.3 # --- edge cases ------------------------------------------------------- Scenario: Empty fragment list compresses to empty Given an empty fragment list When I compress with skeleton_budget 500 Then the result should contain zero fragments Scenario: Single fragment fits within budget Given a single fragment with 100 tokens When I compress with skeleton_budget 200 Then the result should contain one fragment Scenario: Single fragment kept even when it exceeds budget Given a single fragment with 100 tokens When I compress with skeleton_budget 50 Then the result should contain one fragment # --- argument validation ---------------------------------------------- Scenario: Reject non-tuple fragments argument When I compress with a non-tuple fragments argument Then the compressor should raise a TypeError Scenario: Reject fragment with negative token count Given a fragment with negative token count When I compress with skeleton_budget 500 Then the compressor should raise a ValueError for invalid fragment Scenario: Reject fragment with empty id Given a fragment with empty fragment_id When I compress with skeleton_budget 500 Then the compressor should raise a ValueError for invalid fragment Scenario: Reject fragment with relevance out of range Given a fragment with relevance 1.5 When I compress with skeleton_budget 500 Then the compressor should raise a ValueError for invalid fragment Scenario: Reject non-ContextFragment item in tuple When I compress with a tuple containing a non-fragment item Then the compressor should raise a TypeError for invalid item Scenario: Reject non-integer skeleton_budget Given context fragments with total tokens 1000 When I compress with a non-integer skeleton_budget Then the compressor should raise a TypeError for invalid budget type Scenario: Reject skeleton metadata with compressed exceeding original When I create skeleton metadata with compressed exceeding original Then a validation error should be raised for compressed exceeding original # --- skeleton_budget integration with plan model ----------------------- Scenario: Plan model accepts skeleton_metadata Given a skeleton metadata with ratio 0.5 and 1000 original tokens and 500 compressed When I attach skeleton_metadata to a plan Then the plan should expose skeleton metadata in cli dict # --- _validate_fragments edge-cases ------------------------------------ Scenario: Reject fragment with negative token_count Given a context fragment constructed with negative token_count When I validate the invalid fragments Then the compressor should raise a ValueError mentioning "token_count must be >= 0" Scenario: Reject fragment with out-of-range relevance_score Given a context fragment constructed with relevance_score 1.5 When I validate the invalid fragments Then the compressor should raise a ValueError mentioning "relevance_score must be in" Scenario: Reject fragment with empty fragment_id Given a context fragment constructed with empty fragment_id When I validate the invalid fragments Then the compressor should raise a ValueError mentioning "fragment_id must be non-empty" # --- structural subtype assertion ------------------------------------- Scenario: SkeletonCompressorService satisfies SkeletonCompressor protocol When I check that SkeletonCompressorService satisfies the SkeletonCompressor protocol Then the structural subtype assertion should pass