@rt-tools/agent-kit 0.8.0 → 0.8.2

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 (104) hide show
  1. package/README.md +24 -19
  2. package/assets/agents/qa-engineer.md +1 -1
  3. package/assets/checks/board.github.mjs +56 -17
  4. package/assets/checks/check-board.github.mjs +49 -5
  5. package/assets/checks/check-reuse.mjs +9 -7
  6. package/assets/checks/task-new.github.mjs +33 -5
  7. package/assets/commands/agent-kit-digest.md +10 -5
  8. package/assets/commands/next-session.md +4 -4
  9. package/assets/commands/skill-curator.md +11 -9
  10. package/assets/defaults/gate-map.sh +11 -4
  11. package/assets/defaults/project.sh +46 -0
  12. package/assets/docs/GLOSSARY.md +28 -26
  13. package/assets/hooks/docs-guard.sh +19 -3
  14. package/assets/hooks/git-guard-delivery.sh +106 -13
  15. package/assets/hooks/proposal-guard.sh +93 -0
  16. package/assets/hooks/reuse-first-guard.sh +68 -14
  17. package/assets/hooks/skill-gate-layers.sh +1 -1
  18. package/assets/hooks/skill-gate.sh +26 -0
  19. package/assets/hooks/task-flow-guard.sh +44 -18
  20. package/assets/hooks/window-fill-guard.sh +1 -1
  21. package/assets/laws/delivery.md +13 -7
  22. package/assets/laws/project-documentation.md +21 -0
  23. package/assets/laws/verifiability.md +6 -1
  24. package/assets/laws/work-conduct.md +67 -3
  25. package/assets/patterns/git-workflow-commit.azure.md +10 -2
  26. package/assets/patterns/git-workflow-commit.github.md +15 -2
  27. package/assets/patterns/git-workflow-commit.gitlab.md +10 -2
  28. package/assets/patterns/git-workflow-merge.md +1 -1
  29. package/assets/patterns/reuse-first-extend.md +12 -3
  30. package/assets/patterns/spec-driven-domain.md +7 -1
  31. package/assets/patterns/spec-driven-rule.md +6 -0
  32. package/assets/patterns/task-flow-close.md +78 -9
  33. package/assets/patterns/task-flow-handoff.md +27 -4
  34. package/assets/patterns/task-flow-resume.md +23 -5
  35. package/assets/patterns/task-flow-start.md +5 -1
  36. package/assets/rules/browser-verification.md +10 -1
  37. package/assets/rules/doc-style.md +13 -5
  38. package/assets/rules/git-workflow.azure.md +12 -7
  39. package/assets/rules/git-workflow.github.md +31 -13
  40. package/assets/rules/git-workflow.gitlab.md +12 -7
  41. package/assets/rules/reuse-first.md +1 -1
  42. package/assets/rules/spec-driven.md +4 -0
  43. package/assets/rules/task-flow.md +47 -22
  44. package/assets/rules/testing.md +19 -0
  45. package/assets/rules/typescript-conventions.md +12 -0
  46. package/assets/skills/agent-kit-extend.md +173 -0
  47. package/assets/skills/agent-kit.md +62 -10
  48. package/assets/traits.json +14 -0
  49. package/bin/agent-kit.d.ts.map +1 -1
  50. package/bin/agent-kit.js +31 -16
  51. package/bin/agent-kit.js.map +1 -1
  52. package/index.d.ts +1 -0
  53. package/index.d.ts.map +1 -1
  54. package/index.js +1 -0
  55. package/index.js.map +1 -1
  56. package/lib/argv.d.ts +17 -0
  57. package/lib/argv.d.ts.map +1 -0
  58. package/lib/argv.js +44 -0
  59. package/lib/argv.js.map +1 -0
  60. package/lib/cargo.d.ts +88 -0
  61. package/lib/cargo.d.ts.map +1 -0
  62. package/lib/cargo.js +16 -0
  63. package/lib/cargo.js.map +1 -0
  64. package/lib/catalog.d.ts +18 -1
  65. package/lib/catalog.d.ts.map +1 -1
  66. package/lib/catalog.js +12 -2
  67. package/lib/catalog.js.map +1 -1
  68. package/lib/commands.d.ts +0 -26
  69. package/lib/commands.d.ts.map +1 -1
  70. package/lib/commands.js +78 -122
  71. package/lib/commands.js.map +1 -1
  72. package/lib/companion.d.ts +37 -0
  73. package/lib/companion.d.ts.map +1 -1
  74. package/lib/companion.js +42 -1
  75. package/lib/companion.js.map +1 -1
  76. package/lib/config.d.ts +28 -0
  77. package/lib/config.d.ts.map +1 -1
  78. package/lib/config.js +20 -0
  79. package/lib/config.js.map +1 -1
  80. package/lib/ship.d.ts +39 -0
  81. package/lib/ship.d.ts.map +1 -0
  82. package/lib/ship.js +87 -0
  83. package/lib/ship.js.map +1 -0
  84. package/lib/shipment.d.ts +60 -0
  85. package/lib/shipment.d.ts.map +1 -0
  86. package/lib/shipment.js +247 -0
  87. package/lib/shipment.js.map +1 -0
  88. package/lib/snapshot.d.ts +30 -0
  89. package/lib/snapshot.d.ts.map +1 -0
  90. package/lib/snapshot.js +73 -0
  91. package/lib/snapshot.js.map +1 -0
  92. package/lib/traits.d.ts +32 -0
  93. package/lib/traits.d.ts.map +1 -0
  94. package/lib/traits.js +82 -0
  95. package/lib/traits.js.map +1 -0
  96. package/package.json +6 -2
  97. package/rt-tools-agent-kit-0.8.2.tgz +0 -0
  98. package/lib/submit.d.ts +0 -24
  99. package/lib/submit.d.ts.map +0 -1
  100. package/lib/submit.js +0 -26
  101. package/lib/submit.js.map +0 -1
  102. package/rt-tools-agent-kit-0.8.0.tgz +0 -0
  103. /package/assets/rules/{entity-conventions.md → entity-conventions.needs-admin.md} +0 -0
  104. /package/assets/rules/{observability.md → observability.needs-app.md} +0 -0
@@ -81,7 +81,7 @@ bash .claude/hooks/tests/run.sh # если конфликт задел х
81
81
 
82
82
  ## Тело открытого PR перечитывается после мержа
83
83
 
84
- Отчёт описывал дерево на день, когда его написали. Мерж главной ветки меняет то, о чём он
84
+ PR описывал дерево на день, когда его написали. Мерж главной ветки меняет то, о чём он
85
85
  утверждает: тело говорило, что оба дефекта заведены в `docs/BACKLOG.md`, а главная ветка этот
86
86
  список к тому времени разобрала. Правится тело вызовом REST — `gh pr edit` в этом репозитории
87
87
  отвечает отказом про Projects (classic) и до правки не доходит:
@@ -82,9 +82,18 @@ grep -rn "<похожий приём>" libs/admin libs/site --include='*.html' |
82
82
  <input type="tel" qa-dataid="phone-input" />
83
83
  ```
84
84
 
85
- Маркер `native-ok` ставится в той же строке и объясняет, **чего именно нет в ките**. «Эти
86
- строки были здесь раньше» причиной не считается: гард вычёркивает из проверяемого текста то,
87
- что уже лежит в файле, поэтому отказ означает новый текст.
85
+ Маркер `native-ok` объясняет, **чего именно нет в ките**. «Эти строки были здесь раньше»
86
+ причиной не считается: гард вычёркивает из проверяемого текста то, что уже лежит в файле,
87
+ поэтому отказ означает новый текст.
88
+
89
+ Стоит он комментарием строкой выше кода или в самой строке — снимаются обе. В разметке годится
90
+ только первое: форматировщик разносит тег, у которого атрибуты не влезли в предел ширины, по
91
+ строкам, и первый атрибут всегда уезжает на строку ниже имени тега. Признак считает имя тега,
92
+ то есть первую строку, а маркер, поставленный атрибутом, оказывается на второй и не снимает
93
+ ничего. Короткий тег форматировщик не трогает — и маркер работает ровно до тех пор, пока к тегу
94
+ не добавили ещё один атрибут.
95
+
96
+ Дальше следующей строки маркер не достаёт: он снимает свой случай, а не блок вокруг себя.
88
97
 
89
98
  Сверка идёт без отступов — при переезде блок меняет отступ, оставаясь тем же кодом.
90
99
 
@@ -43,6 +43,12 @@ docs/specs/<домен>/
43
43
 
44
44
  Текст заголовка сверяется дословно. «Не применимо» — законный ответ, отсутствие раздела — нет.
45
45
 
46
+ `## Решения` — временное место. Решение живёт в нём, пока не найден слой, которому оно
47
+ принадлежит; найденный слой забирает его пунктом, а в спеке не остаётся ничего. Разросшийся
48
+ раздел читается как признак незаведённого правила, а не как свойство сложного домена: делить
49
+ такой спек по строкам бесполезно, потому что делится в нём не описание домена, а ненаписанное
50
+ правило.
51
+
46
52
  Шапка несёт статус, дату ревизии, префикс сценариев, зависимости от других доменов, строку
47
53
  `**Законы:**` — законы, которые домен применяет, — и строку `**Процедуры:**` — корни либ, чьи
48
54
  процедуры домен обслуживает.
@@ -129,7 +135,7 @@ docs/specs/<домен>/
129
135
  - Пометка «Не покрыто» при существующем тесте — отказ: долг закрыли, а отметку не сняли.
130
136
  - Пометка «Не покрыто» читается дословно и с начала строки. Любое слово между ней и двоеточием
131
137
  — «Не покрыто, и прогоном не покрывается вовсе: …» — и сценарий считается непомеченным вовсе,
132
- а причина, ради которой пометку и писали, до отчёта не доезжает.
138
+ а причина, ради которой пометку и писали, до PR не доезжает.
133
139
  - Закон, названный в тексте, но забытый в строке `**Законы:**`: по закону тогда не узнать,
134
140
  какие домены на нём стоят.
135
141
  - Правка `.proto` без спеков задетых доменов: `docs-guard` отбивает такой коммит.
@@ -123,6 +123,12 @@ description: Паттерн правила git-workflow. Брать … Не б
123
123
  правку сущности оказались привязаны к механике, которую не зовёт ни один экран.
124
124
  - Утверждение переформулировали, а строку в привязке не тронули: связь идёт по тексту, и
125
125
  проверка перестанет её находить.
126
+ - Строка привязки дописана в конец компаньона, а не вставлена в таблицу. После таблицы там идут
127
+ ещё разделы — «Чем это проверяется», «Что ещё стоит знать при чтении кода», — и приписанная в
128
+ конец строка в таблицу не попадает вовсе: утверждение читается непривязанным, а сверка спеков
129
+ на это молчит, потому что ищет строку в таблице. Место строки то же, что у её утверждения в
130
+ правиле: порядок обеих сторон держится одинаковым, иначе утверждение и его привязка перестают
131
+ находиться друг по другу.
126
132
  - В `description` не сказано, когда паттерн **не** брать, — соседний паттерн того же правила
127
133
  становится неотличимым.
128
134
  - Блок готового кода принят по виду, а не сверкой с объявлением. Вызов в примере повторяет имя,
@@ -2,7 +2,7 @@
2
2
  name: task-flow-close
3
3
  kind: pattern
4
4
  rule: task-flow
5
- description: Паттерн правила task-flow. Брать при закрытии работы — вливание договорённости в спек домена последним коммитом отчёта, разбор папки задачи, переезд в архив, сверка очереди работ. Не брать для хода работы — это паттерн task-flow-resume.
5
+ description: Паттерн правила task-flow. Брать при закрытии работы — вливание договорённости в спек домена последним коммитом PR, разбор папки задачи, переезд в архив, сверка очереди работ. Не брать для хода работы — это паттерн task-flow-resume.
6
6
  ---
7
7
 
8
8
  # Закрытие работы
@@ -12,12 +12,12 @@ description: Паттерн правила task-flow. Брать при закр
12
12
 
13
13
  ## Когда брать
14
14
 
15
- - Этапы замысла закрыты, проверки зелёные, отчёт готовится к публикации.
15
+ - Этапы замысла закрыты, проверки зелёные, PR готовится к публикации.
16
16
  - `npm run check:specs` перечислил договорённость в разделе «Пора вливать».
17
17
 
18
18
  ## 9. Договорённость вливается в спек домена
19
19
 
20
- Последним коммитом отчёта, до слияния. Код к этому моменту написан, поэтому привязки
20
+ Последним коммитом PR, до слияния. Код к этому моменту написан, поэтому привязки
21
21
  `файл:символ` известны — правило въезжает в спек домена сразу проверяемым.
22
22
 
23
23
  ```bash
@@ -78,17 +78,69 @@ grep -rn -A3 "Чего из закона здесь нет" <каталог пр
78
78
  ```
79
79
 
80
80
  **Закон в ветке не правится.** Статья закона — договорённость с владельцем, и меняет её он.
81
- Работа с ней разошлась — пишется готовый текст статьи: в ход работы и в тело отчёта. Файл
81
+ Работа с ней разошлась — пишется готовый текст статьи: в ход работы и в тело PR. Файл
82
82
  закона правится после ответа. С законами приложения так же: деньги, локали и доступ — та же
83
83
  договорённость, только про это приложение.
84
84
 
85
- Что сделали на этом шаге, пишется в тело отчёта: что перечитали, что изменили, а если ничего
85
+ Что сделали на этом шаге, пишется в тело PR: что перечитали, что изменили, а если ничего
86
86
  не изменили — почему. Форма раздела — паттерн `git-workflow-commit`.
87
87
 
88
88
  ## 11. Папка задачи разбирается
89
89
 
90
+ **Заход, открывший PR, называет владельцу оставшийся шаг вслух:** после одобрения ветка
91
+ получает ещё один коммит — разбор папки, — и только потом вливается. Порядок этот записан
92
+ здесь, а читает его исполнитель; вливает же владелец, и молчание он читает как «работа
93
+ кончена» — видит зелёный PR и мержит его тем же ходом. Промах случается ровно в шов между
94
+ двумя ходами, и стоит он отдельной задачи: после слияния папку разбирать уже некому.
95
+
96
+ ### Два сообщения владельцу, и между ними — прогон
97
+
98
+ Оба обязательны, и порядок между ними один. Ни одно не заменяется другим: первое говорит, что
99
+ работа отдана и чего она ждёт, второе — что она готова.
100
+
101
+ Сразу после открытия PR:
102
+
103
+ ```
104
+ PR #<номер> открыт. Жду прогона: пока он идёт, о работе известно только то, что она
105
+ запушена. Как закончится — разберу папку задачи последним коммитом и попрошу тебя влить.
106
+ Пока жду, беру задачу #<номер следующей>.
107
+ ```
108
+
109
+ Прогон зелёный, папка разобрана и запушена:
110
+
111
+ ```
112
+ PR #<номер> готов к слиянию: прогон зелёный, папка задачи разобрана, за работой убрано.
113
+ Влей его, пожалуйста.
114
+ ```
115
+
116
+ Прогон красный — сообщение то же по форме, но говорит о красном и о том, что с ним делается;
117
+ просьбы влить в нём нет. Просьба звучит один раз и только тогда, когда работа готова целиком:
118
+ сказанная заранее, она перестаёт что-либо значить, и владелец возвращается к прежнему —
119
+ вливать по зелёной странице.
120
+
121
+ Между двумя сообщениями исполнитель не ждёт: работа отдана на разбор, и тем же движением
122
+ берётся следующая задача. Возвращается он к PR тем ходом, которым читает конец прогона.
123
+
124
+ Разбор идёт по трём исходам, а не по двум.
125
+
126
+ **Первым отбирается действующее требование.** Всё, что останется верным и завтра, становится
127
+ статьёй закона, пунктом правила или разделом паттерна — по тому, о чём оно говорит. Признак
128
+ отбора один и записан здесь заранее: перестанет ли текст быть верным, если завтра всё
129
+ переделать. Перестанет — это рассказ о состоявшемся; не перестанет — требование, и место ему в
130
+ слое правил. Закон при этом в ветке не правится — его статья приносится владельцу текстом.
131
+
132
+ **Вторым отбирается рассказ о состоявшемся переезде.** Он уезжает в описание прошлого и
133
+ называет для каждого перенесённого решения, куда оно ушло: иначе решение, ставшее правилом, и
134
+ решение, потерянное при переносе, выглядят одинаково — записью, на которую никто не ссылается.
135
+
136
+ **Третьим удаляется остальное.**
137
+
138
+ Порядок именно такой: начав с переезда, исполнитель увозит вместе с ним и действующее — под
139
+ конец работы это дешевле, чем разбирать.
140
+
90
141
  Целиком в архив не переносится: `docs/archive/` — место для записей о состоявшемся, которые
91
- кто-то читает, а не свалка ходов работы.
142
+ кто-то читает, а не свалка ходов работы. Таблица ниже говорит о том, что осталось после
143
+ первого отбора.
92
144
 
93
145
  | Файл | Куда |
94
146
  | ------------- | ------------------------------------------------------------------------------------------------------------------ |
@@ -103,9 +155,26 @@ cat docs/tasks/<КЛЮЧ>-<номер>-<slug>/grill.md > docs/archive/<ЧТО_Р
103
155
  rm -r docs/tasks/<КЛЮЧ>-<номер>-<slug>
104
156
  ```
105
157
 
106
- Разбор идёт в том же отчёте, что и работа: папка, оставленная до мержа, попадает в главную
158
+ Разбор идёт в том же PR, что и работа: папка, оставленная до мержа, попадает в главную
107
159
  ветку и читается там как текущая.
108
160
 
161
+ ### Работа, разбирающая чужую папку, разбирает две
162
+
163
+ Своя папка у такой работы есть — она заводится наравне со всеми, исключения из этого нет. Обе
164
+ снимаются последним коммитом, и порядок между ними один: сперва чужая, потом своя. Начав со
165
+ своей, исполнитель теряет замысел на диске, а он ещё нужен — гард отбивает правку без него, а
166
+ правка по замечаниям разбора идёт в ту же ветку.
167
+
168
+ ```bash
169
+ cat docs/tasks/<чужая>/grill.md > docs/archive/<ЧТО_РЕШАЛИ_ТАМ>.md
170
+ rm -r docs/tasks/<чужая>
171
+ cat docs/tasks/<своя>/grill.md > docs/archive/<ЧТО_РЕШАЛИ_ЗДЕСЬ>.md
172
+ rm -r docs/tasks/<своя>
173
+ ```
174
+
175
+ Две записи в архиве, а не одна: работы разные, и решения в них разные. Сверка очереди работ
176
+ после этого не называет ни одной папки — этим и проверяется, что разобраны обе.
177
+
109
178
  ## 12. Сверка
110
179
 
111
180
  ```bash
@@ -121,7 +190,7 @@ npm run check:docs # пути, названные в текстах, суще
121
190
  отвечает — работа перешла к следующей задаче, и находка достанется чужому заходу. Три раза
122
191
  подряд папка закрытой задачи так и уехала в главную ветку, в последний раз их набралось
123
192
  пять. Теперь это держит гард поставки: слияние отбивается, пока папка лежит в ветке.
124
- - **Разбирают последним коммитом, а не перед открытием отчёта.** Пока идёт ревью, замысел
193
+ - **Разбирают последним коммитом, а не перед открытием PR.** Пока идёт ревью, замысел
125
194
  нужен на диске: без него правку по замечаниям не пропустит гард хода работы. Порядок такой:
126
195
  правки по ревью, потом разбор папки, потом слияние.
127
196
  - **Разбор папки идёт последним, после того как гейт пуша прошёл целиком.** Гард хода работы
@@ -165,7 +234,7 @@ npm run check:docs # пути, названные в текстах, суще
165
234
  в нём нет. Паттерн находится по имени правленого символа, а не по теме работы.
166
235
  - **Правило без привязки в спек домена не въезжает.** Кода, который его исполняет, нет —
167
236
  значит это намерение, и место ему в открытых вопросах домена, а не в правилах.
168
- - **Замысел линии работ правят только там, где вписывают «чем кончилась».** Границы линии и
237
+ - **Замысел эпика правят только там, где вписывают «чем кончился».** Границы эпика и
169
238
  порядок задач в ней при этом остаются прежними, а работа их уже нарушила: задача, решившая
170
239
  читать спеки, оставила над собой границу «спеки — вторая очередь», и следующий исполнитель
171
240
  прочитает её как действующую. Границы линии перечитываются целиком тем же заходом, что и
@@ -26,7 +26,7 @@ description: Паттерн правила task-flow. Брать, когда з
26
26
 
27
27
  Пороги сторожит гард заполнения окна; размер окна он берёт из настройки дерева — из записи
28
28
  захода тот не выводится. Место между порогами и есть то, на что заход закрывается: дописать ход
29
- работы, написать передачу, закоммитить и открыть отчёт, если работа кончена.
29
+ работы, написать передачу, закоммитить и открыть PR, если работа кончена.
30
30
 
31
31
  ## Точка остановки
32
32
 
@@ -54,7 +54,7 @@ description: Паттерн правила task-flow. Брать, когда з
54
54
 
55
55
  ### Коммит
56
56
 
57
- Проверенное коммитится сразу, а не копится до конца задачи. Работа кончена — открывается отчёт:
57
+ Проверенное коммитится сразу, а не копится до конца задачи. Работа кончена — открывается PR:
58
58
  паттерн `git-workflow-commit`.
59
59
 
60
60
  ### Передача
@@ -86,12 +86,35 @@ mkdir -p <каталог передачи>
86
86
  - <прочее, чего нет ни в правилах, ни в ходе работы>.
87
87
  ```
88
88
 
89
+ Третьим разделом идёт «Эпик» — таблица положения. Работа вне эпика этого раздела не несёт:
90
+ таблица из одной строки повторяет раздел «Работа» и читается как эпик из одной задачи.
91
+
92
+ ```markdown
93
+ ### Эпик <номер> — <возможность, названная замыслом>
94
+
95
+ | № | Задача | Состояние |
96
+ | --- | --------------------------------- | --------- |
97
+ | 1 | <КЛЮЧ>-<номер> — <что делает> | закрыта |
98
+ | 2 | **<КЛЮЧ>-<номер> — <что делает>** | в работе |
99
+ | 3 | <КЛЮЧ>-<номер> — <что делает> | впереди |
100
+ ```
101
+
102
+ Три колонки, строка на задачу. Заголовок называет номер эпика и возможность — ту, что записана в
103
+ замысле, а не пересказанную заново. `№` — место по порядку: фактическое у закрытых, назначенное
104
+ замыслом у будущих. `Задача` — номер и что она делает, теми же словами, что в замысле.
105
+ `Состояние` — «закрыта», «в работе» или «впереди»; строка текущей задачи выделяется целиком.
106
+
107
+ Состав берётся из замысла эпика, а состояние — из очереди работ: замысел о том, что закрыто, не
108
+ знает, а очередь не знает порядка. Задача, дописанная в эпик после планирования, стоит в очереди
109
+ и в таблице, а в замысле её нет — расхождение называется вслух, а не заглаживается.
110
+
89
111
  Разделы фиксированы, и порядок у них тот же:
90
112
 
91
113
  1. **Работа** — номер задачи, её название, рабочее дерево полным путём, ветка и её состояние.
92
114
  2. **Где искать** — что придёт хуком само, а что читается по надобности.
93
- 3. **Сделано и следующий шаг** одной строкой каждое; подробности уже в ходе работы.
94
- 4. **Что учесть** особенности этого захода, которых нет ни в правилах, ни в ходе работы:
115
+ 3. **Эпик**таблица положения; у работы вне эпика раздела нет.
116
+ 4. **Сделано и следующий шаг** одной строкой каждое; подробности уже в ходе работы.
117
+ 5. **Что учесть** — особенности этого захода, которых нет ни в правилах, ни в ходе работы:
95
118
  поднятые стенды, отставшие зависимости, чужие процессы на портах, незакрытые вопросы к
96
119
  владельцу.
97
120
 
@@ -59,16 +59,16 @@ git log --oneline origin/main..HEAD
59
59
  - **Следующий шаг:** сценарии обоих хуков, затем подключение в настройках
60
60
  - **Незакоммиченное:** всё, ветка пока без коммитов
61
61
  - **Ждём владельца:** нет
62
- - **Отчёт:** ещё не открыт
62
+ - **PR:** ещё не открыт
63
63
  ```
64
64
 
65
- Строка про отчёт обязательна с той минуты, как этапы кончились: между открытием отчёта и
65
+ Строка про PR обязательна с той минуты, как этапы кончились: между открытием PR и
66
66
  слиянием проходит день и больше, и заход обрывается там чаще всего. Без неё следующий заход
67
- читает «этап последний, всё зелено» и об открытом отчёте узнаёт только из истории ветки или у
67
+ читает «этап последний, всё зелено» и об открытом PR узнаёт только из истории ветки или у
68
68
  владельца — то есть ровно тем пересказом, ради отмены которого всё и заведено:
69
69
 
70
70
  ```markdown
71
- - **Отчёт:** #1396, ждёт разбора · отвечено 3 замечания из 5 · не сделано: разбор папки задачи
71
+ - **PR:** #1396, ждёт разбора · отвечено 3 замечания из 5 · не сделано: разбор папки задачи
72
72
  ```
73
73
 
74
74
  Решение, принятое по ходу, — вместе с причиной и с тем, что было альтернативой:
@@ -94,12 +94,30 @@ git log --oneline origin/main..HEAD
94
94
  - Доэтапное, не этой работы: сверка очереди перечисляет шесть закрытых задач вне борды.
95
95
  ```
96
96
 
97
+ ## 13. Следующая задача эпика берётся тем же движением
98
+
99
+ Задача закрыта, PR открыт и ждёт владельца — заход на этом не кончается. Отданное на разбор
100
+ ждёт человека, а не машину: пока эпик не кончился, следующая его задача берётся сразу, тем же
101
+ движением, которым предыдущая ушла на разбор.
102
+
103
+ Берётся, а не выбирается: порядок назначен на планировании и лежит в замысле эпика. Выбор,
104
+ предложенный владельцу при назначенном порядке, — просьба назначить его заново.
105
+
106
+ ```bash
107
+ # что назначено следующим — читается в замысле эпика, а не спрашивается
108
+ # состояние задач — в очереди работ: замысел о закрытом не знает
109
+ ```
110
+
111
+ Останавливает заход только предел заполнения окна — тогда идёт передача, паттерн
112
+ `task-flow-handoff`. Эпик кончился — заход закрывается тем же порядком, и владельцу называется,
113
+ что кончился именно эпик, а не одна его задача.
114
+
97
115
  ## Ловушки
98
116
 
99
117
  - **Заход, кончившийся ничем, тоже записывается.** Иначе следующий пойдёт той же дорогой:
100
118
  «пробовали так — не вышло, потому что» стоит одной строки и экономит целый заход.
101
119
  - **Незакоммиченное называется явно.** Работа живёт в дереве неделями; строка «что лежит
102
- несохранённым и почему» — единственное, по чему это видно, пока отчёта нет.
120
+ несохранённым и почему» — единственное, по чему это видно, пока PR нет.
103
121
  - **Подтверждение — вывод команды или замер, а не пересказ.** «Проверил, работает» через
104
122
  заход неотличимо от «казалось, что работает».
105
123
  - **Число из передачи пересчитывается до того, как на нём что-то делят.** Передача описывает
@@ -73,6 +73,10 @@ Agent(subagent_type: "Explore", prompt: "<тема просьбы>: что по
73
73
  <Вопрос>
74
74
  ```
75
75
 
76
+ Под вопросом идёт таблица положения эпика — та же, что в передаче. Под, а не над: остановка
77
+ называется первой строкой, и положение эпика — то, из чего владелец решает, а не то, о чём его
78
+ спрашивают. Работа вне эпика таблицы не несёт.
79
+
76
80
  Замеры, находки ролей и список решений к этому моменту уже записаны в ход работы, и в
77
81
  сообщении владельцу они лишние. Отчёт, в конце которого стоит вопрос, выглядит добросовестно
78
82
  ровно настолько, насколько надёжно вопрос в нём тонет: владелец трижды переспрашивал, почему
@@ -163,5 +167,5 @@ cp docs/tasks/_template/progress.md docs/tasks/<КЛЮЧ>-<номер>-<slug>/pr
163
167
  - **Slug ветки берётся из терминологии договорённости, а не из слов просьбы.** Договорённость
164
168
  пишется раньше ветки и как раз там отказывается от слова владельца: спек завёл своё имя
165
169
  предмету и прямо сказал, каким словом его не называть, — а ветка и папка задачи остались с
166
- отвергнутым. Заголовок задачи и отчёта поправить можно, имя ветки после открытия отчёта
170
+ отвергнутым. Заголовок задачи и PR поправить можно, имя ветки после открытия PR
167
171
  уже нет.
@@ -30,7 +30,9 @@ description: Правило под «Закон о проверяемости».
30
30
 
31
31
  - **Второй экземпляр уже поднятого приложения не поднимается.** До первого запроса выясняется,
32
32
  кто отвечает на порту: поднятый заново экземпляр отвечает своей сборкой, а не той, которую
33
- проверяют. Кто поднимает стенд — владелец или агент, — сказано в именах дерева.
33
+ проверяют. Кто поднимает стенд — владелец или агент, — сказано в именах дерева. Занятый порт,
34
+ обнаруженный поздно, означает, что стенд уже есть: запущенное поверх него останавливается по
35
+ идентификатору процесса, а не по имени команды — у обоих экземпляров оно одно.
34
36
  - **Браузер водится одним драйвером на закреплённом профиле.** Остальные двери — второй
35
37
  драйвер, `open`, `osascript`, запуск бинарника — закреплённый профиль не спрашивают вовсе.
36
38
  - **Выбор браузера протухает и требует повторного вызова.** Выбор, сделанный в начале
@@ -66,6 +68,13 @@ description: Правило под «Закон о проверяемости».
66
68
  отвечает 200 старым кодом, а заведённого в ветке обработчика у него нет вовсе, и 404 читается
67
69
  как дефект регистрации. Таких процессов бывает несколько; снятие по шаблону команды не
68
70
  попадает ни в один — убивать по PID из `lsof`, каждый.
71
+ - **Шаблон имени команды не годится ни чтобы попасть, ни чтобы не задеть.** Два экземпляра
72
+ одного стенда — уже поднятый и только что запущенный — по тексту команды неотличимы: она у них
73
+ одна и та же. Снятие по шаблону уносит оба, и разобрать это потом нечем: снятым оказывается
74
+ ровно тот стенд, ради которого всё затевалось. Своё и чужое различает только идентификатор
75
+ процесса, снятый разбором порта; им и останавливают, поштучно. Обратный промах тот же по
76
+ природе — оболочка запускает процесс под именем, которого в шаблоне нет, и снятие не попадает
77
+ ни во что.
69
78
  - Инкрементальная сборка протухает поштучно: разметка бывает уже новая, а клиентский чанк — от
70
79
  компиляции до правки. Признак дев-сборки — имена бандла без хеша (`main.js`). Расхождение
71
80
  между `curl` и страницей после гидратации — повод пересобрать, а не искать дефект в коде.
@@ -115,7 +115,7 @@ description: Правило под «Закон о документации пр
115
115
  паттерн `doc-style-sweep`.
116
116
  - **Словарь действует и на разговор с владельцем, не только на файлы.** Он приходит в контекст
117
117
  на запуске сессии, поэтому «не читал» основанием не бывает. Слово из левой колонки «Так не
118
- пишем» всплывало именно в ответах: в дереве его уже вычистили, а в отчёте о сделанном оно
118
+ пишем» всплывало именно в ответах: в дереве его уже вычистили, а в PR о сделанном оно
119
119
  оставалось, и владелец читал ровно то слово, от которого отказались.
120
120
  - **Термин берётся из `docs/GLOSSARY.md`, а не придумывается на месте.** Слова, которого там
121
121
  нет, у читателя нет тоже: «журнал приложения» простоял в спеке почты, пока владелец не
@@ -131,19 +131,27 @@ description: Правило под «Закон о документации пр
131
131
  - **Снятое имя вычищается одним грепом по всему дереву:** правила, их зеркала в скилах,
132
132
  документы и комментарии. Описание того, чего в коде уже нет, читается как действующее
133
133
  указание.
134
+ - **У снятого слова второе значение возвращается после сплошной замены, а не обходится до
135
+ неё.** Слово снимают ровно потому, что оно стояло над двумя вещами, и второе значение при
136
+ этом остаётся законным. Отобрать его заранее нечем: какое из двух значений в строке, видно
137
+ только по соседнему тексту, а строк бывают сотни. Порядок обратный — сплошная замена, затем
138
+ сплошной просмотр самой правки, и найденное второе значение возвращается поимённо. Из 353
139
+ замен так вернулись шесть, и две первые были поломкой: сверка печатала новое имя дважды
140
+ подряд, а комментарий обещал «поломку вместо PR о том, что долгов нет». Просматривается
141
+ правка, а не дерево после неё: в дереве обе стороны выглядят одинаково верными.
134
142
  - **Поиск по дереву не покрывает того, что уже уехало наружу.** Заголовок задачи и её тело,
135
- заголовок отчёта и его тело, заголовки коммитов лежат вне файлов, и проверки текстов их не
143
+ заголовок PR и его тело, заголовки коммитов лежат вне файлов, и проверки текстов их не
136
144
  читают вовсе. Вычистив слово в дереве, обходят те же места в очереди работ и в истории:
137
145
 
138
146
  ```bash
139
- <клиент хостинга> api "<путь к отчёту>" --jq '.title, .body' | grep -i '<слово>'
147
+ <клиент хостинга> api "<путь к PR>" --jq '.title, .body' | grep -i '<слово>'
140
148
  <клиент хостинга> api "<путь к задаче>" --jq '.title, .body' | grep -i '<слово>'
141
149
  git log --format='%s%n%b' <база>..HEAD | grep -i '<слово>'
142
150
  ```
143
151
 
144
- Заголовок отчёта правится вызовом хостинга, заголовок коммита — только переписыванием ветки,
152
+ Заголовок PR правится вызовом хостинга, заголовок коммита — только переписыванием ветки,
145
153
  поэтому его проверяют до пуша. Выдуманное слово было вычищено из трёх файлов и объявлено
146
- снятым, а в заголовке отчёта и в заголовке коммита осталось — владелец прочитал именно его.
154
+ снятым, а в заголовке PR и в заголовке коммита осталось — владелец прочитал именно его.
147
155
 
148
156
  - **Число в тексте пересчитывается командой в том же коммите, где пишется.** Оно стареет
149
157
  внутри одной ветки: «шестнадцать пар» стало неправдой через два коммита после того, как
@@ -21,7 +21,7 @@ description: Правило под «Закон о поставке» для д
21
21
  | задача | рабочий элемент (work item) рода `Task` или `Bug`, заголовок `[<номер>] <Что не так>`, исполнитель — учётная запись машинной работы; PR прикрепляется к нему при создании флагом `--work-items`, а коммит — строкой `AB#<номер>` |
22
22
  | очередь работ | Azure Boards проекта. Рабочий элемент попадает на доску тем, что заведён: доска показывает элементы своей области и итерации |
23
23
  | состояние задачи в очереди работ | поле `State` рабочего элемента: `New` у заведённого, `Active` у взятого в работу, `Resolved` у ждущего разбора. Набор состояний зависит от процесса проекта и назван в `implementation.md`; закрытая задача уходит из очереди слиянием |
24
- | отчёт о задаче | заголовок PR `[<номер>] <Что сделано>` — тот же номер, что у рабочего элемента, и его название, переведённое в сделанное; тип и область коммита сюда не идут |
24
+ | PR о задаче | заголовок PR `[<номер>] <Что сделано>` — тот же номер, что у рабочего элемента, и его название, переведённое в сделанное; тип и область коммита сюда не идут |
25
25
  | обсуждение правки | разбор PR: ревьювер — владелец репозитория, исполнитель — учётная запись машинной работы, метки — те же, что у рабочего элемента |
26
26
  | попадание правки в главную ветку | слияние PR; оно же запускает выкатку — `azure-pipelines.yml` |
27
27
  | образ того коммита | `IMAGE_TAG=<sha>` в командах `docker compose` на сервере |
@@ -48,6 +48,11 @@ description: Правило под «Закон о поставке» для д
48
48
  открытие, пока вершина главной ветки не стала предком текущей, и называет расхождение числом
49
49
  коммитов. PR с разошедшейся ветки показывает ревьюверу свою правку вперемешку с чужой, а всё,
50
50
  что автор проверил до публикации, он проверил от основания, которого в главной ветке уже нет.
51
+ - **Заведённый рабочий элемент подтверждается ответом очереди работ, а не выводом команды
52
+ заведения.** Команда отвечает за свои вызовы: она может завести элемент и не довести его до
53
+ доски, и её собственный разбор ошибок этот случай называет. Напечатанный номер значит «вызов
54
+ прошёл», а не «работа видна тому, кто по ней придёт». Спрашивается очередь — по номеру, одним
55
+ вызовом, — и ответ читается присутствием элемента на доске, его состоянием и исполнителем.
51
56
  - **Номер ветки и номер в заголовке PR сверяются на месте, а состояние — по доске.** Формат
52
57
  читается из текста команды и работает без сети; существование рабочего элемента, его
53
58
  состояние, исполнитель и то, что он ещё открыт, — только когда есть чем спросить. Нет сети
@@ -58,13 +63,13 @@ description: Правило под «Закон о поставке» для д
58
63
  набор вызовов по памяти. Перевод идёт сразу за шагом, который его вызвал: очередь работ
59
64
  читают между шагами, а не после них.
60
65
  - **Отставшее состояние находится сверкой очереди, а не глазами.** Сверка судит состояние по
61
- отчёту в обе стороны: открытый PR при элементе не в разборе и разбор без открытого PR — оба
66
+ PR в обе стороны: открытый PR при элементе не в разборе и разбор без открытого PR — оба
62
67
  расхождения. Момента, когда задачу берут в работу, ей не видно: ветки на доске нет.
63
68
  - **Задачи, чинящиеся одной правкой, сливаются до слияния ветки.** Вторая закрывается как
64
69
  дубликат, а недостающее из неё дописывается в первую. После слияния слить уже нельзя: ветка
65
70
  въехала, и откатывается она целиком.
66
71
  - **Работа, которую одним заходом не закрыть, помечена в двух местах, и они сверяются.** Метка
67
- на доске и строка о заходах с передачей в линии работ говорят одно и то же двум читателям:
72
+ на доске и строка о заходах с передачей в замысле эпика говорят одно и то же двум читателям:
68
73
  исполнитель открывает карточку раньше, чем линию, а планирует по линии. Одна пометка без
69
74
  другой лжёт молча, поэтому сверка очереди судит пару в обе стороны. Помечается только то, что
70
75
  законно не делится: пометка объёма правом делить не становится.
@@ -88,9 +93,9 @@ description: Правило под «Закон о поставке» для д
88
93
  ветке, а задание выкатки прибито условием к главной: прогон ради проверки доходит до сборок и
89
94
  там кончается. Прогон команд задания на своей машине его не покрывает: он проверяет команды,
90
95
  а не файл конвейера, — верность самого файла читается только по списку прогонов после пуша.
91
- - **Отчёт проверяется до слияния тем же конвейером, что и главная ветка.** Проверки и сборки
96
+ - **PR проверяется до слияния тем же конвейером, что и главная ветка.** Проверки и сборки
92
97
  образов идут на конвейере проверки PR, выкатка — нет: её держит условие по главной ветке у
93
- своего задания, а образ отчёта в реестр не уезжает.
98
+ своего задания, а образ PR в реестр не уезжает.
94
99
  - **Расхождение прода с главной веткой видно сверкой очереди работ.** Рабочий элемент уходит из
95
100
  очереди слиянием, но слияние — ещё не прод: отказавшая выкатка не трогает ни элемент, ни его
96
101
  состояние, и заметить её неоткуда. Сверка спрашивает последний прогон главной ветки и судит
@@ -145,7 +150,7 @@ description: Правило под «Закон о поставке» для д
145
150
 
146
151
  Гард поставки стоит на командах агента, поэтому ветку, заведённую руками в редакторе, он не
147
152
  видит: имя такой ветки держится памятью. Требование от этого не слабеет — просто отдельной
148
- проверки под него не заводится: работа опознаётся заголовком рабочего элемента и отчёта, а это
153
+ проверки под него не заводится: работа опознаётся заголовком рабочего элемента и PR, а это
149
154
  сверяется у всех. Сверка очереди имя ветки не судит вовсе: у открытого PR его не переименовать.
150
155
 
151
156
  Взятие задачи в работу не стережёт ничто: доска ветки не видит, а гард поставки её видит, но
@@ -191,7 +196,7 @@ description: Правило под «Закон о поставке» для д
191
196
  - **Учётная запись для пуша и автор PR выбираются отдельно.** Если пушить пришлось из-под другой
192
197
  записи, на следующий вызов это не переносится: PR открывают токеном учётной записи машинной
193
198
  работы, и от того, чьей записью он открыт, зависит, кого можно назначить ревьювером. Однажды
194
- смена записи ради пуша утекла в публикацию — отчёт вышел от владельца.
199
+ смена записи ради пуша утекла в публикацию — PR вышел от владельца.
195
200
  - **Невалидный файл конвейера виден прогоном нулевой длительности сразу после пуша.** Прогон
196
201
  заводится и кончается на разборе файла, не начав ни одного задания: в списке он стоит
197
202
  отказом, а внутри нет ни задания, ни лога — читается только длительность. Поэтому список