Слой 4 (трассировка) эпика ORCH-52, замыкающий цепочку 52b/52c/52d. Docs + prompts-only: src/**, STAGE_TRANSITIONS, QG_CHECKS, src/frontmatter.py, схема БД — не тронуты; новый QG не вводится; ретро-фит 51 маркера вне объёма. - Новый нормативный стандарт docs/_standards/TRACEABILITY.md: формат маркера, правило размещения, чтение истории с реальным проверяемым примером (src/serial_gate.py → ORCH-088 → ADR-001-serial-gate.md), fallback-доступ (git show origin/main:...), анти-археология (3+ → сводный сквозной ADR), каноничный текст правила чтения (единый источник). - Точечные аддитивные врезки в промпты (52d-канон не переписан): developer.md (правило чтения чужого маркера + fallback, «❌ X → ✅ Y»), architect.md (правило чтения + анти-археология), reviewer.md (усиление оси «Соответствие ADR» под-пунктом: слом маркированного инварианта → finding ≥P1). Все три ссылаются на единый текст в TRACEABILITY.md, не копируют (анти-дубль BR-6). - Сопутствующе: CLAUDE.md, docs/architecture/README.md (слой 4 эпика 52), CHANGELOG.md. - Анти-регресс: расширен tests/test_agent_prompts_canon.py (9 новых проверок); проверки 52d и test_agent_frontmatter_no_model.py зелёные; полный pytest tests/ -q зелёный (1253 passed), src/ не изменён. Refs: ORCH-078 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
10 KiB
TRACEABILITY — стандарт маркеров-трассировки ORCH-NNN (golden source трассировки)
Назначение. Единый нормативный контракт: как нетривиальная строка/блок/инвариант в коде привязывается к work item, который его ввёл, и к его архитектурному решению (ADR). Это слой 4 (трассировка) эпика ORCH-52 — рядом с
PIPELINE_DOCS.md(слой 1, структура документов) иHANDOFF_PROTOCOL.md(слой 2, машинный frontmatter-контракт).Статус истины. Документ кодифицирует сложившуюся практику, а не вводит новый синтаксис. Источник истины о поведении остаётся код (
src/stages.py,src/qg/checks.py,src/stage_engine.py); этот стандарт — описательно-нормативный, не машинный гейт конвейера. Соблюдение держится на дисциплине агентов + оси ревью (reviewer.md), а не на CI-lint.
Введён задачей ORCH-078 (ORCH-52e). Сквозной ADR:
docs/architecture/adr/adr-0022-traceability-marker-standard.md;
детально — docs/work-items/ORCH-078/06-adr/ADR-001-traceability-marker-standard.md. Продолжает
цепочку стандартов эпика 52: adr-0019 (52b), adr-0020 (52c), adr-0021 (52d).
1. Назначение и определение
Маркер ORCH-NNN (а для проекта enduro-trails — ET-NNN) в коде = обязательный стандарт
трассировки: он привязывает нетривиальную строку / блок / инвариант к work item, который его ввёл,
и к его ADR. Это даёт читающему агенту прямой путь «строка кода → решение, которое её породило»,
вместо git blame-археологии.
Факт (сверено на 2026-06-09): в src/ де-факто живёт 51 уникальный маркер ORCH-NNN
(grep -rhoE 'ORCH-[0-9]+' src/ | sort -u | wc -l → 51) — сложившаяся практика. Этот стандарт её
формализует. Массовый ретро-фит существующих 51 маркера вне объёма — стандарт нормативен «на
будущее»: его правила применяются к новому и правимому коду.
2. Формат маркера
Маркер — это inline-комментарий (или фрагмент docstring модуля/функции), содержащий идентификатор
work item ORCH-NNN. Рекомендуется рядом указывать ссылку на конкретное решение в ADR, чтобы трасса
вела не просто к задаче, а к пункту решения:
# Ordering term — ``t2.id < jobs.task_id`` (FIFO, ORCH-088, ADR-001 D1 / FR-2): a task
# does not enter `analysis` while an earlier unfinished task exists in the same repo.
Нового синтаксиса не вводится — кодифицируется уже сложившийся стиль (ORCH-NNN[, ADR-001 D1]).
3. Где ставится маркер
Маркер ставится рядом с нетривиальным инвариантом, понимание которого требует контекста решения:
- выбор fail-open / fail-closed поведения;
- точное условие сериализации / упорядочивания (FIFO, lease, барьер);
- идемпотентность / защита от повторной обработки;
- обходимая «дыра» конвейера, которую блок закрывает;
- любое условие, чьё «почему именно так» зафиксировано в ADR.
Маркер НЕ ставится на тривиальном/самоочевидном коде (геттеры, простые присваивания, очевидные проверки) — это только зашумляет.
Правило для нового кода: вводишь значимый инвариант → ставь маркер своей задачи (ORCH-NNN)
рядом, по возможности со ссылкой на пункт ADR.
4. Как читать историю (с реальным проверяемым примером)
Пошагово, от строки кода к решению:
- Видишь в коде маркер
ORCH-NNNу строки/блока, который собираешься менять. - Открываешь его архитектурное решение:
docs/work-items/ORCH-NNN/06-adr/. - Читаешь зафиксированный инвариант ПЕРЕД правкой; не ломаешь его (см. §7).
Проверяемый пример из реального кода (main):
src/serial_gate.pyнесёт условие сериализацииt2.id < jobs.task_idс маркером ORCH-088 и отсылкойADR-001 D1 / FR-2(FIFO-уточнение serial-gate). Чтобы понять, почему задача не входит вanalysis, пока в репо есть более ранняя незавершённая задача, читаешь:docs/work-items/ORCH-088/06-adr/ADR-001-serial-gate.md.
Пример ссылается на реально существующие в main файл и ADR — иначе стандарт опровергал бы сам
себя (нерабочая трассировка).
5. Fallback-доступ к чужому ADR
Папки docs/work-items/ORCH-NNN/ может не быть в текущей ветке (она срезана от main без неё —
типично для ветки другой задачи). Штатный способ прочитать чужой ADR — взять его из origin/main:
git fetch origin # при необходимости заранее
git ls-tree origin/main:docs/work-items/ORCH-NNN/06-adr/ # листинг доступных ADR
git show origin/main:docs/work-items/ORCH-NNN/06-adr/ADR-001-<slug>.md # прочитать конкретный
Это не блокер: отсутствие папки в ветке ≠ отсутствие решения — оно всегда есть в main.
6. Анти-археология: 3+ маркеров → сводный сквозной ADR
Если функция/блок несёт 3+ маркеров ORCH-NNN (эволюционировал через много задач), раскопки по
каждому work item нечитаемы. Вместо перечисления всех задач ставится одна сводная ссылка на
сквозной ADR (docs/architecture/adr/adr-NNNN-*), агрегирующий эволюцию.
Числовой порог 3 — граница, за которой inline-перечисление перестаёт быть читаемым (один-два
маркера ещё информативны, три и больше — уже археология).
Пример из кода: src/merge_gate.py несёт маркеры ORCH-043/065/071/073 (и ещё несколько) →
читать сводные сквозные adr-0006 (merge-gate), adr-0013 (merge-verify-gate),
adr-0014 (sha-source-of-truth), adr-0016 (ensure-open-PR) в docs/architecture/adr/, а не 8
отдельных work item.
Это конвенция для нового/правимого блока; массовая переразметка существующих файлов вне объёма.
7. Правило чтения (каноничная формулировка — единый источник)
Это единственное место, где живёт каноничный текст правила. Промпты агентов
(developer.md/architect.md/reviewer.md) ссылаются на него, а не копируют — чтобы не было
дрейфа формулировок между файлами.
Правишь код с маркером
ORCH-NNN→ прочитай егоdocs/work-items/ORCH-NNN/06-adr/ПЕРЕД изменением; не сломай зафиксированный инвариант. Не можешь сохранить инвариант — эскалируй / верни задачу в анализ, не правь вслепую. Папки нет в ветке → читай изorigin/main(§5). Блок несёт 3+ маркеров → опирайся на сводный сквозной ADR (§6).
Кто и как применяет правило:
- developer / architect — обязаны выполнить чтение ПЕРЕД правкой маркированного кода.
- architect — при введении/правке блока с 3+ маркерами оформляет/обновляет сводный сквозной ADR.
- reviewer — проверяет соблюдение: правка маркированного (
ORCH-NNN) кода без сверки с его ADR или со сломом инварианта → finding (рекомендуемая severity P1; слом критического инварианта конвейера — на усмотрение reviewer вплоть до P0).
Связи
- Сквозной ADR:
adr-0022. - Стандарты-соседи:
PIPELINE_DOCS.md(слой 1),HANDOFF_PROTOCOL.md(слой 2). - Цепочка эпика 52: adr-0019 (52b) / adr-0020 (52c) / adr-0021 (52d) / adr-0022 (52e).
- Прецедент класса ошибки (слом инварианта без чтения ADR):
docs/history/LESSONS_2026-06-08_phantom-merge.md.