<?xml version="1.0" encoding="UTF-8"?>
<spec xmlns="https://vibevm.org/spec/1">
  <title id="root">Progress Control — руководство владельца</title>
  <status stage="doc" state="done" action="drift" audience="dev" comment="владельческий гайд; жанр — guide, не контракт; fact grain 2026-07-24; S1 предшествует fact-поправке PROP-043 S3.8 items 4-6 — нет элементов списков, ячеек, ##-якорей (F-020)"/>
  <list ordered="false" p="1">
    <item><fact id="guide-purpose" status="doc/done">Этот документ — для человека. Контракт системы — [PROP-043](../vibe-facts/PROP-043-facts-markup.xml) (грамматика) и [PROP-047](PROP-047-progress-campaigns.xml) (инструмент и кампании);
  план кампании — [SPEC-ACTUALIZATION-CAMPAIGN-v0.1](../../terraforms/SPEC-ACTUALIZATION-CAMPAIGN-v0.1.xml).</fact></item>
    <item><fact id="guide-scope" status="doc/done">Здесь — как этим пользоваться, что смотреть и какие решения ждут лично вас.</fact></item>
    <item><fact id="guide-language" status="doc/done">Язык — русский, потому что аудитория этого файла — владелец проекта.</fact></item>
  </list>
  <section title="1. Как читать маркеры в спеках">
    <p p="2"><fact id="marker-reading" status="doc/done">Маркер — XML-тег в тексте. Читается как «стадия/состояние [+ что делать]»:</fact></p>
    <fence p="3">&lt;status stage="impl" state="work"/&gt;</fence>
    <p p="4"><fact id="shorthand-examples" status="doc/done">— «реализация в процессе». То же самое сокращённо: `@impl` (state=work
подразумевается). `@test/plan` — «тестирование запланировано».</fact></p>
    <p p="5"><fact id="vocab-lead" status="doc/done">Полный словарик:</fact></p>
    <table p="6">
      <tr>
        <td>stage</td>
        <td>значит</td>
      </tr>
      <tr>
        <td><fact id="ST-IDEA" status="doc/done">`idea`</fact></td>
        <td><fact id="ST-IDEA-COLUMN-2" status="doc/done">идея, ещё не специфицирована</fact></td>
      </tr>
      <tr>
        <td><fact id="ST-SPEC" status="doc/done">`spec`</fact></td>
        <td><fact id="ST-SPEC-COLUMN-2" status="doc/done">пишем/написали спеку</fact></td>
      </tr>
      <tr>
        <td><fact id="ST-IMPL" status="doc/done">`impl`</fact></td>
        <td><fact id="ST-IMPL-COLUMN-2" status="doc/done">реализуем/реализовано</fact></td>
      </tr>
      <tr>
        <td><fact id="ST-TEST" status="doc/done">`test`</fact></td>
        <td><fact id="ST-TEST-COLUMN-2" status="doc/done">тестируем/протестировано</fact></td>
      </tr>
      <tr>
        <td><fact id="ST-DOC" status="doc/done">`doc`</fact></td>
        <td><fact id="ST-DOC-COLUMN-2" status="doc/done">документируем/задокументировано</fact></td>
      </tr>
      <tr>
        <td><fact id="ST-FREEZE" status="doc/done">`freeze`</fact></td>
        <td><fact id="ST-FREEZE-COLUMN-2" status="doc/done">замораживаем (plan → work → done = заморожено; разморозка = смена маркера назад)</fact></td>
      </tr>
      <tr>
        <td><fact id="ST-UNKNOWN" status="doc/done">`unknown`</fact></td>
        <td><fact id="ST-UNKNOWN-COLUMN-2" status="doc/done">«смотрел и не понял» — явный запрос на триаж</fact></td>
      </tr>
    </table>
    <table p="7">
      <tr>
        <td>state</td>
        <td>значит</td>
      </tr>
      <tr>
        <td><fact id="SS-PLAN" status="doc/done">`plan`</fact></td>
        <td><fact id="SS-PLAN-COLUMN-2" status="doc/done">собираемся</fact></td>
      </tr>
      <tr>
        <td><fact id="SS-WORK" status="doc/done">`work`</fact></td>
        <td><fact id="SS-WORK-COLUMN-2" status="doc/done">делаем</fact></td>
      </tr>
      <tr>
        <td><fact id="SS-DONE" status="doc/done">`done`</fact></td>
        <td><fact id="SS-DONE-COLUMN-2" status="doc/done">сделали (для этой стадии)</fact></td>
      </tr>
      <tr>
        <td><fact id="SS-HOLD" status="doc/done">`hold`</fact></td>
        <td><fact id="SS-HOLD-COLUMN-2" status="doc/done">сознательно отложено</fact></td>
      </tr>
    </table>
    <p p="8"><fact id="optional-fields-lead" status="doc/done">Необязательные поля:</fact></p>
    <list ordered="false" p="9">
      <item><fact id="FIELD-ACTION" status="doc/done">`action` — вердикт «что делать»
  (`continue` — доделать; `drift` — разъехалось с реальностью, свести;
  `rework` — переделать; `remove` — убрать);</fact></item>
      <item><fact id="FIELD-ACTIONSTAGE" status="doc/done">`actionstage` — на какую стадию
  действует action (`remove`+`actionstage="doc"` = «удалить документацию»);</fact></item>
      <item><fact id="FIELD-AUDIENCE" status="doc/done">`audience` — для кого это документировать (`user` — пользователь vibevm,
  `author` — автор пакетов, `dev` — мы сами);</fact></item>
      <item><fact id="FIELD-COMMENT-REF" status="doc/done">`comment`, `ref` (ссылка на
  задачу DRIFT-NNN или spec://-анкер).</fact></item>
    </list>
    <p p="10"><fact id="placement-lead" status="doc/done">Куда можно ставить маркер — шесть гранулярностей (PROP-043 §3.8):</fact></p>
    <list ordered="false" p="11">
      <item><fact id="PLACE-DOCUMENT" status="doc/done">в преамбуле, до первого заголовка (весь документ). В файле без
  преамбулы — а это стандартная форма в этом репозитории — маркер сразу после первого
  заголовка и есть документный;</fact></item>
      <item><fact id="PLACE-SECTION" status="doc/done">отдельной строкой сразу после заголовка (секция) — кроме первого
  заголовка файла без преамбулы: там эта позиция занята документным маркером;</fact></item>
      <item><fact id="PLACE-PARAGRAPH" status="doc/done">первым или последним токеном внутри абзаца (абзац);</fact></item>
      <item><fact id="PLACE-LIST-ITEM" status="doc/done">последним токеном внутри элемента списка (элемент списка);</fact></item>
      <item><fact id="PLACE-TABLE-CELL" status="doc/done">внутри ячейки таблицы (ячейка);</fact></item>
      <item><fact id="PLACE-FRAGMENT" status="doc/done">парным тегом вокруг текста (фрагмент).</fact></item>
      <item><fact id="PLACE-FACT-ANCHOR" status="doc/done">Любая из этих единиц может нести якорь факта `@fact:&lt;ID&gt;` в начале —
  тогда она адресуема по `spec://…#&lt;ID&gt;`. Прежнее написание `##&lt;ID&gt;` значит ровно то
  же и по-прежнему читается, но пишется теперь первое. Закон anchored-when-marked:
  размеченный факт обязан быть заякорен;</fact></item>
      <item><fact id="STANDALONE-ERROR" status="doc/done">Одинокий маркер между
  абзацами — ошибка, инструмент его отвергнет.</fact></item>
    </list>
  </section>
  <section title="2. Ежедневные команды">
    <p p="12"><fact id="DAILY-COMMANDS" status="doc/done">Команды ниже — **утверждение о том, что умеет
инструмент сегодня**, а не пример: забор входит в тело этого факта, поэтому
любая правка внутри него приводит факт к пересуду. Первая строка когда-то
утверждала обратное тому, что есть на самом деле, и прожила так долго именно
потому, что забор нельзя было осудить.</fact></p>
    <fence lang="bash" fact="DAILY-COMMANDS" p="13">vibe progress check --exhaustive   # валидация разметки; С 2026-08-06 стоит и в гейт-панели
vibe progress report --md      # статус дерева таблицей
vibe progress report --md --view todo        # что доделать
vibe progress report --md --view qa          # что тестировать
vibe progress report --md --view remove      # что удалить
vibe progress report --md --view doc --audience user   # оглавление user-доки
vibe progress weave --digest   # карта всего корпуса, влезает в контекст LLM</fence>
    <list ordered="false" p="14">
      <item><fact id="HYGIENE-RULE" status="doc/done">Правило гигиены между кампаниями (одно): **правите юнит спеки — обновите его
  маркер в том же коммите.**</fact></item>
      <item><fact id="tool-guards" status="doc/done">Всё остальное караулит инструмент.</fact></item>
    </list>
  </section>
  <section title="3. Кампания: запуск, наблюдение, ваша роль">
    <list ordered="false" p="15">
      <item><fact id="campaign-home" status="doc/done">Кампания живёт в `campaigns/&lt;id&gt;/` (например `campaigns/progress-2026-08/`).</fact></item>
      <item><fact id="guide-side-pointer" status="doc/done">Все стадии, гейты и правила — в плане кампании; здесь — ваша сторона.</fact></item>
    </list>
    <section title="3.1 Дашборд">
      <fence lang="bash" p="16">node tools/progress-dashboard/serve.mjs    # затем открыть http://localhost:&lt;port&gt;</fence>
      <list ordered="false" p="17">
        <item><fact id="DASH-RESUME" status="doc/done">Первый экран — Resume: что не завершено (красным), что дальше, свежесть
  состояния (жёлтая плашка = state давно не обновлялся — загляните, жива ли
  сессия).</fact></item>
        <item><fact id="DASH-CORPUS" status="doc/done">Дальше: Корпус (дерево файлов цветом по статусу),</fact></item>
        <item><fact id="DASH-STITCHING" status="doc/done">Сшивка (график
  открытых обязательств по волнам — линия обязана падать),</fact></item>
        <item><fact id="DASH-TASKS" status="doc/done">Задачи (чем занят
  Opus, что застряло в review).</fact></item>
        <item><fact id="DASH-READ-ONLY" status="doc/done">Дашборд read-only: он ничего не считает и
  ничего не может испортить.</fact></item>
        <item><fact id="dash-terminology" status="doc/done">(Терминология: эта страница — «дашборд», не
  «витрина»/«storefront» — те слова заняты витриной магазина vibevm.)</fact></item>
      </list>
    </section>
    <section title="3.2 Какие решения ждут лично вас (по стадиям кампании)">
      <list ordered="false" p="18">
        <item><fact id="OWNER-A" status="doc/done">**A (scaffold):** ратифицировать PROP-043; подтвердить имя зоны
  `campaigns/`; ничего больше.</fact></item>
        <item><fact id="OWNER-B" status="doc/done">**B (разметка):** выборочно читать диффы батчей — маркеры и сплиты, смысл
  текста меняться не должен. Сигнал тревоги: любой содержательный дифф.</fact></item>
        <item><fact id="OWNER-C" status="doc/done">**C (верификация):** ничего решать не нужно; полезно поглядывать на
  сводку X% confirmed / Y% drift — это первый измеренный уровень
  актуальности ваших спеков.</fact></item>
        <item><fact id="OWNER-D" status="doc/done">**D (сшивка):** к вам приходят только **эскалации** — пары документов, чей
  конфликт не сходится две волны. Это концептуальные развилки: нужен ваш
  вердикт, какая трактовка верна. Плюс все правки спек по мотивам
  sync-from-code показываются вам ДО применения — как и всегда в этом
  проекте.</fact></item>
        <item><fact id="OWNER-E" status="doc/done">**E (кодирование):** приёмка спорных PR после ревью Fable; вердикты по
  `remove`/`rework` спискам (удалять ли, отключать ли фичефлагом).</fact></item>
        <item><fact id="OWNER-F" status="doc/done">**F (планы):** три плана (release / улучшения / идеи) приходят к вам на
  утверждение приоритетов.</fact></item>
        <item><fact id="OWNER-G" status="doc/done">**G (документация):** вычитка глав двух гайдов — регистр и правда. Все
  примеры в доке уже реально исполнялись (это гарантия конвейера), ваша
  проверка — «то ли это, что я хотел сказать людям».</fact></item>
      </list>
    </section>
    <section title="3.3 Если сессия оборвалась (бюджет, питание, что угодно)">
      <p p="19"><fact id="crash-recovery" status="doc/done">Ничего не чините руками. Новая сессия (любая — Fable или Opus) начинает с:</fact></p>
      <fence p="20">прочитай campaigns/&lt;id&gt;/run/RESUME.md и продолжай по нему</fence>
      <list ordered="false" p="21">
        <item><fact id="RESUME-CONTRACT" status="doc/done">RESUME.md сгенерирован журналом и говорит буквально: какой шаг не закрыт,
  какие файлы откатить (`git restore …`), что делать следующим.</fact></item>
        <item><fact id="MAX-LOSS-ONE-STEP" status="doc/done">Максимальная
  потеря при любом обрыве — один шаг (один файл разметки / один юнит
  верификации / одна задача).</fact></item>
      </list>
    </section>
    <section title="3.4 Перезапуск через месяц (и далее регулярно)">
      <fence lang="bash" p="22">vibe progress rescan --baseline campaigns/&lt;прошлая&gt;/baseline.json</fence>
      <list ordered="false" p="23">
        <item><fact id="RESCAN-TRIAGE" status="doc/done">Инструмент сам разложит корпус на «новое / изменившееся (перепроверить) /
  нетронутое (переносим вердикт)». Дальше — тот же цикл, но объёмом O(дельты):
  дни, не месяц.</fact></item>
        <item><fact id="FOUR-SURVIVORS" status="doc/done">Между кампаниями из зоны кампании хранятся только четыре вещи
  (PROP-047 §5.4): `baseline.json` (ускоритель перепроверки), `deferrals.md` (открытые
  хвосты), `harvest/` (сырьё для доки) и `tasks/` (корпус задач). Маркеры тоже
  переживают кампанию, но они живут в спеках — это корпус, а не зона.</fact></item>
        <item><fact id="ERASURE-SAFE" status="doc/done">Всё остальное можно
  стирать в любой момент — знание не теряется.</fact></item>
      </list>
    </section>
  </section>
  <section title="4. Аварийные случаи">
    <list ordered="false" p="24">
      <item><fact id="EMERG-DISPUTED-MARKER" status="doc/done">**Маркер спорный / кажется неправдой** — правьте смело или ставьте
  `unknown`: маркер — это state-слой (как WAL), а не нормативный текст;
  ваша правка законна всегда.</fact></item>
      <item><fact id="EMERG-TOOL-FALSE-POSITIVE" status="doc/done">**Инструмент ругается на легальный, по-вашему, случай** — это баг
  инструмента или пробел PROP-047; фиксируйте как обычный баг, маркер
  временно допустимо сопроводить `comment="check false-positive: …"`.</fact></item>
      <item><fact id="EMERG-DASHBOARD-WEIRD" status="doc/done">**Дашборд показывает странное** — он лишь проекция; истина в
  `campaigns/&lt;id&gt;/run/state/*.json`, а выше неё — маркеры в спеках. Конфликт
  решается перегенерацией (`vibe progress scan`), никогда правкой JSON.</fact></item>
      <item><fact id="EMERG-ABANDON-SAFE" status="doc/done">**Хочется бросить кампанию посреди** — безопасно в любой момент: границы
  батчей закоммичены, RESUME.md всегда говорит, где вы. Возврат через месяц
  = п. 3.4.</fact></item>
    </list>
  </section>
</spec>
