Skip to content

fix(adoption): re-check donor growth at retire time, not just at export - #93739

Merged
kshitijk4poor merged 1 commit into
NousResearch:mainfrom
kshitijk4poor:fix/adoption-retire-toctou
Aug 24, 2026
Merged

kshitijk4poor merged 1 commit into
NousResearch:mainfrom
kshitijk4poor:fix/adoption-retire-toctou

Conversation

@kshitijk4poor

Copy link
Copy Markdown
Contributor

Summary

Closes the TOCTOU window flagged by review on #93369 (adoption heal, merged via #93430): the divergence guard compared EXPORT-TIME message counts, so messages appended to the donor by another backend between the export snapshot and the retire loop could still be stamped behind the non-recoverable adopted_by_profile archive — the exact data-stranding class the guard exists to prevent, via a narrower race.

Change

hermes_state_portability.py — the retire loop re-reads live donor vs local counts immediately before end_session; any donor-ahead signal skips the stamp (donor_retired=False, warn-logged). The next resume's export-time guard then handles the divergence normally. Equal-count CONTENT divergence (donor rewind+rewrite) remains invisible to count comparison — documented in-code as accepted: bytes stay in the donor store either way, only reachability differs.

Validation

Check Result
new regression (donor append mid-adoption via export wrapper) — red-first verified against main fails on main, passes with fix
adoption + db-ownership suites 25 passed
ruff clean

Follow-up to #93369/#93430; part of the #93091 train.

Closes the TOCTOU window flagged in review on NousResearch#93369 (merged via
NousResearch#93430): the divergence guard compared EXPORT-TIME message counts, but
another backend can append donor messages between the export snapshot
and the retire loop — that growth would be stamped behind the
non-recoverable adopted_by_profile archive, the exact H2 class the
guard exists to prevent, just via a narrower race.

The retire loop now re-reads live donor vs local counts immediately
before end_session and leaves the donor unretired (donor_retired=False,
warn-logged) on any donor-ahead signal; the next resume's export-time
guard then handles the divergence normally. Equal-count CONTENT
divergence (donor rewind+rewrite) remains invisible to count comparison
— documented as accepted: bytes stay in the donor store either way.

New red-first-verified regression simulates the exact race by appending
to the donor from inside an export_session_lineage wrapper.
adoption+ownership suites: 25 passed; ruff clean.
@kshitijk4poor
kshitijk4poor force-pushed the fix/adoption-retire-toctou branch from 552464a to 2ea8e67 Compare August 24, 2026 09:32
@kshitijk4poor
kshitijk4poor enabled auto-merge (rebase) August 24, 2026 09:33
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/tui Terminal UI (ui-tui/ + tui_gateway/) sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state labels Aug 24, 2026
@kshitijk4poor
kshitijk4poor merged commit dc50f02 into NousResearch:main Aug 24, 2026
38 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/tui Terminal UI (ui-tui/ + tui_gateway/) P2 Medium — degraded but workaround exists sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants