@rt-tools/agent-kit 0.19.0 → 0.21.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 (85) hide show
  1. package/assets/checks/check-board.github.mjs +2 -2
  2. package/assets/checks/check-reuse.mjs +11 -1
  3. package/assets/checks/check-specs.mjs +8 -23
  4. package/assets/checks/check-states.mjs +1 -1
  5. package/assets/checks/signals/core.json +12 -2
  6. package/assets/checks/signals.mjs +17 -0
  7. package/assets/checks/spec-proposed.mjs +122 -0
  8. package/assets/defaults/gate-map.sh +6 -1
  9. package/assets/defaults/shell.sh +8 -0
  10. package/assets/hooks/browser-guard-device-id.sh +3 -0
  11. package/assets/hooks/browser-guard-no-asking.sh +3 -0
  12. package/assets/hooks/browser-guard-no-listing.sh +3 -0
  13. package/assets/hooks/browser-guard-no-other-drivers.sh +3 -0
  14. package/assets/hooks/browser-guard-require-select.sh +3 -0
  15. package/assets/hooks/claim-guard.sh +3 -0
  16. package/assets/hooks/conscience-guard.sh +3 -0
  17. package/assets/hooks/deny-tail.sh +12 -0
  18. package/assets/hooks/dev-server-guard.sh +3 -0
  19. package/assets/hooks/docs-guard.sh +4 -11
  20. package/assets/hooks/exam-guard.sh +3 -0
  21. package/assets/hooks/git-guard-delivery.sh +4 -4
  22. package/assets/hooks/git-guard-main.sh +4 -9
  23. package/assets/hooks/git-guard-push-tests.sh +3 -0
  24. package/assets/hooks/grill-gate.sh +3 -0
  25. package/assets/hooks/guard-note.sh +45 -0
  26. package/assets/hooks/handoff-entry-guard.sh +3 -0
  27. package/assets/hooks/handoff-write.sh +58 -7
  28. package/assets/hooks/override-write-guard.sh +4 -4
  29. package/assets/hooks/postmortem-guard.sh +15 -3
  30. package/assets/hooks/proposal-guard.sh +3 -0
  31. package/assets/hooks/prose-style-guard.sh +3 -0
  32. package/assets/hooks/qa-dataid-guard.sh +3 -0
  33. package/assets/hooks/rerun-guard.sh +3 -0
  34. package/assets/hooks/reuse-first-guard.sh +3 -0
  35. package/assets/hooks/rule-article.sh +1 -1
  36. package/assets/hooks/rule-source-guard.sh +4 -4
  37. package/assets/hooks/sql-guard.sh +3 -0
  38. package/assets/hooks/task-context-load.sh +1 -1
  39. package/assets/hooks/task-flow-draft-guard.sh +3 -0
  40. package/assets/hooks/task-flow-guard.sh +3 -0
  41. package/assets/hooks/turn-entry-load.sh +27 -2
  42. package/assets/hooks/turn-exit-guard.sh +8 -5
  43. package/assets/hooks/waiting-turn-guard.sh +31 -10
  44. package/assets/hooks/window-fill-guard.sh +3 -0
  45. package/assets/hooks/work-start-guard.sh +3 -0
  46. package/assets/hooks/write-targets.sh +59 -10
  47. package/assets/laws/delivery.md +5 -0
  48. package/assets/laws/work-conduct.md +5 -0
  49. package/assets/patterns/browser-verification-stand.md +24 -9
  50. package/assets/patterns/git-workflow-merge.md +17 -0
  51. package/assets/patterns/git-workflow-pr.github.md +29 -22
  52. package/assets/patterns/spec-driven-domain.md +5 -0
  53. package/assets/patterns/spec-driven-rule.md +41 -1
  54. package/assets/patterns/task-flow-archive.md +39 -0
  55. package/assets/patterns/task-flow-handoff.md +25 -2
  56. package/assets/patterns/task-flow-resume.md +16 -0
  57. package/assets/patterns/task-flow-start.md +40 -40
  58. package/assets/patterns/testing-e2e.md +15 -0
  59. package/assets/patterns/testing-unit.md +13 -0
  60. package/assets/pitfalls/git-workflow.github.md +19 -1
  61. package/assets/pitfalls/spec-driven.md +28 -0
  62. package/assets/pitfalls/task-flow.md +81 -38
  63. package/assets/pitfalls/testing.md +9 -0
  64. package/assets/pitfalls/turn-conduct.md +8 -0
  65. package/assets/rules/spec-driven.md +23 -24
  66. package/assets/rules/turn-conduct.md +13 -15
  67. package/assets/rules/turn-entry.md +6 -4
  68. package/assets/rules/typescript-conventions.md +7 -0
  69. package/assets/skills/agent-kit-extend.md +11 -0
  70. package/assets/skills/agent-kit.md +17 -3
  71. package/assets/templates/findings.md +27 -0
  72. package/bin/agent-kit.d.ts.map +1 -1
  73. package/bin/agent-kit.js +3 -0
  74. package/bin/agent-kit.js.map +1 -1
  75. package/lib/commands.d.ts +5 -0
  76. package/lib/commands.d.ts.map +1 -1
  77. package/lib/commands.js +94 -1
  78. package/lib/commands.js.map +1 -1
  79. package/lib/observations.d.ts +13 -1
  80. package/lib/observations.d.ts.map +1 -1
  81. package/lib/observations.js +7 -1
  82. package/lib/observations.js.map +1 -1
  83. package/package.json +1 -1
  84. package/rt-tools-agent-kit-0.21.0.tgz +0 -0
  85. package/rt-tools-agent-kit-0.19.0.tgz +0 -0
@@ -106,6 +106,19 @@ globalThis.fetch = (): Promise<Response> => Promise.resolve(Response.json({ succ
106
106
  заголовке и едет в ветке. Признак временного файла — его заголовок не называет ни одного
107
107
  сценария.
108
108
 
109
+ ## Зелёное, которое ничего не проверяет
110
+
111
+ **Проба, ждущая молчания, идёт в паре с пробой, ждущей отказа.** Молчание наступает и тогда,
112
+ когда проверять было нечем: приставка перед командой в конвейере действует на одно звено, и
113
+ хук, получивший пустое значение, молчит ровно так же, как хук, которому нечего отбивать. Две
114
+ пробы из трёх при этом зелены — они и ждали молчания, — и промах виден только по третьей,
115
+ которая ждёт отказа.
116
+
117
+ **Проба на мину, которая не срабатывает, зелена и без починки.** Сценарий на таблицу кодов
118
+ отказа у спека без процедур проходил бы и до правки: читать эту таблицу сверке не приходится
119
+ вовсе. Проверяется такая проба обеими сторонами — прежнее состояние возвращается на минуту и
120
+ прогоняется: не покраснело, значит проба ничего не сторожит.
121
+
109
122
  ## Частые промахи
110
123
 
111
124
  - Либа без своего `vitest.config.mts`: `nx test <проект>` пройдёт зелёным, не запустив ни
@@ -193,7 +193,7 @@
193
193
  же, чего гард и добивается.
194
194
  - **Свои черновики судятся все разом.** Уход в соседнюю ветку выключал гард целиком: за один
195
195
  заход так разошлись с главной четыре заявки подряд, и заметил это владелец, а не проверка.
196
- Разбор — `docs/postmortems/2026-08-25-run-left-unwatched.md`.
196
+ Разбор — запись «2026-08-25-run-left-unwatched» в приёме.
197
197
  - **Подпись машинной записи на каждом коммите вклада.** Пять коммитов одной стопки уехали
198
198
  подписанными владельцем, который правки не делал: гард судит только коммит, назвавшийся
199
199
  машинной записью, и ищет расхождение в числе служебного адреса.
@@ -219,3 +219,21 @@
219
219
  ни статус, ни сверка, а команда, прошедшая между прятаньем и возвратом, пишет в те же файлы —
220
220
  и возврат встаёт конфликтом. Так ушли в прятанье восемь незакоммиченных файлов при живом
221
221
  запрете на эту команду: запрет читался в начале захода, а команда набиралась через сорок ходов.
222
+ - **Вывод команды, которой нужен репозиторий, собирается в каталоге репозитория.**
223
+ Перенаправление создаёт файл раньше, чем команда успевает отказать: клиент хостинга, позванный
224
+ из каталога временных файлов, падает строкой о том, что это не репозиторий, а пустой файл к
225
+ этой минуте уже записан. Уехав дальше — в тело заявки, в замысел, в правило, — он стирает
226
+ написанное, и восстанавливается это только историей правок на стороне хостинга. Файл вывода
227
+ поэтому кладётся в дереве, а записанное проверяется до того, как его куда-то отправят.
228
+
229
+ - **Очередь конвейера, заведённая на всё дерево, снимает ждущего чужим пушем.** Группа
230
+ одновременности с отменой уже идущего экономит машину ровно до первого соседа: его пуш снимает
231
+ прогон чужой ветки, и та остаётся с вершиной без единого прогона — заявка при этом выглядит
232
+ непроверенной, а прогонять её заново некому. Группа поэтому заводится своя на ветку, и общей
233
+ остаётся только у шагов, которым нужен стенд: их и правда нельзя гнать вдвоём на одной машине.
234
+
235
+ - **Команды дерева зовутся из его корня, а не из каталога пакета.** В подкаталоге со своим
236
+ манифестом запуск берёт его, а не корневой, и отвечает «такой команды нет» — при том что в
237
+ дереве она есть и написана верно. Читается это как поломка команды, а лечится каталогом: путь
238
+ до неё называется от корня, и звать её оттуда.
239
+
@@ -34,6 +34,14 @@
34
34
  его привязка перестают находиться друг по другу. После разрешения гоняется
35
35
  `npm run check:specs` — конфликт в спеке кода не задевает, и ни сборка, ни линтеры его не
36
36
  увидят.
37
+ - **Сложение отвечает на две дописи, а не на снятие: сторона, у которой текста нет вовсе, тоже
38
+ правка.** Раздел, вынесенный в описание прошлого или свёрнутый в правило, сложением
39
+ возвращается обратно — один абзац встаёт в двух редакциях, и снятая читается как
40
+ действующая. Случай не редкий: он приходит ровно тогда, когда снятия потребовал сам слой
41
+ правил, а ветки, начатые раньше, несут прежнюю редакцию. Признак прямой — у одной стороны
42
+ текста нет; тогда конфликт решается тем, что с разделом сделали, а не сложением. Снятое
43
+ остаётся снятым, а допись второй стороны переезжает туда, куда уехал раздел, — или не
44
+ переезжает вовсе, если уехал он потому, что стал правилом.
37
45
 
38
46
  - **Строку требования к соседнему ресурсу не проверяет ничто, и расхождение видно только
39
47
  счётом.** Правило без неё выглядит целым: разделы на месте, привязки сходятся, сверка
@@ -50,6 +58,26 @@
50
58
  и число это падает по мере того, как их читают. Счёт при этом грубый: строка, показанная
51
59
  образцом внутри ограды, считается наравне с настоящей — тот, кто учит её писать, попадает
52
60
  в число объявивших.
61
+ - **Закон, которого не назвало ни одно правило, не судит никто, и виден он только счётом.**
62
+ Статья правила без адреса отбивает сверку спеков — привязка у неё требуется. У статьи закона
63
+ адреса нет по устройству: закон говорит, что должно быть верно, и на код не показывает. Ловить
64
+ это отказом нельзя — закон, которому в этом дереве нечего исполнять, законное состояние, — а
65
+ незамеченным он живёт сколько угодно: две статьи так и легли молча, пока две соседние статьи
66
+ правила отбивали сверку требованием адреса. Судят поэтому два числа рядом: сколько законов в
67
+ каталоге и какие из них ни одно правило не назвало.
68
+
69
+ ```bash
70
+ ls <каталог законов>/*.md | wc -l
71
+ for law in <каталог законов>/*.md; do
72
+ grep -rqlF "constitution/$(basename "$law")" <каталог правил>/*/SKILL.md || echo "$law"
73
+ done
74
+ ```
75
+
76
+ Названный список читается глазами: у закона, который дереву нечего исполнять, это законное
77
+ состояние, а у остальных — забытая половина работы. Счёт грубый и здесь: закон, названный
78
+ правилом в одной строке и не разобранный ни одной его статьёй, в список не попадает —
79
+ связь статьи с правилом держится текстом, а не ключом.
80
+
53
81
  - **Привязка пишется по тексту статьи, а не по смыслу имени гарда.** Гард, чьё имя звучит про то
54
82
  же самое, статью не закрывает: статья перечисляла шесть действий по отдельному слову владельца
55
83
  — коммит, пуш, открытие заявки, запись в вики, заведение задачи, правка закона, — а
@@ -7,6 +7,12 @@
7
7
 
8
8
  ## Ловушки
9
9
 
10
+ - **Задача, отобранная в эпик по своему телу, бывает закрыта до начала работы.** Между заведением
11
+ задачи и её взятием проходят недели, и всё это время дерево правится соседними работами: у двух
12
+ задач одного эпика по три части из четырёх оказались сделанными — тело описывало дерево
13
+ месячной давности. Отбор поэтому начинается с чтения кода, а разбор просьбы называет, что из
14
+ тела задачи в дереве ещё верно.
15
+
10
16
  - **Разрешение владельца, оставленное в репозитории, теряется на каждой новой ветке.** Оно
11
17
  записано номером в файл ветки, а следующая ветка отводится от главной и его не несёт: гард
12
18
  отбивает работу, которую владелец разрешил, — и повторяется это ровно столько раз, сколько
@@ -31,13 +37,13 @@
31
37
  договорённость обязана его пережить: её сценарии получают номера в общей нумерации домена,
32
38
  и на них ссылаются заголовки тестов. Обратное тоже верно — ход работы не кладётся в
33
39
  `proposed/`: спек, в котором завелись шаги, снова становится планом и умирает после мержа.
34
- - **У меню нет строки «вопрос не тот».** Меню годится для выбора значения из закрытого набора;
40
+ - **У меню нет строки «вопрос не тот».** Меню годится там, где выбор действительно закрыт;
35
41
  пока постановка вопроса не подтверждена, отвергнуть её владельцу нечем — он выбирает из
36
- вариантов, выведенных из неверной посылки. Настройки владельца, требующие меню, требование
37
- не снимают: тогда к каждому вопросу добавляется свободный вариант, и он же — единственное
38
- место, где вопрос отвергается целиком. Три вопроса ушли одним меню, у одного постановка была
39
- ложной, и сказать «вопрос не тот» было нечем. Выбор слова, имени и термина узким вопросом не
40
- является никогда.
42
+ вариантов неверной посылки, и выйти из набора может только руками. Настройки владельца,
43
+ требующие меню, требование не снимают: тогда к каждому вопросу добавляется свободный вариант,
44
+ и он же — единственное место, где вопрос отвергается целиком. Три вопроса ушли одним меню, у
45
+ одного постановка была ложной. Там, где под сомнением сама уместность вопроса, его сперва
46
+ проверяют по репликам владельца — и чаще всего не задают.
41
47
  - **Субагент вопросов владельцу не задаёт.** Ни роли, ни конвейер до него не достучатся —
42
48
  они возвращают текст главному агенту. Поэтому разбор ведёт главный агент, а роли стоят по
43
49
  обе стороны от него.
@@ -48,20 +54,17 @@
48
54
  Спрашивают до правки, а не показывают замер после.
49
55
  - **Путь, предложенный человеку, судится числом его шагов и тем, чем ему для этого надо
50
56
  владеть.** Со стороны кода вариант выглядит дешёвым — «меньше путей», «строку запуска не
51
- трогаем», — а человеку он стоит захода на сервер. Однажды рекомендуемым вариантом так стояла
52
- выдача токена, за которой владельцу надо было идти по ssh в работающий контейнер; отбивал
53
- этот вариант он сам. Цена называется со стороны того, кто пойдёт: сколько шагов и что ему для
54
- них нужно. Пересказ действующего порядка без такой оценки владелец читает как одобрение.
57
+ трогаем», — а человеку он стоит захода на сервер: рекомендуемым так стояла выдача токена, за
58
+ которой владельцу надо было идти по ssh в работающий контейнер. Цена называется со стороны
59
+ того, кто пойдёт; пересказ порядка без неё владелец читает как одобрение.
55
60
  - **Эпик по теме читается до того, как решается раскладка.** Замысел эпика держит решения,
56
61
  которые пережили десяток задач, и разведка по коду их не находит: снятое решение следа в
57
62
  дереве не оставляет. Домен, заведённый генератором и снесённый через полчаса, стоял в замысле
58
63
  прямым запретом — но замысел открыли уже после того, как он был заведён во второй раз.
59
64
  - **Работа, которая разбирает чужую папку задачи, разбирает и свою — одним коммитом.** Свою
60
- папку она заводит наравне со всеми: исключения из этого требования нет. Круг, которым
61
- исключение оправдывали, закрывается не отказом от папки, а порядком разбора: последний
62
- коммит снимает обе, и после работы неубранного не остаётся. Однажды такой разбор оставил
63
- свою папку, и на неё пришлось заводить третью задачу — лечится это порядком, а не правом
64
- работать без замысла на диске. Как разобрать две папки — паттерн `task-flow-archive`.
65
+ папку она заводит наравне со всеми, и круг, которым исключение оправдывали, закрывается
66
+ порядком разбора: последний коммит снимает обе. Однажды такой разбор оставил свою папку, и на
67
+ неё пришлось заводить третью задачу. Как разобрать две папки паттерн `task-flow-archive`.
65
68
  - **Слово для нового понятия берётся из `docs/GLOSSARY.md` или заводится там же.** Третий файл
66
69
  папки задачи называется `progress.md`, а не `journal.md`, ровно поэтому: журнал в этом
67
70
  дереве один, и он другой.
@@ -81,6 +84,43 @@
81
84
  задание, он даёт заходу работу, которой владелец не просил. То же с любой репликой без
82
85
  глагола: спросить, что с этим делать, дешевле, чем написать полсотни файлов мимо просьбы.
83
86
 
87
+ - **Признак готовности этапа пишется о своей половине вывода, а не обо всём выводе.** Проверка
88
+ считает всё дерево, а этап правит его часть: «вывод без единой строки долга» не сходится не
89
+ потому, что этап не сделан, а потому, что три строки принадлежат невлитой соседней ветке.
90
+ Признак называет свои строки и своё число, а сказанное обо всём выводе держится до первого
91
+ соседа.
92
+
93
+ - **Копия образца папки задачи несёт шапку раскладки, и первая же правка отбивается гардом.**
94
+ Образец разложен пакетом наравне с остальным разложенным, а гард места правки судит по шапке:
95
+ копия под задачу выглядит разложенным файлом, и отказ называет адрес источника пакета — то
96
+ есть уводит править образец вместо своей копии. Команда заведения задачи шапку снимает сама,
97
+ копирование руками — нет. Правится такая копия только записью заново: правку по месту гард
98
+ отбивает и её.
99
+ - **Имя проекта в признаке готовности этапа спрашивается у сборщика, а не пишется по памяти.**
100
+ На неизвестное имя сборщик отвечает «задач не запущено» и выходит нулём: команда признака не
101
+ прогнала ни одной пробы и промолчала так же, как зелёный прогон. Видно это только по числу
102
+ прогнанных задач, а его никто не читает.
103
+
104
+ - **Этап, закрытый без пуша, гоняет проверки гейта своим последним движением.** Признак этапа
105
+ зовёт свои команды и общих не знает, а гейт краснеет только на отправке: ветка без пушей копит
106
+ красное до первой из них, и промах уезжает на два этапа от места, где его сделали.
107
+
108
+ - **У признака закрытия спрашивают, может ли исполнитель подтвердить его сам.** Признак,
109
+ требующий человека — пароля, кнопки в чужой панели, взгляда владельца, — останавливает работу
110
+ на последнем шаге: сделано всё, а сказать «закрыто» нечем. Спрашивается это при разборе
111
+ просьбы.
112
+
113
+ - **Признак закрытия проверяет исход у той стороны, которая его хранит, а не ответ вызова.**
114
+ Вызов отвечает о себе: ушёл, принят, код нулевой — и всё это верно при том, что записанного
115
+ нет. Восемь задач подряд считали отметку работающей по ответу команды, а она не двигала
116
+ ничего.
117
+
118
+ - **Своё временное кладётся вне дерева кода — иначе его снятие судится как правка приложения.**
119
+ Признак записи считает записью и удаление, и это в нём нарочно: снятое без замысла не
120
+ оставляет следа. Отличить свой временный каталог от каталога домена признаку нечем — путь у
121
+ обоих под тем же корнем, — и гард требует замысла за уборку черновика. Каталог называет
122
+ профиль дерева, и лежит он вне дерева кода.
123
+
84
124
  - **Тело задачи, написанное вперёд замысла, называет способ, и способ стареет раньше дефекта.**
85
125
  Задача серии заводится за недели до того, как её берут, и к этому дню предложенный ход бывает
86
126
  уже неверен: привезённое пакетом умеет то, что задача звала написать, названного места в
@@ -116,10 +156,15 @@
116
156
  подряд не пересилили одну строку на диске. Снимается она тем же ходом, которым владелец
117
157
  ответил, — а не тем, в котором о ней вспомнили.
118
158
 
119
- - **У меню с закрытым набором нет строки «вопрос не тот».** Вариантами вопрос выглядит
120
- разобранным, и владельцу, чтобы отвергнуть саму постановку, приходится выходить из набора
121
- руками. Спрашивают меню то, где выбор действительно закрыт; там, где под сомнением сама
122
- уместность вопроса, его сперва проверяют по репликам владельца и чаще всего не задают.
159
+ - **Очередь работ эпиком не кончается.** Занятый другими исполнителями или законченный эпик
160
+ означает следующую задачу из очереди, а не остановку: «свободных задач эпика нет» ответом на
161
+ «чем заняться» не бывает, потому что отвечает на этот вопрос не эпик, а очередь. Спрашивается
162
+ она командой, а не вспоминается по передаче: утверждение переданного текста описывает то
163
+ дерево и тот день, в котором его писали.
164
+ - **Шаг закрытия работы за взятие следующей задачи не считается.** Перевод закрываемой задачи в
165
+ колонку разбора и снятие её папки — обязательные шаги закрытия, и оба случаются тем же ходом,
166
+ которым открывается заявка. Ход, в котором больше ничего нет, работу не двигает, сколько бы
167
+ команд в нём ни стояло.
123
168
 
124
169
  ## Поведение исполнителя — по разборам происшествий
125
170
 
@@ -175,29 +220,27 @@
175
220
  Отказ при этом уводит править образец пакета вместо копии под задачу.
176
221
  - **Правка по замечаниям идёт без замысла на диске.** Папка разобрана коммитом ветки раньше
177
222
  открытия заявки, и состояния у работы с этой минуты нет: судит её история ветки.
178
- - **Прогон, поставленный раньше дешёвых шагов, съел окно захода.** Потративший его на прогон
179
- упирался в порог заполнения на четырёх строках привязки то есть на работе минут на пять.
180
- - **Граница состояния выглядит законченным куском лучше всякой вехи.** Владельцу отчёт о взятой
181
- задаче неотличим от остановки: названы номер, ветка и колонка, и всё названное правда.
223
+ - **Граница состояния выглядит законченным куском лучше всякой вехи.** Отчёт о взятой задаче
224
+ владельцу неотличим от остановки: номер, ветка и колонка названы, и всё названное правда.
182
225
  - **Заявка на чужом языке.** В дереве, где заявки пишутся на другом языке, чужой заголовок
183
226
  дважды уехал на хостинг, и оба раза до него добрались глазами.
184
- - **Вопрос, утонувший в отчёте.** Владелец трижды переспрашивал, почему работа стоит, и каждый
185
- круг стоил захода обоим.
186
- - **Чужой эпик в списке очереди.** Дважды подряд следующей была взята первая задача чужого
187
- эпика — по списку она выглядела ровно как своя.
227
+ - **Вопрос, утонувший в отчёте.** Владелец трижды переспрашивал, почему работа стоит.
228
+ - **Чужой эпик в списке очереди.** Дважды подряд следующей брали первую задачу чужого эпика:
229
+ по списку она выглядит своей.
188
230
 
189
231
  - **Некоммиченная папка задачи отказывает там, где чинить уже нечего.** Гард спрашивает её с
190
- диска, поэтому все правки проходят без единого отказа, а признак отданной работы берётся из
191
- истории ветки. Отказ приходит на открытии заявки — в минуту, когда папка разобрана своими
192
- руками: замысел снят, и собирать его приходится заново по памяти. Владелец при этом всю
193
- работу видит ветку без единого следа того, что в ней делается, а следующий заход находит
194
- пустоту вместо «Где стоим».
232
+ диска, поэтому все правки проходят без отказа, а признак отданной работы берётся из истории
233
+ ветки. Отказ приходит на открытии заявки — когда папка разобрана своими руками: замысел снят,
234
+ и собирать его приходится по памяти. Владелец при этом всю работу видит ветку без следа того,
235
+ что в ней делается.
195
236
  - **Прогон, поставленный первым шагом закрытия, съедает окно захода.** Он стоит дороже всех
196
- остальных шагов вместе, и потративший его на прогон упирался в порог заполнения на четырёх
197
- строках привязки — то есть на работе, которая стоила бы минуты, если бы шла первой.
237
+ остальных шагов вместе: потративший его упирался в порог заполнения на четырёх строках
238
+ привязки — на работе, которая шла бы минуту, будь она первой.
198
239
  - **Разрешение работать вне назначенного эпика принадлежит рабочему дереву, а не ветке.**
199
240
  Записанное в файл репозитория, оно уезжает вместе с веткой: из соседней его не видно, и гард
200
- эпика отбивает ровно ту работу, которую владелец разрешил. За один заход это случилось дважды
201
- сперва на отказе конца хода, потом на переводе колонки, и оба раза номер дописывался заново.
202
- Место такому разрешению там же, где передача захода: оно не откатывается вместе с правкой и не
203
- принадлежит ни одной задаче.
241
+ эпика отбивает ровно ту работу, которую владелец разрешил за один заход дважды. Место ему
242
+ там же, где передача захода: оно не откатывается с правкой и не принадлежит ни одной задаче.
243
+ - **Задача, вынесенная в другой эпик, снимается из состава прежнего тем же ходом.** Вынос два
244
+ движения, и сделанное наполовину оставляет задачу в двух составах сразу: эпик выглядит
245
+ незакрытым при всех сделанных работах. Итог вписывается там же, где правится состав:
246
+ отложенный, он пишется по памяти о том, сколько задач было, а не сколько осталось.
@@ -38,6 +38,15 @@
38
38
  - **Первому прогону сразу после установки браузера верить нельзя.** Два падения сквозного
39
39
  набора не повторились ни при отдельном прогоне тех же тестов, ни при втором полном. Такой
40
40
  прогон повторяют, а выводы делают по второму.
41
+ - **Повторный прогон через гейт пуша повторяет весь набор, а не упавший тест.** Гейт гоняет то,
42
+ что перечислил профиль дерева, целиком и с нуля: у сквозного набора это минуты, и каждая
43
+ попытка пуша стоит их заново. Соседняя ловушка верна ровно до этого места: повторить дёшево —
44
+ через гейт уже нет, и «повторить» превращается в «пушить, пока не пройдёт». Полный набор
45
+ поэтому гоняется руками до вызова пуша, а гейт только подтверждает уже известное. Тест,
46
+ упавший в полном наборе и прошедший при отдельном прогоне, зелёным не считается: это
47
+ нестабильный тест, и он заводится задачей тем же ходом. Прогон до зелёного уносит признак
48
+ вместе с падением, и следующий заход встречает то же самое как новость — а отличить чужую
49
+ нестабильность от своей регрессии ему нечем: оба случая выглядят одинаково.
41
50
  - Сквозная спека, которой нужен вход, без учётных данных в окружении пропускается молча — в
42
51
  отчёте она значится `skipped`, и прогон выглядит успешным. Имена переменных — при дереве.
43
52
  - **Справочник флоу вторых сценариев не заводит.** В `docs/E2E_<ДОМЕН>_FLOWS.md` кладут то,
@@ -80,3 +80,11 @@
80
80
  в него, встаёт целиком там, где мимо него шло ещё несколько ходов дела. Делается всё, что от
81
81
  разрешения не зависит, а несделанное называется в теле заявки, разделом об оставшемся шаге:
82
82
  он ровно про это и написан.
83
+ - **Ответ на реплику владельца, пришедшую посреди хода, ход не кончает.** Выход «вопрос
84
+ владельцу» — про вопрос ОТ исполнителя; обратный случай под него не подходит вовсе, и
85
+ прочитанный так, он превращает каждую реплику владельца в конец захода. За один заход это
86
+ стоило трёх остановок подряд: владелец спрашивал, исполнитель отвечал и вставал.
87
+ - **Работа не гейтится на подтверждение, которого владелец не обещал.** «Скажи — и я сделаю»
88
+ переносит ход к владельцу без его согласия: он не просил, чтобы у него спрашивали, и ответа с
89
+ него никто не ждал. Выглядит это вежливостью, а не остановкой, и потому не читается как
90
+ остановка ни исполнителем, ни им.
@@ -93,24 +93,25 @@ flowchart TD
93
93
  - **Каждое утверждение привязано к месту в коде, и связь сверяется в обе стороны.** Ключ
94
94
  связи — сам текст утверждения, поэтому переформулировать его, забыв про привязку, нельзя.
95
95
  - **Первая колонка компаньона — текст статьи, скопированный, а не пересказанный.** Ключ связи —
96
- сам текст, поэтому строка, написанная по смыслу статьи, разрывает связь, оставаясь на вид
97
- заполненной. Проверка считает статьи без адреса и о статье, адрес которой описывает не её, не
98
- знает ничего: совпадает род, а не перечень, и строка стоит до перечитывания диффа.
96
+ сам текст: строка, написанная по смыслу, разрывает связь, оставаясь на вид заполненной. Проверка
97
+ считает статьи без адреса и о статье с чужим адресом не знает ничего.
99
98
  - **Привязка не ведёт в код, который никто не зовёт:** нигде не зовущийся символ — не место.
99
+ - **Привязка «не исполняется» переезжает вместе со своей статьёй.** Иначе строка компаньона
100
+ держит в горячей части статью, за которой не стоит ничего: снятая одна, она оставляет привязку
101
+ без пункта, и сверка краснеет. Переезжают обе стороны разом.
100
102
  - **Таблица процедур сверяется с декораторами в обе стороны, право — вместе с именем.** Иначе
101
- процедура, которую домен обслуживает, но забыл описать, видна только в
102
- декораторе, а право, разошедшееся со спеком, — нигде.
103
- - **Код отказа принимается, только если он в домене бросается.** Коды выписывались по
104
- замыслу, и на одном пути обещанный отказ не бросал никто.
105
- - **Префикс сценариев в спеке один, и по всему дереву он занят им одним.** Второй префикс
106
- внутри спека означает, что предмет описан дважды; занятый чужим — что по номеру не видно,
107
- чей это сценарий. Договорённость о продукте — исключение: она нумеруется вместе со спеком, в
108
- который вольётся, и занятым префикс от неё не становится.
109
- - **Номер сценария выдаётся один раз и повторно не используется.** Новый сценарий берёт
110
- следующий свободный номер, а не вставляется в середину и не занимает номер удалённого: на
111
- месте удалённого номер так и остаётся пустым. Номер единственное, чем сценарий связан с
112
- тестом, и отданный второй раз он оставляет старую ссылку правильной на вид и ведущей не туда.
113
- Пересчитать номера подряд особенно дёшево на вид: тесты зелёные и до, и после.
103
+ процедура, которую домен обслуживает, но забыл описать, видна только в декораторе, а право,
104
+ разошедшееся со спеком, — нигде.
105
+ - **Код отказа принимается, только если он в домене бросается.** Коды выписывались по замыслу, и
106
+ на одном пути обещанный отказ не бросал никто.
107
+ - **Префикс сценариев в спеке один, и по всему дереву он занят им одним.** Второй префикс внутри
108
+ спека означает, что предмет описан дважды; занятый чужим — что по номеру не видно, чей это
109
+ сценарий. Договорённость о продукте нумеруется вместе со спеком, в который вольётся, и занятым
110
+ префикс от неё не становится.
111
+ - **Номер сценария выдаётся один раз и повторно не используется.** Новый берёт следующий
112
+ свободный, а не вставляется в середину и не занимает номер удалённого на месте удалённого
113
+ номер остаётся пустым. Номер связывает сценарий с тестом, и отданный второй раз он оставляет
114
+ старую ссылку верной на вид; пересчёт подряд дёшев обманчиво тесты зелёные и до, и после.
114
115
  - **Сценарий и заголовок его теста правятся одним изменением.** Изменилось обещание — номер тот
115
116
  же, а заголовок теста правится тем же коммитом; удалён сценарий — удаляется и тест.
116
117
  Разъехавшись, они оставляют прогон зелёным, хотя проверяет он уже не то.
@@ -126,7 +127,7 @@ flowchart TD
126
127
  привязывать не к чему, а требование правила заставило бы завести его с якорями в
127
128
  несуществующие места. Признак стоит строкой статуса в самом законе, а не в списке исключений
128
129
  рядом с проверкой.
129
- - **Закон, назвавший файл проекта, — отказ.** Путям и привязкам место в правиле: иначе закон
130
+ - **Закон, назвавший файл проекта, — отказ.** Путям и привязкам место в правиле, иначе закон
130
131
  нельзя ни прочитать без знания дерева, ни применить на другом приложении.
131
132
  - **Описание правила не длиннее трёхсот знаков и отвечает на один вопрос — брать это правило
132
133
  или нет.** Описание едет в системный промпт каждого захода целиком, и платит его заход, чем бы
@@ -271,18 +272,16 @@ flowchart TD
271
272
  что текст судится не слабее своей копии, что невыбранная редакция судится наравне с выбранной и
272
273
  что набор разделов объявлен отдельно от образца, исполняются там, где эти тексты пишут, — в
273
274
  наборе того пакета, который их везёт. В дереве-потребителе лежат разложенные копии, и краснеть
274
- у него на промахе, который правится не у него, проверка не должна. Согласие двух текстов между
275
- собой не считается нигде и ни у кого: оно ищется чтением.
275
+ у него на чужом промахе проверка не должна. Согласие двух текстов ищется чтением.
276
276
 
277
277
  Форму сжатой статьи не проверяет ничто, и проверки на неё не будет: машине видно число знаков,
278
278
  но не то, принимается ли по сжатой статье прежнее решение. Довод, вырезанный вместе с границей
279
- утверждения, короче правильного и проходит любой счёт знаков. Стережёт это одно предел длины
280
- текста: он говорит, что правило переросло, и молчит о том, что именно из него резать. Судится
281
- сжатие пересказом, и судит его тот, кто правит по сжатой статье следующим.
279
+ утверждения, короче правильного и проходит любой счёт знаков. Стережёт это один предел длины
280
+ текста: он говорит, что правило переросло, и молчит, что именно резать. Судится сжатие
281
+ пересказом тем, кто правит по сжатой статье следующим.
282
282
 
283
283
  Долю довода в правиле не считает ничто. Замер, на котором стоит форма, сделан разовым проходом
284
- и в дерево не поехал: он отвечает на вопрос «где вес», а не «сошлось ли», и повторяют его тогда,
285
- когда снова спрашивают о весе.
284
+ и в дерево не поехал: он отвечает на «где вес», а не на «сошлось ли».
286
285
 
287
286
  ## Паттерны
288
287
 
@@ -173,7 +173,7 @@ flowchart TD
173
173
  Страж читает прежний номер этапа из истории ветки и не выпускает ход, в котором номер вырос, а
174
174
  команда не запускалась: через заход отмеченное по памяти неотличимо от проверенного.
175
175
  - **Слово об остановке страж читает у владельца, а не у исполнителя.** Иначе остановку объявляет
176
- тот, кому она в эту минуту удобна, и запрет держится ровно до первого неудобства.
176
+ тот, кому она удобна, и запрет держится до первого неудобства.
177
177
  - **Утверждение о состоянии дерева стережёт гард утверждения, а не память исполнителя.** Всё, что
178
178
  ответ владельцу говорит о дереве, несёт команду и её вывод: сказанное без команды утверждением
179
179
  не считается — ни «проверено», ни «снято», ни «готово». Гард читает текст, сказанный владельцу
@@ -259,24 +259,22 @@ flowchart TD
259
259
  проверяется деревом. Порядок входа — четыре шага в паттерне возвращения; стережёт его гард, а не
260
260
  память.
261
261
  - **Состояние незаконченной работы приходит в контекст на запуске сессии.** Замысел и ход работы
262
- отдаются целиком, разбор просьбы — путём. Ветка вида `<КЛЮЧ>-*` без папки даёт предупреждение с
263
- готовой командой, но сессию не рвёт.
262
+ отдаются целиком, разбор просьбы — путём. Ветка вида `<КЛЮЧ>-*` без папки предупреждает готовой
263
+ командой, но сессию не рвёт.
264
264
  - **Заполненное окно кончает ход только там, где сжатия нет.** Где оно объявлено, окно —
265
265
  продолжение хода: заход сжимается и работает дальше, а порог остановки срабатывает лишь тогда,
266
- когда сжатие не пришло. Ход, закрытый ниже порога, теряет остаток окна, за
267
- который дерево заплатило настройкой, и ловит это один владелец.
266
+ когда сжатие не пришло. Ход, закрытый ниже порога, теряет остаток окна, за который дерево
267
+ заплатило настройкой, и ловит это один владелец.
268
268
  - **Заполнение окна захода стережёт гард, а не память исполнителя.** На первом пороге он
269
- напоминает выбирать точку остановки, на втором отбивает всё, кроме записи хода работы, передачи
270
- и команд поставки. Размер окна и оба порога дерево задаёт само; не задавшее размера стража не
271
- получает.
269
+ напоминает выбирать точку остановки, на втором отбивает всё, кроме передачи, команд поставки и
270
+ папки задачи — папки целиком: на закрытии правят и решение по ходу, и пересмотр этапа. Размер окна и оба порога дерево задаёт само; не задавшее размера стража не получает.
272
271
  - **Порог сжатия контекста дерево задаёт само, и стоит он НИЖЕ порога остановки.** Совпавшие
273
- пороги согласием не бывают: это гонка, и выигрывает её страж он стоит на вызове, а сжатие
274
- приходит между ходами. Расстояние объявляется числом, а не выводится разницей; сведены пороги
275
- или нет, говорит разбор состояния раскладки.
276
- - **Заход закрывается передачей, которая лежит вне дерева.** Состояние работы коммитится ходом
277
- работы, а передача его пересказывает для вставки в новый заход: рабочее дерево, ветка,
278
- сделанное, следующий шаг и особенности захода. В историю она не едет иначе рядом с ходом
279
- работы заводится вторая запись об одном и том же.
272
+ пороги гонка, и выигрывает её страж: он стоит на вызове, а сжатие приходит между ходами. Расстояние объявляется числом, а не выводится разницей; сведены
273
+ ли пороги, говорит разбор состояния раскладки.
274
+ - **Заход закрывается передачей, и лежит она разделом хода работы.** Он коммитится и едет в
275
+ ветку значит передача переживает переход на другую машину, а второй записи об одном и том
276
+ же не заводится. В ней дерево, ветка, сделанное, следующий шаг и особенности захода; у работы
277
+ без папки задачи она уезжает файлом вне дерева.
280
278
 
281
279
  - **Вариант, глушащий проверку, в меню не ставится вовсе.** Выключенное правило линтера, строка
282
280
  в списке известного, выведенный из-под проверки файл — все они чинят показание, а не то, на что
@@ -17,7 +17,7 @@ description: Правило под «Закон о ведении работы»
17
17
  | В законе | Здесь |
18
18
  | -------------------------- | ----------------------------------------------------------------------------- |
19
19
  | вход в заход | то, что хук старта кладёт в контекст до первой реплики |
20
- | переданное прошлым заходом | файл по имени ветки в каталоге передач; пишет его хук перед сжатием контекста |
20
+ | переданное прошлым заходом | раздел «Передача захода» в ходе работы этой ветки, а у работы без папки задачи — файл по имени ветки в каталоге передач; пишет его хук перед сжатием контекста |
21
21
  | порядок ведения работы | карта хода — состояния с обязательными действиями и четыре выхода хода |
22
22
  | запуск | первый запуск, возобновление, сжатие контекста, очистка |
23
23
 
@@ -32,9 +32,11 @@ description: Правило под «Закон о ведении работы»
32
32
 
33
33
  ```mermaid
34
34
  flowchart TD
35
- A[Запуск захода] --> B{Есть передача по имени текущей ветки}
36
- B -->|Да| C[Передача кладётся в контекст целиком]
37
- B -->|Нет| D[О передаче не говорится ничего]
35
+ A[Запуск захода] --> B{Есть раздел передачи в ходе работы этой ветки}
36
+ B -->|Да| C[Раздел кладётся в контекст целиком, файл вне дерева не читается]
37
+ B -->|Нет| B2{Есть файл передачи по имени ветки}
38
+ B2 -->|Да| C
39
+ B2 -->|Нет| D[О передаче не говорится ничего]
38
40
  C --> E{Разложен ресурс карты хода}
39
41
  D --> E
40
42
  E -->|Да| F[Карта кладётся следом: состояния, действия, четыре выхода]
@@ -80,6 +80,13 @@ flowchart TD
80
80
  молча, а компилируется из них только одна.
81
81
  <!-- rt-when: *.ts -->
82
82
 
83
+ - **Значение, объявленное одной стороной обмена, второй стороной не пересчитывается, а берётся
84
+ у первой.** Два счёта одного значения расходятся молча: признак дерева считали и отправка, и
85
+ отметка — каждая своей копией, — копии разошлись, и отметка не нашла ни одной своей записи ни
86
+ разу. Обе стороны при этом отвечали как обычно, и промах нашёлся только с третьей стороны:
87
+ чтением того, что легло на самом деле.
88
+ <!-- rt-when: *.ts -->
89
+
83
90
  - **Двухступенчатое приведение `as unknown as` запрещено правилом линтера.** Вместо него —
84
91
  честный тип, сужение проверкой или чтение поля формой (`Reflect.get`); место, где иначе
85
92
  нельзя, помечается точечным отключением с причиной в той же строке.
@@ -62,6 +62,17 @@ awk '/^```/ { fence = !fence } !fence && /^## / { print }' <файл ресур
62
62
  От ресурса целиком отказываются не здесь, а списком `skip` в конфиге: надстройка правит текст,
63
63
  `skip` отменяет файл.
64
64
 
65
+ ## Надстройку карты гейта не проверяет ничто
66
+
67
+ Сценарии пакета гоняют его умолчание и веток дерева не касаются: своих проб у надстройки нет, и
68
+ места для них тоже. Карта решает, какое правило грузится под каждую правку, то есть чем заход
69
+ руководствуется в работе, а держится она прогоном руками и памятью того, кто её правил.
70
+
71
+ Промах в ней молчит: неверная ветка не отказывает, а тихо отдаёт не то правило — заметен он
72
+ только по объёму загруженного и по тому, что в загруженном не нашлось ответа. Поэтому правка
73
+ карты кончается вызовом гейта на трёх путях: на том, ради которого правили, на соседнем,
74
+ который правка задеть не должна была, и на файле, у которого правила нет вовсе.
75
+
65
76
  ## Гейт: своя ветка решает раньше умолчания
66
77
 
67
78
  Гейт спрашивает `skill_for` — она печатает имя правила или молчит. Молчание значит «правила на
@@ -81,8 +81,13 @@ npx agent-kit sync --check # ничего не писать, отказать
81
81
  npx agent-kit stats # чем пользовались, чем ни разу, обо что спотыкались
82
82
  npx agent-kit enroll --code <код> # завести дерево в приёме и положить его токен
83
83
  npx agent-kit propose # отправить груз в приём: сводку, предложения и разборы
84
+ npx agent-kit adopt [файлы] # отдать пакету свой файл, лежащий на его пути
84
85
  ```
85
86
 
87
+ Отдача откладывает прежнее содержимое рядом, с пометкой `.before-rt-kit`, и освобождает путь под
88
+ раскладку; без имён отдаются все чужие файлы разом. Названа она здесь потому, что иначе её
89
+ находят по тексту отказа раскладки — то есть в ту минуту, когда работа уже встала.
90
+
86
91
  Часть команд слоя исполняет агент, а не программа: `/feedback` кладёт слово о правилах блоком в
87
92
  файл предложений, `/skill-curator` разбирает закрытую задачу, `/next-session` закрывает заход.
88
93
 
@@ -103,7 +108,11 @@ npx agent-kit propose # отправить груз в приём: сво
103
108
  cp -r node_modules/@rt-tools/agent-kit/assets /tmp/agent-kit-assets-<прежняя версия>
104
109
  ```
105
110
 
106
- 2. **Установка и раскладка.** Обычным порядком.
111
+ 2. **Установка и раскладка.** Обычным порядком. Раскладка кладёт ту редакцию, которая **установлена**,
112
+ а не ту, что объявило дерево: перепутать их легко — установленная остаётся от соседней ветки,
113
+ где её как раз поднимали, и ложится целиком, молча, с тем же успешным выходом. Расхождение
114
+ точного номера раскладка отбивает сама и называет обе редакции; починка — поставить
115
+ зависимости и повторить вызов.
107
116
  3. **Сверка замещённых разделов по снимку.** Какие разделы замещены, называет `doctor` — строкой
108
117
  «замещено надстройками разделов» и перечнем «ресурс · заголовок». Каждый из них читается в
109
118
  снимке и в новой редакции: что пакет дописал, дописывается в надстройку руками.
@@ -223,8 +232,13 @@ npx agent-kit propose # отправить груз в приём: сво
223
232
  2. Снимок того, что говорят проверки дерева, до единой правки. Он и есть мерило.
224
233
  3. Ресурс за ресурсом: пакетную редакцию довести до здешней, предметность вынести в
225
234
  надстройку, снять отказ, разложить, прогнать сценарии и сверить снимок.
226
- 4. Разложенное поверх своего пакет не пишет: файл без шапки для него чужой. Снять его —
227
- решение владельца, и до этого раскладка отказывает поимённо.
235
+ 4. Разложенное поверх своего пакет не пишет: файл без шапки для него чужой. Отдаётся он
236
+ командой `adopt` прежнее содержимое ложится рядом с пометкой `.before-rt-kit`, и снять его
237
+ потом решает владелец.
238
+ 5. Свои сценарии отданного файла переписываются под пакетное поведение либо снимаются. Чинить
239
+ пакетную редакцию на месте нельзя: правка разложенной копии живёт до следующей раскладки, а
240
+ её адрес — источник пакета или надстройка дерева. Сценарий, ждущий поведения снятого файла,
241
+ краснеет и после верной отдачи: он проверяет то, чего в дереве больше нет.
228
242
 
229
243
  ## Свойства дерева
230
244