@rt-tools/agent-kit 0.16.0 → 0.17.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 (106) hide show
  1. package/assets/checks/board-paths.github.mjs +88 -0
  2. package/assets/checks/board-runs.github.mjs +8 -0
  3. package/assets/checks/board-titles.github.mjs +66 -0
  4. package/assets/checks/check-board.github.mjs +17 -4
  5. package/assets/checks/check-file-size.mjs +10 -2
  6. package/assets/checks/check-glossary.mjs +170 -0
  7. package/assets/checks/check-push-gate.mjs +59 -1
  8. package/assets/checks/check-schema-drift.mjs +12 -5
  9. package/assets/checks/spec-contract.mjs +9 -0
  10. package/assets/defaults/gate-map.sh +13 -4
  11. package/assets/defaults/project.sh +22 -3
  12. package/assets/docs/GLOSSARY.md +1 -1
  13. package/assets/hooks/browser-device-id.sh +20 -4
  14. package/assets/hooks/browser-guard-device-id.sh +5 -2
  15. package/assets/hooks/git-guard-delivery-folder.sh +19 -0
  16. package/assets/hooks/git-guard-delivery.sh +39 -0
  17. package/assets/hooks/git-guard-push-tests.sh +21 -1
  18. package/assets/hooks/grill-gate-ask.sh +25 -0
  19. package/assets/hooks/grill-gate.sh +12 -5
  20. package/assets/hooks/lint-after-edit.sh +44 -16
  21. package/assets/hooks/proposal-guard.sh +17 -1
  22. package/assets/hooks/skill-gate-layers.sh +7 -0
  23. package/assets/hooks/skill-gate.sh +29 -0
  24. package/assets/hooks/task-context-load.sh +10 -0
  25. package/assets/hooks/task-flow-context.sh +185 -0
  26. package/assets/hooks/task-flow-draft-guard.sh +92 -0
  27. package/assets/hooks/task-flow-guard.sh +27 -159
  28. package/assets/hooks/turn-exit-guard.sh +8 -1
  29. package/assets/hooks/window-fill-guard.sh +5 -1
  30. package/assets/laws/delivery.md +19 -0
  31. package/assets/laws/frontend-application.md +4 -0
  32. package/assets/laws/verifiability.md +21 -0
  33. package/assets/laws/work-conduct.md +15 -0
  34. package/assets/patterns/browser-verification-stand.md +7 -2
  35. package/assets/patterns/doc-style-write.md +41 -1
  36. package/assets/patterns/git-workflow-commit.github.md +15 -2
  37. package/assets/patterns/git-workflow-docker.md +14 -0
  38. package/assets/patterns/git-workflow-merge.md +18 -0
  39. package/assets/patterns/git-workflow-migration.md +11 -0
  40. package/assets/patterns/git-workflow-pr.github.md +6 -1
  41. package/assets/patterns/git-workflow-secrets.md +14 -0
  42. package/assets/patterns/git-workflow-stack.md +63 -1
  43. package/assets/patterns/spec-driven-domain.md +34 -1
  44. package/assets/patterns/spec-driven-rule.md +11 -0
  45. package/assets/patterns/spec-driven-sweep.md +57 -0
  46. package/assets/patterns/task-flow-archive.md +46 -14
  47. package/assets/patterns/task-flow-close.md +78 -2
  48. package/assets/patterns/task-flow-resume.md +17 -5
  49. package/assets/patterns/task-flow-start.md +42 -4
  50. package/assets/pitfalls/agent-kit.md +73 -3
  51. package/assets/pitfalls/doc-style.md +5 -0
  52. package/assets/pitfalls/git-workflow.github.md +68 -0
  53. package/assets/pitfalls/spec-driven.md +16 -0
  54. package/assets/pitfalls/task-flow.md +93 -0
  55. package/assets/pitfalls/turn-conduct.md +14 -0
  56. package/assets/rules/browser-verification.md +39 -0
  57. package/assets/rules/deploy-flow.azure.md +8 -0
  58. package/assets/rules/deploy-flow.github.md +18 -0
  59. package/assets/rules/deploy-flow.gitlab.md +8 -0
  60. package/assets/rules/doc-style.md +14 -0
  61. package/assets/rules/git-workflow.azure.md +5 -0
  62. package/assets/rules/git-workflow.github.md +85 -75
  63. package/assets/rules/git-workflow.gitlab.md +5 -0
  64. package/assets/rules/reuse-first.md +8 -0
  65. package/assets/rules/shared-code.md +5 -0
  66. package/assets/rules/spec-driven.md +14 -0
  67. package/assets/rules/task-flow.md +112 -112
  68. package/assets/rules/testing.md +14 -1
  69. package/assets/rules/turn-conduct.md +40 -27
  70. package/assets/rules/turn-entry.md +6 -0
  71. package/assets/samples/tasks/_template/grill.md +5 -0
  72. package/assets/samples/tasks/_template/plan.md +3 -0
  73. package/assets/skills/agent-kit.md +99 -76
  74. package/assets/templates/postmortem.md +5 -1
  75. package/bin/agent-kit.d.ts.map +1 -1
  76. package/bin/agent-kit.js +30 -6
  77. package/bin/agent-kit.js.map +1 -1
  78. package/lib/catalog.d.ts.map +1 -1
  79. package/lib/catalog.js +2 -1
  80. package/lib/catalog.js.map +1 -1
  81. package/lib/commands.d.ts.map +1 -1
  82. package/lib/commands.js +96 -7
  83. package/lib/commands.js.map +1 -1
  84. package/lib/hooks-map.d.ts +26 -0
  85. package/lib/hooks-map.d.ts.map +1 -1
  86. package/lib/hooks-map.js +58 -2
  87. package/lib/hooks-map.js.map +1 -1
  88. package/lib/sections.d.ts +6 -0
  89. package/lib/sections.d.ts.map +1 -1
  90. package/lib/sections.js +19 -0
  91. package/lib/sections.js.map +1 -1
  92. package/lib/shipment.d.ts +2 -0
  93. package/lib/shipment.d.ts.map +1 -1
  94. package/lib/shipment.fixture.d.ts +5 -0
  95. package/lib/shipment.fixture.d.ts.map +1 -1
  96. package/lib/shipment.fixture.js +7 -0
  97. package/lib/shipment.fixture.js.map +1 -1
  98. package/lib/shipment.js +13 -1
  99. package/lib/shipment.js.map +1 -1
  100. package/lib/sync.d.ts +35 -3
  101. package/lib/sync.d.ts.map +1 -1
  102. package/lib/sync.js +59 -8
  103. package/lib/sync.js.map +1 -1
  104. package/package.json +1 -1
  105. package/rt-tools-agent-kit-0.17.0.tgz +0 -0
  106. package/rt-tools-agent-kit-0.16.0.tgz +0 -0
@@ -117,18 +117,50 @@ npm run check:docs # пути, названные в текстах, суще
117
117
  3. **Вернувшиеся находки принимают одним ходом** — записать и вернуться к прежнему. Разбор,
118
118
  отложенный «до удобного момента», не случается вовсе: заход кончается раньше.
119
119
 
120
- **Следующее движение:** пока роль разбирает, тот же ход занят следующей задачей; вернувшиеся
121
- находки принимаются одним ходом — записать и продолжить прежнее.
120
+ ### Записи груза переводятся в «готово» тем же ходом
122
121
 
123
- ## Состояние `влито`: находки разбора ложатся в папку задачи и ждут владельца
122
+ Работа, начатая с приехавшего груза, кончается здесь, а не на разборе папки: до слияния правки в
123
+ дереве нет, и отметка утверждала бы то, чего в главной ветке ещё не лежит. Это единственное
124
+ состояние, где слияние уже случилось, а ход о задаче ещё идёт.
124
125
 
125
- Ответ роли живёт в переписке и умирает вместе с ней, поэтому он сразу ложится на диск в папку
126
- задачи, файлом рядом с ходом работы. Пишет его исполнитель: роль файлов не пишет.
126
+ Ключи берутся из описания прошлого папки задачи на диске к этой минуте нет,и подставляются
127
+ полными, как их печатает чтение приёма:
127
128
 
128
- Папка задачи умирает со слиянием, а находки должны пережить весь эпик — владелец читает их
129
- разом, когда эпик кончился. Поэтому при разборе папки файл находок не удаляется вместе
130
- с остальным, а **переезжает к замыслу эпика**: там его найдут и после того, как ветка въехала.
131
- Работа вне эпика показывает находки владельцу сразу, тем же ходом.
129
+ ```bash
130
+ npm run cargo:mark -- --state fixed \
131
+ --proposal <полный ключ> --proposal <полный ключ> \
132
+ --fix '<чем исправлено: статья правила, гард, проверка, правка кода>'
133
+ ```
134
+
135
+ Приём починки один на вызов, поэтому записи едут пачками по тому, чем закрыты, а не всей задачей
136
+ разом. Ответ читается: «переведено 0» означает, что этот разбор не двинул ничего.
137
+
138
+ **Следующее движение:** пока роль разбирает, тот же ход занят следующей задачей; записи груза
139
+ переводятся в «готово» этим же ходом, вернувшиеся находки принимаются одним ходом — записать и
140
+ продолжить прежнее, а владельцу о них говорится, когда кончился эпик.
141
+
142
+ ## Находки разбора ложатся к замыслу эпика и ждут владельца
143
+
144
+ Ответ роли живёт в переписке и умирает вместе с ней, поэтому он сразу ложится на диск. Пишет
145
+ его исполнитель: роль файлов не пишет.
146
+
147
+ **Пишутся находки сразу в файл рядом с замыслом эпика, а не в папку задачи.** Разбор идёт
148
+ фоном, и когда он кончится, не знает никто; папка задачи к этому времени бывает уже разобрана,
149
+ а ветка влита и снята. Оба срока назначает не исполнитель, поэтому переезд «из папки к замыслу
150
+ эпика» держится на совпадении, которого может и не случиться. Тем же местом пользуется находка,
151
+ замеченная не разбором, а по ходу работы. Работа вне эпика показывает находки владельцу тем же
152
+ ходом.
153
+
154
+ **Находки, вернувшиеся после того, как ветка ушла, едут веткой следующей задачи.** Пуш в снятую
155
+ ветку её не обновляет, а заводит заново: коммит остаётся вне главной ветки и пропадает вместе
156
+ с ней. Следующая задача к этому времени уже взята — её веткой уборка за предыдущей и едет.
157
+ Эпик кончился и следующей задачи нет — находки уезжают своей задачей.
158
+
159
+ **Накопительный файл находок делится до дописи, а не после.** Длина смотрится одной командой
160
+ перед первой написанной строкой: раздел задачи занимает десятки строк, и предел длины документа
161
+ он переходит молча. Гейт пуша показывает превышение, когда допись уже закоммичена, — тогда
162
+ деление идёт задним числом, вместе с правкой ссылок на файл. Не влезает — заводится следующая
163
+ часть, и раздел пишется сразу в неё.
132
164
 
133
165
  **Наружу без слова владельца уезжает только сводка наблюдений.** Она говорит, чем пользовались
134
166
  и чем не пользовались ни разу, — это факт, и мнением он не станет. Предложение — другое дело:
@@ -155,9 +187,6 @@ npm run check:docs # пути, названные в текстах, суще
155
187
  котором владелец сказал вслух, уходит наружу в тот же ход: написанное и не отправленное лежит в
156
188
  дереве неотличимо от отправленного.
157
189
 
158
- **Следующее движение:** записанные находки работу не держат — следующая задача уже идёт, а
159
- владельцу о них говорится, когда кончился эпик.
160
-
161
190
  ## Ловушки
162
191
 
163
192
  - **Папку разбирают до открытия заявки — потом о ней уже никто не вспомнит.** Сверка очереди
@@ -165,8 +194,11 @@ npm run check:docs # пути, названные в текстах, суще
165
194
  следующей задаче, и находка достанется чужому заходу. Держит это гард поставки:
166
195
  открытие заявки отбивается, пока папка лежит в ветке.
167
196
  - **Разбор папки идёт последним коммитом, после того как гейт пуша прошёл целиком.** Порядок
168
- один: мерж главной ветки, все линтеры и проверки зелёные, вливание договорённости, приведение
169
- текстов домена, разбор папки — и только потом заявка.
197
+ один: мерж главной ветки, вливание договорённости, приведение текстов домена, все линтеры и
198
+ проверки зелёные, разбор папки — и только потом заявка. Дешёвый шаг стоит раньше дорогого:
199
+ заход, потративший окно на прогон, упирался в порог заполнения на четырёх строках привязки, и
200
+ дописать их было уже нечем. Второй довод сильнее: прогон, стоящий после вливания, проверяет и
201
+ само вливание — иначе он смотрит то состояние дерева, которое в главную ветку не поедет.
170
202
  - **После разбора замысла на диске нет, и собирать папку заново не надо.** Правку по замечаниям
171
203
  разбора и починку красного прогона гард хода работы пропускает по признаку из истории ветки:
172
204
  папка, снятая её коммитом, и есть признак отданной работы. Собранная заново папка вернула бы
@@ -12,14 +12,22 @@ description: Паттерн правила task-flow. Брать при дове
12
12
 
13
13
  ## Когда брать
14
14
 
15
- - Этапы замысла закрыты, набор гейта прогнан целиком.
15
+ - Этапы замысла закрыты.
16
16
  - `npm run check:specs` перечислил договорённость в разделе «Пора вливать».
17
+ - Спек меряется длиной сразу после вливания: выросший делится тем же коммитом.
17
18
  - Тексты домена приводятся к тому, что работа сделала.
19
+ - Набор гейта прогнан целиком — после вливания и приведения текстов, а не до них.
18
20
  - Папка задачи разобрана, и заявка открывается черновиком.
19
21
  - Прогон на вершине зелёный, и с заявки снимается черновик.
20
22
 
21
23
  Разбор самой папки сюда не относится — это паттерн `task-flow-archive`. Он стоит между
22
- приведением текстов и открытием заявки: заявка открывается уже за убранной работой.
24
+ прогоном набора и открытием заявки: заявка открывается уже за убранной работой.
25
+
26
+ **Прогон стоит после вливания договорённости и приведения текстов, а не перед ними.** Оба этих
27
+ шага стоят минуты, а прогон — окно захода: заход, потративший его на прогон, упирался в порог
28
+ заполнения на четырёх строках привязки, и дописать их было уже нечем. Второй довод сильнее
29
+ первого — прогон, идущий после вливания, проверяет и само вливание; идущий до него, он смотрит
30
+ то состояние дерева, которое в главную ветку не поедет.
23
31
 
24
32
  ## Состояние `этапы-кончились`: договорённость вливается в спек домена
25
33
 
@@ -30,11 +38,19 @@ description: Паттерн правила task-flow. Брать при дове
30
38
  npm run check:specs # раздел «Пора вливать» называет готовые директории
31
39
  ```
32
40
 
41
+ **Спек меряется длиной тем же ходом.** Вливание — известное движение, растящее спек: одно
42
+ довело его до 572 строк при пределе 500, и узнал об этом исполнитель отказом гарда пуша, то
43
+ есть после коммита. Выросший делится на поддомены здесь же, а не на пуше.
44
+
33
45
  Порядок переезда:
34
46
 
35
47
  - правила из `proposed/<фича>/spec.md` дописываются в `spec.md` домена, в его разделы;
36
48
  - сценарии переезжают в `scenarios.md` домена **с прежними номерами**: на них ссылаются
37
49
  заголовки тестов, и пересчёт рвёт сверку;
50
+ - сценарии, у которых работа переписала обещание, правятся на месте: номер прежний, текст
51
+ новый, заголовок теста правится тем же коммитом. Работа, снимающая приём, переписывает уже
52
+ записанное обещание чаще, чем заводит новое, а список, перечисляющий одну допись, эту правку
53
+ не называет вовсе;
38
54
  - привязки из `proposed/<фича>/implementation.md` дописываются в `implementation.md` домена
39
55
  и проставляются на код, который теперь есть;
40
56
  - законы, объявленные фичей в шапке, дописываются в шапку спека домена;
@@ -103,11 +119,60 @@ grep -rn -A3 "Чего из закона здесь нет" <каталог пр
103
119
  работа ждёт владельца, а не машину, и заход на этом не кончается: следующая задача берётся тем
104
120
  же движением, паттерн `task-flow-resume`.
105
121
 
122
+ **Готовность меряется рассказанностью, а не пройденностью.** Перечень того, что сделано к
123
+ открытию, читается как список обязательных проверок, и границы у него не видно. Она есть:
124
+ проверка, которую исполнитель не может пройти по причине вне работы — отбитое разрешение,
125
+ недоступная среда, ключ у человека, — готовность не отменяет. Она попадает в «Не гонялось» и в
126
+ «Оставшийся шаг», названная вместе с причиной; умолчание о ней читается как пройденная.
127
+
106
128
  Состояния на диске уже нет — ход работы уехал вместе с папкой. Это цена того, что уборка стоит
107
129
  до заявки: хвост из четырёх шагов — открыть заявку, дождаться прогона, снять черновик, попросить
108
130
  влить — держится этим паттерном, а не строкой в файле. Гард признаёт работу отданной по истории
109
131
  ветки: папка, снятая её коммитом, и есть признак.
110
132
 
133
+ ### Раздел об оставшемся шаге пишется в теле заявки, а не дописывается потом
134
+
135
+ Он стоит там с минуты открытия. Сказанного вслух мало, и одним этим требование не держится:
136
+ реплика живёт до следующей реплики, а решение о слиянии принимается на странице заявки — там
137
+ переписки нет вовсе. Владелец вливает, как только видит зелёное, и заявка, открытая без раздела,
138
+ уезжает в главную ветку раньше, чем раздел успевают дописать: так папка задачи однажды и уехала
139
+ неразобранной, пока шёл прогон. Раздел стоит последним и говорит ровно одно: осталось ли что-то
140
+ до слияния.
141
+
142
+ ```markdown
143
+ ## Оставшийся шаг
144
+
145
+ Папка задачи разобрана коммитом `<sha>` — за работой убрано. Осталось дождаться прогона и снять
146
+ черновик; до этого кнопка слияния заблокирована хостингом.
147
+ ```
148
+
149
+ Черновик снят — раздел переписывается тем же вызовом, которым правится тело:
150
+
151
+ ```markdown
152
+ ## Оставшийся шаг
153
+
154
+ Не осталось: прогон зелёный, черновик снят. Можно вливать.
155
+ ```
156
+
157
+ Заголовок раздела и слова обоих образцов пишутся языком заявки, а не языком паттерна. Образцы
158
+ набраны тем языком, которым написан сам паттерн, и переносятся целиком — порядок мыслей,
159
+ формулировки и заголовок, заголовок последним: он выглядит частью формы, а не частью текста.
160
+ То же верно и для двух сообщений владельцу ниже: они образцы того, **что** сказано, а не того,
161
+ какими словами.
162
+
163
+ Пустым раздел не оставляется и не удаляется вовсе: отсутствие раздела и «шагов не осталось»
164
+ читаются одинаково, а значат разное. Образец тела заявки целиком — в паттерне заведения коммита
165
+ и заявки, если дерево его разложило.
166
+
167
+ Держит это гард поставки, а не память пишущего: он читает тело прямо из команды открытия —
168
+ доводом оно передано или файлом — и отбивает вызов вместе с остальным несошедшимся. Образец
169
+ заголовка при этом называет дерево, потому что заголовок пишется языком заявки, а пакет чужих
170
+ слов не знает; не названный, раздел не судится вовсе. Сверка очереди работ тела по-прежнему не
171
+ читает: промах ловится в минуту открытия, то есть там, где он ещё исправим одним вызовом.
172
+
173
+ Разница между разделом и сказанным вслух одна, и она вся: реплику владелец прочитает, только
174
+ если вернётся в переписку, а раздел он видит там, куда смотрит, нажимая кнопку.
175
+
111
176
  ### Два сообщения владельцу, и между ними — прогон
112
177
 
113
178
  Оба обязательны, и порядок между ними один. Ни одно не заменяется другим: первое говорит, что
@@ -175,6 +240,12 @@ PR #<номер> готов к слиянию: прогон зелёный, че
175
240
  читаются одинаково, а значат разное. Образец тела заявки целиком — в паттерне заведения коммита
176
241
  и заявки, если дерево его разложило.
177
242
 
243
+ Открытая заявка перечитывается той записью, которая будет её вливать, а не той, что её открыла.
244
+ Ответ хостинга автору говорит лишь, что вызов прошёл: право на открытие и видимость открытого —
245
+ разные вещи, и вторая проверяется только со стороны читателя. Невидимая заявка ничем себя не
246
+ выдаёт — она есть в ответе своему автору, у неё стоят метки, а очередь разбора у владельца просто
247
+ пуста.
248
+
178
249
  Проверить это машиной нечем, и проверки не будет: тело заявки не читает ни одна сверка, а
179
250
  хостинг не спрашивает ни о чём, кроме заголовка. Требование держится тем же, чем и слова
180
251
  вслух, — тем, кто пишет тело. Разница между ними одна, и она вся: реплику владелец прочитает,
@@ -186,6 +257,11 @@ PR #<номер> готов к слиянию: прогон зелёный, че
186
257
  нет, и собирать папку заново не надо: гард хода работы пропускает правку по признаку из истории
187
258
  ветки. Что именно чинится, берётся из замечания, а не из замысла.
188
259
 
260
+ Главная ветка, влитая ради того, чтобы что-то посмотреть, — такая же правка, как влитая ради
261
+ работы, и уезжает тем же ходом. Конфликт тут ни при чём: он делает промах заметнее, а не создаёт
262
+ его. Слияние, оставшееся в рабочей копии, либо пушится тем же ходом, либо не делается — иначе
263
+ владелец видит прежнее состояние и решает по нему.
264
+
189
265
  **Следующее движение:** прогон зелёный и замечаний нет — черновик снимается, и владельцу
190
266
  говорится, что работа готова.
191
267
 
@@ -32,6 +32,11 @@ description: Паттерн правила task-flow. Брать при возв
32
32
  - **Не спрашивать владельца о том, что записано.** Ради этого всё и заведено.
33
33
  - **Не начинать заново то, что отмечено сделанным.** Отметка стоит в ходе работы; сомнение в
34
34
  ней проверяется деревом — сборкой, тестами, чтением файла, — а не вопросом.
35
+ - **Не выводить записанное заново из кода.** Запрет на вопрос этого не покрывает: решение,
36
+ выведенное из кода и поданное находкой, обходится дороже лишнего вопроса — владельцу
37
+ предлагают принять заново то, что он уже принял, и список вариантов звучит убедительнее
38
+ записи, которой он не видит. Прежде чем выводить, ищут в разборе просьбы, в ходе работы и в
39
+ замысле.
35
40
  - **Не править замысел.** С ним сверяют результат; пересмотр идёт записью в ходе работы.
36
41
 
37
42
  ## Вход из передачи захода
@@ -154,10 +159,17 @@ git log --oneline origin/main..HEAD
154
159
  несохранённым и почему» — единственное, по чему это видно, пока PR нет.
155
160
  - **Подтверждение — вывод команды или замер, а не пересказ.** «Проверил, работает» через
156
161
  заход неотличимо от «казалось, что работает».
157
- - **Число из передачи пересчитывается до того, как на нём что-то делят.** Передача описывает
158
- день, когда её писали, лежит вне дерева, и не читает её ни одна проверка. Оценка «работы
159
- вдвое больше предыдущей» при пересчёте на текущем коммите не подтвердилась: по числу
160
- утверждений объёмы оказались почти равны. Деление работы по чужой оценке делит не то, и
161
- владельцу называются свои числа.
162
+ - **Число из передачи и из «Где стоим» пересчитывается перед тем, как попасть в любой новый
163
+ текст.** Не только перед делением работы: перенесённое в разбор просьбы или в ход работы, оно
164
+ читается следующими заходами как замер и не проверяется больше никем. Передача описывает
165
+ день, когда её писали, лежит вне дерева, и не читает её ни одна проверка. Счёт, взятый
166
+ непересчитанным, разошёлся с деревом на восемь и нашёлся сценарием подсчёта, а не чтением; та
167
+ же цена у оценки «работы вдвое больше предыдущей» — на текущем коммите объёмы оказались почти
168
+ равны. Пересчёт стоит одной команды, и в текст едет своё число.
162
169
  - **Доэтапное отделяется от своего.** Красное, найденное по дороге и не этой работой
163
170
  сделанное, помечается таковым сразу: иначе следующий заход примет его за свою поломку.
171
+ - **Разбор, написанный этим заходом, требованием для него не становится.** Запись объясняет
172
+ механизм, а исполняется он тем же, чем исполнялось прежнее, — вниманием того, кто ведёт ход:
173
+ через один ход после записи механизм повторился в той же форме. Поэтому разбор кончается не
174
+ текстом, а тем, что из него вышло: правкой ресурса, гардом или предложением с адресом. Заход,
175
+ дописавший разбор и вернувшийся к работе прежним, платит за него дважды.
@@ -33,6 +33,16 @@ Agent(subagent_type: "Explore", prompt: "<тема просьбы>: что по
33
33
 
34
34
  Находки складываются в раздел «Что уже есть в дереве» разбора.
35
35
 
36
+ Дерево — не единственное место, где может лежать ответ. Решение, принятое прошлым заходом и
37
+ никуда не записанное, живёт только в записи того захода: записи заходов лежат в каталоге заходов
38
+ агента, и поиск по ним словом темы стоит одной команды. Найденное там ответом не остаётся на
39
+ месте — тем же ходом оно переписывается в дерево: в замысел эпика, если связывает задачи, и в
40
+ ход работы, если касается одной.
41
+
42
+ Разведка, не нашедшая ничего, разрешением спрашивать не становится. Сначала называется, где
43
+ искали, потом добираются места, которых в списке не было: замысел эпика, описание прошлого,
44
+ записи прошлых заходов.
45
+
36
46
  Разведка кончается не ощущением, а выводом команд. До первого вопроса владельцу исполнитель
37
47
  знает: как устроен репозиторий (корневая памятка), что лежит в каталоге, о котором пойдёт речь
38
48
  (`ls`), и есть ли уже написанное по теме (поиск по документации и правилам). Вопрос называет,
@@ -68,6 +78,17 @@ Agent(subagent_type: "Explore", prompt: "<тема просьбы>: что по
68
78
  | Чем будет видно, что задача закрыта | «работает» признаком не является |
69
79
  | Есть ли образец, с которого снимается подход | разведка найдёт похожее, а не то |
70
80
 
81
+ Список шести — набор того, что должно быть закрыто к началу работы, а не набор реплик, которые
82
+ надо произнести. Обязательный вопрос, ответ на который владелец уже дал, отмечается закрытым, а
83
+ не задаётся: ответ ищется в двух местах — в документации и в том, что владелец сказал в этом же
84
+ заходе, включая исходную просьбу. Слово, повторённое в просьбе несколько раз, ответом является.
85
+ Закрытый вопрос отмечается в разборе просьбы вместе с тем, чем он закрыт.
86
+
87
+ Объём работы основанием для вопроса о границах не бывает. «Это большая работа» и «делать ли её
88
+ целиком» — разные вопросы: первый исполнитель решает сам, второй владелец решает раньше, чем
89
+ работа началась. Вопрос о границах задаётся тогда, когда владелец границ не назвал, — а не
90
+ тогда, когда названные оказались широкими.
91
+
71
92
  Форму вопроса задают настройки владельца: где они требуют меню, спрашивается меню, и тогда к
72
93
  каждому вопросу добавляется свободный вариант — у закрытого набора нет строки «вопрос не тот».
73
94
  Выбор слова, имени и термина уточняется прозой в любом случае.
@@ -121,6 +142,11 @@ Workflow(name: "plan", args: "docs/tasks/_draft-<slug>")
121
142
  «не входит». Находка критика, расходящаяся с ответом владельца, относится владельцу — она не
122
143
  исполняется молча и не считается закрытой правкой текста.
123
144
 
145
+ Ход на этой границе не кончается. Закрытый разбор выглядит законченным куском: ответы владельца
146
+ лежат на диске, файл закоммичен, отчитаться есть чем — и отчёт встаёт ровно на то место, которое
147
+ должна была занять договорённость. Пишется она тем же ходом, конвейером ролей или рукой
148
+ исполнителя, и разницы между этими двумя случаями для конца хода нет.
149
+
124
150
  **Следующее движение:** сверенная с разбором договорённость коммитится, и тем же ходом
125
151
  заводятся задача, ветка и папка — а вышла из разбора серия, сперва объявляется эпик.
126
152
 
@@ -155,6 +181,13 @@ Workflow(name: "plan", args: "docs/tasks/_draft-<slug>")
155
181
  таблицы, с меткой эпика. Выданные номера возвращаются в ту же таблицу — колонкой или приставкой
156
182
  к названию, — и с этой минуты «взять следующую» отвечает номером, а не названием.
157
183
 
184
+ Задача, заведённая под эпик, называет его в своём теле: номер карточки эпика и путь к замыслу —
185
+ одной строкой. Замысел называет задачу со своей стороны, и односторонняя привязка выглядит целой
186
+ ровно так же, как двусторонняя — читатель приходит то от линии работ, то от карточки, и вторая
187
+ сторона существует только для одного из них. Держалась она подражанием: пока тело писалось с
188
+ образца соседней задачи того же эпика, строка копировалась вместе с формой, а задача, заведённая
189
+ посреди работы находкой сверки, писалась не с образца.
190
+
158
191
  **Следующее движение:** объявленный эпик коммитится вместе с номерами задач, и тем же ходом
159
192
  берётся первая его задача — заведением ветки и папки.
160
193
 
@@ -208,6 +241,13 @@ cp docs/tasks/_template/progress.md docs/tasks/<КЛЮЧ>-<номер>-<slug>/pr
208
241
  **Поведение:** меняется
209
242
  ```
210
243
 
244
+ Дерево, у которого каталога «предложено» нет, называет договорённость самим спеком домена — там
245
+ она пишется прямо в него, и переезжать при закрытии работы нечему:
246
+
247
+ ```markdown
248
+ **Спек:** `docs/specs/bookings/spec.md`
249
+ ```
250
+
211
251
  Работа, не задевающая `apps/**` и `libs/**`, договорённости не требует:
212
252
 
213
253
  ```markdown
@@ -254,7 +294,5 @@ cp docs/tasks/_template/progress.md docs/tasks/<КЛЮЧ>-<номер>-<slug>/pr
254
294
  - **Задача заводится командой, а не четырьмя вызовами подряд.** Борда к репозиторию не
255
295
  привязана, и задача попадает на неё только явным добавлением.
256
296
  - **Slug ветки берётся из терминологии договорённости, а не из слов просьбы.** Договорённость
257
- пишется раньше ветки и как раз там отказывается от слова владельца: спек завёл своё имя
258
- предмету и прямо сказал, каким словом его не называть, а ветка и папка задачи остались с
259
- отвергнутым. Заголовок задачи и PR поправить можно, имя ветки после открытия PR —
260
- уже нет.
297
+ пишется раньше ветки и как раз там отказывается от слова владельца. Заголовок задачи и PR
298
+ поправить можно, имя ветки после открытия PRуже нет.
@@ -42,9 +42,18 @@
42
42
  отдельным шагом, отбивается как неиспользуемый ещё до того, как появится строка, которая его
43
43
  зовёт, и работа встаёт на половине. Правка делается одним вызовом либо в порядке «сначала
44
44
  использование, потом импорт».
45
- - **Прогонять сценарии гардов можно, ничего не раскладывая.** Обвязка набора принимает каталог
46
- гардов переменной, и пакетную редакцию гоняют по сценариям дерева до установки. Заход,
47
- потраченный на диагноз по последствиям, стоил ровно этой строки.
45
+ - **Прогонять сценарии гардов можно, ничего не раскладывая, но только там, где сам пакет живёт
46
+ исходниками.** Обвязка набора принимает каталог гардов переменной, и пакетную редакцию гоняют
47
+ по сценариям дерева до установки. Заход, потраченный на диагноз по последствиям, стоил ровно
48
+ этой строки. В поставке ни обвязки, ни каталога сценариев нет: они живут в репозитории пакета,
49
+ и дерево-потребитель, поверившее совету, ищет у себя то, чего ему не отгружали.
50
+
51
+ - **Прогонять сценарии гардов можно, ничего не раскладывая, — там, где эти сценарии есть.**
52
+ Обвязка набора принимает каталог гардов переменной, и пакетную редакцию гоняют до установки.
53
+ Живёт она в репозитории самого пакета: в поставку едут ресурсы, строка запуска и библиотека, а
54
+ каталога сценариев в ней нет вовсе. Дереву-потребителю остаются свои сценарии на свои гарды —
55
+ искать у себя пакетные значит потратить заход на диагноз по последствиям, ровно тот, от
56
+ которого совет обещал избавить.
48
57
  - **Отбитая правка не всегда про текст гарда.** Гард зовут по пути, и файл без права на
49
58
  запуск отвечает отказом доступа — ненулевым кодом, который читается как «правка отбита».
50
59
  Набор при этом отбивает подряд всё, включая сборку и тесты, и причины не называет.
@@ -78,3 +87,64 @@
78
87
  ровно так же, как с кодом дерева: запись в файл вне репозитория была отбита гардом хода
79
88
  работы с требованием замысла, к ней не относящегося. Путь в профиле сначала приводится к
80
89
  корню дерева, и всё, что вне корня, признака не получает.
90
+ - **Похожесть текстов ближайшую статью не находит.** Замер показал, что законное соседство двух
91
+ статей одного правила и законный перенос удачной статьи на соседнее место дают одно и то же
92
+ число: цитата поэтому ищется точным совпадением, а не мерой похожести.
93
+ - **Отметка об отправке живёт в рабочем дереве, а дерево у каждой ветки своё.** Поставленная в
94
+ одной ветке, в соседней она не видна, и тот же текст уезжает вторым разом; второй записью он
95
+ при этом не становится — приём отбирает уже приехавшее по признаку предложения, и его ответ
96
+ говорит, сколько записей легло и сколько уже лежало. Строка «принято 0, уже лежало 3» означает,
97
+ что нового не уехало ничего.
98
+ - **Отметка, поставленная только на принятое, объявила бы неотправленным то, что дошло раньше.**
99
+ Файл остался бы без неё навсегда: принятым он больше не станет никогда, а гард предложений
100
+ отбивал бы ход у каждого следующего захода. Отправителю разница между принятым и уже лежавшим
101
+ ничего не меняет — оба исхода значат одно: груз доехал.
102
+ - **Отказ отправки, называющий один лишь ключ конфига, уводит читателя не туда.** Ни адреса, ни
103
+ токена в конфиге нет и не будет: оба приходят от владельца приёма — адрес словом, токен
104
+ одноразовым кодом приглашения. Отказ поэтому называет приглашение, а не ключ: ушедший править
105
+ конфиг ответа там не находит и второй раз спрашивает уже владельца.
106
+ - **Редакция пакета, поднятая без раскладки, запирает дерево целиком.** Красит она не свою
107
+ ветку, а главную: сверка раскладки стоит в гейте пуша, и на ней отбивается чужая работа, пакета
108
+ не касающаяся вовсе. Своей веткой такой автор починить это не может — правка лежит в чужой.
109
+ - **Правка разложенного файла без гарда на месте всплывает в чужой ветке.** Знал о ней один
110
+ `sync --check`, а говорил он на следующей раскладке: отказ приходил тому, кто в этот день
111
+ правил соседний ресурс, и выглядел поломкой его работы.
112
+
113
+ ## Подъём версии: чем сверять замещённые разделы
114
+
115
+ Замерено на двух подъёмах подряд: в одном шесть замещённых разделов недосчитались новых
116
+ утверждений, в другом два раздела — одиннадцати статей, и ни одна команда об этом не сказала.
117
+ Прежняя редакция при этом нашлась случайной копией в чужом рабочем дереве: установка стирает её
118
+ без следа, поэтому снимок и стоит первым шагом подъёма.
119
+
120
+ Сверяются статьи, а не заголовки — заголовок как раз и совпал, этим раздел замещён:
121
+
122
+ ```bash
123
+ sec() { awk -v s="$2" '$0 ~ "^## "s {f=1;next} /^## /{f=0} f' "$1" \
124
+ | grep '^- \*\*' | sed 's/^- \*\*//;s/\*\*.*//'; }
125
+ comm -13 <(sec "$OLD/<ресурс>" '<заголовок>' | sort) <(sec "$NEW/<ресурс>" '<заголовок>' | sort)
126
+ ```
127
+
128
+ Строка в выводе — статья, которую надстройка проглотила: пакет её дописал, а дерево не увидело.
129
+ Переносится она в надстройку руками.
130
+
131
+ ## Выключенная роль: что бывает с настройкой
132
+
133
+ - **Настройка, которую не прочитать, роль не выключает.** Не нашлось `jq`, нет настройки, в
134
+ настройке сломан разбор — гард судит, как судил. Обратный выбор гасил бы слой правил молча, и
135
+ заметить это было бы нечем.
136
+ - **Ключ, написанный не списком, ловит раскладка, а не гард.** Гарду виден только список имён:
137
+ строка вместо списка читается им как «роль включена», и роль работает, хотя дерево считает её
138
+ выключенной. Отказывает на этом разбор настройки — первой же раскладкой, называя ключ.
139
+ - **Выключение живёт в настройке дерева, а не в настройке агента.** Строка, вырезанная из
140
+ настроек агента руками, теряется на первой же правке того файла, и вернуть роль будет нечем.
141
+ Здесь оно объявлено в одном месте и видно всякому, кто читает настройку дерева.
142
+
143
+ ## Свойства дерева: две границы
144
+
145
+ - **`only` сильнее требования.** Ресурс, названный поимённо, ложится и при неотвеченном
146
+ требовании; перечень раскладки называет это вслух, а отказ по его пустому компаньону зовёт
147
+ снять ресурс, а не заполнять черновик.
148
+ - **Свойство, которого пакет не объявлял, роняет раскладку** — что в `has` дерева, что в имени
149
+ ресурса. Объявлены свойства перечнем при пакете, рядом с осями различия.
150
+
@@ -7,6 +7,11 @@
7
7
 
8
8
  ## Ловушки
9
9
 
10
+ - **Отступление от просьбы называется в том же докладе, где показан результат.** Сделанное не
11
+ тем способом, о котором просили, отличается от сделанного просимым способом даже при совпавшем
12
+ ответе, и разницу называет исполнитель — одной строкой «сделал не тем, чем сказано, вот чем и
13
+ вот почему». Умолчание держится ровно до того, как просьбу приходится повторять, а платит за
14
+ него доверие ко всему докладу.
10
15
  - **Оставшаяся работа не записывается в документ, а заводится задачей.** `docs/BACKLOG.md`
11
16
  держит только то, что задачей не бывает: договорённости и решения, которые решено не
12
17
  править. Признак — утверждение остаётся, если править его никто не собирается. «Сделать
@@ -97,8 +97,57 @@
97
97
  Сюда уехали случаи, числа и отвергнутые лекарства, стоявшие прежде при статьях правила. Ни одно
98
98
  решение по правке на них не стоит: они нужны тому, кто разбирает промах или спорит с гардом.
99
99
 
100
+ - **Отказ на слиянии остаётся вторым рубежом.** Человек вливает, как только видит зелёное, и до
101
+ второго рубежа дело просто не доходит.
102
+
103
+ - **Список, в котором всё серое, читается как «работа не сделана».** Черновик и недоделанное
104
+ выглядят одинаково; находит такие заявки сверка — ночью, в чужой сессии, после закрытого
105
+ разговора.
106
+ - **Логин рядом со служебным числом не сверяет никто.** Промах в почте изнутри не виден вовсе:
107
+ коммит выглядит своим, а подписан посторонним.
108
+
109
+ - **Ключ задач, разошедшийся с формой ветки в профиле.** Они не отказывают, а перестают узнавать
110
+ номер: проверка, искавшая работу без задачи, пропускает всё подряд.
111
+ - **Сложение у указателя зовут не ради спора, а ради тишины.** Без объявления человека зовут при
112
+ каждом слиянии — по строке, которая нужна целиком с обеих сторон.
113
+
114
+ - **Гейт — обещание, что пуш не приедет красным.** Набор без сборки и снимков обещает то, чего не
115
+ проверяет.
116
+ - **Борда показывает, что сделано и что осталось.** Заявка отвечает на другой вопрос и
117
+ связывается с карточкой сама — отдельной карточки ей не нужно.
118
+
119
+ - **Сливаемость выводили из локального вливания.** Между ним и взглядом владельца главная уходит
120
+ вперёд, и «у меня слилось» о кнопке не говорит ничего. Дерево, чей помощник очереди о поле
121
+ `mergeable` не говорит вовсе, работает как прежде: поля нет — требования нет.
122
+ - **Личность вызова, открывающего заявку.** Дерево, не назвавшее машинной записи, требования
123
+ подстановки токена не получает: сверять ответ хостинга не с чем.
124
+
125
+ - **Ветки, заведённые от главной подряд, роняют друг друга.** Замер по ста шести накопленным
126
+ веткам одного основания: вливание одной делает расходящимися до двадцати трёх, в среднем семь с
127
+ половиной; не расходятся ни с кем двенадцать. Считался он `git merge-tree` в памяти — рабочего
128
+ дерева замер не трогает и веток не двигает.
129
+
130
+ ```bash
131
+ # проба слияния без единой правки в дереве: коммит-слияние заводится в объектной базе
132
+ tree="$(git merge-tree --write-tree origin/main <ветка> | head -1)"
133
+ probe="$(git commit-tree "$tree" -p origin/main -p <ветка> -m проба)"
134
+ git merge-tree --write-tree "$probe" <другая ветка> >/dev/null; echo $? # 1 — разойдутся
135
+ ```
136
+
137
+ Дерево аргументом сюда не годится: истории у него нет, общее основание не считается, и любая
138
+ проба отвечает «сойдётся».
139
+
140
+ - **Расходится не правка, а строка, куда дописали обе стороны.** В том же замере исходник
141
+ ресурса сливался чисто, а его разложенная копия расходилась первой строкой — той, где стоит
142
+ контрольная сумма ресурса. Две работы правили разные разделы разных файлов, и всё равно
143
+ требовали разбора. Отсюда и правило ветвиться чередой: снимать пришлось бы не расхождение, а
144
+ сам способ хранить копию рядом с исходником.
145
+
100
146
  - **Сборка входит в набор гейта.** Четыре мержа подряд уехали в главную ветку, ломая выкатку:
101
147
  ошибка типов в непокрытом коде пережила линт и юниты и всплыла на сборке образа.
148
+ - **Набор, переписанный строками, выглядит полным.** В одном дереве шесть проверок лежали рядом
149
+ с гоняемыми и не гонялись ни гейтом, ни конвейером: восемь строк из четырнадцати читались как
150
+ весь набор, и разница была видна только сличением с умолчанием пакета.
102
151
  - **Набор гейта не бывает уже набора конвейера.** Дважды подряд правка, прошедшая гейт целиком,
103
152
  была отбита конвейером — и оба раза зелёный гейт был прочитан как «локально всё зелено». Отсюда
104
153
  и требование отбивать пуш на шаге без строки в наборе, а не печатать предупреждение рядом.
@@ -110,6 +159,12 @@
110
159
  в шести ветках за один заход. Обещать по объявлению «конфликтов больше не будет» нельзя: не
111
160
  будет ручной работы, а вливать главную в открытые ветки после каждого слияния придётся
112
161
  по-прежнему.
162
+ - **Заведённое видно только заводящему.** Шестнадцать задач так были заведены дважды, а заявка
163
+ названа владельцу номером, которого для него не существовало: ограниченная запись видела своё,
164
+ а хостинг отвечал остальным «не найдено».
165
+ - **Обойдённый отказ унёс признак ограничения.** Предел запросов у ограниченной записи стоял на
166
+ нуле — не исчерпан, а не положен вовсе. Отказ обошли вызовом другого рода, обход сработал, и
167
+ расхождение всплыло через двадцать минут и четыре следа, которые пришлось переписывать.
113
168
  - **Личность вызова, открывающего заявку.** Прежде обе стороны — подстановка токена и ответ
114
169
  хостинга об авторе — держались статьёй и разбором происшествия, и промах повторился на третий
115
170
  день.
@@ -131,3 +186,16 @@
131
186
  дали, а запрос разбора на автора хостинг принимает молча и не создаёт.
132
187
  - **Ревьюверы спрашиваются вызовом REST.** Под токеном машинной записи выборка клиента падает
133
188
  целиком, без токена проходит зелёной — отличить «сошлось» от «спросить было нечем» нечем.
189
+
190
+ - **Полнота набора гейта судится по именам шагов конвейера.** Проверки, которой нет и в
191
+ конвейере, там нет тоже: набор, переписанный строками вместо вызова умолчания пакета, теряет
192
+ ровно те проверки, которые пакет заведёт следующей редакцией. Своя строка вместо умолчания
193
+ законна там, где она покрывает то же строже либо зовёт названный скрипт.
194
+ - **Черновик, чья ветка везёт папку задачи, означает идущую работу, а не брошенную.** Оба
195
+ признака нужны вместе: зелёный прогон на вершине без разобранной папки говорит, что работа
196
+ ещё не отдана. Дерево, не назвавшее машинной записи, этой сверки не получает вовсе.
197
+ - **Метку сливаемости не гасит и объявленное сложение обеих сторон.** Хостинг считает сложение
198
+ своим приёмом и настроек слияния не читает: пока ветка не вобрала главную и это не уехало на
199
+ хостинг, заявка стоит конфликтующей при разрешённом на месте расхождении.
200
+ - **Сверки раскладки нет в конвейере, поэтому шага, который она бы закрывала, там тоже нет.**
201
+ Правка мимо источника в день, когда её делают, не ломает ничего.
@@ -34,3 +34,19 @@
34
34
  его привязка перестают находиться друг по другу. После разрешения гоняется
35
35
  `npm run check:specs` — конфликт в спеке кода не задевает, и ни сборка, ни линтеры его не
36
36
  увидят.
37
+
38
+ - **Строку требования к соседнему ресурсу не проверяет ничто, и расхождение видно только
39
+ счётом.** Правило без неё выглядит целым: разделы на месте, привязки сходятся, сверка
40
+ полноты зелёная. Требовать её у всех нельзя — правило, которому нечего требовать, её не
41
+ пишет, — поэтому судит не проверка, а два числа рядом: сколько правил в каталоге и сколько из
42
+ них требование объявило.
43
+
44
+ ```bash
45
+ ls <каталог правил> | wc -l
46
+ grep -rl '^\*\*Требует:\*\*' <каталог правил> | wc -l
47
+ ```
48
+
49
+ Расхождение отказом само по себе не бывает. Оно называет, сколько правил прочитать глазами,
50
+ и число это падает по мере того, как их читают. Счёт при этом грубый: строка, показанная
51
+ образцом внутри ограды, считается наравне с настоящей — тот, кто учит её писать, попадает
52
+ в число объявивших.