Skip to content
← Усі документи специфікації

Шар записів

Обсяг версії: Ця сторінка переказує нормативний шар записів v6, на якому будується поточний стандарт DWP 7.0.0. Канонічні джерела в релізі v7.9.0: V6_CONTRACT.md і V6_LIFECYCLE.md. Якщо ця сторінка й ці файли розходяться, перевагу мають файли. Плани v5 зберігають рівень стану плану і ніколи не мігрують неявно.

Версія 6.0.0, розширена у 7.0.0. Статус: стабільний. Шар записів замінює наративне завершення записами: контракт є авторитетом, журнал — памʼяттю, записи виконують допоміжні скрипти, а кожен згенерований файл є проєкцією. Ключові слова MUST, MUST NOT, SHOULD, SHOULD NOT та MAY тлумачаться згідно з RFC 2119.

Модель в одному рядку

План — це два авторські артефакти й одна захищена послідовність. Markdown плану (README.md і файли завдань) описує, що буде зроблено. Контракт результату (contract.json) визначає, що вважається виконаним і що плану дозволено робити. Журнал (journal.ndjson) фіксує, що насправді відбулося. state.json і views/ перегенеровуються з журналу та MUST NOT редагуватися вручну; коли згенерований файл і журнал розходяться, перевагу має журнал, а файл перегенеровується.

Визначення покоління

Папка плану є планом лінії v6 тоді й лише тоді, коли вона містить manifest.json, чий вказівник contract розвʼязується, contract.json або ланцюжок ревізій contracts/. Визначення MUST спиратися на ці артефакти, а не на версію встановленого пакета: поточний пакет може містити плани v5, а старіший пакет може натрапити на план v6.

URL schema контракту називає його покоління, і маніфест та кожна подія журналу його віддзеркалюють:

Покоління Контракт Події журналу Маніфест Додає
v6 plan-contract/v6 journal-event/v6 plan-manifest/v6 —
v7 plan-contract/v7 journal-event/v7 plan-manifest/v7 parallel_safe і подію delegation (Делегування)

Нові плани, створені пакетом 7.x, за замовчуванням належать до v7; явний запит v6 і далі матеріалізує контракт v6. План ніколи не змінює покоління, а журнал, що змішує покоління, MUST бути відхилений. Обидва покоління проєктуються в ту саму форму plan-snapshot/v6.

Контракт результату

Один контракт на план, що відповідає схемі свого покоління. Він містить формулювання результату й визначення успіху, критерії приймання, завдання з їхніми передумовами, торкнутою поверхнею та наміром gate, інваріанти рівня плану, scope (дозволені шляхи, класи команд, заборонені операції), ресурсний конверт, обмеження планування, дозволи й запис авторизації.

  • Ідентичність. contract_id — це SHA-256 канонічних байтів контракту без поля id. Кожен запис, створений за контрактом, посилається на нього.
  • Незмінність. Після початку виконання контракт MUST NOT змінюватися. Змінений контракт — це нова ревізія в contracts/, що посилається на батьківську, з безперервною нумерацією ревізій і заново зафіксованими повноваженнями.
  • Стабільні id. Критерії (AC-*), інваріанти (INV-*) і завдання (T-*) MUST бути унікальними, а записи посилаються на id, ніколи на позиції в списку. Граф завдань MUST бути ациклічним, і кожен намір gate MUST посилатися на оголошений критерій.
  • Дозволи. Надані й ненадані можливості MUST бути неперетинними підмножинами замкненого набору: gate_command_exec, fs_write_plan_scope, fs_write_repo_scope, git_operations, network_access, host_adapter_metering, agent_delegation, context_export.
  • Авторизація. Механізм — рівно plan_authorship (людина написала або переглянула план до виконання) або pre_authorization (постійний дозвіл із визначеним конвертом, як у trust-режимі). Обидва працюють як gate однаково; різниться лише зафіксоване джерело повноважень.
  • Закривність. Кожен критерій MUST бути закривним: критерій, який перевіряє gate завдання, закривається доказом observed від цього gate або підтвердженням людини класу asserted — відповідно до класів доказів, які він приймає. Чернетковий критерій, що не приймає жодного з них, відхиляється.

Матеріалізація

План матеріалізує допоміжний скрипт із пакета (ledger.py materialize), ніколи не вручну, рівно в такому порядку; кожен крок ідемпотентний і відновлюваний:

  1. manifest.json із вказівником на контракт — записується першим, щоб покоління плану можна було визначити навіть після перерваної матеріалізації.
  2. contract.json — валідований і адресований за вмістом.
  3. Подія журналу approval, що посилається на id контракту й дайджест markdown плану.

Лише ця подія схвалення відкриває gate старту завдань. Скопійований вручну контракт без неї відхиляється на старті завдання, а маніфест, чий вказівник не збігається з контрактом, що матеріалізується, відхиляється, а не переписується.

Журнал

journal.ndjson — лише для додавання: один замкнений JSON-обʼєкт на рядок, який ніколи не редагується й не видаляється. Виправлення — це пізніша подія. Кожна подія містить свою схему, тип, строго зростаючий seq, мітку часу, план, contract_id і актора (helper, agent, host_adapter або human). Каталог подій охоплює старти завдань, схвалення, запуски gate, спостереження, адаптації, поправки, втручання, вибірки ресурсів, контрольні пари, вибори планувальника, відмови, рендеринг представлень, узгодження й виправлення журналу; v7 додає події делегування. Кожна відмова сама фіксується.

Класи доказів

Події, що несуть докази, фіксують мітку довіри:

  1. observed — допоміжний скрипт із пакета сам виконав перевірку з оголошеними робочою директорією, середовищем, тайм-аутом і захопленим виводом. Лише запускач gate (ledger.py gate) створює докази gate класу observed; агент, який просто записує результат, про який сам повідомляє, цього не може.
  2. imported — узято з відповідного зовнішнього джерела з походженням, наприклад мігрований запис gate v5, чий вказівник на докази розвʼязується.
  3. asserted — заявлено без незалежного встановлення.

Кожен критерій оголошує, які класи він приймає, тож критерій лише для observed ніколи не закриється на основі заяви. Контрольні суми встановлюють побайтову ідентичність, а не семантичну істинність; шар записів перевіряє структуру й походження і не доводить семантику продукту.

Підтвердження людиною

Критерій, який має оцінити людина, закривається через ledger.py signoff --criterion <AC> --evidence-path <artifact> --authority <who>. Підтвердження фіксується як asserted, посилається на артефакт, на якому ґрунтується, зараховується лише у вікні доказів завдання, що його оголошує, і закриває лише критерій, який приймає asserted. Агент ніколи не підтверджує замість людини. Записи з актором-людиною, створені поза матеріалізацією, несуть явний маркер повноважень (нотатку, написану людиною й зафіксовану за шляхом і дайджестом, або інтерактивне підтвердження); реєстр не може автентифікувати особу, тож маркер робить заяву придатною до аудиту, а не спостереженою.

Контрольовані критерії

Критерій, оголошений як контроль регресії чи розрізнення, закривається лише розрізнювальною контрольною парою: перевірка падає на початковій ревізії й проходить на новій. Пара, що проходить на обох гілках, фіксується як нерозрізнювальна й ніколи не округлюється вгору; брудний старт або недоступна стара гілка фіксуються як недоступний контроль і ніколи не синтезуються.

Виконання й завершення

Диспетчеризацію виконує детермінований планувальник (scheduler.py ready), а ledger.py start відхиляє завдання з незавершеними передумовами. Кожен старт завдання фіксує відбиток робочого дерева, і докази повторно використовуються лише для того самого завдання й критерію на еквівалентному відбитку.

Інваріанти мають рівень плану. Кожен оголошений інваріант діє впродовж усього плану й оцінюється на кожній межі як спостереження (INV-<id>: pass або INV-<id>: fail: <reason>). Властивість, яку мають зберігати лише деякі завдання, є критерієм приймання цих завдань, а не інваріантом.

Завершення виводиться, а не оголошується. ledger.py complete відмовляє — і фіксує відмову, — поки будь-якому критерію бракує прийнятого доказу у вікні або будь-якому інваріанту бракує свіжої успішної оцінки. Знімок показує завдання завершеним рівно тоді, коли записи це підтверджують.

Адаптації й поправки

Зміни під час виконання — це пропозиції планувальнику, обмежені замкненим набором: split, reorder, insert, change_strategy і retry. Адаптація MUST NOT видаляти вимогу, послаблювати чи підміняти приймання, розширювати scope чи дозволи, витрачати понад конверт або позначати невиконаний сценарій завершеним.

Зміна scope, критеріїв приймання, дозволів чи конверта — це поправка до контракту: ledger.py amend готує переглянутий контракт як наступну ревізію, фіксує поправку разом із критеріями, чиї попередні докази вона анулює, вимагає нового схвалення з маркером повноважень людини і лише тоді перемикає активний контракт. Перервана поправка відновлюється з першого відсутнього кроку; авторство плану ніколи не переноситься на ревізію.

Квитанції, представлення й експорт

outcomes.py receipt переобчислює результат плану із записів, тож він змінюється, коли змінюються записи; він ніколи не пишеться вручну. views.py render перегенеровує людиночитані представлення; представлення, яке редагувала людина, позначається у звіті й ніколи мовчки не перезаписується, а саме узгодження фіксується. Оскільки .dwp/ є в gitignore, ledger.py export --dest <dir> пакує журнал, знімок, ланцюжок контрактів і кожен згаданий артефакт доказів для довговічності або для іншого хоста.

Поверхні лише для читання й відновлення

status і verify ніколи не пишуть у план лінії v6; вони звітують через чисті команди й згенеровані проєкції. Хост, що відновлює роботу, діє у фіксованому порядку (огляд, валідація, проєкція, рендеринг із зафіксованими повноваженнями) і трактує застарілий відбиток як анульований доказ, який треба перезапустити, а не як придатний до повторного використання результат. Журнал ніколи не відтворюється як контекст розмови: робота відновлюється через цикл execute з маніфестом контексту для кожного завдання.

Співіснування й міграція

Плани v5 і лінії v6 MAY співіснувати в одній .dwp/plans/, і кожен виконується за своїм поколінням упродовж усього життя. Єдиний шлях від v5 до v6 — явна міграція з попереднім переглядом (migrate_v6.py, через refine) із перевіреною резервною копією й відкатом; мігрована історія v5 стає imported, коли її докази розвʼязуються, і asserted в іншому разі, але ніколи observed. Зворотної міграції немає.

Повʼязане