Skip to content

feat(compression): type-aware compression module + retrieve_v2 integration (#434) - #493

Merged
robotrocketscience merged 4 commits into
mainfrom
feat/issue-434-type-aware-compression
May 8, 2026
Merged

feat(compression): type-aware compression module + retrieve_v2 integration (#434)#493
robotrocketscience merged 4 commits into
mainfrom
feat/issue-434-type-aware-compression

Conversation

@robotrocketscience

@robotrocketscience robotrocketscience commented May 8, 2026

Copy link
Copy Markdown
Owner

Closes-progress on #434 (type-aware compression). Lands the mechanically-correct, default-OFF form of the feature per the spec's bench-gate / ship-or-defer policy (docs/feature-type-aware-compression.md § "Bench-gate / ship-or-defer policy").

What landed

1. src/aelfrice/compression.py (commit 1)

Pure, deterministic compress_for_retrieval(belief, *, locked) → CompressedBelief. Strategy table per spec:

Retention class Locked Unlocked
fact verbatim verbatim
snapshot verbatim headline
transient verbatim stub
unknown verbatim verbatim
  • Headline: first sentence on . / .\n boundary, with . Code-fence-aware (does not split inside ``` blocks). Content that is wholly a single code fence renders verbatim (impl-PR resolution of spec open-question 3). Hard-truncates at last whitespace ≤ MAX_HEADLINE_CHARS=240 if no boundary found.
  • Stub: [stub: belief={id} class=transient] — falls back to verbatim when the marker would cost more than the source content.
  • 18 unit tests cover the strategy table, headline edge cases, locked-override rule, token-monotone-non-increasing invariant (corpus-level recheck), and deterministic re-evaluation.

2. retrieve_v2() integration (commit 2)

  • New flag use_type_aware_compression with the established 4-stage precedence (env > kwarg > TOML > default-OFF). Env var: AELFRICE_TYPE_AWARE_COMPRESSION.
  • RetrievalResult gains a parallel compressed_beliefs: list[CompressedBelief] field. Same length and order as beliefs when the flag resolves True; empty when OFF — preserves byte-identical v1.x adapter behavior.
  • 10 integration tests cover flag-precedence resolution and the parallel-field invariant on a mixed-class fixture.
  • Out of scope: the budget-accounting pack-loop rewrite that turns this parallel field into measurable recall@k uplift (A2). That requires a follow-up PR plus the lab-side bench evidence.

3. tests/bench_gate/test_compression_uplift.py (commit 3)

Lab-mounted bench gate. Skips on public CI (autouse bench_gated marker). When AELFRICE_CORPUS_ROOT points at a populated compression_uplift/ directory, asserts the upstream invariant A2 depends on: compressed total tokens < uncompressed total tokens. The strict A2 recall@k comparison waits on the budget rewrite.

4. docs/CONFIG.md (commit 4)

Adds use_type_aware_compression to the [retrieval] section header, the .aelfrice.toml example, and a dedicated Keys subsection with the strategy table.

Acceptance status

  • A1 (corpus): lab-side. tests/corpus/v2_0/compression_uplift/ row schema documented in the gate's module docstring.
  • A2 (token-budget recovery): deferred — requires the pack-loop budget rewrite that consumes compressed_beliefs[*].rendered_tokens. Bench-gate harness exists for the precondition; full A2 measurement is the follow-up.
  • A3 (determinism): covered by test_compression.py::test_compress_is_deterministic and the test_token_monotone_non_increasing property test (16 inputs × 4 retention classes × 2 lock states).
  • A4 (rebuilder fidelity): deferred — same dependency chain as A2 (rebuilder consumes the post-pack output; needs the budget rewrite).
  • A5 (composition tracker doc row): deferreddocs/RETRIEVAL_COMPOSITION.md does not exist yet (per [v2.0] HRR vocabulary bridge — close vocabulary-gap-recovery claim #433's spec note: "or wherever the [retrieval] Pipeline composition tracker — unified retrieve() with feature-flag gate #154 tracker doc lands by ship-time"). When the tracker doc lands, a one-line row for use_type_aware_compression should be added.

Test plan

  • uv run pytest tests/test_compression.py — 18 passed
  • uv run pytest tests/test_compression_integration.py — 10 passed
  • uv run pytest tests/bench_gate/test_compression_uplift.py — skipped (public CI; corpus absent)
  • uv run pytest tests/ — 2864 passed, 40 skipped, no regressions vs main
  • AELFRICE_CORPUS_ROOT=~/projects/aelfrice-lab/tests/corpus/v2_0 uv run pytest tests/bench_gate/test_compression_uplift.py — operator/lab-side; ratifies A2 precondition

Follow-up issues

Refs #434, #154 (composition tracker), #437 (canonical bench harness).

Summary by Sourcery

Add a type-aware compression module and integrate it with retrieve_v2 behind a configurable, default-off flag.

New Features:

  • Introduce a deterministic type-aware compression system for beliefs with strategies based on retention class and lock status.
  • Expose compressed belief renderings via a new compressed_beliefs field on RetrievalResult, populated when type-aware compression is enabled.
  • Add a configurable use_type_aware_compression flag with environment, kwarg, and TOML precedence for retrieval.

Enhancements:

  • Document the new type-aware compression configuration knob and behavior in CONFIG.md, including retention-class strategy details.

Tests:

  • Add unit tests for compression strategies, headline behavior, determinism, and token-cost invariants.
  • Add integration tests covering retrieve_v2 compression integration and flag-precedence resolution.
  • Introduce a bench-gated compression uplift test that validates corpus-level token reduction when compression is enabled.

Summary by CodeRabbit

  • New Features

    • Added optional type-aware compression for retrieval results, configurable via TOML, environment variable, or function parameter.
    • Compression strategies vary by belief type: facts and unknowns render in full; snapshots compress to headlines; transient beliefs compress to stubs.
  • Documentation

    • Extended configuration documentation with compression feature details, including default behavior and precedence rules.

Adds src/aelfrice/compression.py with the spec-pinned strategy table:
fact + unknown render verbatim, snapshot → headline (when not locked),
transient → stub (when not locked), locks always render verbatim.

Headline extraction splits on the first '. ' or '.\n' outside a balanced
``` fence; falls back to whitespace-aligned hard truncation at
MAX_HEADLINE_CHARS (240). Content that is wholly a single code fence
renders verbatim (impl-PR resolution of spec open-question 3). Stub
falls back to verbatim when the marker would cost more than the source.

Pure deterministic — no store, clock, env, or random reads. Token
estimator duplicated from retrieval._estimate_tokens to avoid a
circular import (retrieval will consume this module in a follow-up).

18 unit tests cover the strategy table, headline edge cases (short
content, no boundary, code-fence-only, in-fence period), the
locked-override rule, the token-monotone-non-increasing invariant, and
deterministic re-evaluation.
Adds the use_type_aware_compression flag with the established 4-stage
precedence (env > kwarg > TOML > default-OFF) and the
`AELFRICE_TYPE_AWARE_COMPRESSION` env override. Default-OFF preserves
byte-identical v1.x adapter behavior at v2.0.0; the bench gate
(A2 + A4 in docs/feature-type-aware-compression.md) flips the default
after lab-side benchmark evidence clears.

RetrievalResult gains a parallel `compressed_beliefs` field
(list[CompressedBelief]). Same length and order as `beliefs` when the
flag resolves True; empty list when OFF. Consumers that want raw
beliefs keep reading `.beliefs`; consumers that want the
type-aware-compressed render read `.compressed_beliefs[i].rendered`.

Locked-state classification: `belief.lock_level == LOCK_USER`. This
mirrors the L0-never-trimmed rule the rest of retrieval already
applies (retrieval.py:950). Compression is applied after the existing
pack and the optional temporal_sort pass.

This commit does not rewrite the budget-accounting pack loops — the
parallel-field shape is the minimum viable change called out in the
spec at the "RetrievalResult shape" section. The actual recall@k
uplift gated by A2 requires the budget rewrite plus the lab corpus
bench cut; both are follow-up work.

10 integration tests cover flag precedence (default OFF, kwarg
override, env override, env-garbage fall-through, TOML resolution),
the parallel-field invariant (same length / order as beliefs), and
the strategy-dispatch path through retrieve_v2 (fact verbatim,
snapshot headline, transient stub, locked verbatim). Full suite:
2840 passed, 22 skipped, no regressions.
Adds the lab-mounted bench gate for #434. Skips on public CI (autouse
`bench_gated` marker) and skips again when the
`tests/corpus/v2_0/compression_uplift/` directory is empty.

Measures the upstream invariant A2 depends on: on a mixed-retention-class
corpus, compressed total tokens must be strictly less than uncompressed
total tokens. If compression doesn't reduce cost on the lab corpus, no
pack-loop rewrite can deliver A2's recall@k uplift no matter how it is
wired.

A2's strict recall@k comparison requires the budget-rewrite follow-up
that consumes `compressed_beliefs[*].rendered_tokens` in the pack
loops. This gate is the precursor measurement.

Row schema documented in the module docstring. Mirrors the corpus
contract for #197 (dedup) and other bench-gated modules.
Adds the v2.1 type-aware-compression flag to the [retrieval] section
header, the .aelfrice.toml example, and the dedicated Keys subsection.
Mirrors the documentation pattern established for use_bm25f_anchors
and use_hrr_structural.

Includes the strategy table for operator reference (fact/snapshot/
transient/unknown × locked/unlocked) and the precedence chain for the
flag (env > kwarg > TOML > default-OFF). Notes that the default-on
flip is gated on both the lab-side compression_uplift bench and the
pack-loop budget rewrite that turns the parallel-field shape into
recall@k uplift.
@sourcery-ai

sourcery-ai Bot commented May 8, 2026

Copy link
Copy Markdown

Reviewer's Guide

Implements a deterministic, type-aware belief compression module and wires it into retrieve_v2 behind a default-OFF, multi-source flag, adding tests, a bench gate, and configuration docs while preserving existing RetrievalResult behavior when the feature is disabled.

Sequence diagram for retrieve_v2 with type-aware compression flag

sequenceDiagram
    actor Caller
    participant Retrieval as retrieve_v2
    participant Env as _env_type_aware_compression_override
    participant Config as _read_toml_flag_for
    participant Compress as compress_for_retrieval
    participant Result as RetrievalResult

    Caller->>Retrieval: retrieve_v2(query, ..., use_type_aware_compression)
    activate Retrieval

    note over Retrieval: Resolve use_type_aware_compression
    Retrieval->>Env: _env_type_aware_compression_override()
    activate Env
    Env-->>Retrieval: env_value or None
    deactivate Env

    alt env_value is not None
        Retrieval-->>Retrieval: flag = env_value
    else env_value is None
        alt explicit kwarg is not None
            Retrieval-->>Retrieval: flag = explicit
        else explicit is None
            Retrieval->>Config: _read_toml_flag_for(TYPE_AWARE_COMPRESSION_FLAG, start)
            activate Config
            Config-->>Retrieval: toml_value or None
            deactivate Config
            alt toml_value is not None
                Retrieval-->>Retrieval: flag = toml_value
            else no decisive source
                Retrieval-->>Retrieval: flag = False
            end
        end
    end

    note over Retrieval: run retrieval pipeline to produce beliefs
    Retrieval-->>Retrieval: beliefs = [...]

    alt flag is True
        loop for each belief in beliefs
            Retrieval->>Compress: compress_for_retrieval(belief, locked=(belief.lock_level == LOCK_USER))
            activate Compress
            Compress-->>Retrieval: CompressedBelief
            deactivate Compress
        end
        Retrieval-->>Result: construct RetrievalResult(beliefs, compressed_beliefs=[...], ...)
    else flag is False
        Retrieval-->>Result: construct RetrievalResult(beliefs, compressed_beliefs=[], ...)
    end

    Result-->>Caller: RetrievalResult
    deactivate Retrieval
Loading

Class diagram for type-aware compression and RetrievalResult integration

classDiagram
    class Belief {
        +str id
        +str retention_class
        +str content
        +str lock_level
    }

    class CompressedBelief {
        +Belief belief
        +str rendered
        +int rendered_tokens
        +str strategy
    }

    class RetrievalResult {
        +list~Belief~ beliefs
        +list~CompressedBelief~ compressed_beliefs
        +list~str~ entity_hits
        +list~str~ locked_ids
        +list~str~ l1_ids
        +list bfs_chains
    }

    class compression_module {
        +CompressedBelief compress_for_retrieval(belief, locked)
        +int _estimate_tokens(text)
        +str _headline(content)
        +str _stub(belief)
    }

    class retrieval_module {
        +RetrievalResult retrieve_v2(query, bm25f_cache, temporal_sort, temporal_half_life_seconds, use_type_aware_compression)
        +bool resolve_use_type_aware_compression(explicit, start)
        +bool _env_type_aware_compression_override()
        +bool _read_toml_flag_for(key, start)
    }

    Belief "1" <-- "1" CompressedBelief : wraps
    RetrievalResult "*" o-- "*" Belief : beliefs
    RetrievalResult "*" o-- "*" CompressedBelief : compressed_beliefs

    compression_module ..> Belief : uses
    retrieval_module ..> Belief : uses
    retrieval_module ..> CompressedBelief : populates
    retrieval_module ..> compression_module : calls
Loading

Flow diagram for resolving use_type_aware_compression flag

flowchart TD
    Start([Start resolve_use_type_aware_compression])
    Env["Read env AELFRICE_TYPE_AWARE_COMPRESSION"]
    EnvDec{Env value<br/>truthy/falsy?}
    ExplicitDec{explicit kwarg<br/>is not None?}
    Toml["Read TOML [retrieval] use_type_aware_compression"]
    TomlDec{TOML value<br/>is not None?}
    EnvTrue[Set flag = True]
    EnvFalse[Set flag = False]
    UseExplicit[Set flag = explicit]
    UseToml[Set flag = TOML value]
    UseDefault[Set flag = False<br/>default OFF]
    End([Return flag])

    Start --> Env
    Env --> EnvDec
    EnvDec -- Yes, truthy --> EnvTrue --> End
    EnvDec -- Yes, falsy --> EnvFalse --> End
    EnvDec -- No, unset/invalid --> ExplicitDec

    ExplicitDec -- Yes --> UseExplicit --> End
    ExplicitDec -- No --> Toml

    Toml --> TomlDec
    TomlDec -- Yes --> UseToml --> End
    TomlDec -- No --> UseDefault --> End
Loading

File-Level Changes

Change Details Files
Introduce a pure, deterministic type-aware compression module that produces per-belief compressed renderings with token-cost monotonicity guarantees.
  • Add CompressedBelief dataclass capturing original belief, rendered string, token estimate, and strategy tag.
  • Implement lightweight token estimator and helpers to detect single code-fence content and find first sentence boundary outside fenced blocks.
  • Implement headline extraction that respects code fences, prefers sentence boundaries, and hard-truncates with an ellipsis when needed while never increasing token cost over the source.
  • Implement transient stubs keyed by belief id and ensure stubbing never expands token cost, falling back to verbatim when it would.
  • Implement compress_for_retrieval dispatcher over (retention_class, locked) with a locked-override rule and safe fallback to verbatim for unknown classes.
src/aelfrice/compression.py
Integrate type-aware compression into retrieve_v2 via a new flag and parallel compressed_beliefs field while maintaining backward-compatible defaults and flag precedence.
  • Define TYPE_AWARE_COMPRESSION_FLAG and ENV_TYPE_AWARE_COMPRESSION constants for TOML and env configuration.
  • Add _env_type_aware_compression_override and resolve_use_type_aware_compression with precedence env > explicit kwarg > TOML > default False.
  • Extend RetrievalResult with compressed_beliefs parallel to beliefs, defaulting to an empty list to preserve v1.x adapters when compression is off.
  • Update retrieve_v2 signature to accept use_type_aware_compression and populate compressed_beliefs by calling compress_for_retrieval per belief when the resolved flag is True.
src/aelfrice/retrieval.py
Document and expose the new retrieval flag in configuration docs, including behavior, precedence, and strategy table.
  • Extend the [retrieval] CONFIG.md overview list with use_type_aware_compression and a short behavior description.
  • Add use_type_aware_compression key to the example .aelfrice.toml with comments explaining the feature and env override.
  • Add a dedicated CONFIG.md subsection detailing the strategy table, deterministic behavior, parallel-field semantics, and flag precedence.
docs/CONFIG.md
Add unit and integration tests validating compression behavior, flag resolution, retrieve_v2 integration, and backward compatibility.
  • Create tests/test_compression.py to cover the strategy table, headline edge cases (including code fences and truncation), the locked-override rule, token-monotone-non-increasing invariant, determinism, totality, unknown-class fallback, and stub format and cost behavior.
  • Create tests/test_compression_integration.py to test flag precedence (env, kwarg, TOML, default), compressed_beliefs population and ordering in retrieve_v2, strategy dispatch by retention class and lock state, and that the default call leaves compressed_beliefs empty.
tests/test_compression.py
tests/test_compression_integration.py
Add a bench-gated corpus-level test that ensures type-aware compression reduces total token cost by a minimum amount on a lab corpus before flipping defaults or using it for budget accounting.
  • Introduce tests/bench_gate/test_compression_uplift.py that loads a lab corpus, reconstructs Belief objects, and aggregates uncompressed vs compressed token totals using compress_for_retrieval.
  • Assert corpus-level monotone non-increase, require strict reduction with a minimum 1% savings threshold, and skip when the corpus is empty or contains only verbatim cases, integrating with the existing bench_gated marker and AELFRICE_CORPUS_ROOT mechanism.
tests/bench_gate/test_compression_uplift.py

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@robotrocketscience robotrocketscience added author-Setr PR coordination mutex attn:review Needs review (PR open, awaiting reviewer) labels May 8, 2026
@coderabbitai

coderabbitai Bot commented May 8, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR implements a complete type-aware belief compression feature for the aelfrice retrieval system. It introduces a new compression.py module with CompressedBelief and compress_for_retrieval, integrates conditional compression into the retrieve_v2 API with configurable flag resolution (env/kwarg/TOML precedence), documents the feature in CONFIG.md, and provides comprehensive unit, integration, and benchmark-gated test coverage.

Changes

Type-Aware Compression Feature

Layer / File(s) Summary
Data Contracts and Strategy Constants
src/aelfrice/compression.py, src/aelfrice/retrieval.py
New CompressedBelief dataclass pairs each belief with its rendered string, token cost, and strategy label. Constants define STRATEGY_VERBATIM, STRATEGY_HEADLINE, STRATEGY_STUB, TYPE_AWARE_COMPRESSION_FLAG, and ENV_TYPE_AWARE_COMPRESSION.
Compression Core Logic
src/aelfrice/compression.py
compress_for_retrieval(belief, locked) implements retention-class dispatch: fact and unknown render verbatim; snapshot renders as headline when unlocked and token-beneficial; transient renders as stub when unlocked and token-beneficial. Token estimation, headline extraction (with code-fence awareness), and stub formatting are included.
Retrieval API Integration
src/aelfrice/retrieval.py
resolve_use_type_aware_compression() implements env > kwarg > TOML > default precedence. retrieve_v2() gains use_type_aware_compression kwarg; when enabled, computes RetrievalResult.compressed_beliefs by applying compress_for_retrieval to each surfaced belief (passing locked status).
Configuration Documentation
docs/CONFIG.md
Adds use_type_aware_compression flag documentation (opt-in, v2.1+): default OFF, env var override, retention-class → output mapping, and precedence rules.
Unit Tests: Compression Strategies
tests/test_compression.py
Tests strategy selection (fact/unknown always verbatim; snapshot headline when unlocked; transient stub when unlocked). Validates headline edge cases (code fence handling, newline/period splitting, truncation), token monotonicity, determinism, and unknown class fallback.
Integration Tests: Flag Resolution and retrieve_v2
tests/test_compression_integration.py
Verifies flag resolver precedence across default/kwarg/env/TOML, ensures compressed_beliefs is empty when disabled and populated when enabled with correct strategy dispatch, confirms locked beliefs force verbatim, and validates env-var-only enabling.
Benchmark Test: Corpus-Wide Effectiveness
tests/bench_gate/test_compression_uplift.py
Bench-gated test loads JSONL corpus, compares uncompressed vs compressed token totals, asserts monotonic non-increase, skips if no compression occurs, and enforces ≥1% reduction on mixed-retention-class corpus.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

  • robotrocketscience/aelfrice#434: This PR directly implements the type-aware compression feature (compress_for_retrieval, CompressedBelief, strategy dispatch, config wiring) requested in the issue.

Possibly related PRs

  • robotrocketscience/aelfrice#450: This PR implements the type-aware compression spec from PR #450 (adds compress_for_retrieval, CompressedBelief, strategies, and config wiring).
  • robotrocketscience/aelfrice#320: The new bench-gated compression test relies on the bench-gate harness (pytest marker, corpus-root fixture, autouse skip behavior) introduced in PR #320.

Suggested labels

docs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 22.92% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: adding a type-aware compression module and integrating it with retrieve_v2, matching the changeset's primary objectives.
Description check ✅ Passed The description is comprehensive, covering summary, linked issues, type of change (feat), verification steps, test plan, and notes for reviewer, aligning well with the template structure.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/issue-434-type-aware-compression

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 2 issues, and left some high level feedback:

  • The token estimator constants and logic (_CHARS_PER_TOKEN, _estimate_tokens) are duplicated between retrieval.py and compression.py; consider centralising them in a small shared module to avoid silent drift if you ever tune the heuristic.
  • For ENV_TYPE_AWARE_COMPRESSION, garbage values currently fail open and silently fall through; you might want to log or warn on unrecognised values so misconfigured environments are easier to diagnose.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The token estimator constants and logic (`_CHARS_PER_TOKEN`, `_estimate_tokens`) are duplicated between `retrieval.py` and `compression.py`; consider centralising them in a small shared module to avoid silent drift if you ever tune the heuristic.
- For `ENV_TYPE_AWARE_COMPRESSION`, garbage values currently fail open and silently fall through; you might want to log or warn on unrecognised values so misconfigured environments are easier to diagnose.

## Individual Comments

### Comment 1
<location path="src/aelfrice/compression.py" line_range="49-58" />
<code_context>
+
+
+@dataclass(frozen=True)
+class CompressedBelief:
+    """A `Belief` plus its packed-render form.
+
+    `rendered_tokens` is monotone-non-increasing in `_estimate_tokens(belief.content)`:
+    the compressor never produces a render that costs more than the source.
+    """
+
+    belief: Belief
+    rendered: str
+    rendered_tokens: int
+    strategy: str
+
+
</code_context>
<issue_to_address>
**suggestion:** Tighten `strategy` typing to avoid misuse and ease refactors.

`strategy` only permits three values (`STRATEGY_VERBATIM`, `STRATEGY_HEADLINE`, `STRATEGY_STUB`) but is typed as `str`. Using a `Literal[...]` or small `Enum` would prevent invalid values and give stronger type-checker/editor support as more strategies are added.

Suggested implementation:

```python
StrategyName = Literal["verbatim", "headline", "stub"]


@dataclass(frozen=True)
class CompressedBelief:
    """A `Belief` plus its packed-render form.

    `rendered_tokens` is monotone-non-increasing in `_estimate_tokens(belief.content)`:
    the compressor never produces a render that costs more than the source.
    """

    belief: Belief
    rendered: str
    rendered_tokens: int
    strategy: StrategyName

```

1. Ensure `Literal` is imported from `typing`. For example, if you currently have `from typing import Final`, update it to `from typing import Final, Literal`. If the import line differs, adjust accordingly.
2. If there are other places in this file (or callers) that construct `CompressedBelief` with `strategy` values, verify they only use `"verbatim"`, `"headline"`, or `"stub"` (or the corresponding constants `STRATEGY_VERBATIM`, `STRATEGY_HEADLINE`, `STRATEGY_STUB` whose values must be these strings) to keep mypy and other type-checkers happy.
</issue_to_address>

### Comment 2
<location path="tests/test_compression.py" line_range="90" />
<code_context>
+    assert cb.rendered == b.content
+
+
+def test_snapshot_unlocked_takes_headline() -> None:
+    content = (
+        "the first sentence is the headline. "
+        "the second sentence and rest of body should be dropped. "
+        "and a third sentence."
+    )
+    b = _mk(content, retention_class=RETENTION_SNAPSHOT)
+    cb = compress_for_retrieval(b, locked=False)
+    assert cb.strategy == STRATEGY_HEADLINE
+    assert cb.rendered.startswith("the first sentence is the headline")
+    assert cb.rendered.endswith("…")
+    assert cb.rendered_tokens < _estimate_tokens(content)
+
+
</code_context>
<issue_to_address>
**suggestion (testing):** Add a test that snapshot headline with a terminal period but no trailing body does not get an ellipsis appended

The `_headline` branch that returns the prefix without an ellipsis when `sentence_end >= len(content)` isn’t covered. Please add a test for a snapshot where the headline is a complete single sentence with a trailing period and no further text (e.g. `"single sentence only."`), and assert `cb.rendered == content` so this behavior is locked in and protected against regressions in the splitting logic.

```suggestion
    assert cb.rendered_tokens < _estimate_tokens(content)


def test_snapshot_headline_single_sentence_no_ellipsis() -> None:
    content = "single sentence only."
    b = _mk(content, retention_class=RETENTION_SNAPSHOT)
    cb = compress_for_retrieval(b, locked=False)
    assert cb.strategy == STRATEGY_HEADLINE
    assert cb.rendered == content
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +49 to +58
class CompressedBelief:
"""A `Belief` plus its packed-render form.

`rendered_tokens` is monotone-non-increasing in `_estimate_tokens(belief.content)`:
the compressor never produces a render that costs more than the source.
"""

belief: Belief
rendered: str
rendered_tokens: int

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Tighten strategy typing to avoid misuse and ease refactors.

strategy only permits three values (STRATEGY_VERBATIM, STRATEGY_HEADLINE, STRATEGY_STUB) but is typed as str. Using a Literal[...] or small Enum would prevent invalid values and give stronger type-checker/editor support as more strategies are added.

Suggested implementation:

StrategyName = Literal["verbatim", "headline", "stub"]


@dataclass(frozen=True)
class CompressedBelief:
    """A `Belief` plus its packed-render form.

    `rendered_tokens` is monotone-non-increasing in `_estimate_tokens(belief.content)`:
    the compressor never produces a render that costs more than the source.
    """

    belief: Belief
    rendered: str
    rendered_tokens: int
    strategy: StrategyName
  1. Ensure Literal is imported from typing. For example, if you currently have from typing import Final, update it to from typing import Final, Literal. If the import line differs, adjust accordingly.
  2. If there are other places in this file (or callers) that construct CompressedBelief with strategy values, verify they only use "verbatim", "headline", or "stub" (or the corresponding constants STRATEGY_VERBATIM, STRATEGY_HEADLINE, STRATEGY_STUB whose values must be these strings) to keep mypy and other type-checkers happy.

Comment thread tests/test_compression.py
assert cb.strategy == STRATEGY_HEADLINE
assert cb.rendered.startswith("the first sentence is the headline")
assert cb.rendered.endswith("…")
assert cb.rendered_tokens < _estimate_tokens(content)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (testing): Add a test that snapshot headline with a terminal period but no trailing body does not get an ellipsis appended

The _headline branch that returns the prefix without an ellipsis when sentence_end >= len(content) isn’t covered. Please add a test for a snapshot where the headline is a complete single sentence with a trailing period and no further text (e.g. "single sentence only."), and assert cb.rendered == content so this behavior is locked in and protected against regressions in the splitting logic.

Suggested change
assert cb.rendered_tokens < _estimate_tokens(content)
assert cb.rendered_tokens < _estimate_tokens(content)
def test_snapshot_headline_single_sentence_no_ellipsis() -> None:
content = "single sentence only."
b = _mk(content, retention_class=RETENTION_SNAPSHOT)
cb = compress_for_retrieval(b, locked=False)
assert cb.strategy == STRATEGY_HEADLINE
assert cb.rendered == content

@robotrocketscience

Copy link
Copy Markdown
Owner Author

[claim:review:Gylf:2026-05-08T18:36:48Z]

@robotrocketscience

Copy link
Copy Markdown
Owner Author

[claim:review:Toug:2026-05-08T18:36:56Z]

@robotrocketscience

Copy link
Copy Markdown
Owner Author

[release:review:Toug:2026-05-08T18:37:01Z]

Comment thread tests/test_compression.py
"""
from __future__ import annotations

import pytest
"""
from __future__ import annotations

import os

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/aelfrice/retrieval.py (1)

1451-1451: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fix merge-blocking deadcode on use_hrr.

use_hrr is intentionally forward-compat, but currently unused and is tripping vulture in CI.

Proposed minimal fix
 def retrieve_v2(
@@
 ) -> RetrievalResult:
@@
+    _ = use_hrr  # reserved for forward-compat; keeps deadcode checks green
     (
         out,
         locked_ids_list,
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/aelfrice/retrieval.py` at line 1451, The parameter use_hrr is declared
but unused and causing CI deadcode warnings; mark it as used without changing
behavior by adding a no-op reference (for example, add a single line like "_ =
use_hrr" or "del use_hrr  # forward-compat" at the top of the function that
contains the use_hrr parameter) so tools like vulture no longer flag it; locate
the function whose signature includes "use_hrr: bool = False" and add the no-op
reference there.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/aelfrice/retrieval.py`:
- Line 1451: The parameter use_hrr is declared but unused and causing CI
deadcode warnings; mark it as used without changing behavior by adding a no-op
reference (for example, add a single line like "_ = use_hrr" or "del use_hrr  #
forward-compat" at the top of the function that contains the use_hrr parameter)
so tools like vulture no longer flag it; locate the function whose signature
includes "use_hrr: bool = False" and add the no-op reference there.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: ef145d85-16da-40f1-901e-9c47bbfdaed8

📥 Commits

Reviewing files that changed from the base of the PR and between 2af0a49 and a6f1582.

📒 Files selected for processing (6)
  • docs/CONFIG.md
  • src/aelfrice/compression.py
  • src/aelfrice/retrieval.py
  • tests/bench_gate/test_compression_uplift.py
  • tests/test_compression.py
  • tests/test_compression_integration.py

@robotrocketscience
robotrocketscience merged commit a6f1582 into main May 8, 2026
29 of 36 checks passed
@robotrocketscience
robotrocketscience deleted the feat/issue-434-type-aware-compression branch May 8, 2026 18:40
@robotrocketscience

Copy link
Copy Markdown
Owner Author

[release:review:Gylf:2026-05-08T18:40:38Z]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

attn:review Needs review (PR open, awaiting reviewer) author-Setr PR coordination mutex

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants