Description
В жизненном цикле создания и закрытия рабочего продукта (РП) одновременно действуют несколько несовместимых контрактов:
.claude/skills/wp-new/SKILL.md объявляет, что новый РП атомарно записывается в четыре локальных места.
- Этот же скилл задаёт папочный контекст
inbox/WP-{N}/WP-{N}.md.
- Скилл прямо утверждает, что архивная заготовка больше не создаётся при регистрации.
scripts/create-wp.sh продолжает создавать padded-путь WP-009 и отдельный archive stub.
memory/protocol-close.md требует перемещать исходную папку контекста из inbox/ в archive/wp-contexts/.
scripts/close-wp.sh вместо перемещения исходной папки создаёт ещё один плоский архивный файл.
В результате создание и закрытие РП могут породить несколько представлений одного контекста, а create-wp.sh может сообщить об успешной атомарной регистрации, даже если WeekPlan или active-wp.md фактически не обновлены.
Проблема состоит не только в archive stub. Нужно согласовать и проверить весь контракт:
create
→ context
→ Registry
→ WeekPlan
→ active-wp
→ close
→ archive
Contract Drift
1. Документированный context path не совпадает с фактическим
/wp-new объявляет:
При следующем номере 9 ожидаемый по буквальному контракту путь:
Но create-wp.sh использует:
WP_ID=$(printf '%03d' "$WP_NUM")
и создаёт:
При этом разные представления одного идентификатора используют разные форматы:
- frontmatter:
wp: 9;
- consent file:
wp-consent-9;
- Registry/WeekPlan: обычно
9 или WP-9;
- путь и H1:
WP-009.
Само дополнение нулями может быть допустимым архитектурным решением, но оно должно быть единым и явно закреплённым во всех потребителях. Сейчас документация, пути и downstream-скрипты используют разные формы.
2. create-wp.sh создаёт archive stub, который документация объявляет удалённым
/wp-new говорит:
Archive stub больше не создаётся при регистрации. close-wp.sh создаёт архивный файл при закрытии, чтобы не конфликтовать с каноническим git mv.
Фактический create-wp.sh продолжает выполнять отдельный шаг:
и создаёт:
archive/wp-contexts/WP-009-<slug>.md
до того, как РП завершён.
Таким образом, сразу после регистрации существуют:
inbox/WP-009/WP-009.md
archive/wp-contexts/WP-009-<slug>.md
Оба файла относятся к одному РП, но имеют разные роли, статусы и lifecycle.
3. close-wp.sh создаёт ещё один архивный объект вместо переноса исходного контекста
memory/protocol-close.md задаёт каноническое закрытие:
git mv inbox/WP-N archive/wp-contexts/WP-N
То есть исходная папка с полным контекстом должна быть перенесена в архив.
Но close-wp.sh создаёт новый плоский файл:
archive/wp-contexts/WP-N-<slug>.md
и дописывает в него секцию закрытия.
При этом исходный папочный контекст может:
- остаться в
inbox/;
- быть отдельно перенесён другим протоколом;
- получить статус, отличный от плоского archive-файла;
- существовать одновременно с archive stub, созданным при регистрации.
Возможный итог:
inbox/WP-9/WP-9.md
archive/wp-contexts/WP-009-<slug>.md
archive/wp-contexts/WP-9-<другой-slug>.md
archive/wp-contexts/WP-9/WP-9.md
Даже если не все четыре объекта возникают в каждом запуске, текущие контракты допускают их появление.
4. Ошибка записи WeekPlan не всегда нарушает успешный результат создания
create-wp.sh позиционируется как атомарный writer.
Но если скрипт не распознаёт таблицу WeekPlan, внутренний Python-блок печатает предупреждение:
WeekPlan: таблица недели не найдена — добавить вручную
и завершается с успешным кодом.
Shell-обёртка воспринимает шаг как успешно выполненный и продолжает создание РП.
В результате возможен фактический итог:
- context file создан;
- Registry обновлён;
- WeekPlan не обновлён;
- скрипт сообщает
WP создан.
Это не атомарная запись в четыре места.
Проблема воспроизводится на легитимной пользовательской схеме WeekPlan, например:
| Приоритет | Режим ТВС | РП / направление | Бюджет | Hard cap | Срок | Результат |
Такая таблица содержит семантику РП, но не содержит буквальную колонку Статус, которую требует текущий writer.
5. Ошибка пересборки active-wp.md не блокирует успешное создание
Если build-active-wp.py:
- отсутствует;
- завершился с ошибкой;
- не смог распознать Registry;
create-wp.sh печатает предупреждение, но продолжает и сообщает успешное создание РП.
Однако /wp-new включает пересборку active-wp.md в обязательные четыре локальные записи.
Следовательно, нужно выбрать один контракт:
active-wp.md — обязательная часть атомарной транзакции, тогда ошибка должна приводить к rollback;
active-wp.md — производный необязательный индекс, тогда документация не должна называть его обязательным локальным местом атомарной регистрации.
Сейчас документация и реализация расходятся.
6. create-wp.sh может самовольно менять схему WP Registry
На legacy Registry без колонок P, Репо или Бюджет writer может автоматически расширить таблицу:
- добавить новые колонки;
- дописать
— во все существующие строки;
- создать большой несвязанный diff.
Это изменение схемы не является частью создания конкретного РП и может затронуть весь исторический реестр.
Даже если миграция нужна, она должна быть:
- отдельной явной операцией;
- покрыта тестом;
- описана в migration contract;
- либо включаться только после явного schema version check.
Создание одного РП не должно молча переписывать структуру всего Registry.
7. Тесты закрепляют конфликтующие контракты
Часть тестов ожидает:
- padded-пути
WP-009;
- archive stub уже после регистрации;
- плоский архивный файл.
При этом /wp-new и protocol-close.md описывают:
WP-{N};
- отсутствие archive stub;
- перенос папки при закрытии.
Получается, что тесты доказывают корректность поведения, которое документация одновременно объявляет устаревшим.
Impact
Несколько источников истины
Контекст выполнения может остаться в inbox/, а сведения о закрытии — попасть в отдельный archive-файл. Непонятно, какой файл должен читать следующий агент.
Потеря полного контекста при закрытии
Плоский файл, созданный close-wp.sh, может содержать только краткую секцию закрытия, тогда как полный журнал фаз, решений и handoff остаётся в исходной папке.
Ложная атомарность
Агент получает сообщение об успешном создании РП, хотя WeekPlan или active-wp.md не обновлены.
Ошибки downstream-аудитов
Детекторы могут искать только одну из схем:
archive/wp-contexts/WP-N.md
archive/wp-contexts/WP-N-<slug>.md
archive/wp-contexts/WP-N/WP-N.md
и переставать видеть РП после его закрытия.
Шумный Registry diff
Создание одного РП может неожиданно изменить десятки исторических строк из-за автоматической миграции колонок.
Нестабильный WP-ID
Один РП фигурирует как 9, WP-9 и WP-009, что усложняет точный поиск, связывание с внешними системами и предотвращение дубликатов.
Expected Behavior
Нужен один явный lifecycle-контракт.
Рекомендуемый вариант:
Регистрация
После успешного создания существуют ровно четыре согласованных локальных представления:
inbox/WP-N/WP-N.md
docs/WP-REGISTRY.md
current/WeekPlan ...
current/active-wp.md
Архивного контекста до закрытия нет.
Закрытие
При закрытии:
-
context получает содержательный факт приёмки;
-
статус меняется на terminal;
-
папка целиком перемещается:
git mv inbox/WP-N archive/wp-contexts/WP-N
-
Registry и WeekPlan обновляются;
-
active-wp.md пересобирается;
-
после закрытия существует ровно один канонический архивный контекст:
archive/wp-contexts/WP-N/WP-N.md
Legacy-плоские файлы можно продолжать читать, но новые РП не должны их создавать.
Atomicity
Создание должно закончиться одним из двух результатов:
SUCCESS: все обязательные локальные представления обновлены
FAIL: все частичные изменения откачены
Предупреждение без rollback допустимо только для явно необязательного пост-шага, например внешнего трекера.
Open Design Decision: WP-ID Format
Перед исправлением нужно явно решить, какой формат является каноническим.
Вариант A — без дополнения нулями
Преимущества:
- совпадает с пользовательским названием РП;
- совпадает с
wp: 9;
- совпадает с большинством текстовых ссылок;
- соответствует буквальному
WP-{N} в документации.
Недостаток:
- лексикографическая сортировка файлов отличается от числовой.
Вариант B — дополнение нулями только в файловом ID
Если выбирается этот вариант, необходимо явно обновить:
/wp-new;
- WP-434 / INBOX-CONVENTION;
protocol-open.md;
protocol-close.md;
close-wp.sh;
archive-done-wp.sh;
- Registry readers;
- WeekPlan readers;
- внешние tracker adapters;
- тестовые фикстуры.
Недопустимо оставлять формат неявным и одновременно поддерживать разные формы без нормализующего слоя.
Steps to Reproduce
Reproduction A — padded path и archive stub
-
Подготовить установку, где максимальный номер в Registry меньше 9.
-
Запустить:
bash scripts/create-wp.sh \
--title "Lifecycle contract test" \
--budget 2h \
--priority P3 \
--no-consent-check
-
Проверить:
find inbox archive/wp-contexts \
-maxdepth 2 \
\( -name 'WP-009*' -o -name 'WP-9*' \) \
-print
-
Наблюдаемый результат:
inbox/WP-009/WP-009.md
archive/wp-contexts/WP-009-lifecycle-contract-test.md
-
Сравнить с /wp-new, который обещает inbox/WP-{N}/WP-{N}.md и отсутствие stub.
Reproduction B — WeekPlan не обновлён, но создание успешно
-
Использовать WeekPlan с легитимной таблицей:
| Приоритет | Режим ТВС | РП / направление | Бюджет | Hard cap | Срок | Результат |
|---|---|---|---:|---:|---|---|
-
Запустить create-wp.sh.
-
Получить предупреждение:
WeekPlan: таблица недели не найдена — добавить вручную
-
Проверить код завершения и итоговое сообщение.
-
Наблюдаемый результат: создание считается успешным, хотя обязательная запись WeekPlan отсутствует.
Reproduction C — закрытие создаёт второй архивный объект
-
Создать РП.
-
Закрыть его через close-wp.sh.
-
Затем выполнить канонический git mv из protocol-close.md.
-
Проверить:
find archive/wp-contexts -maxdepth 2 -name 'WP-9*' -print
-
Возможный результат: плоский closure-файл и папочный полный контекст существуют одновременно.
Suggested Fix
Phase 1 — зафиксировать контракт
- Выбрать канонический формат WP-ID.
- Выбрать единственную новую archive-схему.
- Зафиксировать, является ли
active-wp.md обязательной частью атомарной записи.
- Зафиксировать, может ли создание РП выполнять schema migration Registry.
Phase 2 — исправить создание
- Привести
create-wp.sh к выбранному WP-ID.
- Удалить создание archive stub.
- Считать отсутствие записи WeekPlan ошибкой обязательного шага.
- Либо успешно пересобирать
active-wp.md, либо выполнять rollback.
- Не мигрировать Registry молча в ходе обычного create.
- Сохранять внешний tracker как отдельный необязательный пост-шаг после локальной транзакции.
Phase 3 — исправить закрытие
- Использовать исходный context как единственный объект закрытия.
- Добавлять секцию
## Закрытие в исходный файл.
- Обновлять terminal status и дату.
- Перемещать исходную папку в
archive/wp-contexts/WP-N/.
- Не создавать параллельный плоский closure-файл для новых РП.
- Сохранить read-only совместимость с legacy-плоскими архивами.
Phase 4 — обновить consumers
Проверить и согласовать:
build-active-wp.py;
close-wp.sh;
archive-done-wp.sh;
memory-drift-scan.py;
- Day Open;
- Day Close;
- Week Close;
- WP sync bundle;
- session guard;
- внешние tracker adapters;
- навигационные и индексные скрипты.
Phase 5 — добавить тесты
Минимальный набор:
Create contract
create → context + Registry + WeekPlan + active-wp
No premature archive
create → archive/wp-contexts не изменился
Atomic rollback
ошибка WeekPlan → нет context, Registry row и других частичных записей
Active index failure
ошибка build-active-wp → поведение соответствует объявленному контракту
Close contract
create → close → один context перемещён в archive
No duplicate archive
после close нет второго плоского closure-файла
Legacy compatibility
старые плоские архивы читаются, но новые не создаются
ID normalization
9 / WP-9 / WP-009 однозначно приводятся к выбранной канонической форме
Custom WeekPlan schema
легитимная таблица «РП / направление» обрабатывается либо явно блокируется до любых записей
Registry schema
создание одного РП не меняет схему всего Registry без явной миграции
Acceptance Criteria
Environment
- OS: Linux
- Surface: Codex Cloud
- Setup mode: core/cloud
- Install level: T1
- Checked against: upstream
main, 2026-08-13
Evidence
Upstream /wp-new объявляет:
и утверждает, что archive stub больше не создаётся.
Upstream create-wp.sh одновременно содержит:
WP_ID=$(printf '%03d' "$WP_NUM")
ARCHIVE_STUB="$ARCHIVE_DIR/WP-${WP_ID}-${SLUG}.md"
и выполняет отдельный шаг:
Upstream close-wp.sh утверждает, что stub уже удалён из create, но создаёт новый плоский archive-файл.
Upstream protocol-close.md требует вместо этого перемещать папку исходного context.
Таким образом, расхождение подтверждается непосредственно текущими платформенными файлами и не зависит от конкретной пользовательской установки.
Related
- Follow-up architecture proposal: подключаемый адаптер внешнего трекера.
- Этот bug следует исправлять отдельно от выбора Linear, GitHub Issues или другого внешнего трекера: проблема находится в базовом lifecycle РП.
Description
В жизненном цикле создания и закрытия рабочего продукта (РП) одновременно действуют несколько несовместимых контрактов:
.claude/skills/wp-new/SKILL.mdобъявляет, что новый РП атомарно записывается в четыре локальных места.inbox/WP-{N}/WP-{N}.md.scripts/create-wp.shпродолжает создавать padded-путьWP-009и отдельный archive stub.memory/protocol-close.mdтребует перемещать исходную папку контекста изinbox/вarchive/wp-contexts/.scripts/close-wp.shвместо перемещения исходной папки создаёт ещё один плоский архивный файл.В результате создание и закрытие РП могут породить несколько представлений одного контекста, а
create-wp.shможет сообщить об успешной атомарной регистрации, даже если WeekPlan илиactive-wp.mdфактически не обновлены.Проблема состоит не только в archive stub. Нужно согласовать и проверить весь контракт:
Contract Drift
1. Документированный context path не совпадает с фактическим
/wp-newобъявляет:При следующем номере
9ожидаемый по буквальному контракту путь:Но
create-wp.shиспользует:WP_ID=$(printf '%03d' "$WP_NUM")и создаёт:
При этом разные представления одного идентификатора используют разные форматы:
wp: 9;wp-consent-9;9илиWP-9;WP-009.Само дополнение нулями может быть допустимым архитектурным решением, но оно должно быть единым и явно закреплённым во всех потребителях. Сейчас документация, пути и downstream-скрипты используют разные формы.
2.
create-wp.shсоздаёт archive stub, который документация объявляет удалённым/wp-newговорит:Фактический
create-wp.shпродолжает выполнять отдельный шаг:и создаёт:
до того, как РП завершён.
Таким образом, сразу после регистрации существуют:
Оба файла относятся к одному РП, но имеют разные роли, статусы и lifecycle.
3.
close-wp.shсоздаёт ещё один архивный объект вместо переноса исходного контекстаmemory/protocol-close.mdзадаёт каноническое закрытие:То есть исходная папка с полным контекстом должна быть перенесена в архив.
Но
close-wp.shсоздаёт новый плоский файл:и дописывает в него секцию закрытия.
При этом исходный папочный контекст может:
inbox/;Возможный итог:
Даже если не все четыре объекта возникают в каждом запуске, текущие контракты допускают их появление.
4. Ошибка записи WeekPlan не всегда нарушает успешный результат создания
create-wp.shпозиционируется как атомарный writer.Но если скрипт не распознаёт таблицу WeekPlan, внутренний Python-блок печатает предупреждение:
и завершается с успешным кодом.
Shell-обёртка воспринимает шаг как успешно выполненный и продолжает создание РП.
В результате возможен фактический итог:
WP создан.Это не атомарная запись в четыре места.
Проблема воспроизводится на легитимной пользовательской схеме WeekPlan, например:
Такая таблица содержит семантику РП, но не содержит буквальную колонку
Статус, которую требует текущий writer.5. Ошибка пересборки
active-wp.mdне блокирует успешное созданиеЕсли
build-active-wp.py:create-wp.shпечатает предупреждение, но продолжает и сообщает успешное создание РП.Однако
/wp-newвключает пересборкуactive-wp.mdв обязательные четыре локальные записи.Следовательно, нужно выбрать один контракт:
active-wp.md— обязательная часть атомарной транзакции, тогда ошибка должна приводить к rollback;active-wp.md— производный необязательный индекс, тогда документация не должна называть его обязательным локальным местом атомарной регистрации.Сейчас документация и реализация расходятся.
6.
create-wp.shможет самовольно менять схему WP RegistryНа legacy Registry без колонок
P,РепоилиБюджетwriter может автоматически расширить таблицу:—во все существующие строки;Это изменение схемы не является частью создания конкретного РП и может затронуть весь исторический реестр.
Даже если миграция нужна, она должна быть:
Создание одного РП не должно молча переписывать структуру всего Registry.
7. Тесты закрепляют конфликтующие контракты
Часть тестов ожидает:
WP-009;При этом
/wp-newиprotocol-close.mdописывают:WP-{N};Получается, что тесты доказывают корректность поведения, которое документация одновременно объявляет устаревшим.
Impact
Несколько источников истины
Контекст выполнения может остаться в
inbox/, а сведения о закрытии — попасть в отдельный archive-файл. Непонятно, какой файл должен читать следующий агент.Потеря полного контекста при закрытии
Плоский файл, созданный
close-wp.sh, может содержать только краткую секцию закрытия, тогда как полный журнал фаз, решений и handoff остаётся в исходной папке.Ложная атомарность
Агент получает сообщение об успешном создании РП, хотя WeekPlan или
active-wp.mdне обновлены.Ошибки downstream-аудитов
Детекторы могут искать только одну из схем:
и переставать видеть РП после его закрытия.
Шумный Registry diff
Создание одного РП может неожиданно изменить десятки исторических строк из-за автоматической миграции колонок.
Нестабильный WP-ID
Один РП фигурирует как
9,WP-9иWP-009, что усложняет точный поиск, связывание с внешними системами и предотвращение дубликатов.Expected Behavior
Нужен один явный lifecycle-контракт.
Рекомендуемый вариант:
Регистрация
После успешного создания существуют ровно четыре согласованных локальных представления:
Архивного контекста до закрытия нет.
Закрытие
При закрытии:
context получает содержательный факт приёмки;
статус меняется на terminal;
папка целиком перемещается:
Registry и WeekPlan обновляются;
active-wp.mdпересобирается;после закрытия существует ровно один канонический архивный контекст:
Legacy-плоские файлы можно продолжать читать, но новые РП не должны их создавать.
Atomicity
Создание должно закончиться одним из двух результатов:
Предупреждение без rollback допустимо только для явно необязательного пост-шага, например внешнего трекера.
Open Design Decision: WP-ID Format
Перед исправлением нужно явно решить, какой формат является каноническим.
Вариант A — без дополнения нулями
Преимущества:
wp: 9;WP-{N}в документации.Недостаток:
Вариант B — дополнение нулями только в файловом ID
Если выбирается этот вариант, необходимо явно обновить:
/wp-new;protocol-open.md;protocol-close.md;close-wp.sh;archive-done-wp.sh;Недопустимо оставлять формат неявным и одновременно поддерживать разные формы без нормализующего слоя.
Steps to Reproduce
Reproduction A — padded path и archive stub
Подготовить установку, где максимальный номер в Registry меньше
9.Запустить:
bash scripts/create-wp.sh \ --title "Lifecycle contract test" \ --budget 2h \ --priority P3 \ --no-consent-checkПроверить:
Наблюдаемый результат:
Сравнить с
/wp-new, который обещаетinbox/WP-{N}/WP-{N}.mdи отсутствие stub.Reproduction B — WeekPlan не обновлён, но создание успешно
Использовать WeekPlan с легитимной таблицей:
Запустить
create-wp.sh.Получить предупреждение:
Проверить код завершения и итоговое сообщение.
Наблюдаемый результат: создание считается успешным, хотя обязательная запись WeekPlan отсутствует.
Reproduction C — закрытие создаёт второй архивный объект
Создать РП.
Закрыть его через
close-wp.sh.Затем выполнить канонический
git mvизprotocol-close.md.Проверить:
find archive/wp-contexts -maxdepth 2 -name 'WP-9*' -printВозможный результат: плоский closure-файл и папочный полный контекст существуют одновременно.
Suggested Fix
Phase 1 — зафиксировать контракт
active-wp.mdобязательной частью атомарной записи.Phase 2 — исправить создание
create-wp.shк выбранному WP-ID.active-wp.md, либо выполнять rollback.Phase 3 — исправить закрытие
## Закрытиев исходный файл.archive/wp-contexts/WP-N/.Phase 4 — обновить consumers
Проверить и согласовать:
build-active-wp.py;close-wp.sh;archive-done-wp.sh;memory-drift-scan.py;Phase 5 — добавить тесты
Минимальный набор:
Create contract
No premature archive
Atomic rollback
Active index failure
Close contract
No duplicate archive
Legacy compatibility
ID normalization
Custom WeekPlan schema
Registry schema
Acceptance Criteria
create → close → archiveпроходит.active-wp.mdсовпадает с заявленной атомарностью.Environment
main, 2026-08-13Evidence
Upstream
/wp-newобъявляет:и утверждает, что archive stub больше не создаётся.
Upstream
create-wp.shодновременно содержит:и выполняет отдельный шаг:
Upstream
close-wp.shутверждает, что stub уже удалён из create, но создаёт новый плоский archive-файл.Upstream
protocol-close.mdтребует вместо этого перемещать папку исходного context.Таким образом, расхождение подтверждается непосредственно текущими платформенными файлами и не зависит от конкретной пользовательской установки.
Related