Состояние плана
Версия 1.0. Статус: стабильная. Этот документ специфицирует машиночитаемый слой состояния плана методологии Deep Work Plan. Ключевые слова MUST, MUST NOT, SHOULD, SHOULD NOT и MAY следует трактовать так, как описано в RFC 2119.
Два JSON-артефакта — manifest.json (статическая идентичность плана) и state.json (живое, пер-задачное состояние выполнения, включая результаты validation gates) — которые каждый план MAY нести рядом со своими markdown-файлами, и которые неавтономное выполнение (см. Протокол агента) и рабочие пространства агента без git (см. Архетипы §3) MUST нести.
Markdown-план остаётся человекочитаемым источником истины. Слой JSON — это производная проекция: он регенерируется агентом в определённых протокольных точках, никогда не редактируется вручную и ни в коем случае не должен молча расходиться с markdown. Его цель — интероперабельность: линтинг, проверка соответствия, diffing, дашборды, обнаружение в реестре и синхронизация с внешней инфраструктурой сессий — ни одно из этих применений нельзя строить надёжно на прозе.
Зачем это нужно
До версии v1.1 планы существовали только как прозаический markdown. Это сохраняло их проверяемость и агент-нейтральность, но не оставляло ничего, что инструмент мог бы валидировать, сравнивать или потреблять: никакого conformance gate, никакого обнаружения рассинхронизации между README.md и PROGRESS.md, никакого способа для демона или облачной сессии узнать состояние плана, не разбирая прозу. Версия v1.2 добавляет JSON-проекцию, не понижая markdown — проекция производится из markdown так же, как lockfile производится из манифеста.
Расположение
План, использующий слой состояния, имеет следующую структуру:
.dwp/plans/PLAN_{name}/
├── README.md ← человеческий источник истины (без изменений)
├── PROGRESS.md ← нарративный журнал (без изменений)
├── PROMPTS.md ← без изменений
├── manifest.json ← статическая идентичность (записывается при материализации)
├── state.json ← живое состояние (перезаписывается в протокольных точках)
├── analysis_results/
└── {N}.task_{...}.md
manifest.json MUST быть записан ровно один раз — когда поток create материализует план — и MUST NOT изменяться впоследствии, за исключением миграции версии спецификации, зафиксированной в PROGRESS.md.
state.json MUST перезаписываться агентом в каждой из этих протокольных точек: материализация плана (все задачи pending), начало задачи (in_progress), каждый запуск validation gate (запись gate добавляется или обновляется) и завершение задачи (completed, в составе протокола завершения задачи в Спецификации DWP).
Оба файла MUST записываться атомарно: записать во временный файл в той же директории, затем переименовать поверх целевого. Аварийная запись MUST NOT оставлять усечённый JSON-файл на месте.
Когда слой обязателен
- При интерактивном выполнении в git-репозитории слой состояния RECOMMENDED для новых планов и OPTIONAL для планов до версии v1.2. План без него остаётся conformant.
- При автономном (unattended) выполнении слой состояния REQUIRED.
- В рабочем пространстве агента без git слой состояния REQUIRED:
state.jsonнесёт информацию для восстановления, которую git log несёт в репозитории.
manifest.json — идентичность плана
{
"schema": "https://deepworkplan.com/schema/plan-manifest/v1.json",
"spec_version": "2.2.0",
"name": "PLAN_payment_webhooks",
"title": "Add payment webhook handling",
"archetype": "individual",
"rigor": "standard",
"created_at": "2026-06-09T14:00:00Z",
"created_by": { "agent": "claude-code", "model": "claude-fable-5" },
"tags": ["backend", "payments"],
"task_count": 7,
"parent_plan": null
}
schema, spec_version, name, archetype, rigor, created_at и task_count REQUIRED.
archetype MUST быть одним из: individual, orchestrator-hub, agent-workspace.
rigor MUST быть одним из: micro, standard, deep (см. Пропорциональная строгость).
parent_plan связывает дочерний план с планом-оркестратором ({repo}:{plan_name} или null).
created_by SHOULD идентифицировать создавшего агента и модель. Он MUST NOT содержать секреты, токены или идентификаторы пользователей помимо отображаемого имени.
state.json — живое состояние выполнения
{
"schema": "https://deepworkplan.com/schema/plan-state/v1.json",
"plan": "PLAN_payment_webhooks",
"updated_at": "2026-06-09T16:42:10Z",
"updated_by": { "agent": "claude-code", "model": "claude-fable-5" },
"status": "in_progress",
"completed_count": 2,
"task_count": 7,
"tasks": [
{
"id": 1,
"file": "1.task_webhook_endpoint.md",
"title": "Create webhook endpoint",
"status": "completed",
"started_at": "2026-06-09T14:10:00Z",
"completed_at": "2026-06-09T15:02:33Z",
"commit": "a1b2c3d",
"gates": [
{
"command": "pnpm run test",
"passes": true,
"exit_code": 0,
"last_run": "2026-06-09T15:01:50Z",
"evidence": "42 passed, 0 failed"
}
],
"outcome": {
"tried": ["raw body parsing via middleware"],
"failed": ["initial signature check used wrong header"],
"worked": "verify signature against X-Sig header before JSON parse",
"notes": "stripe-style HMAC; see analysis_results/webhook_notes.md"
}
},
{
"id": 3,
"file": "3.task_retry_queue.md",
"title": "Add retry queue",
"status": "in_progress",
"started_at": "2026-06-09T16:30:00Z",
"gates": []
}
],
"checkpoint": {
"task": 3,
"step": "instructions:4",
"at": "2026-06-09T16:42:10Z",
"note": "queue table migrated; worker loop not yet wired"
},
"blocked": null
}
Записи задач
Каждый файл задачи в плане MUST иметь ровно одну запись в tasks, с ключами по номеру (id) и имени файла (file).
status MUST быть одним из: pending, in_progress, completed, blocked, skipped. skipped допустим только когда пользователь явно исключил задачу из области через refine; state.json MUST NOT использоваться для молчаливого пропуска работы.
Запись completed MUST содержать completed_at и, где план делает коммиты, короткий хеш коммита (commit) — это ссылка трассируемости между планом и кодом.
Записи gate
Каждый запуск команды валидации SHOULD записываться как gate-запись: command, passes (булево), exit_code, last_run и краткая человекочитаемая строка evidence (итоговая строка или путь в analysis_results/, но никогда не полный вывод команды).
Задача MUST NOT помечаться как completed в state.json, пока любая из её gate-записей имеет passes: false без последующего успешного запуска. Gate-записи — это машинный эквивалент принципа «никогда не помечать завершённым без доказательств» — шаблон флага passes для каждого элемента, защищающий от преждевременного завершения.
Записи outcome как эпизодическая память
Завершённая задача SHOULD нести запись outcome: что было tried, что failed, что worked и свободные notes. Каждая запись должна умещаться в одну строку.
Записи outcome превращают завершённый план в доступную эпизодическую память: агент (или платформа для индексации памяти) впоследствии сможет вспомнить, как была решена конкретная проблема, а не только то, что она была решена. Они питают обязательную итоговую задачу «Обнаружение навыков и агентов», которая SHOULD читать их при поиске паттернов. На таких платформах, как Hermes, индексирующих память агентов, записи outcome в state.json делают завершённые планы напрямую доступными через будущие сессии.
Контрольная точка и заблокированное состояние
checkpoint фиксирует наиболее детальную точку возобновления внутри текущей задачи: id задачи, свободный локатор step, метку времени и однострочную заметку. Агент SHOULD обновлять его при каждой паузе внутри задачи; он MUST обновлять его перед любым запланированным прерыванием в автономном режиме.
blocked равен null или { "task": N, "reason": "...", "since": "...", "needs": "..." }. Автономный агент, столкнувшийся с условием остановки, MUST заполнить поле blocked перед остановкой — именно так следующее «сердцебиение» демона или человек узнает, почему план остановился.
Проекция и согласование
Markdown MUST выигрывать каждое разногласие. Если state.json говорит, что задача 4 completed, но план README показывает непомеченный чекбокс, — файл состояния устарел.
Возобновляющий агент MUST сравнить список чекбоксов в README с state.json перед продолжением. При рассинхронизации он MUST регенерировать state.json из markdown (и git log, где он доступен), зафиксировать согласование в PROGRESS.md и только после этого продолжать.
Под-навык verify MUST рассматривать рассинхронизацию как conformance-находку: сообщить, какие задачи расходятся и в каком направлении.
Инструменты, отличные от исполняющего агента, MUST рассматривать оба JSON-файла как доступные только для чтения.
Версионирование схем
Обе схемы версионируются через URL (/v1.json). Аддитивные поля допустимы в рамках версии; переименование или изменение типа поля требует /v2.json и примечания о миграции в журнале изменений спецификации. Поле spec_version в манифесте фиксирует версию спецификации DWP, под которой был создан план; агент, встречающий план новее своей установленной спецификации, SHOULD сообщить об этом, а не угадывать.