Reroll (swipe/regenerate/continue = no-new-user) now deterministically
reapplies the parent user floor's stored bme_recall block in
GENERATE_BEFORE_COMBINE_PROMPTS, bypassing the transaction gate and
runRecall entirely. AFTER_COMMANDS defers no-new-user work to
before-combine. Staleness guard recomputes when the user edited the
floor; settings gate honors plugin/recall disable. Fresh normal sends
are unaffected. Compute machinery retained as fallback.
Prior generation's recall transaction was reused for a later reroll
because findRecentGenerationRecallTransactionForChat matched by chat
alone and the peer-hook bridge forced reuse. That set shouldRun=false,
skipped runRecall, and bypassed the persisted-recall reuse gate, so
reroll silently inherited the previous fresh result. Stamp each
transaction with the active host generation id and scope recent-lookup
to the same generation, preserving intra-generation hook bridging.
- Add hasContiguousJournalCoverageThroughFloor to check if current
batchJournal contiguously covers back through the old retained floor
- Add reconcileManualBackupBatchJournalCoverage that clears stale
coverage when actual journals have bridged the gap
- Self-clean during normalizeGraphRuntimeState (load-time) and
appendBatchJournal (write-time)
- findJournalRecoveryPoint now uses reconciled coverage so stale
manual backup floors no longer block valid reverse-journal recovery
- Add regression tests for gap-not-yet-bridged and bridged scenarios
- Add extractActionMode setting (default: pending) to settings-defaults.js
- Panel refresh restores dropdown from settings.extractActionMode
- Dropdown change event persists selection via _patchSettings
- Extract button reads settings as fallback when DOM value missing
- Add default value assertion in tests/default-settings.mjs