@rt-tools/agent-kit 0.10.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/assets/checks/check-state-next.mjs +194 -0
  2. package/assets/checks/check-states.mjs +142 -0
  3. package/assets/checks/check-turn-map.mjs +146 -0
  4. package/assets/commands/agent-kit-digest.md +6 -5
  5. package/assets/defaults/project.sh +58 -6
  6. package/assets/defaults/turn-map.md +46 -0
  7. package/assets/hooks/browser-device-id.sh +2 -0
  8. package/assets/hooks/browser-guard-device-id.sh +2 -0
  9. package/assets/hooks/browser-guard-no-asking.sh +2 -0
  10. package/assets/hooks/browser-guard-no-listing.sh +2 -0
  11. package/assets/hooks/browser-guard-no-other-drivers.sh +2 -0
  12. package/assets/hooks/browser-guard-require-select.sh +2 -0
  13. package/assets/hooks/claim-guard.sh +2 -0
  14. package/assets/hooks/commit-msg.sh +2 -0
  15. package/assets/hooks/conscience-guard.sh +2 -0
  16. package/assets/hooks/constitution-index.sh +2 -0
  17. package/assets/hooks/dev-server-guard.sh +2 -0
  18. package/assets/hooks/docs-guard.sh +2 -0
  19. package/assets/hooks/exam-guard.sh +2 -0
  20. package/assets/hooks/git-guard-delivery-signature.sh +2 -0
  21. package/assets/hooks/git-guard-delivery.sh +2 -0
  22. package/assets/hooks/git-guard-main.sh +2 -0
  23. package/assets/hooks/git-guard-push-tests.sh +2 -0
  24. package/assets/hooks/glossary-load.sh +2 -0
  25. package/assets/hooks/grill-gate.sh +2 -0
  26. package/assets/hooks/handoff-entry-guard.sh +2 -0
  27. package/assets/hooks/handoff-write.sh +103 -0
  28. package/assets/hooks/lint-after-edit.sh +2 -0
  29. package/assets/hooks/observe.sh +2 -0
  30. package/assets/hooks/postmortem-guard.sh +2 -0
  31. package/assets/hooks/proposal-guard.sh +2 -0
  32. package/assets/hooks/prose-style-guard.sh +2 -0
  33. package/assets/hooks/qa-dataid-guard.sh +2 -0
  34. package/assets/hooks/rerun-guard.sh +2 -0
  35. package/assets/hooks/reuse-first-guard.sh +2 -0
  36. package/assets/hooks/roles.sh +2 -0
  37. package/assets/hooks/skill-gate-layers.sh +2 -0
  38. package/assets/hooks/skill-gate-rearm.sh +2 -0
  39. package/assets/hooks/skill-gate.sh +2 -0
  40. package/assets/hooks/skill-loaded.sh +2 -0
  41. package/assets/hooks/sql-guard-parse.sh +2 -0
  42. package/assets/hooks/sql-guard-request.sh +2 -0
  43. package/assets/hooks/sql-guard-target.sh +2 -0
  44. package/assets/hooks/sql-guard-write.sh +2 -0
  45. package/assets/hooks/sql-guard.sh +2 -0
  46. package/assets/hooks/task-context-load.sh +2 -0
  47. package/assets/hooks/task-flow-guard.sh +2 -0
  48. package/assets/hooks/turn-entry-load.sh +62 -0
  49. package/assets/hooks/turn-exit-guard.sh +2 -0
  50. package/assets/hooks/utf8.sh +35 -0
  51. package/assets/hooks/waiting-turn-guard.sh +2 -0
  52. package/assets/hooks/window-fill-guard.sh +31 -1
  53. package/assets/laws/work-conduct.md +29 -0
  54. package/assets/patterns/cargo-triage-mark.md +119 -0
  55. package/assets/patterns/task-flow-close.md +21 -0
  56. package/assets/patterns/task-flow-handoff.md +18 -0
  57. package/assets/patterns/task-flow-resume.md +6 -0
  58. package/assets/patterns/task-flow-start.md +41 -0
  59. package/assets/patterns/turn-entry-map.md +81 -0
  60. package/assets/rules/cargo-triage.md +126 -0
  61. package/assets/rules/task-flow.md +14 -1
  62. package/assets/rules/turn-entry.md +93 -0
  63. package/bin/agent-kit.d.ts.map +1 -1
  64. package/bin/agent-kit.js +42 -1
  65. package/bin/agent-kit.js.map +1 -1
  66. package/lib/cargo-state.d.ts +62 -0
  67. package/lib/cargo-state.d.ts.map +1 -0
  68. package/lib/cargo-state.js +118 -0
  69. package/lib/cargo-state.js.map +1 -0
  70. package/lib/cargo.d.ts +42 -0
  71. package/lib/cargo.d.ts.map +1 -1
  72. package/lib/cargo.js +2 -0
  73. package/lib/cargo.js.map +1 -1
  74. package/lib/commands.d.ts.map +1 -1
  75. package/lib/commands.js +64 -4
  76. package/lib/commands.js.map +1 -1
  77. package/lib/observations.d.ts +35 -1
  78. package/lib/observations.d.ts.map +1 -1
  79. package/lib/observations.js +14 -2
  80. package/lib/observations.js.map +1 -1
  81. package/lib/ship.d.ts +3 -0
  82. package/lib/ship.d.ts.map +1 -1
  83. package/lib/ship.js +56 -0
  84. package/lib/ship.js.map +1 -1
  85. package/lib/thresholds.d.ts +49 -0
  86. package/lib/thresholds.d.ts.map +1 -0
  87. package/lib/thresholds.js +151 -0
  88. package/lib/thresholds.js.map +1 -0
  89. package/package.json +1 -1
  90. package/rt-tools-agent-kit-0.11.0.tgz +0 -0
  91. package/rt-tools-agent-kit-0.10.0.tgz +0 -0
@@ -30,6 +30,8 @@
30
30
  # ОТКАЗ В ПОЛЬЗУ РАБОТЫ: при любой ошибке, нехватке `jq`, отсутствии записи хода и повторном
31
31
  # заходе ход РАЗРЕШАЕТСЯ (exit 0). Сломанный гард не имеет права заклинить разговор.
32
32
 
33
+ . "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/utf8.sh" 2>/dev/null || true
34
+
33
35
  input="$(cat 2>/dev/null)"
34
36
  [ -z "$input" ] && exit 0
35
37
 
@@ -16,12 +16,21 @@
16
16
  # Место между порогами и есть то, на что закрывается заход: дописать ход работы, написать
17
17
  # передачу, закоммитить проверенное.
18
18
  #
19
+ # Там, где дерево объявило порог сжатия ниже порога остановки, напоминание говорит обратное:
20
+ # точку остановки выбирать не надо, потому что заход через порог пройдёт сам — сжатие придёт
21
+ # первым, передачу к тому времени напишет свой хук, и работа продолжится тем же заходом. Отбой
22
+ # при этом остаётся: он превращается из конца захода в страховку на случай, когда сжатие не
23
+ # пришло. Напоминание, зовущее закрывать заход там, где закрывать его не надо, — это остановка
24
+ # работы без причины, и стоит она ровно того же, что и отбой.
25
+ #
19
26
  # Размер окна берётся из настройки дерева. Из записи захода он не выводится: модель записана
20
27
  # там без пометки о расширенном окне, и заход на широкое окно от захода на узкое неотличим.
21
28
  #
22
29
  # ОТКАЗ В ПОЛЬЗУ РАБОТЫ: нет размера окна, нет записи захода, нет разборщика, битый разбор —
23
30
  # работа РАЗРЕШАЕТСЯ (exit 0). Сломанный гард не имеет права заклинить работу.
24
31
 
32
+ . "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/utf8.sh" 2>/dev/null || true
33
+
25
34
  input="$(cat 2>/dev/null)"
26
35
  [ -z "$input" ] && exit 0
27
36
 
@@ -49,6 +58,21 @@ esac
49
58
 
50
59
  warn_pct="${RT_WINDOW_WARN_PCT:-40}"
51
60
  stop_pct="${RT_WINDOW_STOP_PCT:-50}"
61
+
62
+ # Доля, на которой контекст сжимает сам инструмент. Объявлена деревом — заход через порог
63
+ # проходит сам: сжатие приходит первым, передачу к тому моменту уже написал свой хук, и работа
64
+ # идёт дальше тем же заходом. Не объявлена — прежний порядок: заход кончается передачей.
65
+ #
66
+ # От этого зависит текст напоминания, а не отказ. Отбой на пороге остановки остаётся в обоих
67
+ # случаях: он и есть страховка на случай, когда сжатие не пришло — настройка снята, версия
68
+ # другая, сжатие отказало. Отобрав отбой у дерева, объявившего сжатие, страж пустил бы такой
69
+ # заход до предела окна, где работа теряется целиком.
70
+ compact_pct="${CLAUDE_AUTOCOMPACT_PCT_OVERRIDE:-}"
71
+ case "$compact_pct" in
72
+ '' | *[!0-9]*) compact_pct='' ;;
73
+ esac
74
+ [ -n "$compact_pct" ] && [ "$compact_pct" -ge "$stop_pct" ] 2>/dev/null && compact_pct=''
75
+
52
76
  tasks_dir="${RT_TASKS_DIR:-docs/tasks}"
53
77
  handoff_dir="${RT_HANDOFF_DIR:-.claude/handoff}"
54
78
 
@@ -99,7 +123,13 @@ if [ "$event" = "PostToolUse" ]; then
99
123
  printf '%s' "$step" > "$mark" 2>/dev/null
100
124
 
101
125
  if [ "$pct" -ge "$stop_pct" ]; then
102
- text="ЗАПОЛНЕНИЕ ОКНА ${pct}% (${fill_k}k из ${window_k}k) — заход закрывается сейчас. Всё, кроме записи хода работы, передачи и команд поставки, уже отбивается."
126
+ if [ -n "$compact_pct" ]; then
127
+ text="ЗАПОЛНЕНИЕ ОКНА ${pct}% (${fill_k}k из ${window_k}k) — заход закрывается сейчас. Сжатие объявлено на ${compact_pct}% и не пришло: порог остановки ${stop_pct}% пройден, а контекст прежний. Всё, кроме записи хода работы, передачи и команд поставки, уже отбивается — закрывай заход и скажи владельцу, что сжатие не сработало."
128
+ else
129
+ text="ЗАПОЛНЕНИЕ ОКНА ${pct}% (${fill_k}k из ${window_k}k) — заход закрывается сейчас. Всё, кроме записи хода работы, передачи и команд поставки, уже отбивается."
130
+ fi
131
+ elif [ -n "$compact_pct" ]; then
132
+ text="ЗАПОЛНЕНИЕ ОКНА ${pct}% (${fill_k}k из ${window_k}k). Точку остановки выбирать не надо: на ${compact_pct}% инструмент сожмёт контекст сам, передачу к тому времени напишет хук, и работа пойдёт дальше этим же заходом. Порог остановки ${stop_pct}% — страховка на случай, если сжатие не придёт. Работай дальше."
103
133
  else
104
134
  text="ЗАПОЛНЕНИЕ ОКНА ${pct}% (${fill_k}k из ${window_k}k). Пора выбирать точку остановки: с ${stop_pct}% останется только закрыть заход. Доведи текущий шаг до состояния, с которого следующий заход продолжит, перепиши «Где стоим» в ходе работы, напиши передачу и отдай владельцу путь к ней — паттерн task-flow-handoff."
105
135
  fi
@@ -71,6 +71,15 @@
71
71
  владельца.** Владелец знает, что работа не кончена, но не знает, где именно она стоит;
72
72
  пересказ он даёт по своей памяти, а не по ходу работы, и следующий заход начинает с чужой
73
73
  картины.
74
+ - **Переданное прошлым заходом приходит в новый заход само, а не кладётся рукой.** Передача,
75
+ написанная и не прочитанная, равна ненаписанной: следующий заход о ней не знает и начинает с
76
+ пустого места — то есть с того же, ради чего её и писали. Кладёт её человек ровно до тех пор,
77
+ пока это не поручено машине; поручённое машине не забывается ночью.
78
+ - **Порядок ведения работы приходит в заход вместе с работой, а не разыскивается им.** Заход,
79
+ знающий задачу и не знающий, что с ней делают дальше, первым движением идёт читать правило
80
+ целиком — и тратит на это ту часть места, ради которой заход и начали заново. Приходит
81
+ короткая выжимка: состояния, обязательное действие каждого и то, чем ход кончается. Правило
82
+ она не заменяет и заменить не может — она отвечает на вопрос «что делать», а не «почему».
74
83
  - **Замысел и ход работы — разные записи.** Замысел — то, с чем сверяют результат при
75
84
  приёмке; правленный по ходу, он перестаёт отличаться от PR, и приёмке сверять нечего.
76
85
  - **Сделанное отмечается в одном месте.** Две записи об одном разъезжаются молча, и после
@@ -142,6 +151,26 @@
142
151
  остановиться позволяет только предел заполнения окна. Заход, закрытый на готовой задаче,
143
152
  оставляет владельцу пустое место и стоит целого захода на возвращение к тому, что и так было
144
153
  под рукой.
154
+ - **Предел заполнения окна останавливает заход только там, где инструмент не сжимает контекст
155
+ сам.** Где сжатие объявлено и приходит раньше предела, окно — не конец захода, а его
156
+ продолжение: контекст сжимается, записанное состояние работы возвращается в него, и работа
157
+ идёт дальше тем же заходом. Останавливаться там незачем, а остановка стоит того же, что и
158
+ всякая другая: владелец возвращает исполнителя в работу руками.
159
+ - **Порог, на котором заход останавливают, стоит позже порога, на котором его продолжают.**
160
+ Два порога на одном числе — это не согласие, а гонка, и выигрывает её тот, кто ближе к
161
+ действию: остановка приходит на вызове, а сжатие — между ходами. Расстояние между ними
162
+ объявляется, а не выводится разницей: сжатие идёт не мгновенно, и порог, отстоящий на волос,
163
+ требование «раньше» удовлетворяет, а работу не спасает.
164
+ - **Переход из состояния в состояние исполнителя не останавливает.** Обязательное
165
+ действие сделано — следующее начинается тем же движением, без отчёта владельцу и без его
166
+ слова. Граница между состояниями выглядит законченным куском лучше всякой другой вехи:
167
+ сделанное названо, отчитаться есть чем, — и отчёт встаёт ровно на то место, где должно было
168
+ стоять следующее действие. Владелец читает такой отчёт как сделанную работу, а работа стоит.
169
+ - **Текст, ведущий состояние работы, называет, что делается сразу за ним.** Дочитанный до
170
+ последнего приёма, он кончается ничем: следующего движения в нём нет, и исполнитель выводит
171
+ его из пустоты — то есть останавливается. Названное движение стоит там же, где приёмы, и
172
+ своими словами: одинаковая на все состояния строка перестаёт замечаться раньше, чем
173
+ понадобится.
145
174
  - **Работа, отданная на разбор, освобождает исполнителя, а не останавливает его.** Отданное на
146
175
  разбор ждёт владельца, а не машину: следующая задача эпика берётся тем же движением, которым
147
176
  предыдущая ушла на разбор.
@@ -0,0 +1,119 @@
1
+ ---
2
+ name: cargo-triage-mark
3
+ kind: pattern
4
+ rule: cargo-triage
5
+ description: Паттерн правила cargo-triage. Брать при разборе приехавшего груза — готовые вызовы отметки: сухой прогон, пачка записей за вызов, приём починки при переходе в готово, версия выпуска при выпуске, разбор отбитой строки. Не брать для сведения предложений в правки пакета — это своя команда.
6
+ ---
7
+
8
+ # Отметка записей груза
9
+
10
+ Паттерн правила `cargo-triage`. Что при этом должно быть верно — закон
11
+ `docs/constitution/work-conduct.md`.
12
+
13
+ Вызовы ниже идут строкой запуска самого пакета и токеном дерева: токен лежит вне дерева, и без
14
+ него команда отбивает вызов, не ходя в сеть.
15
+
16
+ ## Когда брать
17
+
18
+ - Разбирается приехавший груз, и по записи принято решение.
19
+ - Правка по записи влита в главную ветку.
20
+ - Опубликована редакция, увёзшая починку к потребителю.
21
+ - Вызов отметки вернул отбитую строку.
22
+
23
+ ## Что читается раньше вызова
24
+
25
+ Список неразобранного — в админке приёма, отбором по состоянию «новое» и порядком приезда.
26
+ Пока список не сужен, разобранное и нетронутое стоят вперемешку, и разбор идёт по второму
27
+ кругу.
28
+
29
+ Имя команды, адрес приёма и слова состояний у каждого дерева свои — они названы в
30
+ `implementation.md` правила. Ниже они стоят так, как их зовёт пакет.
31
+
32
+ ## Взятие в работу: задача и отметка одним ходом
33
+
34
+ Сначала задача — иначе отметка говорит, что запись взяли, и молчит о том, где идёт работа:
35
+
36
+ ```bash
37
+ npm run task:new -- --title '<что не так>' --slug <короткое-имя> --label bug < тело.md
38
+ ```
39
+
40
+ Отметка идёт следом, тем же ходом, и несёт все записи, которые эта задача закрывает:
41
+
42
+ ```bash
43
+ npx agent-kit mark --state in_work \
44
+ --postmortem 2026-08-14-structure-invented-beside-the-sample.md \
45
+ --postmortem 2026-08-15-guard-denied-shell-wrote-anyway.md \
46
+ --proposal <признак предложения>
47
+ ```
48
+
49
+ Род записи называется своим доводом: разбор происшествия — именем файла, предложение —
50
+ признаком текста. Записи обоих родов едут одним вызовом.
51
+
52
+ Сухим прогоном смотрят, что уехало бы, — он ничего не отправляет и следа наружу не оставляет:
53
+
54
+ ```bash
55
+ npx agent-kit mark --state in_work --postmortem <файл> --dry-run
56
+ ```
57
+
58
+ Сухой прогон вместо настоящего вызова оставляет запись в прежнем состоянии. Отметкой он не
59
+ считается.
60
+
61
+ ## Починка: переход вместе с ответом на «чем»
62
+
63
+ Ставится после того, как правка влита в главную ветку, — не по открытой заявке:
64
+
65
+ ```bash
66
+ npx agent-kit mark --state fixed \
67
+ --postmortem <файл> \
68
+ --fix 'заведена статья правила о разборе груза и паттерн с готовыми вызовами'
69
+ ```
70
+
71
+ Текст отвечает на «чем», а не на «где»: статья правила, гард, проверка, правка кода. Без него
72
+ строка отбивается — переход в починку без ответа на «чем» приёмник не принимает.
73
+
74
+ ## Выпуск: версия называется тем, кто публикует
75
+
76
+ Идёт тем же движением, что и публикация редакции:
77
+
78
+ ```bash
79
+ npx agent-kit mark --state released --postmortem <файл> --release 'rt-agent-kit@0.10.1'
80
+ ```
81
+
82
+ Версия — та, которой назван выпуск, увёзший починку. Не номер редакции приёмника и не время
83
+ выкатки.
84
+
85
+ ## Ответ читается
86
+
87
+ Вызов отвечает тремя числами и списком:
88
+
89
+ ```
90
+ переведено 2, уже стояло 1, отбито 1
91
+ строка 3: <ключ> — записи у дерева нет
92
+ ```
93
+
94
+ - **Переведено 0, уже стояло N** — этот разбор не двинул ничего: записи отмечены раньше либо
95
+ ключи названы не те.
96
+ - **Отбито N** — эти записи остались там, где были. Причина названа при строке, и повтор того
97
+ же вызова отбивается ровно так же.
98
+
99
+ Причины отбоя и что делать с каждой:
100
+
101
+ | Что сказано | Что это значит | Что делать |
102
+ | ---------------------- | ---------------------------------------------- | ------------------------------------ |
103
+ | записи у дерева нет | ключ назван не тот либо запись прислало не оно | сверить ключ со списком в админке |
104
+ | переход не разрешён | шаг через состояние либо ход назад | пройти состояние, которое пропустили |
105
+ | перехода без текста | починка без ответа на «чем» | добавить довод с текстом починки |
106
+ | текста не при том шаге | текст приехал с переходом, который не починка | убрать довод либо сменить состояние |
107
+ | перехода без версии | выпуск без ответа на «где искать фикс» | добавить довод с версией выпуска |
108
+ | версии не при том шаге | версия приехала с переходом, который не выпуск | убрать довод либо сменить состояние |
109
+
110
+ ## Ловушки
111
+
112
+ - **Вызов без токена отбивается без сети.** Токен лежит вне дерева, и на свежей рабочей копии
113
+ его нет: команда называет это прямо, а не молчит.
114
+ - **Своё дерево называется признаком из токена, а не доводом.** Приём сверяет его сам, и
115
+ назваться чужим деревом вызов не может.
116
+ - **Записи, отмеченные в одной ветке, в соседней выглядят неотмеченными только в файлах.**
117
+ Состояние лежит в приёме, а не в дереве: смотрят его в админке, а не в рабочей копии.
118
+ - **Повторная отметка тем же состоянием промахом не считается.** Рабочий порядок повторяют, и
119
+ вторая та же отметка отбивается ответом «уже стояло», а не отказом.
@@ -102,6 +102,9 @@ PR #<номер> готов к слиянию: прогон зелёный, па
102
102
  кто пишет тело. Разница между ними одна, и она вся: реплику владелец прочитает, только если
103
103
  вернётся в переписку, а раздел он видит там, куда смотрит, нажимая кнопку.
104
104
 
105
+ **Следующее движение:** тем же ходом берётся следующая задача эпика, а разбор закрытой работы
106
+ уходит в фон. Прогон и владелец идут без исполнителя, и ждать их состоянием работы не бывает.
107
+
105
108
  ## Состояние `разбор-кончился`: договорённость вливается в спек домена
106
109
 
107
110
  Последним коммитом PR, до слияния. Код к этому моменту написан, поэтому привязки
@@ -131,6 +134,9 @@ npm run check:specs # раздел «Пора вливать» называе
131
134
  npm run check:specs # после вливания: привязки на месте, сценарии не потерялись
132
135
  ```
133
136
 
137
+ **Следующее движение:** за влитой договорённостью тем же ходом идут тексты домена — правила,
138
+ паттерны и разделы, которые работа задела.
139
+
134
140
  ## Состояние `разбор-кончился`: тексты домена приводятся к сделанному
135
141
 
136
142
  В спек уезжает только то, что записали до кода. Остальные тексты — правила, паттерны, законы
@@ -172,6 +178,9 @@ grep -rn -A3 "Чего из закона здесь нет" <каталог пр
172
178
  Что сделали на этом шаге, пишется в тело PR: что перечитали, что изменили, а если ничего
173
179
  не изменили — почему. Форма раздела — паттерн `git-workflow-commit`.
174
180
 
181
+ **Следующее движение:** приведённые тексты коммитятся, и тем же ходом разбирается папка
182
+ задачи — последним коммитом ветки.
183
+
175
184
  ## Состояние `разбор-кончился`: папка задачи разбирается
176
185
 
177
186
  Разбор идёт по трём исходам, а не по двум.
@@ -229,6 +238,9 @@ rm -r docs/tasks/<своя>
229
238
  Две записи в архиве, а не одна: работы разные, и решения в них разные. Сверка очереди работ
230
239
  после этого не называет ни одной папки — этим и проверяется, что разобраны обе.
231
240
 
241
+ **Следующее движение:** разобранная папка уезжает в ветку тем же коммитом, и следом за ним
242
+ сверяется очередь работ.
243
+
232
244
  ## Состояние `папка-разобрана`: сверка очереди работ
233
245
 
234
246
  ```bash
@@ -237,6 +249,9 @@ npm run check:specs # договорённость влита, привязк
237
249
  npm run check:docs # пути, названные в текстах, существуют
238
250
  ```
239
251
 
252
+ **Следующее движение:** расхождения, названные сверками, чинятся тем же ходом; чинить нечего —
253
+ тот же ход снимает черновик и просит владельца влить, называя номер.
254
+
240
255
  ## Состояние `влито`: работа разбирается правилами — фоном, следом за PR
241
256
 
242
257
  Шаг о слое правил, а не о продукте: что за эту работу грузилось, что помогло, чего не хватило и
@@ -261,6 +276,9 @@ npm run check:docs # пути, названные в текстах, суще
261
276
  3. **Вернувшиеся находки принимают одним ходом** — записать и вернуться к прежнему. Разбор,
262
277
  отложенный «до удобного момента», не случается вовсе: заход кончается раньше.
263
278
 
279
+ **Следующее движение:** пока роль разбирает, тот же ход занят следующей задачей; вернувшиеся
280
+ находки принимаются одним ходом — записать и продолжить прежнее.
281
+
264
282
  ## Состояние `влито`: находки разбора ложатся в папку задачи и ждут владельца
265
283
 
266
284
  Ответ роли живёт в переписке и умирает вместе с ней, поэтому он сразу ложится на диск — в папку
@@ -296,6 +314,9 @@ npm run check:docs # пути, названные в текстах, суще
296
314
  котором владелец сказал вслух, уходит наружу в тот же ход: написанное и не отправленное лежит в
297
315
  дереве неотличимо от отправленного.
298
316
 
317
+ **Следующее движение:** записанные находки работу не держат — следующая задача уже идёт, а
318
+ владельцу о них говорится, когда кончился эпик.
319
+
299
320
  ## Ловушки
300
321
 
301
322
  - **Папку разбирают до слияния — потом о ней уже никто не вспомнит.** Сверка очереди считает
@@ -66,6 +66,24 @@ mkdir -p <каталог передачи>
66
66
  # файл — <каталог передачи>/<ветка>.md
67
67
  ```
68
68
 
69
+ **Черновик передачи пишет хук, а не рука.** Перед сжатием контекста он кладёт по тому же
70
+ адресу то, что есть на диске: ветку, состояние работы, следующий шаг, незакоммиченное, коммиты
71
+ сверх главной. Сжатие приходит и тогда, когда напомнить некому — ночью или посреди длинного
72
+ хода, — и без хука заход в этот момент терял передачу целиком.
73
+
74
+ **Читает передачу тоже хук, а не человек.** На запуске он кладёт её в контекст целиком — вместе
75
+ с картой хода, — и вставлять её руками не приходится ни после сжатия, ни после обрыва, ни после
76
+ очистки. Написанная и не прочитанная, передача равна ненаписанной: следующий заход о ней не
77
+ знает и начинает с пустого места, то есть с того же, ради чего её и писали.
78
+
79
+ Отсюда требование к тексту: передача пишется для машины, которая подаст её без разбора, и для
80
+ захода, который прочтёт её первой строкой. Обращаться в ней к владельцу — «спроси у него, чем
81
+ кончилась проба» — значит писать в пустоту: к моменту чтения владельца в разговоре ещё нет.
82
+
83
+ Написанное хуком — нижняя граница, а не готовая передача. Исполнитель, закрывающий заход по
84
+ правилу, пишет поверх: он знает то, чего на диске нет, — чем кончилась проба, почему выбран
85
+ этот путь, что владелец сказал по дороге. Файл один, последняя запись побеждает.
86
+
69
87
  Внутри — готовый текст для вставки в новый заход, без обращения к владельцу за подробностями:
70
88
 
71
89
  ```markdown
@@ -120,6 +120,9 @@ git log --oneline origin/main..HEAD
120
120
  - Доэтапное, не этой работы: сверка очереди перечисляет шесть закрытых задач вне борды.
121
121
  ```
122
122
 
123
+ **Следующее движение:** отмеченный этап тем же ходом сменяется следующим. Этапы кончились —
124
+ тот же ход гонит набор и открывает PR черновиком.
125
+
123
126
  ## Состояние `работа-отдана`: следующая задача берётся тем же движением
124
127
 
125
128
  Задача закрыта, PR открыт и ждёт владельца — заход на этом не кончается. Отданное на разбор
@@ -138,6 +141,9 @@ git log --oneline origin/main..HEAD
138
141
  `task-flow-handoff`. Эпик кончился — заход закрывается тем же порядком, и владельцу называется,
139
142
  что кончился именно эпик, а не одна его задача.
140
143
 
144
+ **Следующее движение:** по следующей задаче делается действие — заведена задача, ветка или
145
+ папка. Ход кончается после него, а не после слов о нём.
146
+
141
147
  ## Ловушки
142
148
 
143
149
  - **Заход, кончившийся ничем, тоже записывается.** Иначе следующий пойдёт той же дорогой:
@@ -40,6 +40,9 @@ Agent(subagent_type: "Explore", prompt: "<тема просьбы>: что по
40
40
  считается сделанным, разведка исполняется как настроение: прочитанный переданный текст сходит
41
41
  за неё, и по текущему дереву не запускается ни одной команды.
42
42
 
43
+ **Следующее движение:** находки ложатся в разбор, и тем же ходом владельцу уходит первый из
44
+ шести вопросов. Разведка кончилась — состояние осталось прежним, ход тоже.
45
+
43
46
  ### Состояние `просьба-не-разобрана`: разбор с владельцем
44
47
 
45
48
  Ведёт главный агент: субагент до владельца не достучится. Команда — `/grill-me`, один вопрос
@@ -89,6 +92,9 @@ mkdir -p docs/tasks/_draft-<slug>
89
92
  cp docs/tasks/_template/grill.md docs/tasks/_draft-<slug>/grill.md
90
93
  ```
91
94
 
95
+ **Следующее движение:** ответ владельца дописывается в разбор, и следом уходит следующий
96
+ вопрос. Ответы кончились — тем же ходом работа идёт в конвейер ролей.
97
+
92
98
  ### Состояние `разбор-закрыт`: конвейер после разбора
93
99
 
94
100
  Вопросов больше не будет — дальше роли:
@@ -107,6 +113,9 @@ Workflow(name: "plan", args: "docs/tasks/_draft-<slug>")
107
113
  «не входит». Находка критика, расходящаяся с ответом владельца, относится владельцу — она не
108
114
  исполняется молча и не считается закрытой правкой текста.
109
115
 
116
+ **Следующее движение:** сверенная с разбором договорённость коммитится, и тем же ходом
117
+ заводятся задача, ветка и папка — а вышла из разбора серия, сперва объявляется эпик.
118
+
110
119
  ### Состояние `договорённость-записана`: серия задач объявляется эпиком
111
120
 
112
121
  Разбор кончился одной задачей — шаг пропускается. Вышло несколько, и порядок между ними
@@ -134,6 +143,9 @@ Workflow(name: "plan", args: "docs/tasks/_draft-<slug>")
134
143
  Лежит замысел вне папки задачи: та умирает с мержем первой же задачи. Каталог для него называет
135
144
  компаньон правила — у пакета своего пути нет.
136
145
 
146
+ **Следующее движение:** объявленный эпик коммитится, и тем же ходом берётся первая его
147
+ задача — заведением задачи, ветки и папки.
148
+
137
149
  ### Состояние `договорённость-записана`: задача, ветка, папка
138
150
 
139
151
  ```bash
@@ -171,6 +183,9 @@ cp docs/tasks/_template/progress.md docs/tasks/<КЛЮЧ>-<номер>-<slug>/pr
171
183
  Пока не объявлено состояние, в котором код правится, гард отбивает правку и называет
172
184
  обязательное действие того состояния, которое стоит в строке.
173
185
 
186
+ **Следующее движение:** объявив состояние, тот же ход берётся за замысел — начиная с его
187
+ шапки. Заведённая папка ходом не кончается: в ней ещё нет ни одного написанного файла.
188
+
174
189
  ### Состояние `задача-взята`: шапка замысла
175
190
 
176
191
  Её читает гард:
@@ -189,6 +204,32 @@ cp docs/tasks/_template/progress.md docs/tasks/<КЛЮЧ>-<номер>-<slug>/pr
189
204
 
190
205
  Пустая причина не принимается.
191
206
 
207
+ **Следующее движение:** под шапкой пишутся след задачи и этапы, замысел коммитится, и тем же
208
+ ходом начинается первый этап.
209
+
210
+ ### Состояние `замысел-записан`: первый этап начинается тем же ходом
211
+
212
+ Замысел закоммичен — работа переходит в первый этап сразу, не отдавая хода. Строка состояния
213
+ перезаписывается на `этап-идёт`, и дальше работу ведёт паттерн возвращения.
214
+
215
+ ```markdown
216
+ - **Состояние:** `этап-идёт`
217
+ - **Этап:** 1 из 3 — <название первого этапа из замысла>
218
+ ```
219
+
220
+ Ход на этой границе не кончается. Написанный замысел выглядит законченным куском: этапы
221
+ разложены, файл закоммичен, отчитаться есть чем — и отчёт встаёт ровно на то место, которое
222
+ должна была занять работа. Владелец читает такой отчёт как сделанное, а сделано ничего. Так
223
+ и вышло 21 августа: заход кончился строкой «следующий шаг — такой-то» при заполнении окна около
224
+ двух процентов.
225
+
226
+ Кончают ход четыре вещи, и они те же, что у остальных состояний: предел заполнения окна, отказ
227
+ гарда, вопрос владельцу и отданная работа, по которой начата следующая. Дочитанный до конца
228
+ паттерн к ним не относится — текст кончился, работа нет.
229
+
230
+ **Следующее движение:** первый этап делается тем же ходом, а закрытым он объявляется после
231
+ того, как прошла его команда из строки «Чем проверяется».
232
+
192
233
  ## Ловушки
193
234
 
194
235
  - **Номер не бывает первым.** До конца разбора неизвестно даже, сколько задач из него выйдет:
@@ -0,0 +1,81 @@
1
+ ---
2
+ name: turn-entry-map
3
+ kind: pattern
4
+ rule: turn-entry
5
+ description: Паттерн правила turn-entry. Брать при правке карты хода и хука, который её подаёт, — что в карту входит, чем она отличается от правила, как хук молчит о недостающем и как это проверяется. Не брать для формы самой передачи — это паттерн task-flow-handoff.
6
+ ---
7
+
8
+ # Карта хода и её подача — готовый код
9
+
10
+ Паттерн правила `turn-entry`. Что при этом должно быть верно — закон
11
+ `docs/constitution/work-conduct.md`.
12
+
13
+ ## Когда брать
14
+
15
+ - В правило ведения работы добавили состояние — карта отстала.
16
+ - Правится хук входа или порядок, в котором части входа кладутся в контекст.
17
+ - Проверка карты покраснела.
18
+
19
+ ## Что входит в карту, а что нет
20
+
21
+ Карта отвечает на вопрос «что делать», правило — на вопрос «почему». Признак отбора один: строка,
22
+ которую заход прочитает и после которой сделает следующий шаг, — в карту; строка, которая
23
+ объясняет, откуда требование взялось, — в правило.
24
+
25
+ | В карту | В правило |
26
+ | ---------------------------------------------- | -------------------------------------------------- |
27
+ | имя состояния и его обязательное действие | почему это действие обязательно |
28
+ | паттерн, который состояние ведёт | разбор происшествия, из которого оно выросло |
29
+ | четыре выхода хода и чем каждый подтверждается | что бывает, когда ход кончают иначе |
30
+ | строка о том, что остальное — продолжение хода | перечень того, чем ход кончать нельзя, с примерами |
31
+
32
+ Разбор происшествия в карту не переезжает никогда: он объясняет, а объяснение — это правило.
33
+
34
+ ## Подача: сперва передача, потом карта
35
+
36
+ Порядок не безразличен. Передача говорит, где именно стоит эта работа, карта — что делают в
37
+ таком месте вообще. Прочитанная первой, карта отвечает на вопрос, которого заход ещё не задал.
38
+
39
+ ```bash
40
+ # передача — по имени текущей ветки, не выбором из каталога
41
+ handoff="$ROOT/${RT_HANDOFF_DIR:-.claude/handoff}/$(git branch --show-current).md"
42
+ [ -r "$handoff" ] && { printf 'ПЕРЕДАЧА ПРОШЛОГО ЗАХОДА\n\n'; cat "$handoff"; }
43
+
44
+ # карта — своим файлом, а не разбором правила
45
+ [ -r "$map" ] && { printf 'КАРТА ХОДА\n\n'; cat "$map"; }
46
+
47
+ exit 0
48
+ ```
49
+
50
+ Три вещи в этом куске обязательны и легко теряются:
51
+
52
+ - **`-r`, а не `-f`.** Файл может существовать и не читаться; `-f` тогда пропускает `cat`
53
+ дальше, и хук печатает заголовок над пустотой.
54
+ - **`exit 0` в конце и никаких других выходов.** Хук входа ничего не отбивает: заход без части
55
+ контекста лучше, чем отбитый запуск.
56
+ - **Имя файла собирается из ветки.** Выбор «первого попавшегося» в каталоге подаёт чужую
57
+ передачу, и выглядит она как своя.
58
+
59
+ ## Чем это проверяется
60
+
61
+ ```bash
62
+ node tools/check-turn-map.mjs # размер, полнота состояний в обе стороны, четыре выхода
63
+ ```
64
+
65
+ Проверка сверяет имена состояний карты с таблицей правила в обе стороны: состояние, заведённое
66
+ правилом и забытое в карте, и состояние, оставшееся в карте после переименования, — оба
67
+ расхождения.
68
+
69
+ Живая проба хука делается на дереве, где обе части лежат, и повторяется четырежды: обе части,
70
+ без передачи, без карты, без обеих. Последний случай обязан дать пустой вывод и нулевой код —
71
+ хук, промолчавший с ненулевым кодом, читается как отбитый запуск.
72
+
73
+ ## Ловушки
74
+
75
+ - **Предел размера назначается замером, а не на глаз.** Первое число выбрали «вдвое больше
76
+ нынешней карты» — и проверка покраснела на собственном тексте в первом же прогоне: карта в
77
+ кириллице весит вдвое больше, чем кажется по числу строк.
78
+ - **Выход за предел означает деление карты, а не подъём предела.** Поднятый однажды, он
79
+ поднимается и во второй раз, и карта тихо становится вторым экземпляром правила.
80
+ - **Карта, разобранная из правила на месте, ломается молча.** Правку разметки таблицы не видит
81
+ ни одна проверка, а карта после неё приходит пустой — и заход об этом не узнает.