@rt-tools/agent-kit 0.9.0 → 0.10.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.
- package/README.md +21 -7
- package/assets/agents/conscience.md +58 -0
- package/assets/agents/prose-editor.md +44 -0
- package/assets/agents/strict-teacher.md +59 -0
- package/assets/checks/board.github.mjs +56 -1
- package/assets/checks/check-board.github.mjs +24 -0
- package/assets/checks/check-doc-paths.mjs +4 -15
- package/assets/checks/check-dupes.mjs +5 -6
- package/assets/checks/check-file-size.mjs +6 -20
- package/assets/checks/check-prose-style.mjs +137 -0
- package/assets/checks/check-reuse.mjs +5 -5
- package/assets/checks/check-styles.mjs +5 -5
- package/assets/checks/lib-common.mjs +3 -3
- package/assets/checks/rt-kit-checks.config.mjs +85 -1
- package/assets/defaults/project.sh +50 -0
- package/assets/docs/GLOSSARY.md +17 -15
- package/assets/hooks/browser-guard-device-id.sh +9 -1
- package/assets/hooks/browser-guard-no-asking.sh +9 -1
- package/assets/hooks/browser-guard-no-listing.sh +9 -1
- package/assets/hooks/browser-guard-no-other-drivers.sh +7 -1
- package/assets/hooks/browser-guard-require-select.sh +11 -2
- package/assets/hooks/claim-guard.sh +113 -0
- package/assets/hooks/conscience-guard.sh +98 -0
- package/assets/hooks/deny-tail.sh +32 -0
- package/assets/hooks/dev-server-guard.sh +8 -2
- package/assets/hooks/docs-guard.sh +14 -2
- package/assets/hooks/exam-guard.sh +121 -0
- package/assets/hooks/git-guard-delivery-signature.sh +75 -0
- package/assets/hooks/git-guard-delivery.sh +154 -68
- package/assets/hooks/git-guard-main.sh +12 -0
- package/assets/hooks/git-guard-push-tests.sh +49 -2
- package/assets/hooks/grill-gate.sh +12 -0
- package/assets/hooks/handoff-entry-guard.sh +71 -0
- package/assets/hooks/postmortem-guard.sh +12 -0
- package/assets/hooks/proposal-guard.sh +12 -0
- package/assets/hooks/prose-style-guard.sh +73 -0
- package/assets/hooks/qa-dataid-guard.sh +12 -1
- package/assets/hooks/rerun-guard.sh +86 -0
- package/assets/hooks/reuse-first-guard.sh +12 -1
- package/assets/hooks/roles.sh +32 -0
- package/assets/hooks/skill-gate.sh +12 -0
- package/assets/hooks/sql-guard-write.sh +2 -1
- package/assets/hooks/sql-guard.sh +12 -1
- package/assets/hooks/task-flow-guard.sh +71 -7
- package/assets/hooks/turn-exit-guard.sh +189 -0
- package/assets/hooks/waiting-turn-guard.sh +12 -0
- package/assets/hooks/window-fill-guard.sh +12 -1
- package/assets/patterns/task-flow-close.md +8 -8
- package/assets/patterns/task-flow-handoff.md +1 -1
- package/assets/patterns/task-flow-resume.md +30 -4
- package/assets/patterns/task-flow-start.md +15 -6
- package/assets/rules/git-workflow.azure.md +36 -9
- package/assets/rules/git-workflow.github.md +74 -9
- package/assets/rules/git-workflow.gitlab.md +40 -12
- package/assets/rules/task-flow.md +123 -71
- package/assets/rules/testing.md +15 -1
- package/assets/samples/tasks/_template/plan.md +4 -1
- package/assets/samples/tasks/_template/progress.md +1 -0
- package/assets/skills/agent-kit.md +33 -0
- package/assets/templates/project.sh +16 -0
- package/bin/agent-kit.d.ts.map +1 -1
- package/bin/agent-kit.js +4 -2
- package/bin/agent-kit.js.map +1 -1
- package/lib/config.d.ts +8 -0
- package/lib/config.d.ts.map +1 -1
- package/lib/config.js +1 -0
- package/lib/config.js.map +1 -1
- package/lib/enroll.d.ts +9 -1
- package/lib/enroll.d.ts.map +1 -1
- package/lib/enroll.js +65 -18
- package/lib/enroll.js.map +1 -1
- package/package.json +1 -1
- package/rt-tools-agent-kit-0.10.0.tgz +0 -0
- package/rt-tools-agent-kit-0.9.0.tgz +0 -0
|
@@ -72,6 +72,22 @@ flowchart TD
|
|
|
72
72
|
вершина главной ветки не стала предком текущей, и называет расхождение числом коммитов. PR с
|
|
73
73
|
разошедшейся ветки показывает ревьюверу свою правку вперемешку с чужой, а всё, что автор
|
|
74
74
|
проверил до публикации, он проверил от основания, которого в главной ветке уже нет.
|
|
75
|
+
- **Несошедшиеся условия поставки называются одним отказом, а не по одному.** Гард копит их все
|
|
76
|
+
и печатает разом. Отбитый по первому промаху исполнитель правит основание, повторяет вызов,
|
|
77
|
+
упирается в заголовок, правит заголовок, упирается в задачу — и каждый круг стоит ещё одного
|
|
78
|
+
вызова, хотя всё несошедшееся было известно уже на первом.
|
|
79
|
+
- **Условие, известное в начале работы, спрашивается в начале.** Заведение ветки отбивает
|
|
80
|
+
основание, в котором нет вершины главной ветки, и рабочую копию, подписывающую коммиты не той
|
|
81
|
+
почтой, что объявило дерево. На пуше и на открытии PR те же проверки остаются вторым рубежом,
|
|
82
|
+
но там они стоят дороже: основание чинится вливанием с разбором конфликта, подпись —
|
|
83
|
+
переписыванием всей ветки.
|
|
84
|
+
- **Судится то основание, которое названо командой, а не вершина рабочей копии.** Ветку заводят
|
|
85
|
+
и от `origin/main` прямо — этой командой основание как раз и берут свежим, — и гард, читающий
|
|
86
|
+
только текущую вершину, отбивал бы её наравне с веткой от вчерашнего дерева. Основание, о
|
|
87
|
+
котором дерево ничего не знает, не судится вовсе.
|
|
88
|
+
- **Ветка без номера задачи условий поставки не получает.** Локальная ветка под пробу законна, и
|
|
89
|
+
требовать от неё свежего основания значило бы отбивать работу, которая в главную не поедет:
|
|
90
|
+
PR с такой ветки не откроется.
|
|
75
91
|
- **Ключ задач задаётся один раз, и все три формы имени выводятся из него.** Заголовок задачи,
|
|
76
92
|
имя ветки и заголовок PR строит один и тот же ключ: команда заведения задачи собирает по
|
|
77
93
|
нему заголовок, гард поставки достаёт по нему номер из имени ветки, сверка очереди — из
|
|
@@ -89,13 +105,18 @@ flowchart TD
|
|
|
89
105
|
ответ читается присутствием задачи на борде, её колонкой и исполнителем.
|
|
90
106
|
- **Номер ветки и номер в заголовке PR сверяются на месте, а состояние задачи — по борде.**
|
|
91
107
|
Формат читается из текста команды и работает без сети; существование задачи, её присутствие
|
|
92
|
-
на борде,
|
|
93
|
-
или нет токена — второй ярус молча пропускается: проверка, падающая в
|
|
94
|
-
что-либо значить.
|
|
108
|
+
на борде, её колонка, исполнитель, то, что она ещё открыта, и разбор у PR — только когда есть
|
|
109
|
+
чем спросить. Нет сети или нет токена — второй ярус молча пропускается: проверка, падающая в
|
|
110
|
+
самолёте, перестаёт что-либо значить.
|
|
95
111
|
- **Колонка задачи двигается тем же движением, что и работа.** Ветка заведена — задача
|
|
96
112
|
переставляется во взятые в работу, PR открыт — в ждущие разбора; делает это команда
|
|
97
113
|
перевода, а не набор вызовов GraphQL по памяти. Перевод идёт сразу за шагом, который его
|
|
98
114
|
вызвал: очередь работ читают между шагами, а не после них.
|
|
115
|
+
- **Задача, оставшаяся в первой колонке, PR не открывает.** Гард поставки называет её колонку и
|
|
116
|
+
команду перевода: по очереди работ такая задача читается как невзятая, хотя работа по ней
|
|
117
|
+
сделана и выложена. На заведении ветки колонка не спрашивается — там её ещё не двигали, и
|
|
118
|
+
требование отбивало бы первую же команду работы вместе с той, которая его и снимает. Имя
|
|
119
|
+
первой колонки дерево называет само; не названо — колонка не судится вовсе.
|
|
99
120
|
- **На борде стоят задачи, а не PR о них.** Борда показывает, что сделано и что осталось; PR
|
|
100
121
|
отвечает на другой вопрос — как именно сделано, — и открывается из карточки задачи, где связь
|
|
101
122
|
с ним заполняется сама полем «Linked pull requests». Карточка PR живёт своей жизнью: колонки
|
|
@@ -157,6 +178,13 @@ flowchart TD
|
|
|
157
178
|
заблокирована самим хостингом: зелёная страница PR владельцу ничего не разрешает, а список, в
|
|
158
179
|
котором всё серое, читается как «работа не сделана». Гард снятия черновика сюда не достаёт —
|
|
159
180
|
он судит один ход и молчит, пока ветка везёт папку своей задачи.
|
|
181
|
+
- **Конфликтующий открытый PR — расхождение сверки очереди работ.** Конфликт приезжает в
|
|
182
|
+
отданный PR чужим слиянием, без единого действия автора: основание, проверенное на открытии,
|
|
183
|
+
устаревает в ту минуту, когда владелец влил соседнюю работу. Гард снятия черновика сюда не
|
|
184
|
+
достаёт — он судит один ход, а PR стоит в очереди днями, и по списку конфликт не виден вовсе:
|
|
185
|
+
метку хостинг показывает только внутри самого PR. Непосчитанная сливаемость расхождением не
|
|
186
|
+
считается: хостинг считает её заново после каждой правки главной ветки, и строка на
|
|
187
|
+
«ещё не посчитано» краснела бы на каждой свежей вершине.
|
|
160
188
|
- **Расхождение прода с главной веткой видно сверкой очереди работ.** Задача уходит из очереди
|
|
161
189
|
мержем, но мерж — ещё не прод: отказавшая выкатка не трогает ни задачу, ни её колонку, и
|
|
162
190
|
заметить её неоткуда. Сверка спрашивает последний прогон главной ветки и судит только
|
|
@@ -206,12 +234,44 @@ flowchart TD
|
|
|
206
234
|
- **Черновик снимается отдельным вызовом — `gh pr ready <номер>`.** Им исполнитель отвечает за
|
|
207
235
|
готовность: проверки пройдены, доработок не осталось, работа сходится с задачей. Снятие
|
|
208
236
|
черновика и просьба влить — один ход, а не два разных дня.
|
|
237
|
+
- **Черновик не снимается с ветки, которая не сливается.** Зелёный прогон говорит «не
|
|
238
|
+
сломано», сливаемость — «кнопку можно нажать», и владельцу нужно второе: снятый черновик он
|
|
239
|
+
читает как приглашение влить и идёт нажимать. Спрашивается это у хостинга тем же вызовом, что
|
|
240
|
+
автор и ревьювер, — `mergeable` приходит в том же ответе; выводить сливаемость из того, что
|
|
241
|
+
вливание прошло локально, нельзя: между локальным вливанием и взглядом владельца главная
|
|
242
|
+
ветка успевает уйти вперёд. За один заход так было снято три черновика подряд, и все три
|
|
243
|
+
заявки владелец увидел конфликтующими. Держится это гардом поставки, а не памятью: статья
|
|
244
|
+
стояла здесь и до того, и промах повторился в тот же день. Дерево, чей помощник очереди работ
|
|
245
|
+
о сливаемости не говорит вовсе, работает как прежде — поля нет, требования нет.
|
|
246
|
+
- **Указателю, в который ветки только дописывают строки, объявляется сложение обеих сторон.**
|
|
247
|
+
Конфликт там не спор: обе допись нужны целиком, а зовёт он человека при каждом слиянии в
|
|
248
|
+
главную ветку — за один заход одна и та же строка разрешалась шесть раз в шести ветках.
|
|
249
|
+
Объявление снимает ручное разрешение: слияние проходит само. **Метку сливаемости на странице
|
|
250
|
+
заявки оно при этом не снимает** — хостинг считает её своим приёмом и настройки слияния не
|
|
251
|
+
читает. Гаснет метка только после того, как ветка вобрала главную и это уехало на хостинг.
|
|
252
|
+
Обещать по этому объявлению «конфликтов больше не будет» нельзя: не будет ручной работы, а
|
|
253
|
+
вливать главную в открытые ветки после каждого слияния придётся по-прежнему.
|
|
254
|
+
- **Разрешённый конфликт, оставшийся незапушенным, хуже неразрешённого.** Владелец видит
|
|
255
|
+
прежнее состояние и читает его как «не сделано ничего», а сделанное лежит в рабочем дереве
|
|
256
|
+
исполнителя, где его не видит никто. Ветка, в которой разрешён конфликт, пушится тем же
|
|
257
|
+
ходом — либо конфликт не разрешается вовсе.
|
|
258
|
+
- **Одно и то же вливание главной ветки, сделанное третий раз за заход, останавливает
|
|
259
|
+
работу.** Ветки, дописывающие строку в один и тот же список, роняют друг друга в конфликт при
|
|
260
|
+
каждом слиянии, и вливание главной по кругу — это починка проявления. На третьем круге
|
|
261
|
+
называется причина и спрашивается владелец, а не делается четвёртый круг.
|
|
262
|
+
- **Черновик не снимается, пока у PR нет разбора.** Гард поставки смотрит запрошенного ревьювера
|
|
263
|
+
и оставленный отзыв: снятый черновик читается как «можно вливать», а вливать некому. Раньше
|
|
264
|
+
этого хода спросить негде — до открытия PR ревьювера нет вовсе. Судится и вызов без номера:
|
|
265
|
+
без него клиент берёт PR текущей ветки, и требование снималось бы одним пробелом. Возврат PR
|
|
266
|
+
в черновик — `gh pr ready --undo` — требования не получает: он делает то же, чего гард и
|
|
267
|
+
добивается.
|
|
209
268
|
- **Мерж PR нажимает человек, а не исполнитель работы.** Кнопка и вызов слияния равны: запрет
|
|
210
269
|
на них один. Исполнитель сливает свой PR только тогда, когда человек сказал это прямо и про
|
|
211
270
|
этот PR; сказанное об одном PR на следующий не переносится, а молчание разрешением не
|
|
212
271
|
бывает. Работа кончается PR, с которого снят черновик, и в ответе называется его номер.
|
|
213
272
|
- **Автор PR не может быть его ревьювером.** Запрос разбора на самого себя GitHub принимает и
|
|
214
|
-
молча не создаёт — разбор при этом выглядит запрошенным.
|
|
273
|
+
молча не создаёт — разбор при этом выглядит запрошенным. Поэтому в разборе считаются только
|
|
274
|
+
запрос и отзыв не от автора: гард снятия черновика читает состояние PR именно так.
|
|
215
275
|
- **Метки, исполнитель и ревьювер PR ставятся вызовами `gh api`, а не `gh pr edit`.** На
|
|
216
276
|
репозитории со старой бордой `gh pr edit` отвечает отказом про Projects (classic) и до
|
|
217
277
|
правки не доходит вовсе.
|
|
@@ -243,10 +303,11 @@ flowchart TD
|
|
|
243
303
|
проверки под него не заводится: работа опознаётся заголовком задачи и PR, а это сверяется
|
|
244
304
|
у всех. Сверка очереди имя ветки не судит вовсе: у открытого PR его не переименовать.
|
|
245
305
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
306
|
+
Задачу в работу гард не переводит: борду он не правит — правка борды в разборе команды падала бы
|
|
307
|
+
вместе со связью и отбивала бы работу вместо промаха. Перевод держится памятью и подсказкой,
|
|
308
|
+
которую печатает команда заведения задачи. Задачу, оставшуюся в первой колонке, гард называет на
|
|
309
|
+
открытии PR — то есть после того, как её должны были переставить; прочие расхождения колонки
|
|
310
|
+
находит сверка очереди.
|
|
250
311
|
|
|
251
312
|
Свежесть самой вершины главной ветки гард спрашивает вторым ярусом — тем же приёмом, что и
|
|
252
313
|
состояние задачи: есть чем спросить, спрашивает; нет сети или доступа — пропускает молча.
|
|
@@ -284,7 +345,11 @@ flowchart TD
|
|
|
284
345
|
- **Учётная запись для пуша и автор PR выбираются отдельно.** Если пушить пришлось из-под другой
|
|
285
346
|
записи, на следующий вызов это не переносится: PR открывают токеном учётной записи машинной
|
|
286
347
|
работы, и от того, чьей записью он открыт, зависит, кого можно назначить ревьювером. Однажды
|
|
287
|
-
смена записи ради пуша утекла в публикацию — PR вышел от владельца.
|
|
348
|
+
смена записи ради пуша утекла в публикацию — PR вышел от владельца. Разница между читающим и
|
|
349
|
+
пишущим вызовом в самом тексте команды не видна: личность приходит окружением, поэтому у
|
|
350
|
+
вызова на запись токен называется явно, а открытая заявка проверяется ответом хостинга о её
|
|
351
|
+
авторе — напечатанная ссылка говорит, что заявка создана, и молчит о том, кем. Чинится это
|
|
352
|
+
только переоткрытием: автора у заявки не сменить.
|
|
288
353
|
- **Невалидный файл конвейера виден прогоном нулевой длительности сразу после пуша.** GitHub
|
|
289
354
|
заводит такой прогон и на ветке, на которую ни один триггер не подписан: в списке он стоит
|
|
290
355
|
отказом, а внутри у него нет ни задания, ни лога — читается только длительность. Поэтому
|
|
@@ -71,6 +71,22 @@ flowchart TD
|
|
|
71
71
|
вершина главной ветки не стала предком текущей, и называет расхождение числом коммитов. MR с
|
|
72
72
|
разошедшейся ветки показывает ревьюверу свою правку вперемешку с чужой, а всё, что автор
|
|
73
73
|
проверил до публикации, он проверил от основания, которого в главной ветке уже нет.
|
|
74
|
+
- **Несошедшиеся условия поставки называются одним отказом, а не по одному.** Гард копит их все
|
|
75
|
+
и печатает разом. Отбитый по первому промаху исполнитель правит основание, повторяет вызов,
|
|
76
|
+
упирается в заголовок, правит заголовок, упирается в задачу — и каждый круг стоит ещё одного
|
|
77
|
+
вызова, хотя всё несошедшееся было известно уже на первом.
|
|
78
|
+
- **Условие, известное в начале работы, спрашивается в начале.** Заведение ветки отбивает
|
|
79
|
+
основание, в котором нет вершины главной ветки, и рабочую копию, подписывающую коммиты не той
|
|
80
|
+
почтой, что объявило дерево. На пуше и на открытии MR те же проверки остаются вторым рубежом,
|
|
81
|
+
но там они стоят дороже: основание чинится вливанием с разбором конфликта, подпись —
|
|
82
|
+
переписыванием всей ветки.
|
|
83
|
+
- **Судится то основание, которое названо командой, а не вершина рабочей копии.** Ветку заводят
|
|
84
|
+
и от вершины главной ветки прямо — этой командой основание как раз и берут свежим, — и гард,
|
|
85
|
+
читающий только текущую вершину, отбивал бы её наравне с веткой от вчерашнего дерева.
|
|
86
|
+
Основание, о котором дерево ничего не знает, не судится вовсе.
|
|
87
|
+
- **Ветка без номера задачи условий поставки не получает.** Локальная ветка под пробу законна, и
|
|
88
|
+
требовать от неё свежего основания значило бы отбивать работу, которая в главную не поедет:
|
|
89
|
+
MR с такой ветки не откроется.
|
|
74
90
|
- **Правка кода отдаётся человеку открытым MR, а не запушенной веткой.** Ветка в списке ветвей
|
|
75
91
|
ему не показывается, в дела не приходит и обсуждения не имеет: до открытия MR правки для
|
|
76
92
|
человека нет. Открывается он тем же ходом, которым исполнитель говорит, что работу отдаёт, и
|
|
@@ -83,6 +99,12 @@ flowchart TD
|
|
|
83
99
|
- **Черновик снимается отдельным вызовом — `glab mr update <номер> --ready`.** Им исполнитель
|
|
84
100
|
отвечает за готовность: проверки пройдены, доработок не осталось, работа сходится с задачей.
|
|
85
101
|
Снятие черновика и просьба влить — один ход, а не два разных дня.
|
|
102
|
+
- **Черновик не снимается, пока у MR нет разбора.** Гард поставки смотрит запрошенного ревьювера
|
|
103
|
+
и оставленный отзыв: снятый черновик читается как «можно вливать», а вливать некому. Раньше
|
|
104
|
+
этого хода спросить негде — до открытия MR ревьювера нет вовсе. В разборе считаются только
|
|
105
|
+
запрос и отзыв не от автора: разбор на самого себя разбором не бывает. Судится и вызов без
|
|
106
|
+
номера — без него клиент берёт MR текущей ветки, и требование снималось бы одним пробелом;
|
|
107
|
+
возврат MR в черновик требования не получает.
|
|
86
108
|
- **Заведённая задача подтверждается ответом очереди работ, а не выводом команды заведения.**
|
|
87
109
|
Команда отвечает за свои вызовы: она может завести задачу и не довести её до доски, и её
|
|
88
110
|
собственный разбор ошибок этот случай называет. Напечатанный номер значит «вызов прошёл», а не
|
|
@@ -90,13 +112,18 @@ flowchart TD
|
|
|
90
112
|
ответ читается присутствием задачи на доске, её списком и исполнителем.
|
|
91
113
|
- **Номер ветки и номер в заголовке MR сверяются на месте, а состояние задачи — по доске.**
|
|
92
114
|
Формат читается из текста команды и работает без сети; существование задачи, её метка
|
|
93
|
-
списка,
|
|
94
|
-
или нет токена — второй ярус молча пропускается: проверка, падающая в самолёте,
|
|
95
|
-
что-либо значить.
|
|
115
|
+
списка, исполнитель, то, что она ещё открыта, и разбор у MR — только когда есть чем спросить.
|
|
116
|
+
Нет сети или нет токена — второй ярус молча пропускается: проверка, падающая в самолёте,
|
|
117
|
+
перестаёт что-либо значить.
|
|
96
118
|
- **Список задачи двигается тем же движением, что и работа.** Ветка заведена — задача
|
|
97
119
|
переставляется во взятые в работу, MR открыт — в ждущие разбора; делает это команда
|
|
98
120
|
перевода, а не набор вызовов по памяти. Перевод идёт сразу за шагом, который его вызвал:
|
|
99
121
|
очередь работ читают между шагами, а не после них.
|
|
122
|
+
- **Задача, оставшаяся в первом списке, MR не открывает.** Гард поставки называет её список и
|
|
123
|
+
команду перевода: по очереди работ такая задача читается как невзятая, хотя работа по ней
|
|
124
|
+
сделана и выложена. На заведении ветки список не спрашивается — там его ещё не двигали, и
|
|
125
|
+
требование отбивало бы первую же команду работы вместе с той, которая его и снимает. Имя
|
|
126
|
+
первого списка дерево называет само; не названо — список не судится вовсе.
|
|
100
127
|
- **На доске стоят задачи, а не MR о них.** Доска показывает, что сделано и что осталось; MR
|
|
101
128
|
отвечает на другой вопрос — как именно сделано, — и открывается из задачи, где связь с ним
|
|
102
129
|
стоит сама. Карточка MR живёт своей жизнью: метки списка у неё нет, из очереди она не уходит и
|
|
@@ -207,16 +234,17 @@ flowchart TD
|
|
|
207
234
|
проверки под него не заводится: работа опознаётся заголовком задачи и PR, а это сверяется
|
|
208
235
|
у всех. Сверка очереди имя ветки не судит вовсе: у открытого MR его не переименовать.
|
|
209
236
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
237
|
+
Задачу в работу гард не переводит: доску он не правит — правка доски в разборе команды падала бы
|
|
238
|
+
вместе со связью и отбивала бы работу вместо промаха. Перевод держится памятью и подсказкой,
|
|
239
|
+
которую печатает команда заведения задачи. Задачу, оставшуюся в первом списке, гард называет на
|
|
240
|
+
открытии MR — то есть после того, как её должны были переставить; прочие расхождения списка
|
|
241
|
+
находит сверка очереди.
|
|
214
242
|
|
|
215
|
-
Свежесть самой вершины главной ветки гард
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
243
|
+
Свежесть самой вершины главной ветки гард спрашивает вторым ярусом — тем же приёмом, что и
|
|
244
|
+
состояние задачи: есть чем спросить, спрашивает; нет сети или доступа — пропускает молча. Первый
|
|
245
|
+
ярус при этом остаётся, и работает он без сети: локальная ссылка отвечает на вопрос «отстало ли
|
|
246
|
+
основание от того, что уже лежит в дереве», удалённая — на вопрос «не протухла ли сама ссылка».
|
|
247
|
+
Без второго яруса молчание гарда значило лишь первое, а читалось как второе.
|
|
220
248
|
|
|
221
249
|
## Паттерны
|
|
222
250
|
|
|
@@ -11,7 +11,7 @@ description: Правило под «Закон о ведении работы»
|
|
|
11
11
|
про ход работы; здесь — чем это названо в этом дереве, где лежит и что из закона у нас не
|
|
12
12
|
проверяется.
|
|
13
13
|
|
|
14
|
-
**Требует:** `hooks/task-flow-guard.sh`, `hooks/task-context-load.sh`, `hooks/grill-gate.sh`, `hooks/window-fill-guard.sh`
|
|
14
|
+
**Требует:** `hooks/task-flow-guard.sh`, `hooks/task-context-load.sh`, `hooks/grill-gate.sh`, `hooks/window-fill-guard.sh`, `hooks/turn-exit-guard.sh`
|
|
15
15
|
|
|
16
16
|
## Как это называется здесь
|
|
17
17
|
|
|
@@ -34,50 +34,65 @@ description: Правило под «Закон о ведении работы»
|
|
|
34
34
|
переносится между репозиториями, раскладка — нет, и путь, названный в правиле, врёт в первом
|
|
35
35
|
же дереве, которое держит код иначе.
|
|
36
36
|
|
|
37
|
-
##
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
|
51
|
-
|
|
|
52
|
-
|
|
|
53
|
-
|
|
|
54
|
-
|
|
|
55
|
-
|
|
|
56
|
-
|
|
|
57
|
-
|
|
|
58
|
-
|
|
|
59
|
-
|
|
|
60
|
-
|
|
|
61
|
-
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
ускоряется от того, что его ждут, — поэтому шаг 11 случается раньше, чем кончатся 10 и 16, а
|
|
75
|
-
шаг 17 вклинивается в работу следующей задачи ровно на один ход. Порядок номеров говорит, что
|
|
76
|
-
за чем следует, а не что чего дожидается.
|
|
77
|
-
|
|
78
|
-
Список показывается владельцу в начале работы, и на нём же отмечается, где стоим: иначе после
|
|
37
|
+
## Состояния работы
|
|
38
|
+
|
|
39
|
+
Единица работы — состояние, а не шаг. У состояния есть вход, обязательное действие и выход, и
|
|
40
|
+
пока действие не сделано, работа стоит в том же состоянии. Список шагов этого не давал: шаг
|
|
41
|
+
кончался, а что делать дальше, выводилось из соседних строк.
|
|
42
|
+
|
|
43
|
+
Состояние объявляется машиночитаемой строкой в разделе «Где стоим» хода работы и
|
|
44
|
+
перезаписывается вместе с ним:
|
|
45
|
+
|
|
46
|
+
```markdown
|
|
47
|
+
- **Состояние:** `этап-идёт`
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
| Состояние | Вход в него | Обязательное действие | Ведёт паттерн |
|
|
51
|
+
| ------------------------- | ----------------------------------------------- | ------------------------------------------------------ | ------------------ |
|
|
52
|
+
| `просьба-не-разобрана` | реплика владельца о новой работе | разведка по дереву, затем вопросы | `task-flow-start` |
|
|
53
|
+
| `разбор-закрыт` | ответы владельца лежат на диске | договорённость о продукте либо причина её отсутствия | `task-flow-start` |
|
|
54
|
+
| `договорённость-записана` | драфт лежит или причина названа | завести задачу, ветку и папку | `task-flow-start` |
|
|
55
|
+
| `задача-взята` | задача в колонке работы, ветка по номеру, папка | написать замысел | `task-flow-start` |
|
|
56
|
+
| `замысел-записан` | замысел лежит и после записи не правится | делать первый этап | `task-flow-start` |
|
|
57
|
+
| `этап-идёт` | этап начат | доделать этап и отметить в ходе работы | `task-flow-resume` |
|
|
58
|
+
| `этапы-кончились` | все этапы отмечены | прогнать набор и открыть PR черновиком | `task-flow-close` |
|
|
59
|
+
| `работа-отдана` | PR открыт черновиком | взять следующую задачу | `task-flow-resume` |
|
|
60
|
+
| `разбор-кончился` | прогон зелёный, замечаний нет | влить договорённость, привести тексты, разобрать папку | `task-flow-close` |
|
|
61
|
+
| `папка-разобрана` | папки в ветке нет, запись в архиве есть | снять черновик и попросить влить | `task-flow-close` |
|
|
62
|
+
| `влито` | PR слит человеком | разбор работы правилами и сверка очереди | `task-flow-close` |
|
|
63
|
+
|
|
64
|
+
Ни у одного состояния обязательное действие не звучит как «ждать»: ожидание чужого шага
|
|
65
|
+
состоянием работы не является. Прогон, разбор владельцем и слияние идут без исполнителя, и от
|
|
66
|
+
взгляда быстрее не становятся — поэтому в `работа-отдана` обязательное действие смотрит на
|
|
67
|
+
следующую задачу, а не на открытый PR.
|
|
68
|
+
|
|
69
|
+
Заполнение окна захода состоянием работы тоже не бывает: заход кончается передачей, работа
|
|
70
|
+
остаётся в том состоянии, в каком стояла, а следующий заход читает строку и продолжает с неё.
|
|
71
|
+
Ведёт закрытие захода паттерн `task-flow-handoff`.
|
|
72
|
+
|
|
73
|
+
Перечень показывается владельцу в начале работы, и на нём же отмечается, где стоим: иначе после
|
|
79
74
|
шести вопросов не видно ни того, что будет дальше, ни сколько всего впереди.
|
|
80
75
|
|
|
76
|
+
## Выходы хода
|
|
77
|
+
|
|
78
|
+
Ход кончается четырьмя способами, и других нет:
|
|
79
|
+
|
|
80
|
+
| Выход | Чем подтверждается |
|
|
81
|
+
| -------------------------------------------------- | --------------------------------------------------------------- |
|
|
82
|
+
| вопрос владельцу, ответа на который в правилах нет | вопрос задан, и за тот же ход правила читались |
|
|
83
|
+
| отказ гарда | отказ назван владельцу, обход не искался |
|
|
84
|
+
| заполненное окно захода | ход работы дописан, передача написана |
|
|
85
|
+
| работа отдана, и следующая начата | PR открыт, и по следующей задаче сделано действие, а не сказано |
|
|
86
|
+
|
|
87
|
+
Всё остальное — продолжение хода, а не его конец. Веха ходом не кончается: ни коммит, ни
|
|
88
|
+
прочитанная договорённость, ни граница «прочитал — сейчас правлю», ни зелёная проверка. Слова
|
|
89
|
+
«иду дальше» и «работаю дальше» владелец читает как совершающееся действие, и писать их вместо
|
|
90
|
+
результата нельзя.
|
|
91
|
+
|
|
92
|
+
Три способа кончить ход выглядят работой и ею не являются: сводка о чужом шаге, меню при
|
|
93
|
+
назначенном порядке и объявление намерения. Что при этом должно быть верно — ниже, в статьях
|
|
94
|
+
о применении закона.
|
|
95
|
+
|
|
81
96
|
## Ход
|
|
82
97
|
|
|
83
98
|
Ход работы от просьбы владельца до закрытия: где стоит разбор, что требует гард и куда девается
|
|
@@ -113,8 +128,21 @@ flowchart TD
|
|
|
113
128
|
|
|
114
129
|
## Как закон применяется здесь
|
|
115
130
|
|
|
116
|
-
- **Правка кода приложения отбивается, пока
|
|
117
|
-
|
|
131
|
+
- **Правка кода приложения отбивается, пока работа не дошла до состояния, в котором код
|
|
132
|
+
правится.** Гард требует четыре вещи: папку задачи по имени ветки, замысел в ней, объявленное
|
|
133
|
+
в ходе работы состояние и названную в замысле договорённость о продукте.
|
|
134
|
+
- **Гард судит объявленный переход, а не наличие файлов.** Артефакт на диске не говорит, дошла
|
|
135
|
+
ли работа до правки кода: пустой замысел, положенный ради снятия отказа, лежит так же, как
|
|
136
|
+
написанный. Отказ снимает объявленное состояние, и снимают его четыре — `этап-идёт`,
|
|
137
|
+
`этапы-кончились`, `работа-отдана` и `разбор-кончился`: прогон бывает красным, а разбор — с
|
|
138
|
+
замечаниями, и починка идёт в ту же ветку.
|
|
139
|
+
- **Отказ по состоянию называет обязательное действие того состояния, которое объявлено.**
|
|
140
|
+
Исполнитель, которому сказано только «не в том состоянии», перепишет строку состояния вместо
|
|
141
|
+
того, чтобы сделать шаг.
|
|
142
|
+
- **Именем состояния считается только слово из перечня.** Своё слово не говорит ни о входе, ни
|
|
143
|
+
о выходе, ни об обязательном действии, а перечень называет все три.
|
|
144
|
+
- **Состояние судится раньше договорённости и её обхода.** Строка о неизменном поведении
|
|
145
|
+
снимает требование договорённости о продукте, а не требование дойти до правки кода.
|
|
118
146
|
- **Влитая договорённость ветку не запирает.** После вливания директории «предложено» на диске
|
|
119
147
|
нет, а замысел на неё ссылается до конца работы: гард отличает влитое от незаведённого по
|
|
120
148
|
истории ветки и пропускает первое. Иначе последний коммит PR закрывал бы дорогу правкам
|
|
@@ -143,29 +171,50 @@ flowchart TD
|
|
|
143
171
|
Открытый PR при этом читается как приглашение влить — поэтому незаконченная работа идёт
|
|
144
172
|
черновиком, и владельцу не приходится спрашивать, кончилась ли она. Черновик снимается тем
|
|
145
173
|
ходом, которым исполнитель говорит, что решение готово.
|
|
146
|
-
- **Открытый PR остановкой не является.** Отданное на разбор ждёт владельца, а не исполнителя:
|
|
147
|
-
следующая задача берётся тем же движением, которым предыдущая ушла на разбор. Заход,
|
|
148
|
-
закрытый на готовой задаче, стоил владельцу целого захода на то, чтобы вернуть работу в
|
|
149
|
-
движение, — при том что порядок был назначен и лежал записанным в замысле эпика.
|
|
150
|
-
- **Владельцу не предлагается выбор, чем заняться дальше, пока эпик не кончился.** Меню при
|
|
151
|
-
назначенном порядке — это просьба назначить его заново. Если работы в эпике не осталось, так
|
|
152
|
-
и говорится: эпик кончился, — а не «чем займёмся».
|
|
153
174
|
- **Гард замысла — нижняя граница требования, а не его предел.** Он требует папку только под
|
|
154
175
|
правку кода приложения, и работа, которая туда не доходит, проходит мимо него — но папку
|
|
155
176
|
заводит всё равно: статья правила говорит «под любую работу, без исключений». Прочитанный
|
|
156
177
|
как признак, гард становится разрешением работать без замысла везде, куда он не смотрит.
|
|
157
|
-
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
178
|
+
- **Сводка о чужом шаге.** Прогон, разбор владельцем и слияние идут без исполнителя и от взгляда
|
|
179
|
+
быстрее не становятся. Ход, кончившийся такой сводкой, владелец читает как работу: она полна,
|
|
180
|
+
в ней названы номера и состояния, и пустоты за ней не видно. О чужом шаге говорят вместе с
|
|
181
|
+
начатым своим, а не вместо него. За один заход это было нарушено четырежды, и готовая работа
|
|
182
|
+
простояла в невлитом PR почти три часа.
|
|
183
|
+
- **Меню при назначенном порядке.** Выбор, предложенный владельцу, пока эпик не кончился, — это
|
|
184
|
+
просьба назначить порядок заново. Работы в эпике не осталось — так и говорится: эпик
|
|
185
|
+
кончился, — а не «чем займёмся».
|
|
186
|
+
- **Объявление намерения.** «Беру следующую задачу» — не то же самое, что взять её: фраза живёт
|
|
187
|
+
до конца хода, а работа не двигается. Названо может быть только сделанное: номер заведённой
|
|
188
|
+
задачи, имя заведённой ветки, переведённая колонка.
|
|
189
|
+
|
|
190
|
+
- **Прерывание работы владельцем называется вслух.** Пришло задание, останавливающее начатое, —
|
|
191
|
+
исполнитель говорит, что стоит, на чём остановлено и что будет с прежней работой, и только
|
|
192
|
+
потом берётся за новое. Молчание об этом владелец читает как «прежнее кончилось».
|
|
193
|
+
- **Остановка называется отдельной репликой.** Не строкой в конце отчёта: там она тонет —
|
|
194
|
+
владелец читает отчёт как рассказ о сделанном. Называются три вещи: что стоит, чего оно ждёт
|
|
195
|
+
и что владелец может решить.
|
|
196
|
+
- **Выходы хода стережёт страж, а не память исполнителя.** Он читает объявленное состояние
|
|
197
|
+
работы и то, что за ход по ней сделано: правку файла или команду, меняющую дерево. Ход, в
|
|
198
|
+
котором не было ни того ни другого, возвращается исполнителю вместе со следующим шагом из
|
|
199
|
+
хода работы. Отданную и влитую работу страж не судит: она уже дождалась чужого шага.
|
|
200
|
+
- **Этап замысла объявляется закрытым только после того, как его команда проверки прошла.**
|
|
201
|
+
Строка «Чем проверяется» несёт команду обратными кавычками и то, что в её выводе означает
|
|
202
|
+
«сошлось». Страж читает прежний номер этапа из истории ветки и не выпускает ход, в котором
|
|
203
|
+
номер вырос, а команда не запускалась: через заход отмеченное по памяти неотличимо от
|
|
204
|
+
проверенного.
|
|
205
|
+
- **Слово об остановке страж читает у владельца, а не у исполнителя.** Иначе остановку
|
|
206
|
+
объявляет тот, кому она в эту минуту удобна, и запрет держится ровно до первого неудобства.
|
|
207
|
+
- **Утверждение о состоянии дерева стережёт гард утверждения, а не память исполнителя.** Всё,
|
|
208
|
+
что ответ владельцу говорит о дереве, несёт команду и её вывод: сказанное без команды
|
|
209
|
+
утверждением не считается — ни «проверено», ни «снято», ни «готово». Гард читает текст,
|
|
210
|
+
сказанный владельцу за ход, и ищет команду того же хода; у каждого слова назван свой род
|
|
211
|
+
команды, потому что общий признак «команда была» подтверждал бы одно другим. Прошлый ход не
|
|
212
|
+
годится: состояние дерева меняется, и вчерашний вывод о нынешнем молчит. Восемь разборов
|
|
213
|
+
подряд пришлись на этот промах, и каждый раз в правило дописывалась ещё одна статья —
|
|
214
|
+
держит его теперь машина.
|
|
215
|
+
- **Слово-утверждение гард ловит, неверный вывод — нет.** Об образце, судимом по одному его
|
|
216
|
+
файлу, и о пути, которым человек не пойдёт, судить нечем: там нет ни слова, ни команды, с
|
|
217
|
+
которой сверять. Это известная граница гарда, и держат её статьи ниже, а не он.
|
|
169
218
|
- **Ход о чужом шаге стережёт гард ожидания, а не память исполнителя.** Он отбивает завершение
|
|
170
219
|
хода, в котором о чужом шаге сказано, а по следующей задаче не сделано ни одного действия —
|
|
171
220
|
ни заведения задачи, ни ветки, ни папки, ни перевода колонки. Чужой шаг он узнаёт по двум
|
|
@@ -207,6 +256,10 @@ flowchart TD
|
|
|
207
256
|
случился, и ловить раньше нечего. Признание ловится набором образцов, а не пониманием смысла;
|
|
208
257
|
промах, признанный словами вне набора, гард пропускает, и это его известная граница, а не
|
|
209
258
|
обещание.
|
|
259
|
+
- **Заход, начатый с передачи, входит в работу тем же правилом, что и всякий другой.** Передача
|
|
260
|
+
лежит вне дерева, её не читает ни одна проверка, и написана она вчера: всё, что в ней стоит,
|
|
261
|
+
проверяется деревом. Порядок входа — четыре шага в паттерне возвращения; стережёт его гард, а
|
|
262
|
+
не память: порядок, записанный только словами, исполняется, пока о нём помнят.
|
|
210
263
|
- **Состояние незаконченной работы приходит в контекст на запуске сессии.** Замысел и ход
|
|
211
264
|
работы отдаются целиком, разбор просьбы — путём. Ветка вида `<КЛЮЧ>-*` без папки даёт
|
|
212
265
|
предупреждение с готовой командой, но сессию не рвёт.
|
|
@@ -256,13 +309,6 @@ flowchart TD
|
|
|
256
309
|
это заготовка правки чужого дерева, и часть заготовок отпадает при первом же чтении; уехавшая
|
|
257
310
|
без разбора, она становится работой того, кто её не заказывал. Сводка наблюдений уезжает
|
|
258
311
|
всегда: она говорит, чем пользовались и чем нет, и мнением не является.
|
|
259
|
-
- **Ожидание прогона работой не занимают.** Прогон идёт на стороне и быстрее от взгляда на него
|
|
260
|
-
не становится. Пока он идёт, берётся следующая задача, а к прогону возвращаются тем ходом,
|
|
261
|
-
которым читают его конец. Это верно и для разбора владельцем: оба ожидания — не повод стоять.
|
|
262
|
-
- **Остановка, если она всё-таки случилась, называется владельцу отдельной репликой.** Не
|
|
263
|
-
строкой в конце отчёта: там она тонет — владелец читает отчёт как рассказ о сделанном.
|
|
264
|
-
Называются три вещи: что стоит, чего оно ждёт и что владелец может решить — разобрать работу
|
|
265
|
-
первой или сказать, что прогона можно не ждать. Всё остальное идёт после.
|
|
266
312
|
- **Договорённость вливается в спек домена последним коммитом PR.** К этому моменту код
|
|
267
313
|
написан, привязки известны, и в главной ветке директория `proposed/` не появляется вовсе.
|
|
268
314
|
Готовые к вливанию перечисляет `npm run check:specs`.
|
|
@@ -357,6 +403,12 @@ flowchart TD
|
|
|
357
403
|
задаче так ушли две правки подряд: сначала подняли общее число у соседнего узла, потом
|
|
358
404
|
перенесли узел в другое место разметки. Обе владелец отверг, а нужный способ назвал сам.
|
|
359
405
|
Спрашивают до правки, а не показывают замер после.
|
|
406
|
+
- **Путь, предложенный человеку, судится числом его шагов и тем, чем ему для этого надо
|
|
407
|
+
владеть.** Со стороны кода вариант выглядит дешёвым — «меньше путей», «строку запуска не
|
|
408
|
+
трогаем», — а человеку он стоит захода на сервер. Однажды рекомендуемым вариантом так стояла
|
|
409
|
+
выдача токена, за которой владельцу надо было идти по ssh в работающий контейнер; отбивал
|
|
410
|
+
этот вариант он сам. Цена называется со стороны того, кто пойдёт: сколько шагов и что ему для
|
|
411
|
+
них нужно. Пересказ действующего порядка без такой оценки владелец читает как одобрение.
|
|
360
412
|
- **Эпик по теме читается до того, как решается раскладка.** Замысел эпика держит решения,
|
|
361
413
|
которые пережили десяток задач, и разведка по коду их не находит: снятое решение следа в
|
|
362
414
|
дереве не оставляет. Домен, заведённый генератором и снесённый через полчаса, стоял в замысле
|
package/assets/rules/testing.md
CHANGED
|
@@ -113,6 +113,20 @@ flowchart TD
|
|
|
113
113
|
принятое остаётся навсегда, долг накоплен к заведению проверки и только сокращается, — либо
|
|
114
114
|
столько ключей, сколько у записей родов. Причина обязательна: снятая проверка без причины
|
|
115
115
|
через месяц неотличима от недосмотра.
|
|
116
|
+
- **Запись принятого отличается от долга тем, заведена ли на неё работа.** Принятое — то, что
|
|
117
|
+
дерево делить не собирается; долг — то, на что заведена задача, и он только сокращается. Один
|
|
118
|
+
список на оба означал бы, что разбирать нечего: запись без задачи через месяц читается как
|
|
119
|
+
вечная, а запись с задачей — как недосмотр.
|
|
120
|
+
- **У каждой записи стоят своя причина и номер задачи, которой она внесена.** Причина прозой на
|
|
121
|
+
весь список объясняет любую его строку и потому не объясняет ни одной, а запись без номера не
|
|
122
|
+
спросишь ни у кого: тот, кто её внёс, к этому дню не помнит ни повода, ни своего решения.
|
|
123
|
+
Запись без причины или без номера отбивает проверку — и заводится она словом владельца, а не
|
|
124
|
+
решением исполнителя, которому она в эту минуту мешает.
|
|
125
|
+
- **У красного есть назначенное действие, и второй перезапуск в него не входит.** Красное бывает
|
|
126
|
+
двух родов, и в списке прогонов они выглядят одинаково: отказ хостинга на шаге подготовки
|
|
127
|
+
лечится перезапуском, дефект ветки — не лечится им вовсе. Назначенное действие одно: сперва
|
|
128
|
+
журнал этого задания, потом решение. Перезапуск, повторённый до чтения журнала, чинит не
|
|
129
|
+
причину, а её проявление, и в истории выглядит работой.
|
|
116
130
|
- **Строка в список известного не заводится под красную проверку.** Список набран к дню
|
|
117
131
|
заведения проверки и с тех пор только сокращается: дописанная строка гасит сигнал, а не
|
|
118
132
|
причину, и в истории выглядит так же, как починка. Место, где проверка права по букве и не
|
|
@@ -187,7 +201,7 @@ flowchart TD
|
|
|
187
201
|
чего в спеке домена нет и быть не должно: `qa-dataid` элементов, состояния разметки, ловушки
|
|
188
202
|
стенда. Обещанное поведение остаётся сценарием в `scenarios.md`: если списать его во второе
|
|
189
203
|
место, копии разойдутся молча — `npm run check:specs` этого не увидит.
|
|
190
|
-
- `npx nx serve` проверкой не
|
|
204
|
+
- `npx nx serve` проверкой не считается: это шаг из правила `browser-verification`, а не тест.
|
|
191
205
|
- **Кадр, зависящий от загрузки машины, проверяет машину, а не вёрстку.** Ожидание отсчётом
|
|
192
206
|
времени этим и кончается: на свободной машине набор зелен целиком, на занятой падает, и какой
|
|
193
207
|
именно кадр не успел — дело случая. Лечится ожиданием события, а не удлинением отсчёта: шрифты
|
|
@@ -32,7 +32,10 @@
|
|
|
32
32
|
|
|
33
33
|
- **Что делается:** <одной фразой>
|
|
34
34
|
- **Признак готовности:** <что должно стать верным>
|
|
35
|
-
- **Чем проверяется:**
|
|
35
|
+
- **Чем проверяется:** `<команда>` — <что в её выводе означает «сошлось»>
|
|
36
|
+
|
|
37
|
+
Команда пишется обратными кавычками: страж выходов хода читает её и не выпускает ход, в котором
|
|
38
|
+
этап объявлен закрытым, а команда не запускалась. Приём, записанный прозой, подтвердить нечем.
|
|
36
39
|
|
|
37
40
|
## Чего эта работа не делает
|
|
38
41
|
|