# CONVERT-SOURCE — стройка глагола и флип корпуса на XML {#root}

@status:impl/work

[p01] _STATUS: ЗАВЕРШЁН — 2026-08-24: XML-переход доведён до конца (K1…K7 + K6.5-адресуемость; корпус 871+четыре README-хвоста, 2170 ячеечных имён, оба линта, мир рематериализован, панели all green) · остатки — B-106 (доисторическая гниль ссылок) · закон: `vibevm/vibespecs/common/PROP-051-refactor-umbrella.xml` (BUILT)

## Периметр {#perimeter}

[p02] @fact:CONVERT-PERIMETER Мандат владельца покрывает **авторские исходники
спецификаций**: хостовое дерево `spec/` и каждый член `packages/`.
Вне периметра: `vibedeps/` и весь материализованный/генерённый стейт
(PROP-051 ##VIBEDEPS-NEVER-CONVERTED — переезжает рематериализацией),
`CLAUDE.md`/`AGENTS.md`/`GEMINI.md` (имена — контракт харнессов),
`refs/**` (чужое), фикстуры тестов (данные, не исходники), корневые
`*.md` и `campaigns/**` (операционные документы, не спеки; захотим —
тем же глаголом отдельной волной по слову владельца). @status:impl/work

## Нарезка {#slices}

[p03] @fact:K1-TOOL **K1 — глагол.** Ядро классификации в `vibe-specdoc`
(`convert.rs`: класс 1/2/3 по PROP-051 ##HONESTY-BY-REVERSE + loss-diff)
и тонкая команда `vibe refactor convert-source` в `vibe-cli`
(walk + skip-правила ##CONVERT-SOURCE-SURFACE, prompt/`--force`/
`--dry-run`, пофайловый отчёт, коды выхода). Юниты на ядро (все три
класса, комменты как content-loss, оба направления) + e2e на голом
корпусе (tempdir): чистый файл, файл с комментом, `already`, dry-run,
непарность после конверсии. Делегируется; спека коммитится до спавна.
ПОСАЖЕН 2026-08-24 (`bf6a9bd9`): codex-воркер K1-CONVERT, отчёт с
красным доказательством класса 3 в архиве; честная девиация воркера —
канонический `to_markdown` завершает финальный блок двумя `\n`,
фикстура класса 1 обязана нести канонические байты. @status:impl/done

[p04] @fact:K1B-FAMILY **K1b — семейство глаголов (довесок после посадки
ядра).** `--from`/`--to` на всех глаголах (PROP-051 ##FROM-AND-TO),
`convert-package-src` (валидация корня по `vibe.toml`, обход всего
пакета) и `convert-spec-src` (только `spec/` пакета; без аргумента —
текущий корневой проект) — тонкие врапперы над тем же ядром
(##WRAPPERS-SHARE-THE-CORE), плюс алиас `convert-src`. Отдельный
воркер на тёплом worktree K1 или свежий пакет — по состоянию K1.
ПОСАЖЕН 2026-08-24 (`2609cfc3`): тот же codex-воркер свежим тредом на
тёплом worktree; санкционированный сплит `refactor/{mod,convert_source}.rs`;
отказ резолюции корня едет тем же refused-счётчиком, что и файл;
`visible_alias` вместо скрытого clap-`alias` (воркер поймал конфликт
пакета с требованием видимости в `--help`). @status:impl/done

[p05] @fact:K2-INVENTORY **K2 — инвентарь. СНЯТ 2026-08-24** живым инструментом
(`convert-spec-src` по хосту + `convert-package-src` по всем 86 корням
версий). Числа: хост `spec/` — 112 кандидатов (0 byte-stable, 105
IR-stable-loss, 5 ir-divergent, 2 отказа парса, 1 generated-скип,
3 `already`-xml, из них 2 — ЧУЖИЕ xml в research-кэше); пакеты — 840
кандидатов (1 byte-stable, 836 IR-stable-loss, 3 ir-divergent, 16
generated-скипов), причём 129 md под `node_modules` — чужой вендоринг,
конвертировать нельзя. Механический разбор жанра потерь
(токен-мультимножества минус/плюс): **комментарных потерь в авторском
корпусе НОЛЬ** (все 21 — node_modules); 786 файлов — чистый респеллинг
под канон эмиттера (пустые строки после факт-лида и на EOF, пайп-паддинг
таблиц, сброс `:---:`-выравнивания — записанное решение PROP-045 «spelling,
не семантика», перенумерация ordered-списков, легализация вложенных
fences четырьмя бэктиками, демоция повторных H1 в иерархию). Настоящий
хвост, ЖАНРОВО: (а) **БАГ ПИВОТА** — бэктикнутый токен внутри
`comment=` статуса возвращается ПРОБЕЛАМИ той же длины
(`vibevm/vibespecs/design/map-query-language.xml`, `` `471e3b1b` `` → 8 пробелов;
md-фронтенд читает атрибут из замаскированного буфера сканера) —
чинится до флипа, K2.5; (б) **SKILL.md теряют YAML-frontmatter** —
это харнесс-контракт, им нельзя конвертироваться вообще → скип по
имени, K2.5; (в) 7 «reparsed to a different pivot IR» (3 хост-PROP +
2×FRACTALITY-INITIATIVE-PLAN + следы) — разбор конструкции, K2.5;
(г) 2 «td не может нести `|`» (tui-visual-language:130 `` `+-\|` ``,
PROP-002:318 `` `"none" | "token-env" | …` ``) — РЕ-КЛАССИФИЦИРОВАНО
боссовой бисекцией: пайпы стоят внутри КОД-СПАНОВ ячеек, md-форма
существует и репарсится (сканер маскирует код до разбиения ячеек) —
это не предел диалекта, а чрезмерная строгость xml-писателя (проверка
сырого `|` в td без учёта код-спанов); ПОЧИНЕНО K2.6 (`2ec6c0b2`):
ячейки режутся по маске с нарезкой авторского спеллинга, td-проверка
пробует общий сканер — оба файла `ir-stable-loss`, настоящие пределы
(голый пайп, перевод строки) держатся красно-доказанным юнитом; (д) 2 отказа
парса — этот терраформ (`<status>` не под заголовком — починено этим
же коммитом) и `PACKAGES-ACTUALIZATION-CAMPAIGN-v0.1.xml` (14
разметочных долгов anchored-when-marked — ЗАКРЫТО `b988b569`:
хроникальные дневниковые пункты де-маркированы, это проза, не факты).
**КОНТРОЛЬНЫЙ ИНВЕНТАРЬ 2026-08-24 (после K2.5+K2.6): 811 кандидатов
(119 spec + 692 packages), refused=0, ir-divergent=0 по всему
корпусу; skipped-foreign=1 (директорией), skipped-harness=34,
generated-скипы штатны. Корпус готов к массовому флипу K3/K4.** Полные логи:
`$CLAUDE_JOB_DIR/tmp/k2-{spec,packages}.txt` (сессионные), выжимка —
здесь. @status:impl/done

[p06] @fact:K2-5-ENGINEERING-TAIL **K2.5 — инженерный хвост инвентаря (делегируется).**
(1) Дефект маскированного чтения: `StatusEl.comment` (и любой атрибут
элемента) читается из СЫРОГО источника, не из маскированного буфера;
юнит: бэктикнутый токен в comment переживает md→xml→md дословно.
(2) Скипы обхода: `node_modules` (чужой вендоринг — жанр vibedeps) и
харнесс-контрактные имена `CLAUDE.md`/`AGENTS.md`/`GEMINI.md`/
`MEMORY.md`/`SKILL.md` — всегда, с отчётной строкой
`skipped-foreign`/`skipped-harness`. (3) Разбор семи
reparse-дивергенций до именованной конструкции: дефект движка —
чинится; предел диалекта — файл переезжает в ручной список K3.
ПОСАЖЕН 2026-08-24: codex-воркер K25-ENGINE — ВСЕ пять дивергенций
оказались дефектами движка и починены (fragment-`<status>` рядом с
юнитовым `@status` ошибочно назначался статусом факта; многострочный
код-спан с продолжением на `|` ложно открывал таблицу при репарсе;
атрибуты `<status>` читались из маскированного буфера — теперь
scan_text только находит, source_text декодирует, включая `ref=`);
ручной K3-список от дивергенций ПУСТ; скипы skipped-foreign/
skipped-harness живут (явное имя-контракт аргументом — громкий отказ);
19 e2e. Боссов хвост стоил двух красных панелей: пропущенная
specmap-ступень порядка посадки и Windows-локи generated-свапа
(дебрис снесён). @status:impl/done

[p07] @fact:K3-HOST-SPEC **K3 — хостовый `spec/`.** Конверсия всего дерева
(включая `vibevm/vibespecs/WAL.xml` и терраформы; генерённый `vibevm/vibespecs/boot/*` глагол
пропускает сам по маркеру) + свип by-name ссылок на переименованные
пути: инлайн-ссылки в прозе спек, буты/хуки/`TOOLING-MAP.md`, текст
CLAUDE.md, указывающий на `vibevm/vibespecs/WAL.xml`. Гейт: `vibe check` чист,
`wal_wellformed` держит XML-источник через проекцию. ПОСАЖЕН
2026-08-24: 119 файлов одним прогоном `convert-spec-src --to xml
--force`, отказов ноль; в `spec/` остался один .md — генерённый
INDEX.md; свип ссылок — единым скриптом против финального дерева
(двухпроходно: базы-предки для пакетно-относительных путей), новых
висячих ссылок ноль (остаток — доисторическая гниль, B-106). @status:impl/done

[p08] @fact:K4-PACKAGES **K4 — `packages/`.** Каждый член (world, ai-native,
fractality — включая specspace-документы fractality) конвертируется тем
же глаголом; свип их внутренних by-name ссылок и бут-контрактов.
ПОСАЖЕН 2026-08-24: 752 файла одним обходом `convert-source --to xml
--force packages` (версионные корни + specspace-уровень fractality);
вложенные vibedeps/.vibe пакетов не тронуты (законные скипы,
перегенерятся своими установками); харнесс-имена скипнуты по
##FOREIGN-AND-HARNESS-SKIPS. @status:impl/done

[p09] @fact:K5-REMATERIALISE **K5 — рематериализация.** `rm -rf
~/.vibe/cache/<группы>` (B-101), `vibe install` — слоты и ленты
перерождаются из XML-исходников. Ожидаемый дифф STATIC.xml: только
provenance-комменты (расширение источника `.md` → `.xml`; парити-закон
PROP-045 ##INHERITANCE-PARITY), содержимое вкладов byte-identical.
Любое другое движение — находка. ПОСАЖЕН 2026-08-24, две установки:
после конверсий (STATIC.xml байт-в-байт — кэш-стабильный префикс
PROP-048 пережил весь флип нетронутым; INDEX 1512→1514 B — цели
переехали на .xml) и после свипа (STATIC +1 байт — переписанная
ссылка внутри вклада, честное движение содержимого). Найденный и
закрытый фоллаут: (1) вендоренный specmap-движок не имел зеркала
K2.6 — его td-проверка валила весь PROP-002, 122 нерезолвленных
ребра; зеркальная маска посажена в authored-движок +
`sync-engines`, 0 нерезолвленных; (2) `vibe-facts` sync ходил
только по `.md` — обходчик стал формо-слепым
(`is_spec_source` + `load_spec_text`), facts_sync чист;
(3) 34 freshness-предупреждения — хэши пакетов после свипа —
закрыты второй установкой. @status:impl/done

[p10] @fact:K65-CELL-ADDRESSABILITY **K6.5 —
адресуемость ячеечных фактов (рулинг владельца 2026-08-24, дословно:
«проблема не в том, что это атавизм. А в том, что у нас есть факт,
который невозможно адресовать и соответственно проверить его
реализацию в исходнике!»).** Маркированный факт без адреса — дыра
трассируемости, не стиль. Волна: (1) все 604 безымянных ячеечных
факта корпуса получают id — схема `<ID-ряда>-<слаг-заголовка-колонки>`,
именованная XML-форма уже поддержана обоими ридерами (PROP-045
##NAMED-FACT-ELEMENTS; неэлементные id — generic `<fact id=…>`);
(2) закон anchored-when-marked (PROP-043 §3.8) расширяется НА ЯЧЕЙКИ —
маркированная ячейка без id становится громким отказом строгого
фронтенда (red-first), чтобы класс не возрождался; (3) цена: ~604
новых судимых факта — судейский долг растёт, приоритет разбора — за
владельцем по стоячему правилу. Исполнение — после посадки K6. ПОСАЖЕНО 2026-08-24 (`82e6b335`+`7b9b7535`+`9995bb76`): 2170 имён (2049 xml воркером K65-CELLS, скрипт в архиве; 121 md-хвост боссом — четыре reserved-README, открытые новым линтом), оба фронтенда отказывают безымянной маркированной ячейке (red-first), голден 66, STATIC без единой безымянной, панель all green. @status:impl/done

[p11] @fact:K6-GATES **K6 — гейты и свипы.** Полная панель по хвосту; specmap
регенерация (пути юнитов переезжают на `.xml`); судейский долг остаётся
«no debt» (адресация format-blind — PROP-045 ##ADDRESSING-UNCHANGED);
грепом — ни одной живой ссылки на сконвертированный `.md`-путь;
WAL-ожидания обновлены. @status:impl/done

[p12] @fact:K7-WINDDOWN **K7 — финализация.** Статусы PROP-051 → impl/done,
этот план закрывается приёмкой, остатки — в BACKLOG. @status:impl/done

## Приёмка {#acceptance}

[p13] @fact:CONVERT-ACCEPTANCE В периметре не остаётся ни одного авторского
`.md`-спека (вне периметра — нетронуто); панель `all green`;
`vibe check` 0/0/0; judging-debt «no debt»; STATIC.xml — только
ожидаемый provenance-дифф; `vibe refactor convert-source --dry-run`
по обоим деревьям отвечает «already» на 100 % файлов. @status:impl/plan

