- User-turn predicates reuse _is_context_summary_message (single detection path).
- _serialize_for_summary hoists the shared head/tail truncation.
- __init__ initialises per-session state via _reset_session_compaction_state.
- Timeout cooldown ladder (60/300/900s) is one module helper used by both
record_timeout_failure and the summary failure path; module-level so a real
method bound onto a stub compressor still exercises it.
Hunk-by-hunk audit of the compaction commit found 14 dropped WHY/invariant
statements (route-pin scope, persistence-marker sweep failure mode, stamp
asymmetry, reasoning-replay boundary, size-class parity with preflight,
small-context floor cap, tail-anchor ordering rules, defer-baseline backstops).
Each is restored as a compact 1-3 line comment at its anchor.
- Nine near-identical durable-row getters/setters -> _durable_read/_durable_write
(also used for parent-lineage lookups in on_session_start).
- on_session_reset/on_session_end share _reset_session_compaction_state.
- _find_tail_cut_by_tokens: the two backward token walks become one _walk_back
(randomized parity vs. the previous version: 1500 transcripts identical).
- _strip_context_summary_handoff_message: one _unwrapped() helper for all paths
(parity: 1296 content shapes identical).
- ruff SIM102/SIM108/SIM114 collapses.
The 15 rolling micro-compaction methods (cursor resolution, exchange
serialization, one-exchange summarization, defrag, splice, DB sync, telemetry)
move verbatim into MicroCompactionMixin, mixed into ContextCompressor
(MRO: ContextCompressor -> MicroCompactionMixin -> ContextEngine). Origin
constants and call_llm are imported lazily so tests patching
agent.context_compressor.X still apply; logger name parity is kept.
- _generate_summary(): prompt assembly lifted into _build_summary_prompt, the
exception path into _on_summary_failure; the two identical main-model retry
branches are merged behind a reason lookup.
- compress(): terminal summary-failure abort classes are table-driven via
_TERMINAL_SUMMARY_FAILURES (same precedence, log text and telemetry class;
flag reads stay lazy so __new__-built test doubles keep working).
_summarize_tool_result_unguarded routed on tool_name through ~20 if-branches; each
branch is now a small _sum_* function in _TOOL_RESULT_SUMMARIZERS with the generic
fallback unchanged. Output verified byte-identical against the previous version
across 1288 name/args/content combinations.
- delete _cached_prompt_reflects_builtin_memory + _builtin_memory_prompt_snapshot
(zero callers since the commit site moved to byte-equality; the only test
reference asserts their ABSENCE from the commit window)
- delete CompressionExecutorSaturatedError (never raised or caught anywhere)
- _compress_context_via_codex_app_server: three near-identical skip branches
collapse into one skip_reason + single log line (same message text)
Hand-reviewed compaction: non-obvious rules, ordering constraints, invariants,
failure modes and WHY are kept in 1-3 line form; narrative, issue-number history
and code restatements are dropped.
_candidate_rejected(): compressor abort, no-progress, empty transcript and
superseded-attempt checks in their original order; caller handles the
shared release + unchanged-return. Aborted-branch try/finally collapsed
(the finally only released the lease, which the caller now does).
- _fold_todo_snapshot(): stale-snapshot strip + live todo fold into the tail
- _rebuild_system_prompt_at_boundary(): tool refresh + byte-equal keep-prompt
- _salvage_or_refuse_grown_transcript(): commit-site anti-growth guard
- _publish_rotated_compaction(): parent flush, child publish, id re-point,
goal/heartbeat/loop/title carry-over
- old_session_id is now an explicit Optional local instead of locals().get()
compress_context 1181 -> 794 lines; bodies moved verbatim.
Closures -> _StreamingCall methods (shared worker/monitor state on the
instance), codex passthrough and Bedrock Converse branches -> free
functions, _stream_final_text/_emit_stream_* -> module helpers. Bodies
are AST-identical modulo the self.<name> renames (verified by script);
stream event handling and wire shapes unchanged.
- build_environment_hints: split into _local_host_hints / _remote_backend_hint /
_embedder_environment_hint; backend probe split into _run_backend_probe +
_format_backend_probe with image-key / container-config dispatch tables
replacing the if/elif chain.
- Skills index: _SkillFilter (frozen dataclass) unifies the disabled+conditions
check that was copied 4x (snapshot, scan, project, external);
_collect_extra_skills dedupes the project/external scan loops;
_read_category_descriptions dedupes DESCRIPTION.md reading;
_label_visible_entries and _render_skills_index lift the org-labeling and
rendering regions out of _build_skills_system_prompt_inner; snapshot and scan
sources now feed one visibility pass.
- Context files: _read_context_file + _context_section unify the
read/strip/scan/section/truncate sequence across .hermes.md, AGENTS.md,
CLAUDE.md and .cursorrules loaders.
- Dead: _clear_backend_probe_cache (test-only helper; tests clear the dict
directly), unused org_id_of_path re-export.
- Comments/docstrings hand-compacted; every rule, invariant, ordering and
failure-mode rationale kept.
System prompt text verified byte-identical against origin/main over a 273-case
fixture corpus (env hints x backends/probe states, skills index x toolsets /
platforms / project / org / compact, context files x all loaders, full
AIAgent._build_system_prompt_parts x 9 configs). Tool schema byte-identical.
init_agent (2711 LOC) becomes a ~280-line ordered orchestrator over
_resolve_api_mode / _finalize_routing / _init_* / _build_client /
_load_tools / _parse_compression_config -> CompressionSettings /
_resolve_context_length / _build_context_engine / ... phase helpers.
_build_client is further split per wire mode (_init_anthropic_client,
_init_moa_client, _init_bedrock_client, _init_openai_client with
_explicit_client_kwargs / _routed_client_kwargs). Statement order and
every side effect on the agent are preserved (AST body-parity checked
against origin/main).
Dedupe/dead code: drop _relay_moa_reference_event/_moa_reference_output_allowed
(zero callers; only their own test) and their test file; alias
_normalize_route_base_url; _parse_config_int replaces three copies of the
strict int parser; _cfg_flag replaces four inline truthy-set checks;
_client_kwargs_from_routed + _fallback_entries replace duplicated
routed-client/fallback-entry blocks; _warn_invalid_config_int unifies the
three log+stderr invalid-int warnings (byte-identical text);
_bedrock_region_from_url; _memory_provider_init_kwargs; the
host->default_headers if/elif chain becomes the _HOST_DEFAULT_HEADERS
dispatch table; callback params assigned from _CALLBACK_PARAMS.
Comments/docstrings hand-compacted to their rationale (invariants,
ordering, failure modes kept; issue numbers and narrative dropped).
test_pre_compress_checkpoint_contract source-check repointed at the
CompressionSettings field names.
Verified: tests/run_agent (2066 passed) + all agent_init-referencing tests
(1134 passed), get_tool_definitions() byte-identical vs origin/main, import
smokes for cli/run_agent/gateway.run/hermes_cli.main/agent.conversation_loop/
tui_gateway.server.
- scheduler_provider.py: _profile_entry/_profile_cron_scope replace four hand-rolled
home-override+store blocks in the multiplex ticker; comments compacted to the WHY.
- incidents/executions/notepad/monitor/suggestions/blueprint_catalog/__init__: docstrings
and comments compacted; no code change (AST-identical).