План сведения raw и C-level MCP для Sprinter

This commit is contained in:
Александр Петров
2026-09-17 10:53:57 +03:00
parent 12667c865a
commit 619c4c9af5
4 changed files with 162 additions and 5 deletions
+6 -3
View File
@@ -281,12 +281,15 @@ Quick wins:
- [ ] **Довести MCP C-уровня до полного безопасного контракта.** Первый - [ ] **Довести MCP C-уровня до полного безопасного контракта.** Первый
stdio-адаптер с 16 инструментами использует общую sdbg-сессию и stdio-адаптер с 16 инструментами использует общую sdbg-сессию и
owner ID личных точек. Следующее: эксклюзивный control lease для owner ID личных точек. Полный план и матрица всех 30 raw-возможностей —
[mcp-convergence-plan.md](mcp-convergence-plan.md). Следующее:
эксклюзивный control lease для
DAP/MCP, heartbeat/очистка точек при аварийном выходе MCP, безопасные DAP/MCP, heartbeat/очистка точек при аварийном выходе MCP, безопасные
input/screenshot/console API через session server, затем доказанные input/screenshot/console API через session server, затем доказанные
watchpoints, запись typed values, disassemble_src и batch-загрузка watchpoints, запись typed values, disassemble_src и batch-загрузка
точек. Raw `mame_mcp.py` с `-plugin mamebridge` или старым точек. Raw `mame_mcp.py` с `-plugin mamebridge` не подключать к тому же
`mame_bridge.lua` не подключать к тому же MAME в обход общей сессии. MAME в обход общей сессии; старый `mame_bridge.lua` удалить лишь после
проверки 16 общих команд и обновления ссылок.
Отдельно мигрировать raw `mame_mcp.py` с FastMCP SDK 1.x на MCPServer Отдельно мигрировать raw `mame_mcp.py` с FastMCP SDK 1.x на MCPServer
SDK 2.x, если этот standalone-интерфейс сохраняется; сейчас окружения SDK 2.x, если этот standalone-интерфейс сохраняется; сейчас окружения
raw и C-адаптера разделены. raw и C-адаптера разделены.
+3 -1
View File
@@ -540,7 +540,9 @@ console_log и загрузка набора точек. Возвращать bu
DAP-точки отклоняется. Совместный живой прогон подтвердил чтение состояния, DAP-точки отклоняется. Совместный живой прогон подтвердил чтение состояния,
точки и последующее срабатывание DAP-точки. Эксклюзивный control lease, точки и последующее срабатывание DAP-точки. Эксклюзивный control lease,
cleanup при аварийном выходе MCP и остальные интерфейсы этого раздела ещё cleanup при аварийном выходе MCP и остальные интерфейсы этого раздела ещё
не реализованы. Настройка и точный список — [sdbg-mcp.md](sdbg-mcp.md). не реализованы. Настройка и точный список — [sdbg-mcp.md](sdbg-mcp.md);
проверка legacy Lua и перенос всех raw MCP-возможностей в общую сессию —
[mcp-convergence-plan.md](mcp-convergence-plan.md).
### 8.2 DAP MVP и развитие ### 8.2 DAP MVP и развитие
+149
View File
@@ -0,0 +1,149 @@
# План сведения MCP-интерфейсов MAME и C-отладки
## Цель и границы
Для C-приложения один `sdbg_server.py` владеет одним процессом MAME. VS Code
подключается к нему через DAP, Codex и Claude — через MCP, в том числе без
запущенного VS Code. Агент получает возможности нынешнего raw MCP, сохраняя
проверку C-карты, банки, события и владение точками. Один процесс MAME не
загружает одновременно `mamebridge` и `sdbgbridge`.
Сейчас `MAME.HT/plugins/mamebridge` вместе с `src/mame_mcp.py` публикует 30
raw-инструментов. Старый `src/mame_bridge.lua` использует тот же Python
frontend, но обрабатывает только 16 команд и не отвечает при hard-stop.
`toolchain/sdbg_mcp.py` публикует 16 C-инструментов через общую с DAP сессию.
**Цель — покрыть возможности всех 30 raw-инструментов в C-сессии, а не
механически скопировать имена и небезопасную семантику.** Полный raw MCP
остаётся отдельным режимом для задач без C-пакета и других машин MAME.
Матрица покрытия должна для каждого raw-инструмента содержать имя/аргументы,
адресное пространство, состояние CPU, владельца операции, эквивалент в
C-MCP, ограничения совместной работы с DAP и живой тест. «Покрыт» означает
проверенное поведение, а не только регистрацию инструмента в MCP SDK.
## А. Проверить и убрать `mame_bridge.lua`
1. Зафиксировать 16 команд старого Lua-dispatch: `regs`, `mem`, `setmem`,
`bp`, `bpclr`, `bplist`, `wp`, `wpclr`, `step`, `over`, `out`, `cont`,
`pause`, `status`, `dasm`, `cmd`. Проверять именно Lua-обработчики: Python
frontend показывает 30 инструментов и со старым скриптом, хотя 14 из них
получают `unknown command`.
2. Расширить `MAME.HT/scripts/sprinter/probe-raw-mcp.py` отдельным
воспроизводимым профилем. Запускать legacy script и plugin **по очереди**
с одинаковым BIOS, ROM, fixture и изолированными каталогами IPC/дисков.
Для чтения сравнивать нормализованные результаты, для `setmem` писать лишь
в выделенный scratch-буфер и восстанавливать байты. У legacy проверять
создание/перечень/очистку не срабатывающих точек при running CPU; у plugin
дополнительно проверять реальное попадание и очистку после stop.
`cmd` в сравнении ограничить читающей командой, например `print pc`.
Не выполнять reset/state load ради сравнения: безопасный reset ещё не
подтверждён.
3. Старый frame notifier не обслуживает команды при остановленном CPU.
Поэтому stop-dependent `step`/`over`/`out` и интерактивную работу точек
нельзя требовать от legacy в этом состоянии. Для них сверить трансляцию
команд по коду и проверить поведение plugin при stop→step→inspect. Ошибка
или timeout старого скрипта при hard-stop — его известное ограничение,
а не недостающая функция plugin.
4. Отдельно прогнать 30 инструментов plugin через настоящий MCP stdio-клиент
с корректными предусловиями: running для ввода, stopped для шагов,
изолированные пути для снимков. Для каждой команды проверить содержимое
ответа, а не только отсутствие `unknown command`; после ввода и точек
проверить очистку состояния.
5. Если все 16 legacy-команд покрыты plugin и нет внешнего обязательного
потребителя `-autoboot_script mame_bridge.lua`, удалить файл из активного
дерева MAME.HT. Сохранить его в Git-истории; поправить ссылки в
`MAME_MCP_GUIDE.md`, `src/CLAUDE.md`, `scripts/sprinter/README.md`,
`src/mame_mcp.py` и заголовок plugin, где сейчас заявлено, что отличается
только способ опроса. Зафиксировать отдельным коммитом MAME.HT.
**Выход А:** plugin обеспечивает весь прежний набор и 30 своих инструментов;
проверяемых ссылок на удалённый script в текущем способе запуска нет. До
этого шага считать legacy устаревшим, но не удалённым.
## Б. Подготовить общую C-сессию к расширению
1. Ввести control lease между DAP и MCP для `continue`, `pause`, шагов,
записи памяти, ввода и raw-команд. Читающие операции допускают нескольких
клиентов; конфликтующие изменения получают явный отказ или передачу
управления. У каждой точки, watchpoint и удерживаемой клавиши есть owner;
heartbeat и закрытие соединения освобождают их даже после аварии клиента.
2. Все ответы и запросы связывать с session ID, build ID и generation. При
reset/load/exit или замене EXE инвалидировать старые операции и снимки.
Ограничить размеры запросов, очередь событий и время ожидания; после
timeout не повторять изменяющую команду вслепую. Для дополнительных
возможностей расширять один `sdbgbridge`, а не загружать рядом raw plugin.
3. Определить единый контракт адресов: logical Z80, raw program/data/io,
VRAM/share и текущие страницы банков — разные типы адреса. Существующий
C-инструмент `read_memory` оставляет значение «logical Z80»; raw-чтение
получает другое имя, например `read_program_memory`. Аналогично
`clear_breakpoint` продолжает принимать логический ID владельца, а не
незащищённый MAME ID. Совпадение имени не должно менять старую семантику.
**Выход Б:** два MCP-клиента и DAP читают одну сессию; конкурентные мутации
сериализованы, а потеря клиента не оставляет его точек или нажатых клавиш.
## В. Перенести 30 возможностей raw MCP по группам
| Raw-инструменты | Реализация в общей сессии и проверка |
|---|---|
| `status`, `read_registers`, `step`, `step_over`, `step_out`, `resume`, `pause` | Сохранить C-позицию и события; добавить ограниченный счётчик машинных шагов там, где raw его принимает. Проверить F10/F11/Shift+F11, остановку на пользовательской точке, ожидание `getchar()` и управление из VS Code и MCP. |
| `read_memory`, `read_logical_memory`, `read_vram`, `read_share`, `list_shares`, `write_memory` | Явные пространства и пределы длины, чтение без side effects, маркировка банков. Запись — только с lease и при остановленном CPU, с проверкой диапазона и read-back. Изменение кода/банков инвалидирует или повторно проверяет C-карту; не выдавать изменённый EXE за исходный build. |
| `set_breakpoint`, `clear_breakpoint`, `list_breakpoints`, `set_watchpoint`, `clear_watchpoint` | Raw-адрес и условие вынести в отдельный управляемый API; сохранить C-точки по строке/функции. Учитывать owner, bank/window и физический alias, показывать чужие точки только для чтения. Для watchpoint доказать срабатывание на read/write/IO, корректный PC и отсутствие ложного попадания при загрузке DSS. |
| `disassemble`, `debugger_command`, `screenshot`, `read_screen_pixels` | Дизассемблировать с явным пространством/банком. Снимок и пиксели отдавать с размером, форматом, временем кадра и ограничением объёма; при hard-stop сообщать, что кадр может быть старым. `debugger_command` в общей DAP-сессии сначала поддерживает проверенные читающие команды; полный pass-through — только под эксклюзивным raw lease с переоценкой/инвалидацией состояния после команды. Недопустимую команду отклонять явно, не выдавать частичный результат за поддержку. |
| `list_ports`, `press_key`, `type_string`, `type_text`, `move_mouse`, `click_mouse`, `press_input`, `set_input` | Одна очередь ввода с владельцем, временем удержания и гарантированным release при stop/disconnect/error. Вводить лишь после запуска EXE при running CPU; автоматический ввод DSS оставить launcher. Проверить `getchar()`, графическое приложение, мышь, прямую физическую клавиатуру MAME и отсутствие перехвата фокуса другой программы. |
Для каждой группы сначала добавить ограниченный метод `sdbgbridge`, затем
проверку/событие в `sdbg_server.py`, затем MCP-инструмент и документацию.
Не переносить старые строковые Lua-команды напрямую через MCP: они обходят
проверку типов, владения и generation. Если точная семантика raw-инструмента
небезопасна при открытом DAP, сохранить его функцию в явно эксклюзивном
режиме, а в общей сессии вернуть объясняемое ограничение.
**Выход В:** матрица всех 30 строк закрыта живыми тестами; ограничения raw
pass-through и особенности адресов перечислены поимённо. Число методов C-MCP
может быть больше 30 из-за разных адресных пространств и C-операций.
## Г. Сделать запуск пригодным для Codex и Claude без VS Code
Сейчас `sdbg_mcp.py` подключается лишь к уже работающему socket. Сам
`sdbg_launcher.py` умеет поднять MAME→DSS→EXE→`main` и `sdbg_server.py`
без VS Code, но это ещё не удобный жизненный цикл для MCP-клиента.
1. Добавить supervisor/команду запуска C-сессии с параметрами build,
`MAME_HOME`/`MAME_BIN`/ROM/DSS/образов и стабильным session socket.
MCP handshake должен завершаться быстро; запуск MAME выполняется
асинхронным инструментом с событиями прогресса, чтобы долгий DSS boot не
выглядел как зависший MCP-сервер. Предусмотреть attach к уже работающей
VS Code-сессии и DAP attach к сессии, запущенной агентом.
2. Определить судьбу MAME при закрытии каждого клиента: отсоединение одного
агента не завершает VS Code-сессию; явно управляемая автономная сессия
живёт до `stop_session` или закрытия её владельца согласно выбранной
политике. Повторный MCP старт не должен подключаться к старому socket/PID.
3. Проверить реальные stdio-подключения Codex и Claude отдельно: агент
запускает C-приложение без VS Code, останавливается в `main`, читает
переменную и экран, вводит клавишу; затем VS Code подключается к той же
сессии. Обратный порядок: F5 в VS Code, агент подключается по socket и
действует без второго Lua-моста. Проверить смену lease и cleanup.
**Выход Г:** C-отладка полностью доступна агенту без VS Code, а подключение
агента к VS Code-сессии не создаёт второй MAME и не теряет точки DAP.
## Проверки и ограничения на всём пути
- Живые прогоны выполнять на `MAME.HT/sprinter`, собранном командой
`make SUBTARGET=sprinter SOURCES=src/mame/sinclair/sprinter.cpp`; отдельно
проверить stock + `osx` и patched + `sdbg` там, где функция не требует
патча. Lua-изменения не требуют пересборки бинарника, но требуют нового
запуска MAME.
- Использовать локальный pyenv Python 3.12. Raw MCP пока требует SDK 1.x,
C-MCP — SDK 2.x; окружения разделять до явной миграции frontend. Проверять
оба MCP-клиента на реальном протоколе, а не только прямыми Python-вызовами.
- Тесты на macOS включают окно `osx` как опцию, отзывчивость MAME, ручной
ввод и Debug Console. Linux проверять отдельным живым прогоном. Полный
Windows-маршрут пока не поддерживается из-за Unix socket/host launcher.
- Несколько процессов MAME с MCP остаются отдельной отложенной задачей:
их одновременная работа не проверялась и не гарантируется. Не объявлять
её рабочей по результату тестов нескольких клиентов одной сессии.
- Сохранять риск раннего фокуса MAME отдельной финальной задачей: защита от
случайного ввода до старта EXE не должна ломать DSS bootstrap и прямой
ввод после запуска приложения.
+4 -1
View File
@@ -5,7 +5,8 @@ Unix socket. Это отдельный stdio MCP-сервер для C-уров
сессию, карту сборки и журнал, что VS Code/DAP. В репозитории MAME есть две сессию, карту сборки и журнал, что VS Code/DAP. В репозитории MAME есть две
Lua-реализации **другого**, raw MCP-моста: `src/mame_bridge.lua` Lua-реализации **другого**, raw MCP-моста: `src/mame_bridge.lua`
(`-autoboot_script`) и более новый `-plugin mamebridge`. Оба обслуживают (`-autoboot_script`) и более новый `-plugin mamebridge`. Оба обслуживают
один `src/mame_mcp.py` и общий файловый протокол; plugin использует один `src/mame_mcp.py` и одинаковый файловый транспорт, но legacy Lua
обрабатывает только 16 из 30 публикуемых Python-команд. Plugin использует
`register_periodic` и отвечает даже при остановленном CPU. Ни один из этих `register_periodic` и отвечает даже при остановленном CPU. Ни один из этих
вариантов не должен одновременно управлять тем же MAME в обход sdbg-сессии. вариантов не должен одновременно управлять тем же MAME в обход sdbg-сессии.
`src/mame_mcp.py` всё ещё импортирует `FastMCP` по пути SDK 1.x; `src/mame_mcp.py` всё ещё импортирует `FastMCP` по пути SDK 1.x;
@@ -70,6 +71,8 @@ MCP-сервер заново вместе с новой DAP-сессией. А
Это следующий этап, а не запрет на функции raw MCP. Нельзя просто загрузить Это следующий этап, а не запрет на функции raw MCP. Нельзя просто загрузить
`mamebridge` рядом с `sdbgbridge`: два независимых обработчика начнут менять `mamebridge` рядом с `sdbgbridge`: два независимых обработчика начнут менять
CPU и точки без общего owner ID и журнала. CPU и точки без общего owner ID и журнала.
Поэтапные проверки перед удалением legacy Lua и перенос всех 30 возможностей
в общую C-сессию описаны в [плане сведения MCP](mcp-convergence-plan.md).
Чтение памяти принимает десятичный адрес или `0xHEX`, 1256 байт logical Чтение памяти принимает десятичный адрес или `0xHEX`, 1256 байт logical
Z80 memory, только при остановленном CPU, без side effects. Ответ содержит Z80 memory, только при остановленном CPU, без side effects. Ответ содержит