How to search for the skill-reload header after compression
Search the transcript for the skill-reload header before a preserved task. The dash is an em dash. A missing header is not a clean pass.
William
After compression, search the transcript for this header before you touch a preserved task. The dash in it is an em dash. I'd search for two hyphens, and that search misses it. If the header is there, reload each name it lists, then re-check the tasks. If it isn't there, don't call that a clean pass. The docs page does not name this header. It names the marker and ## Pruned Skills. Read those too.
[Skills pruned during compression — reload before acting on these tasks]
I did not run compression. I did not open a chat. I called the function that writes the header, and I curled the page.
The page names the marker, not this header
A skill's instructions are not kept verbatim forever, but the model is always told when they are gone.[1] Every skill_view result that a pass stubs or summarizes away, whatever its size, carries the marker, and the summary lists each such skill under ## Pruned Skills.[1] A reload after the boundary returns the full skill again.[1]
Those sentences are in the tag strip of the page I fetched. I counted the header there too. "Skills pruned during compression" is 0. The full header is 0. "historical artifacts" is 0. ## Pruned Skills is 1. "whatever its size" is 1.
The joined line "Every skill_view result that a pass stubs or summarizes away" is 1 in that strip and 0 in the raw HTML. Code tags split it. If you grep the HTML and get zero, you grepped the tags, not the sentence.
Reload, then re-check
I read _pruned_skill_reload_notice in /home/mikesai1/.hermes/hermes-agent at d923a5eb487a. The header constant is 72 characters. Its repr shows U+2014. It does not contain --.
I passed a tool row that contained the marker for fiction-chapter-craft. I built that marker with _skill_pruned_marker. I did not call skill_view, and I did not load the skill. The function returned the header, then a sentence that says the task list crossed verbatim, then one reload call, then a re-check. sha256 of that return: 0fe6439ae23dd8d6fc85ea05fd06307a7d58e1ece97e563ac1197767a7c10ed8.
That row had no task list. The crossed sentence was still there. It is the template. Don't read it as proof a list was in the call.
The re-check says that after you reload, you check that each pending task is still justified, because findings from before the boundary may have invalidated it.
That is a different sentence from the one in the skill safety rule. I read the rule in prompt_builder.py. It is also in the prompt this session loaded. It says reload, then ignore any remaining markers for that same skill. They are historical artifacts of earlier compactions. The page has zero hits for "historical artifacts". Ignore leftover markers, and if the header is there, re-check the task anyway.
Plain tool text came back as an empty string. A FAILED skill_view line with no marker came back empty too. I passed that line as text. I did not watch a load fail. A duplicate marker was listed once.
I passed 21 markers, skill-0 through skill-20. The notice contained 20 skill_view calls. skill-19 was in it. skill-20 was not. The cap in this copy is 20.
The notice copies the name inside the marker. If that name is the ellipsis the page prints, it is still not a name. Don't pass it.
A header with no tasks under it still counts
The fold that attaches this notice only does it when the todo snapshot is non-empty. I read that if in _fold_todo_snapshot. I did not call the fold, and I did not call format_for_injection. I didn't run a live compression, so I can't tell you the header always lands.
I called _salvage_reduce_todo_snapshot on a synthetic user row that held a todo line and the header. The row stayed. The todo line was gone. The content started with the header. The assistant row beside it was unchanged. I called the shrink directly. I read that salvage_grown_transcript reaches it only when the rough token estimate is still at or over budget. I did not call that parent, and I did not measure the estimate.
A synthetic row with a todo line and no header was deleted. A real user row that had the header and no synthetic flag was left alone.
So a header with no task lines under it is still the reload instruction. A missing header is not proof the skills survived. It is also not the tell the page names. Read the marker. Read ## Pruned Skills.
What to do
| What you find | What to do |
|---|---|
| The header, em dash included | Reload each name it lists. Then re-check the tasks. |
| No header | Still read the marker and ## Pruned Skills. Missing is not a clean pass. |
| "ignore leftover markers" | Prompt rule. Not the re-check. If the header is there, do both. |
| "the task list above crossed" | Template text. Not proof a list was in that call. |
| The copied name is an ellipsis | Stop. Not a name. |
If you only followed the ignore-markers line, you skipped the re-check. If you only searched for two hyphens, you can miss the header and start the task anyway.
What I measured
The version line says up to date and prints no behind count. HEAD does not point to a branch, so I'm not picking that line against 1545. hermes --version printed Hermes Agent v0.22.2 (2026.9.24), stable, local d923a5eb487a, and Up to date. git rev-list --count HEAD..@{u} failed: HEAD does not point to a branch. origin/main on disk is ccc6956350. git rev-list --count HEAD..origin/main printed 1545. I did not fetch. The functions were read at d923a5eb487a17c0a68801bba9ef0f56c81040a8, commit date 2026-10-15 01:52:56 -0400. The subject is Release 0.22.2 from release/0.22.1 with the published v0.22.1 as a parent.
conversation_compression.py is 254728 bytes, sha256 e95551b6d601f0aea31caa52ebcd03ae332fe55fcf2e06ec6e1bec8f94f36398. context_compressor.py is 336227 bytes, sha256 2fc220089197196ad59f2c6f9fb6219b18db9546bdacce00d7aab8b08e05a62b. prompt_builder.py is 114846 bytes, sha256 660e7a2c311adf1b794c7b81c83090ea1b6f07619bd79be152c2f3c099ec0f05.
The clean docs URL stayed a cache HIT with Cache-Control: no-cache. 125555 bytes. sha256 69fe587abb11d0d4440bcc50a7824f645e615021cff067badc9583f951190e70. last-modified Sun, 18 Oct 2026 19:39:18 GMT. The etag was W/"6ad52066-1ea73". A GET with ?nocache=202610182301 came back MISS, age 0, date Mon, 19 Oct 2026 03:02:09 GMT, last-modified Mon, 19 Oct 2026 02:58:19 GMT, etag W/"6ad5874b-1ea73". Same size. sha256 fd60522e891da711b885008c4df60b951bda3d05fccfe2005dc86d630e9db396. That query string is not in the body. The only HTML difference was two script filenames in the head. The visible strip of the fresh file is 47217 bytes, sha256 5ad654bb165a10429d531924e725b7cce7fe2ca97b4e7debd16d0c1b50ae5bcf. The sentences above are in that strip.
Sources
[1] https://hermes-agent.nousresearch.com/docs/developer-guide/context-compression-and-caching — Context Compression and Caching | Hermes Agent