Стан плану
Версія 1.0. Статус: стабільний. Цей документ специфікує машиночитаний рівень стану плану методології Deep Work Plan. Ключові слова MUST, MUST NOT, SHOULD, SHOULD NOT та MAY тлумачаються згідно з RFC 2119.
Два JSON-артефакти — manifest.json (статична ідентичність плану) та state.json (живий стан виконання по завданнях, включно з результатами валідаційних gate) — що будь-який план MAY нести поряд зі своїми markdown-файлами, а автономне виконання (див. Протокол агента) та робочі простори без git (див. Архетипи §3) MUST нести.
Markdown-план залишається людиночитаним джерелом істини. JSON-рівень є похідною проєкцією: він перегенеровується агентом у визначених точках протоколу, ніколи не редагується вручну й ніколи не може мовчки розходитися з markdown. Його призначення — інтероперабельність: лінтинг, перевірка відповідності, порівняння версій, дашборди, виявлення в реєстрах та синхронізація із зовнішньою інфраструктурою сесій — жодне з цього не можна надійно реалізувати на основі прози.
Навіщо це потрібно
До v1.1 плани були виключно у форматі prose markdown. Це зберігало їхню придатність до аудиту й агентонезалежність, але не лишало нічого, що інструмент міг би валідувати, порівнювати чи споживати: жодного 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), кожен запуск валідаційного gate (запис gate додається або оновлюється) та завершення завдання (completed, як частина протоколу завершення завдання в Специфікації DWP).
Обидва файли MUST записуватися атомарно: запис у тимчасовий файл у тому самому каталозі, потім перейменування поверх цільового. Перерваний запис MUST NOT залишати усічений JSON-файл на місці.
Умови застосування рівня
- При інтерактивному виконанні в git-репозиторії рівень стану RECOMMENDED для нових планів і OPTIONAL для планів до v1.2. План без нього залишається відповідним.
- При автономному виконанні рівень стану REQUIRED.
- У робочому просторі агента без git рівень стану REQUIRED:
state.jsonнесе інформацію для відновлення, яку несе журнал git у репозиторії.
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 є дійсним лише тоді, коли користувач явно вилучив завдання зі scope через refine; state.json MUST NOT використовуватися для мовчазного пропускання роботи.
Запис completed MUST містити completed_at і, де план комітить, короткий хеш commit — це посилання на трасування від плану до коду.
Записи gate
Кожен запуск команди валідації SHOULD бути зафіксований як запис gate: command, passes (boolean), exit_code, last_run та короткий людиночитаний рядок evidence (підсумковий рядок або шлях під analysis_results/, ніколи повний вивід команди).
Завдання MUST NOT позначатися completed у state.json, поки будь-який із його записів gate має passes: false і немає пізнішого успішного запуску. Записи gate є машинним еквівалентом принципу «ніколи не позначати завершеним без доказів» — паттерн прапорця passes на кожен елемент, що охороняє від передчасного завершення.
Записи результатів як епізодична пам’ять
Завершене завдання SHOULD містити запис outcome: що було tried, що failed, що worked та вільні notes. Кожен запис слід вміщати в один рядок.
Записи результатів перетворюють завершений план на відновлювану епізодичну пам’ять: агент (або платформа індексування пам’яті) може пізніше згадати, як було вирішено проблему, а не лише те, що вона була вирішена. Вони живлять обов’язкове фінальне завдання Skills & Agents Discovery, яке SHOULD читати їх під час виявлення паттернів. На платформах, таких як Hermes, що індексують пам’ять агента, записи результатів у state.json роблять завершені плани безпосередньо відновлюваними в майбутніх сесіях.
Checkpoint та заблокований стан
checkpoint фіксує найдрібнішу точку відновлення всередині поточного завдання: id завдання, вільний локатор step, мітку часу та однорядкову нотатку. Агент SHOULD оновлювати його щоразу, коли робить паузу всередині завдання; він MUST оновити його перед будь-яким запланованим перериванням в автономному режимі.
blocked є null або { "task": N, "reason": "...", "since": "...", "needs": "..." }. Автономний агент, що стикається з умовою зупинки, MUST заповнити blocked перед зупинкою — саме так наступне heartbeat-повідомлення демона або людина дізнаються, чому план зупинився.
Проєкція та узгодження
Markdown MUST перемагати в кожному розбіжності. Якщо state.json каже, що завдання 4 completed, але README плану показує непозначений прапорець, — файл стану застарілий.
Агент, що відновлює роботу, MUST порівняти список прапорців README із state.json перед продовженням. У разі десинхронізації він MUST перегенерувати state.json із markdown (та журналу git, де він доступний), зафіксувати узгодження в PROGRESS.md і лише тоді продовжити.
Суб-скіл verify MUST розглядати десинхронізацію як знахідку відповідності: повідомляти, які завдання розходяться і в якому напрямку.
Інструменти, відмінні від виконавчого агента, MUST ставитися до обох JSON-файлів як до файлів лише для читання.
Версіонування схем
Обидві схеми версіонуються за URL (/v1.json). Адитивні поля дозволені в межах однієї версії; перейменування або зміна типу поля вимагає /v2.json та нотатки про міграцію в журналі змін специфікації. Поле spec_version у маніфесті фіксує версію специфікації DWP, під якою було створено план; агент, що зустрічає план новіший за встановлену специфікацію, SHOULD повідомити про це, а не здогадуватися.