Skip to content

feat(v1.4): PreCompact hook + rebuild logic in augment mode (closes #139) - #177

Merged
robotrocketscience merged 6 commits into
mainfrom
feat/v1.4-precompact-rebuilder
Apr 28, 2026
Merged

feat(v1.4): PreCompact hook + rebuild logic in augment mode (closes #139)#177
robotrocketscience merged 6 commits into
mainfrom
feat/v1.4-precompact-rebuilder

Conversation

@robotrocketscience

Copy link
Copy Markdown
Owner

Summary

  • Replaces the v1.2.0a0 alpha's per-token union retrieval workaround with the v1.3 retrieve() codepath (L0 + L1 + L2.5 in one call); inherits posterior-weighted ranking automatically when [v1.3] Partial Bayesian-weighted ranking #146 lands.
  • Adds session-scoped retrieval: beliefs whose session_id matches the latest transcript turn are surfaced as a dedicated tier between L0 and L2.5/L1.
  • Wraps the rebuild block in the harness's hookSpecificOutput.additionalContext JSON envelope (matching the v1.2.x search-tool hook shape).
  • New [rebuilder] turn_window_n and [rebuilder] token_budget config keys in .aelfrice.toml (defaults 50 / 4000); aelf rebuild shares the same rebuild_v14() codepath the hook drives.
  • Augment mode only — suppress mode is parked for v2.x per the ROADMAP.

Acceptance (issue #139)

  • Hook fires on PreCompact and emits additionalContext with locked + session-scoped + retrieve() hits, ordered as locked → session-scoped → L2.5/L1.
  • Empty transcript / missing store → exit 0 with no additionalContext written. Tool path unaffected.
  • Latency budget: median ≤ 200 ms on a 10k-belief store. Measured ~2.3 ms median on a workstation; regression test in tests/test_context_rebuilder_hook.py::test_ac4_median_latency_under_200ms_on_10k_belief_store (skip-able under AELFRICE_SKIP_LATENCY=1).
  • Reproducible: same transcript tail + same store state → byte-identical envelope.
  • aelf setup --rebuilder installs the PreCompact hook idempotently (already shipped at v1.2.0a0; carried forward unchanged).
  • aelf rebuild (hidden CLI) invokes the same logic — manual fire of the hook for testing.

Test plan

  • uv run pytest -q --ignore=tests/regression — 1315 passed, 2 skipped (~15s).
  • uv run pyright src/aelfrice/context_rebuilder.py — strict-clean (0 errors).
  • 15 new deterministic tests in tests/test_context_rebuilder_hook.py cover ordering, edge cases, reproducibility, latency, the [rebuilder] config parser, the JSON envelope shape, and session-scoping invariants.
  • Existing test_hook_pre_compact.py updated to parse the JSON envelope; old "no-turns surfaces L0" assertion replaced with the new "no-turns is silent" contract.
  • Existing test_context_rebuilder.py (legacy rebuild() API) untouched and passing.

What is NOT in this PR

  • Suppress mode (parked for v2.x).
  • Threshold-mode trigger calibration (manual / harness-driven only at v1.4.0).
  • Modifications to retrieve() — used as a black box.

…elope

Adds rebuild_v14() that calls the v1.3 retrieve() (L0+L1+L2.5) instead
of the v1.2.0a0 per-token union workaround, threads session_id from
turns.jsonl into per-turn records, and packs L0 -> session-scoped ->
L2.5/L1 within a configurable token budget. emit_pre_compact_envelope()
wraps blocks in the harness's hookSpecificOutput.additionalContext
JSON shape. load_rebuilder_config() honors [rebuilder] turn_window_n
and token_budget keys in .aelfrice.toml (defaults 50 / 4000).

main() entry point added so the module can register as a Claude Code
PreCompact hook directly. Legacy rebuild() and DEFAULT_TOKEN_BUDGET
kept for backwards compat with the existing aelf rebuild CLI and
eval harness.
Switches hook.pre_compact() to call rebuild_v14() and wrap the result
in the harness's hookSpecificOutput.additionalContext JSON envelope.
Resolves the [rebuilder] section of .aelfrice.toml from the payload's
cwd and honors turn_window_n / token_budget overrides; both kwargs
on pre_compact() default to None now and let the config win.

Empty-transcript and missing-store edge cases short-circuit to exit 0
with no additionalContext written, per issue #139 acceptance.

Existing test_hook_pre_compact assertions updated to parse the JSON
envelope via a helper rather than grepping raw stdout. The
no-turns-but-locked-beliefs case used to return the L0 frame; that
behaviour now belongs to the SessionStart channel and the test is
updated to assert silence.
_cmd_rebuild now calls rebuild_v14() (the same path the PreCompact
hook drives) instead of the legacy v1.2.0a0 rebuild(). Defaults
follow [rebuilder] in .aelfrice.toml when present; --n / --budget
flags override. Help text updated. Drops the "[v1.1 rebuilder alpha]"
suffix on the install message.
15 new deterministic tests covering issue #139 acceptance:

- AC1 ordering: locked -> session_scoped -> retrieve() hits, both
  through the hook envelope and via the pure rebuild_v14() boundary.
- AC2 edge cases: empty transcript, missing store, both via the
  pre_compact() hook and via the new context_rebuilder.main entry.
- AC3 reproducibility: two fires against the same inputs produce
  byte-identical envelopes.
- AC4 latency: median <= 200 ms over 10 runs on a 10k-belief store
  via the pure rebuild_v14() function (skip-able under
  AELFRICE_SKIP_LATENCY).

Plus targeted tests on the v1.4-only seams: load_rebuilder_config
defaults / overrides / malformed TOML / wrong-typed values; the
emit_pre_compact_envelope shape; session-scoping invariants; and
the hook contract on malformed stdin.

All deterministic; full suite runs in ~2.5 s on a workstation.
Updates the design doc to reflect what shipped (rebuild_v14 signature,
JSON envelope, [rebuilder] config keys) vs. what remains parked
(suppress mode, threshold-mode trigger calibration). Adds an
"Unreleased" CHANGELOG entry summarising the v1.4 acceptance work
behind issue #139.
The 10k-belief seed phase was taking >5 s on slow CI runners and
hitting the project-wide pytest-timeout=5 default. Switching to an
in-memory SQLite store lets the seed finish quickly without disk
fsync per row; the hot path under test (rebuild_v14) is read-only
and behaves identically. @pytest.mark.timeout(60) makes the
exception explicit so the next slow runner has clear headroom.
@robotrocketscience
robotrocketscience force-pushed the feat/v1.4-precompact-rebuilder branch from 48b8ebe to 69084bc Compare April 28, 2026 07:11
@robotrocketscience
robotrocketscience merged commit 62e3a27 into main Apr 28, 2026
8 checks passed
@robotrocketscience
robotrocketscience deleted the feat/v1.4-precompact-rebuilder branch April 28, 2026 07:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant