Skip to content

feat(compression): flip in_place default to True + guard fix (#38763) [salvage #51959] - #52658

Merged
teknium1 merged 4 commits into
mainfrom
hermes/hermes-4efd4d14
Jun 25, 2026
Merged

feat(compression): flip in_place default to True + guard fix (#38763) [salvage #51959]#52658
teknium1 merged 4 commits into
mainfrom
hermes/hermes-4efd4d14

Conversation

@teknium1

Copy link
Copy Markdown
Contributor

Summary

Flips compression.in_place default False → True so compaction keeps one durable session id instead of rotating — eliminating the session-id rotation that was the root cause of a P1 cluster (#14238 lost pending response, #13840 search black-hole, #36777/#42228 TUI/desktop stale-cwd/sid). Bundles the guard fix that makes the flip safe.

Salvage of #51959 — cherry-picked onto current main, contributor authorship preserved (@srojk34's guard fix + @kshitijk4poor's flip/tests).

This is the staged flip after #49739 (in-place soft-archive machinery, [1/2]) merged and soaked. Rotation remains a working opt-out fallback via compression.in_place: false.

Why the guard fix MUST land with the flip

/compress and the gateway hygiene-compress both build a throwaway AIAgent without a session_db, so archive_and_compact can't run and _last_compaction_in_place stays False. Both guard sites read compression_in_place (the config flag — "is in-place enabled?") instead of _last_compaction_in_place (the result flag — "did in-place succeed?"). Harmless while the default is False; flip the default and every gateway compress passes the guard with no successful compaction → rewrite_transcript() replaces the transcript with summary-only (permanent data loss, the #21301 class). The fix points both guards at the result flag (matching the canonical read already at gateway/run.py).

Changes

  • gateway/run.py, gateway/slash_commands.py: hygiene guard + /compress read _last_compaction_in_place (result flag) not compression_in_place (config flag).
  • hermes_cli/config.py: compression.in_place default False → True.
  • tests/gateway/test_session_hygiene.py: regression test — in-place configured but no session_db must preserve the transcript (fails without the guard fix).
  • 7 rotation-asserting test sites pinned to in_place=False so the rotation fallback keeps coverage; test_in_place_compaction default assertion flipped to defaults_on.
  • scripts/release.py: AUTHOR_MAP entry for @srojk34's legacy prefix-less noreply.

Validation

Buggy (config flag) Fixed (result flag)
in-place configured, no session_db, gateway compress rewrite_transcript called with summary-only → data loss transcript preserved
  • Regression test fails with the guard reverted to the config-flag read, passes with the fix (verified locally).
  • 44/44 targeted compression tests green (session_hygiene, in_place_compaction, rotation_state, logging_session_context, boundary_hook).
  • Rebased onto current main; diff is the 11 intended files only (134/-9).

Closes #51959. Supersedes #50098.

Infographic

nous-system7

srojk34 and others added 4 commits June 25, 2026 12:38
…guard (#50098)

Salvage of #50098 by @srojk34, cherry-picked onto current main.

The hygiene auto-compress guard and the /compress slash command both read
compression_in_place (config flag — is in-place mode enabled?) instead of
_last_compaction_in_place (result flag — did in-place compaction actually
succeed?). Both agents are built without a session_db, so archive_and_compact
always fails silently and _last_compaction_in_place stays False. Reading the
config flag makes the guard think in-place succeeded, triggering
rewrite_transcript() which replaces the original messages with only the
compressed summary — permanent data loss.

Co-authored-by: srojk34 <srojk34@users.noreply.github.com>
In-place compaction (single durable session id, non-destructive soft-archive)
becomes the default. Rotation is now the opt-out fallback via
compression.in_place: false.

Prerequisite: #50098 (hygiene guard reads result flag not config flag) merged
first — without it, flipping the default causes permanent transcript loss on
gateway hygiene-compress and /compress when no session_db is available.

Blast radius (empirically measured on current main): 7 rotation-asserting
tests broke and are pinned to in_place=False in the companion test commit:
- tests/agent/test_compression_concurrent_fork.py (2)
- tests/agent/test_compression_logging_session_context.py (1)
- tests/agent/test_compression_rotation_state.py (1)
- tests/run_agent/test_compression_boundary_hook.py (2 _make_agent helpers)
- tests/gateway/test_compression_concurrent_sessions.py (2)
Rotation stays as a working fallback and deserves continued coverage.

Plan: .hermes/plans/in-place-compaction-38763.md
…d of default flip

These 7 test sites assert rotation behavior (fork, child sessions, lock
contention, logging session-context follows id rotation, boundary hooks fire
on rotation). Pin each builder to in_place=False explicitly so they keep
exercising the retained rotation fallback regardless of the global default
(flipped to True in #38763). Rotation stays a working opt-out fallback and
deserves continued coverage — these are NOT deleted.

Pinned sites:
- test_compression_concurrent_fork._build_agent_with_db
- test_compression_logging_session_context._build_agent_with_db
- test_compression_rotation_state._build_agent_with_db
- test_compression_boundary_hook._make_agent (2 helpers: CompressionBoundaryHook + SessionCompressEvent)
- test_compression_concurrent_sessions._build_agent_with_db
@github-actions

Copy link
Copy Markdown
Contributor

🔎 Lint report: hermes/hermes-4efd4d14 vs origin/main

ruff

Total: 0 on HEAD, 0 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 0 pre-existing issues carried over.

ty (type checker)

Total: 11275 on HEAD, 11265 on base (🆕 +10)

🆕 New issues (7):

Rule Count
unresolved-attribute 7
First entries
tests/agent/test_compression_concurrent_fork.py:83: [unresolved-attribute] unresolved-attribute: Unresolved attribute `compression_in_place` on type `AIAgent`
tests/agent/test_compression_rotation_state.py:59: [unresolved-attribute] unresolved-attribute: Unresolved attribute `compression_in_place` on type `AIAgent`
tests/gateway/test_compression_concurrent_sessions.py:77: [unresolved-attribute] unresolved-attribute: Unresolved attribute `compression_in_place` on type `AIAgent`
tests/run_agent/test_compression_boundary_hook.py:185: [unresolved-attribute] unresolved-attribute: Unresolved attribute `compression_in_place` on type `AIAgent`
tests/agent/test_compression_logging_session_context.py:56: [unresolved-attribute] unresolved-attribute: Unresolved attribute `compression_in_place` on type `AIAgent`
run_agent.py:2989: [unresolved-attribute] unresolved-attribute: Object of type `Self@get_credits_spent_micros` has no attribute `_credits_session_start_micros`
tests/run_agent/test_credits_notices_toggle.py:76: [unresolved-attribute] unresolved-attribute: Unresolved attribute `_credits_session_start_micros` on type `AIAgent`

✅ Fixed issues (1):

Rule Count
invalid-assignment 1
First entries
tests/run_agent/test_credits_notices_toggle.py:76: [invalid-assignment] invalid-assignment: Object of type `None` is not assignable to attribute `_credits_session_start_micros` of type `int`

Unchanged: 5940 pre-existing issues carried over.

Diagnostics are surfaced as warnings — this check never fails the build.

@teknium1
teknium1 merged commit 0654319 into main Jun 25, 2026
27 checks passed
@teknium1
teknium1 deleted the hermes/hermes-4efd4d14 branch June 25, 2026 19:56
@alt-glitch alt-glitch added type/feature New feature or request comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/gateway Gateway runner, session dispatch, delivery comp/cli CLI entry point, hermes_cli/, setup wizard P2 Medium — degraded but workaround exists sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades labels Jun 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/cli CLI entry point, hermes_cli/, setup wizard comp/gateway Gateway runner, session dispatch, delivery P2 Medium — degraded but workaround exists sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants