# Sprinter Commander: conflict-policy F5 0.2/P19 Дата: 10 сентября 2026 года. Статус: `PASS` в MAME 0.288 / BIOS 3.06 / DSS 1.71.57 на HDD `D:`. ## Поведение Если конечное имя файла существует, F5 показывает единый choice-dialog: - `O` — безопасно заменить только этот файл; - `S` — пропустить только этот файл; - `R` — ввести другое DOS 8.3-имя; - `A` — заменить этот и все следующие конфликтующие файлы текущей группы; - `N` — пропустить этот и все следующие конфликты текущей группы; - `Esc` — отменить текущую операцию. Policy `all` живёт только до завершения одного вызова F5 и распространяется на top-level группу и файлы рекурсивной job. Readonly target не заменяется молча даже после ранее выбранного `overwrite all`: для него снова появляется диалог `Read-only target`. Групповые `+/-/*` по-прежнему работают только над файлами; выбор каталогов через `Insert` не менялся. `Rename` меняет только имя target, проверяет один компонент DOS 8.3 и не переименовывает source. Если новое имя тоже занято, policy запрашивается повторно. ## Транзакционная замена Существующий target не удаляется перед копированием. После полной записи и закрытия нового temp выполняется последовательность: 1. выбирается отсутствующее имя `~SBxxxx.BAK` в том же каталоге; 2. readonly временно снимается только после явного разрешения overwrite; 3. старый target переименовывается в backup; 4. новый temp переименовывается в target; 5. новому target назначаются исходные date/time и R/H/S/A; 6. backup удаляется. Если шаг commit нового temp не проходит, старый target переименовывается обратно и его атрибуты восстанавливаются. Заранее существующие backup-имена пропускаются, а не перезаписываются. Ошибка после необратимого commit помечается `ScCopyJob.committed`, поэтому UI не сообщает, что target якобы отсутствует. ## Проверка Отдельная target-проба прошла на реальном DSS-пути: ```text PASS default still refuses existing target PASS overwrite commits through backup PASS explicit readonly overwrite PASS pre-existing backup name skipped PASS replace policy accepts vanished target PASS distinct destination name PASS rename failure rolls original target back PASS EMM restored ALL PASS ``` CHD-check побайтно подтвердил заменённые файлы, rollback исходного payload, сохранность заранее созданного `~SB0000.BAK` и отсутствие новых backup/temp: ```text PASS: transactional overwrite, readonly, collision and rollback. ``` Полный UI-сценарий выбрал три файла для `overwrite all`, получил отдельный readonly prompt, затем применил `skip all` к двум файлам, скопировал `REN.BIN` как `NEXT.BIN` и отменил конфликт `CANCEL.BIN`. Итоговая проверка: ```text PASS: overwrite-all, readonly prompt, skip-all, rename and cancel. ``` Контрольные кадры target-пробы: - [ALL PASS](../artifacts/mame-p19/overwrite-core/all-pass.png); - [чистый возврат](../artifacts/mame-p19/overwrite-core/clean-dss-return.png). UI policy: - [выбор overwrite all](../artifacts/mame-p19/policy/overwrite-choice.png); - [повторный readonly prompt](../artifacts/mame-p19/policy/readonly-reprompt.png); - [три файла заменены](../artifacts/mame-p19/policy/overwrite-complete.png); - [выбор skip all](../artifacts/mame-p19/policy/skip-all-choice.png); - [оба файла пропущены](../artifacts/mame-p19/policy/skip-complete.png); - [rename-conflict](../artifacts/mame-p19/policy/rename-choice.png); - [`NEXT.BIN` создан](../artifacts/mame-p19/policy/renamed.png); - [отмена конфликта](../artifacts/mame-p19/policy/cancel-choice.png); - [диалог полностью убран после Esc](../artifacts/mame-p19/policy/cancel-cleared.png); - [итог пассивной панели](../artifacts/mame-p19/policy/target-result.png); - [чистый возврат в DSS](../artifacts/mame-p19/policy/clean-dss-return.png). В процессе визуальная проверка нашла и устранила stale-dialog: после одиночных conflict `error/cancel/skip` теперь выполняется полный redraw, а не обновление только двух нижних строк. После итоговой правки повторно пройдены P5 copy-fault matrix и P18 exact FAT metadata. ## Компоновка EXEC-модуль перенесён из почти полного BANK2 в BANK1. Его строковые статусы теперь всегда копируются в W2 BSS, поэтому наружу не уходит указатель на bank-local literal. Это позволило оставить приложение двухбанковым: ```text _CODE 9503; DATA 3561; heap 1784 BANK1 14374/16384; BANK2 15665/16384 SPRCMD.EXE 43080 ``` Межбанковый аудит чист. В BANK1 остаётся 2010 байт, в BANK2 — 719. ## Воспроизведение ```sh make hdd-p19-overwrite ALLOCS=3000 tests/run_mame_hdd.sh build/hdd/p19_overwrite.chd \ tests/mame_p19_overwrite.lua artifacts/mame-p19/core-local 180 tests/check_p19_overwrite_hdd.sh build/hdd/p19_overwrite.chd make hdd-p19-policy ALLOCS=3000 tests/run_mame_hdd.sh build/hdd/p19_policy.chd \ tests/mame_p19_policy.lua artifacts/mame-p19/policy-local 200 tests/check_p19_policy_hdd.sh build/hdd/p19_policy.chd ```