Skip to content
UHPUHPDeveloper Guide
Independent resource · Not affiliated with HarnessRouter · Site data checked 23 Sep 2026

Agentic reliability

Session Export Integrity in Agent Harnesses

A session export is not safe merely because a file was written. If export and deletion use different views of durable history, or if the session can change between verification and deletion, a cleanup command can destroy records that were never preserved in the export.

Verified: Evidence: Hermes PR #120435 / merge 880b9cd4Protocol: 2026-09-12

Export-then-delete is a data-integrity transaction, not a formatting convenience. Before destructive cleanup, an agent host has to prove that the export covers the history the user expects to preserve and that the durable session has not changed since that exact history was exported.

Hermes PR #120435, merged on 23 September 2026 as 880b9cd444a96c0c844ca8f67bedcdb98773f1f7, is a useful current implementation example. It fixes a high-impact failure in hermes sessions export --delete-after-verified: in-place compaction could archive older turns as compacted rows, while Markdown, QMD, HTML and --only transcript exports read only active rows. The export could therefore omit older visible history and still proceed to delete the durable session.

The merged fix makes human-readable transcript exports use display history that includes compacted turns, and fences destructive deletion with a single SQLite BEGIN IMMEDIATE transaction that re-reads that same display history and compares it with what was exported. A newly appended turn or an in-place rewrite blocks deletion even when the message count is unchanged. JSONL deliberately remains a raw-store export. These changes are post-v2026.9.21 / Hermes Agent v0.21.4 current-main behavior, not part of that stable tag.

This is a harness persistence and archival-safety concern. It does not revise UHP, MCP, ACP or A2A wire semantics and does not establish new HarnessRouter conformance or native Hermes UHP adoption.

The first invariant: export the history the user is trying to preserve

Section titled “The first invariant: export the history the user is trying to preserve”

Agent sessions often have more than one legitimate history view:

ViewTypical purposeImportant risk
Raw durable storeForensics, migrations, exact internal stateMay include superseded, compacted or implementation-private rows that are not a readable transcript
Active/model historyConstructing current prompts or active session stateMay intentionally omit older rows replaced by compaction
Display historyWhat resume/search/transcript surfaces reconstruct for the userMay combine summaries, compacted history and current active rows
Export projectionPortable Markdown/HTML/QMD/JSONL artifactMust declare which source view it represents

The pre-fix Hermes path crossed those boundaries. In-place compaction did not necessarily destroy older turns; it archived them as compacted durable rows. The human-readable exporters, however, selected only active rows. The destructive command then treated successful file creation as evidence that the session had been preserved.

That is insufficient. A syntactically valid export can still be semantically incomplete.

The reusable rule is:

A destructive export must define its preservation view explicitly and verify deletion against that same view.

For a user-facing transcript, that normally means the same logical history the user can resume, inspect or save—not merely the rows currently eligible for model input.

Compaction creates an archival-view problem

Section titled “Compaction creates an archival-view problem”

Context compaction changes the problem from “write every row” to “preserve the right representation of every logical turn.” A compactor may summarize older material, mark rows inactive, retain compacted originals for display/search, or keep multiple generations for recovery.

Those choices are valid internally, but an exporter cannot infer that active = true means “all history the user expects.” Active-state flags often answer a runtime question, not an archival one.

A safe design should therefore name the projection being exported:

  • display transcript: reconstructed human-visible conversation, including history retained through compaction;
  • raw archive: implementation records sufficient for forensic or migration use;
  • active prompt state: only the state needed to continue model execution;
  • selected/filtered export: a deliberately partial view whose destructive cleanup semantics must be correspondingly limited.

Hermes #120435 keeps JSONL on the raw-store path while moving Markdown/QMD/HTML and /save to display history. That is preferable to silently pretending every format carries the same semantics.

“Verified” must cover content, not only file existence

Section titled ““Verified” must cover content, not only file existence”

A command named --delete-after-verified can give a stronger impression than the implementation deserves if “verified” means only that an output file exists or has the expected number of rows.

Two classes of drift matter:

  1. append drift: a new turn arrives after the export;
  2. rewrite drift: an existing turn changes while the count stays the same.

A row-count comparison catches the first only in simple cases and misses the second entirely. File-size checks have the same weakness. A destructive verifier needs a content identity strong enough to represent the exported preservation view.

Hermes #120435 re-reads the display history and compares it with the exported history before deletion. The PR explicitly tests both a newly added message and a same-length rewrite. In either case the export remains on disk and the session is retained.

The general invariant is:

Deletion must depend on equality of the preserved logical content, not on a weak proxy such as message count, timestamp or file creation success.

Compare-and-delete must be one protected operation

Section titled “Compare-and-delete must be one protected operation”

Even a strong content comparison is unsafe if a writer can modify the session after verification but before deletion.

The unsafe sequence is:

export snapshot A
verify durable state == A
another writer commits B
delete session

The verifier was correct when it ran, but the deletion destroyed state that was never exported.

Hermes closes that time-of-check/time-of-use gap by performing the destructive re-read and deletion under a single SQLite BEGIN IMMEDIATE transaction. The transaction obtains the write reservation before the final comparison, so a conflicting writer cannot slip an unexported change into the gap that the deletion depends on.

The portable architecture rule is not “every harness must use SQLite.” It is:

Final verification and destructive commit need one concurrency boundary.

Depending on the storage layer, that boundary may be a database transaction, compare-and-swap generation, optimistic concurrency token, object version, lease/fence generation or another atomic conditional-delete mechanism.

A useful destructive workflow has a safe refusal state. If verification detects drift, the already-created export should not be rewritten to hide the mismatch, and the durable session should not be deleted.

Hermes follows that model: a post-export change keeps the session and leaves the export unchanged. This gives the operator two inspectable artifacts:

  • the point-in-time export that was actually produced; and
  • the newer durable session that prevented deletion.

The operator can then export again deliberately. The failure mode is duplication and a retry requirement, not silent loss.

This is the same safety bias used in robust migrations: when uncertainty appears between copy and delete, preserve both until ownership/content equivalence is re-established.

Read reliability is part of destructive safety

Section titled “Read reliability is part of destructive safety”

A verifier that reads through a less reliable code path than ordinary session operations can turn a transient storage condition into the wrong cleanup decision.

The reviewed Hermes change retains the existing retry for transient SQLite I/O errors on display-history reads. The PR notes that an earlier version accidentally bypassed that retry and restores it before merge.

The broader requirement is simple: destructive verification should not silently weaken the normal read-consistency or transient-error handling of the source-of-truth path. A read that cannot be trusted should fail closed and preserve the session.

Format and lineage semantics must stay explicit

Section titled “Format and lineage semantics must stay explicit”

Different export modes can have intentionally different behavior. PR #120435 leaves two existing Hermes behaviors unchanged:

  • --lineage logical deletion affects only the tip session; and
  • --format html --delete-after-verified does not delete.

Those boundaries are important because “export a lineage” and “delete everything represented by that file” are not automatically the same operation. Parent/child session graphs, forks and logical lineages require explicit ownership and deletion rules.

A review should therefore ask separately:

  • Which sessions/turns are included in this file?
  • Which durable object is eligible for deletion?
  • Does deleting a tip affect ancestors, descendants or shared lineage?
  • Does every output format support the same destructive mode?
  • Is a partial filter such as --only allowed to authorize deletion of material outside the selected projection?

Names such as export, save, archive and verified do not answer these questions by themselves.

Relation to session recovery and durable-state repair

Section titled “Relation to session recovery and durable-state repair”

Session recovery asks whether persisted state represents live work, interrupted work or a settled terminal outcome and whether another execution may safely begin. Session export integrity asks a later, different question: can this durable history be destroyed after a portable copy is produced?

Durable state repair addresses historical ownership violations across stores and emphasizes snapshot-before-mutation, quiesced writers and convergence checks. Export-then-delete shares the same fail-closed bias, but its proof obligation is content preservation rather than owner migration.

Context compaction is directly relevant because compaction can create several valid representations of one logical conversation. The exporter must know which representation is promised to the user before deletion is allowed.

These concerns compose:

Durable session state
├── recovery: what happened / may work continue?
├── compaction: which history representation remains active?
├── export: what preservation view is written out?
└── destructive cleanup: is that exact view still current?
delete or refuse

The evidence here is upstream source and test evidence, not an independent data-loss benchmark by this site.

PR #120435 reports:

  • 5 focused regressions covering compacted-history export, logical-lineage export, appended-message drift, same-count rewrite drift, /save display history and transient I/O retry behavior as grouped by the PR description; and
  • a live temporary-HERMES_HOME CLI exercise reported as 12/12, covering Markdown, QMD, HTML, --only, JSONL, logical lineage and race cases.

The PR states the five focused tests fail against the pre-fix source and pass with the change. Those are upstream results. This guide does not promote them into independent cross-platform certification.

At this review cutoff, merge 880b9cd4 is an ancestor of Hermes current main. Stable remains v2026.9.21 / v0.21.4, so the export-integrity fix is current-main behavior after that release.

This page documents a harness-local persistence and destructive-cleanup pattern.

  • UHP: does not standardize Hermes transcript export formats, compacted-row storage or --delete-after-verified.
  • MCP: does not define host session archival/deletion semantics here.
  • ACP: session interaction/compaction semantics do not make a local harness transcript export transactionally safe.
  • A2A: remote task/agent interaction does not define this local archival proof.
  • HarnessRouter: no new adapter or conformance claim follows from Hermes #120435.

A product can implement UHP, MCP, ACP or A2A correctly and still have an unsafe local export/delete path. The proof belongs at the durable-state boundary that performs the deletion.

When reviewing session export with optional cleanup, verify:

  1. The export view is named. Raw store, active prompt state, display transcript and filtered output are not treated as interchangeable.
  2. Compacted history is accounted for. Older logical turns cannot disappear merely because they are no longer active prompt rows.
  3. Every destructive format has explicit semantics. Markdown/HTML/JSONL/filtered exports do not silently share assumptions they do not actually satisfy.
  4. Verification compares content identity. Row count, file existence and timestamps are not sufficient proof.
  5. Rewrites are detected. Same-cardinality content changes still block deletion.
  6. Verify and delete share one concurrency fence. A writer cannot commit between the proof and the destructive operation.
  7. Read failure is fail-closed. Transient or ambiguous source reads preserve the durable session.
  8. Drift preserves both artifacts. The export remains inspectable and the newer durable state is not destroyed.
  9. Lineage deletion is explicit. Tip, parent, child and fork behavior is defined independently from what the file displays.
  10. Partial selection cannot authorize broader loss. A filtered export must not imply preservation of omitted durable history.
  11. Tests reproduce the old failure. Regression evidence should fail on the pre-fix path and pass after the correction.
  12. Version scope is stated. Stable-release behavior and post-release current-main behavior remain distinct.

This is an independent technical guide. “Session export integrity” is descriptive architecture terminology grounded in the cited Hermes implementation; it is not a new interoperability standard or vendor certification.