fix(warm): revive the editor draft when write access arrives late (#756)

A same-route remount that cannot edit yet - hass arrives after the
element is inserted (the demo's own order), or a non-admin waits for the
server's can_write - keeps the editor in _pendingNavMode and enters it
later through _resumePendingNavMode -> _setMode. The draft revival was
wired only into the immediate warm adoption (_requestMode(..., adopt)):
on the pending path the draft was lost, _warmRevivePending stayed up for
the instance's life, _warmSnapshot stopped writing dlg, and the next
remount brought back the predecessor's stale draft.

The adoption tail (draft revival once under a held refit, then the
settled stage as the refit baseline) is shared by both paths: the
sequencing lives in src/warm-mode-adoption.ts, the refit bookkeeping in
the card's _holdWarmRefit/_releaseWarmRefit. The pending mode still enters through _setMode, the transition
authority smoke_nav_persist holds it to; resumeWarmMode then settles the
revival. _setMode ends the passive boot grace and refits the camera to
a header measured before the editor chrome rendered, so a camera the
pending window left untouched is put back and held exactly as an
immediate adoption holds it; a camera that has already moved on (View
refit, the user's pan, another space) is left to the ordinary refit. A
mode that did not commit, an explicit mode command in the pending window
and a route departure settle the revival too: no outcome leaves
_warmRevivePending up. The core file gives back 4 lines.

smoke_warm_dialogs gains section H through the UI: the three late-write
orders keep mode, draft, dirty baseline and a frame-by-frame identical
viewport; the chain carries this instance's draft, not the predecessor's;
a space switch in the pending window eats the draft. 14 checks are red
on dev. The mutant warm-pending-mode-leaves-revive-waiting is guarded by
the smoke; docs/WARM-REMOUNT.md §2 describes the pending editor.

Issue: #756
User-Visible: yes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018qZfe7YS4rqEMKoVeS3GKd
This commit is contained in:
Claude
2026-10-01 14:17:33 +03:00
parent 7ce3f6629f
commit 7b7d6582e6
9 changed files with 230 additions and 47 deletions
+12
View File
@@ -13522,6 +13522,18 @@ const MUTANT_DEFINITIONS = [
replace: ' // mutant: the visible draft revives without its dirty baseline',
}],
},
{
id: 'warm-pending-mode-leaves-revive-waiting',
guard: 'node demo/smoke_warm_dialogs.mjs',
because: '#756 AC1: an editor that waited for hass or the server can_write is entered by '
+ '_resumePendingNavMode; if that branch only commits the mode, the revival keeps waiting '
+ 'forever, the draft never opens and the stuck flag later hands the predecessor draft on',
patches: [{
file: 'src/warm-mode-adoption.ts',
find: ' commit();\n if (!host._warmRevivePending) return;\n',
replace: ' commit();\n return; // mutant: the pending branch leaves the revival waiting\n',
}],
},
{
id: 'marker-discard-without-asking',
guard: 'node demo/smoke_device_settings_form.mjs',
+10
View File
@@ -602,6 +602,16 @@ export const SMOKE_LINKS = [
+ 'отрезка решает, где кладка меняет глубину, а смок проверяет кладку, '
+ 'а не толщину, и ни одного имени из резолвера не называет',
},
{
// #756: хвост тёплой адопции редактора. Смоки видят его только как
// воскрешённый черновик и покадрово неизменный `_view` после ре-маунта.
symbols: ['finishWarmModeAdoption', 'resumeWarmMode', '_holdWarmRefit', '_releaseWarmRefit'],
smokes: ['smoke_warm_dialogs.mjs', 'smoke_warm_remount.mjs', 'smoke_nav_persist.mjs'],
because: '#756: the warm editor tail — draft revival once the mode is committed and the '
+ 'refit hold on the adopted camera — is observed only as the revived draft, the '
+ 'frame-by-frame viewport after a remount (immediate or after can_write) and the '
+ 'pending mode entering through _setMode; no smoke names these helpers',
},
];
/** Смоки, связанные с изменёнными символами через реестр. */