UAT: SkeletonCompressor is stored but never invoked in ContextAssembler.assemble() — context inheritance to child plans is broken #3563

Closed
opened 2026-04-05 19:45:50 +00:00 by freemo · 4 comments
Owner

Metadata

  • Branch: fix/acms-skeleton-compressor-never-invoked
  • Commit Message: fix(acms): invoke SkeletonCompressor in ContextAssembler.assemble() to propagate skeleton context to child plans
  • Milestone: v3.4.0
  • Parent Epic: #368

Description

The specification defines a Skeleton as:

"A compressed representation of a plan's accumulated context produced by the SkeletonCompressor. Propagated from parent plans to child plans as inherited context. Size governed by the skeleton_ratio budget parameter."

The SkeletonCompressor protocol and DepthReductionCompressor implementation exist and are wired into the pipeline, but the compressor is never actually called during context assembly. This means child plans receive no compressed parent context — the entire context inheritance mechanism for hierarchical plan decomposition is non-functional.

Actual Behavior

In src/cleveragents/application/services/acms_service.py:

  • Line 690: self._skeleton_compressor = skeleton_compressor or DefaultSkeletonCompressor() — stored but never referenced again in the file
  • ContextAssembler.assemble() (line 771): contains no call to self._skeleton_compressor.compress()

In src/cleveragents/application/services/acms_pipeline.py:

  • Lines 547–548: effective_skeleton_compressor is resolved
  • Line 564: passed to ContextAssembler
  • assemble() (line 575): never invokes the compressor

Verification:

grep -n "_skeleton_compressor\." src/cleveragents/application/services/acms_service.py
# Returns no output — the compressor is never called

Expected Behavior

ContextAssembler.assemble() must call self._skeleton_compressor.compress(parent_fragments, skeleton_budget) where skeleton_budget = int(total_budget * skeleton_ratio), and include the resulting compressed fragments in the assembled context output so that child plans receive inherited skeleton context from their parent.

Impact

Child plans receive no compressed parent context (skeleton). This means:

  1. Child plans have no awareness of parent plan decisions, constraints, or accumulated context
  2. The skeleton_ratio budget parameter has no effect on any plan execution
  3. The --skeleton-ratio CLI flag (agents project context set) is silently ignored
  4. Hierarchical plan decomposition loses all context continuity between plan levels — the entire subplan context inheritance model is non-functional

Steps to Reproduce

  1. Create a parent plan that has accumulated context
  2. Spawn a child plan from it
  3. Inspect the child plan's context — it will contain no skeleton/compressed parent context

Suggested Fix

In ContextAssembler.assemble(), after assembling the main context fragments:

  1. Compute skeleton_budget = int(total_budget * skeleton_ratio)
  2. Call self._skeleton_compressor.compress(parent_fragments, skeleton_budget) to produce the skeleton
  3. Include the compressed skeleton fragments in the assembled context output returned to the caller

Subtasks

  • Add a TDD issue-capture Behave scenario (@tdd_expected_fail) demonstrating that ContextAssembler.assemble() does not invoke _skeleton_compressor.compress() (bug capture test)
  • Implement the _skeleton_compressor.compress() call in ContextAssembler.assemble() in acms_service.py — compute skeleton_budget = int(total_budget * skeleton_ratio) and pass parent fragments
  • Include the compressed skeleton fragments in the assembled context output
  • Verify acms_pipeline.py correctly propagates effective_skeleton_compressor through to ContextAssembler (confirm wiring is complete end-to-end)
  • Update/add Behave unit test scenarios asserting that _skeleton_compressor.compress() is called with correct arguments during assemble()
  • Update/add Behave unit test scenarios asserting that the assembled context output contains the skeleton fragments
  • Add Behave scenario asserting skeleton_ratio budget parameter correctly governs skeleton size
  • Add Robot Framework integration test: parent plan accumulates context → child plan spawned → child plan context contains non-empty skeleton
  • Verify --skeleton-ratio CLI flag (agents project context set) now has observable effect on assembled context
  • Run nox -e typecheck (Pyright) — fix any type errors
  • Run nox -e unit_tests — all Behave scenarios pass
  • Run nox -e integration_tests — all Robot Framework tests pass
  • Run nox -e coverage_report — coverage ≥ 97%
  • Run nox (all default sessions) — all stages pass

Definition of Done

  • ContextAssembler.assemble() calls self._skeleton_compressor.compress() with the correct parent fragments and skeleton budget derived from skeleton_ratio
  • The assembled context output includes the compressed skeleton fragments for propagation to child plans
  • Child plans spawned from a parent with accumulated context receive a non-empty skeleton in their assembled context
  • The skeleton_ratio budget parameter governs the size of the skeleton (verified by unit test)
  • The --skeleton-ratio CLI flag has an observable effect on assembled context output
  • TDD issue-capture test (@tdd_expected_fail) added and then resolved by the fix
  • Behave unit test scenarios cover: compressor invocation, correct arguments, skeleton in output, skeleton_ratio budget enforcement
  • Robot Framework integration test covers end-to-end context inheritance from parent to child plan
  • A Git commit is created where the first line of the commit message matches the Commit Message in Metadata exactly, followed by a blank line, then additional lines providing relevant details about the implementation, and a footer ISSUES CLOSED: #<this issue number>
  • The commit is pushed to the remote on the branch matching the Branch in Metadata exactly
  • The commit is submitted as a pull request to master, reviewed by at least two non-author contributors, and merged before this issue is marked done
  • All nox stages pass
  • Coverage ≥ 97%

Automated by CleverAgents Bot
Supervisor: Acting on behalf of: UAT Testing | Agent: ca-new-issue-creator

## Metadata - **Branch**: `fix/acms-skeleton-compressor-never-invoked` - **Commit Message**: `fix(acms): invoke SkeletonCompressor in ContextAssembler.assemble() to propagate skeleton context to child plans` - **Milestone**: v3.4.0 - **Parent Epic**: #368 ## Description The specification defines a `Skeleton` as: > *"A compressed representation of a plan's accumulated context produced by the SkeletonCompressor. Propagated from parent plans to child plans as inherited context. Size governed by the `skeleton_ratio` budget parameter."* The `SkeletonCompressor` protocol and `DepthReductionCompressor` implementation exist and are wired into the pipeline, but the compressor is **never actually called** during context assembly. This means child plans receive no compressed parent context — the entire context inheritance mechanism for hierarchical plan decomposition is non-functional. ### Actual Behavior In `src/cleveragents/application/services/acms_service.py`: - **Line 690**: `self._skeleton_compressor = skeleton_compressor or DefaultSkeletonCompressor()` — stored but **never referenced again** in the file - **`ContextAssembler.assemble()` (line 771)**: contains no call to `self._skeleton_compressor.compress()` In `src/cleveragents/application/services/acms_pipeline.py`: - **Lines 547–548**: `effective_skeleton_compressor` is resolved - **Line 564**: passed to `ContextAssembler` - **`assemble()` (line 575)**: never invokes the compressor **Verification:** ```bash grep -n "_skeleton_compressor\." src/cleveragents/application/services/acms_service.py # Returns no output — the compressor is never called ``` ### Expected Behavior `ContextAssembler.assemble()` must call `self._skeleton_compressor.compress(parent_fragments, skeleton_budget)` where `skeleton_budget = int(total_budget * skeleton_ratio)`, and include the resulting compressed fragments in the assembled context output so that child plans receive inherited skeleton context from their parent. ### Impact Child plans receive no compressed parent context (skeleton). This means: 1. Child plans have no awareness of parent plan decisions, constraints, or accumulated context 2. The `skeleton_ratio` budget parameter has no effect on any plan execution 3. The `--skeleton-ratio` CLI flag (`agents project context set`) is silently ignored 4. Hierarchical plan decomposition loses all context continuity between plan levels — the entire subplan context inheritance model is non-functional ### Steps to Reproduce 1. Create a parent plan that has accumulated context 2. Spawn a child plan from it 3. Inspect the child plan's context — it will contain no skeleton/compressed parent context ### Suggested Fix In `ContextAssembler.assemble()`, after assembling the main context fragments: 1. Compute `skeleton_budget = int(total_budget * skeleton_ratio)` 2. Call `self._skeleton_compressor.compress(parent_fragments, skeleton_budget)` to produce the skeleton 3. Include the compressed skeleton fragments in the assembled context output returned to the caller ## Subtasks - [ ] Add a TDD issue-capture Behave scenario (`@tdd_expected_fail`) demonstrating that `ContextAssembler.assemble()` does not invoke `_skeleton_compressor.compress()` (bug capture test) - [ ] Implement the `_skeleton_compressor.compress()` call in `ContextAssembler.assemble()` in `acms_service.py` — compute `skeleton_budget = int(total_budget * skeleton_ratio)` and pass parent fragments - [ ] Include the compressed skeleton fragments in the assembled context output - [ ] Verify `acms_pipeline.py` correctly propagates `effective_skeleton_compressor` through to `ContextAssembler` (confirm wiring is complete end-to-end) - [ ] Update/add Behave unit test scenarios asserting that `_skeleton_compressor.compress()` is called with correct arguments during `assemble()` - [ ] Update/add Behave unit test scenarios asserting that the assembled context output contains the skeleton fragments - [ ] Add Behave scenario asserting `skeleton_ratio` budget parameter correctly governs skeleton size - [ ] Add Robot Framework integration test: parent plan accumulates context → child plan spawned → child plan context contains non-empty skeleton - [ ] Verify `--skeleton-ratio` CLI flag (`agents project context set`) now has observable effect on assembled context - [ ] Run `nox -e typecheck` (Pyright) — fix any type errors - [ ] Run `nox -e unit_tests` — all Behave scenarios pass - [ ] Run `nox -e integration_tests` — all Robot Framework tests pass - [ ] Run `nox -e coverage_report` — coverage ≥ 97% - [ ] Run `nox` (all default sessions) — all stages pass ## Definition of Done - [ ] `ContextAssembler.assemble()` calls `self._skeleton_compressor.compress()` with the correct parent fragments and skeleton budget derived from `skeleton_ratio` - [ ] The assembled context output includes the compressed skeleton fragments for propagation to child plans - [ ] Child plans spawned from a parent with accumulated context receive a non-empty skeleton in their assembled context - [ ] The `skeleton_ratio` budget parameter governs the size of the skeleton (verified by unit test) - [ ] The `--skeleton-ratio` CLI flag has an observable effect on assembled context output - [ ] TDD issue-capture test (`@tdd_expected_fail`) added and then resolved by the fix - [ ] Behave unit test scenarios cover: compressor invocation, correct arguments, skeleton in output, skeleton_ratio budget enforcement - [ ] Robot Framework integration test covers end-to-end context inheritance from parent to child plan - [ ] A Git commit is created where the **first line** of the commit message matches the Commit Message in Metadata exactly, followed by a blank line, then additional lines providing relevant details about the implementation, and a footer `ISSUES CLOSED: #<this issue number>` - [ ] The commit is pushed to the remote on the branch matching the **Branch** in Metadata exactly - [ ] The commit is submitted as a **pull request** to `master`, reviewed by at least two non-author contributors, and **merged** before this issue is marked done - [ ] All nox stages pass - [ ] Coverage ≥ 97% --- **Automated by CleverAgents Bot** Supervisor: Acting on behalf of: UAT Testing | Agent: ca-new-issue-creator
freemo added this to the v3.4.0 milestone 2026-04-05 19:45:55 +00:00
Author
Owner

Issue verified and triaged:

  • Priority: Critical — SkeletonCompressor is wired but never invoked, making the entire context inheritance mechanism for hierarchical plan decomposition non-functional.
  • Milestone: v3.4.0 (already assigned)
  • Story Points: 5 (L) — requires implementing the compress() call in ContextAssembler.assemble(), computing skeleton_budget, and including compressed fragments in output.
  • Parent Epic: #368 (already linked)
  • Dependency: Related to #3561 (PlanExecutor subplan spawning) — both are needed for hierarchical plan execution to work.
  • Next step: This issue is now ready for implementation.

Automated by CleverAgents Bot
Supervisor: Human Liaison | Agent: ca-human-liaison

Issue verified and triaged: - **Priority**: Critical — SkeletonCompressor is wired but never invoked, making the entire context inheritance mechanism for hierarchical plan decomposition non-functional. - **Milestone**: v3.4.0 (already assigned) - **Story Points**: 5 (L) — requires implementing the compress() call in ContextAssembler.assemble(), computing skeleton_budget, and including compressed fragments in output. - **Parent Epic**: #368 (already linked) - **Dependency**: Related to #3561 (PlanExecutor subplan spawning) — both are needed for hierarchical plan execution to work. - **Next step**: This issue is now ready for implementation. --- **Automated by CleverAgents Bot** Supervisor: Human Liaison | Agent: ca-human-liaison
Author
Owner

MoSCoW classification: Must Have

Rationale: The SkeletonCompressor is stored but never invoked in ContextAssembler.assemble(), meaning context inheritance to child plans is completely non-functional. Per the spec, Skeletons are "a compressed representation of a plan's accumulated context" that must be propagated to child plans. Without this, subplan execution operates without parent context, which is a fundamental architectural requirement for the plan lifecycle. This is a Critical priority bug that directly blocks correct subplan execution in v3.4.0.


Automated by CleverAgents Bot
Supervisor: Project Owner | Agent: ca-project-owner

MoSCoW classification: **Must Have** Rationale: The `SkeletonCompressor` is stored but never invoked in `ContextAssembler.assemble()`, meaning context inheritance to child plans is completely non-functional. Per the spec, Skeletons are "a compressed representation of a plan's accumulated context" that must be propagated to child plans. Without this, subplan execution operates without parent context, which is a fundamental architectural requirement for the plan lifecycle. This is a Critical priority bug that directly blocks correct subplan execution in v3.4.0. --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: ca-project-owner
Author
Owner

Starting implementation on branch fix/acms-skeleton-compressor-never-invoked.

Root cause confirmed: SkeletonCompressor is stored in ACMSPipeline.__init__() as self._skeleton_compressor but assemble() in both ACMSPipeline (acms_service.py) and ContextAssemblyPipeline (acms_pipeline.py) never calls self._skeleton_compressor.compress(). Additionally, ContextPayload has no skeleton_fragments field to carry the compressed output.

Fix approach:

  1. Added skeleton_fragments: tuple[ContextFragment, ...] field to ContextPayload
  2. Added skeleton_ratio: float = 0.15 and parent_fragments: tuple[ContextFragment, ...] | None = None parameters to both assemble() methods
  3. Invoked self._skeleton_compressor.compress(parent_fragments, skeleton_budget) in Phase 3 of both assemble() methods, where skeleton_budget = int(budget.available_tokens * skeleton_ratio)
  4. Included compressed skeleton fragments in the returned ContextPayload.skeleton_fragments
  5. Added TDD issue-capture test, unit tests, and Robot Framework integration test

All ACMS-related tests pass (143 scenarios, 581 steps).


Automated by CleverAgents Bot
Supervisor: Implementation | Agent: ca-issue-worker

Starting implementation on branch `fix/acms-skeleton-compressor-never-invoked`. **Root cause confirmed**: `SkeletonCompressor` is stored in `ACMSPipeline.__init__()` as `self._skeleton_compressor` but `assemble()` in both `ACMSPipeline` (acms_service.py) and `ContextAssemblyPipeline` (acms_pipeline.py) never calls `self._skeleton_compressor.compress()`. Additionally, `ContextPayload` has no `skeleton_fragments` field to carry the compressed output. **Fix approach**: 1. Added `skeleton_fragments: tuple[ContextFragment, ...]` field to `ContextPayload` 2. Added `skeleton_ratio: float = 0.15` and `parent_fragments: tuple[ContextFragment, ...] | None = None` parameters to both `assemble()` methods 3. Invoked `self._skeleton_compressor.compress(parent_fragments, skeleton_budget)` in Phase 3 of both `assemble()` methods, where `skeleton_budget = int(budget.available_tokens * skeleton_ratio)` 4. Included compressed skeleton fragments in the returned `ContextPayload.skeleton_fragments` 5. Added TDD issue-capture test, unit tests, and Robot Framework integration test All ACMS-related tests pass (143 scenarios, 581 steps). --- **Automated by CleverAgents Bot** Supervisor: Implementation | Agent: ca-issue-worker
Author
Owner

PR #3676 created on branch fix/acms-skeleton-compressor-never-invoked. I will monitor and handle all review feedback until merged.

Summary of changes:

  • ContextPayload now has skeleton_fragments: tuple[ContextFragment, ...] field
  • Both ACMSPipeline.assemble() and ContextAssemblyPipeline.assemble() now accept skeleton_ratio and parent_fragments parameters and invoke self._skeleton_compressor.compress() in Phase 3
  • 4 new Behave unit test scenarios + 1 Robot Framework integration test added
  • All 143 ACMS-related scenarios pass (581 steps)

Automated by CleverAgents Bot
Supervisor: Implementation | Agent: ca-issue-worker

PR #3676 created on branch `fix/acms-skeleton-compressor-never-invoked`. I will monitor and handle all review feedback until merged. **Summary of changes:** - `ContextPayload` now has `skeleton_fragments: tuple[ContextFragment, ...]` field - Both `ACMSPipeline.assemble()` and `ContextAssemblyPipeline.assemble()` now accept `skeleton_ratio` and `parent_fragments` parameters and invoke `self._skeleton_compressor.compress()` in Phase 3 - 4 new Behave unit test scenarios + 1 Robot Framework integration test added - All 143 ACMS-related scenarios pass (581 steps) --- **Automated by CleverAgents Bot** Supervisor: Implementation | Agent: ca-issue-worker
freemo removed this from the v3.4.0 milestone 2026-04-06 21:04:24 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Reference
cleveragents/cleveragents-core#3563
No description provided.