@rt-tools/agent-kit 0.16.1 → 0.18.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/assets/checks/board-epics.github.mjs +123 -0
- package/assets/checks/board-gh.github.mjs +121 -0
- package/assets/checks/board-paths.github.mjs +88 -0
- package/assets/checks/board-runs.github.mjs +8 -0
- package/assets/checks/board-titles.github.mjs +66 -0
- package/assets/checks/board.github.mjs +77 -73
- package/assets/checks/check-board.github.mjs +56 -7
- package/assets/checks/check-file-size.mjs +10 -2
- package/assets/checks/check-glossary.mjs +170 -0
- package/assets/checks/check-hook-scope.mjs +126 -0
- package/assets/checks/check-profile-drift.mjs +195 -0
- package/assets/checks/check-push-gate.mjs +59 -1
- package/assets/checks/check-schema-drift.mjs +12 -5
- package/assets/checks/check-specs.mjs +1 -1
- package/assets/checks/rt-kit-checks.config.mjs +13 -0
- package/assets/checks/spec-anchors.mjs +2 -2
- package/assets/checks/spec-contract.mjs +9 -0
- package/assets/defaults/gate-map.sh +13 -4
- package/assets/defaults/project.sh +31 -108
- package/assets/defaults/shell.sh +139 -0
- package/assets/docs/GLOSSARY.md +1 -1
- package/assets/hooks/browser-device-id.sh +20 -4
- package/assets/hooks/browser-guard-device-id.sh +5 -2
- package/assets/hooks/browser-guard-no-other-drivers.sh +41 -2
- package/assets/hooks/claim-guard.sh +22 -1
- package/assets/hooks/docs-guard.sh +1 -1
- package/assets/hooks/exam-guard.sh +85 -12
- package/assets/hooks/git-guard-delivery-conflict.sh +85 -0
- package/assets/hooks/git-guard-delivery-folder.sh +19 -0
- package/assets/hooks/git-guard-delivery-signature.sh +14 -5
- package/assets/hooks/git-guard-delivery.sh +54 -2
- package/assets/hooks/git-guard-push-tests.sh +21 -1
- package/assets/hooks/grill-gate-ask.sh +25 -0
- package/assets/hooks/grill-gate.sh +75 -11
- package/assets/hooks/lint-after-edit.sh +44 -16
- package/assets/hooks/proposal-guard.sh +11 -4
- package/assets/hooks/rule-source-guard.sh +8 -13
- package/assets/hooks/skill-gate-layers.sh +7 -0
- package/assets/hooks/skill-gate.sh +29 -0
- package/assets/hooks/task-context-load.sh +32 -0
- package/assets/hooks/task-flow-context.sh +194 -0
- package/assets/hooks/task-flow-draft-guard.sh +109 -0
- package/assets/hooks/task-flow-guard.sh +27 -159
- package/assets/hooks/turn-exit-guard.sh +53 -88
- package/assets/hooks/waiting-turn-guard.sh +65 -2
- package/assets/hooks/window-fill-guard.sh +5 -1
- package/assets/hooks/work-start-guard.sh +166 -0
- package/assets/hooks/write-targets.sh +24 -0
- package/assets/laws/delivery.md +19 -0
- package/assets/laws/frontend-application.md +4 -0
- package/assets/laws/verifiability.md +44 -0
- package/assets/laws/work-conduct.md +15 -0
- package/assets/patterns/browser-verification-measure.md +3 -1
- package/assets/patterns/browser-verification-stand.md +17 -4
- package/assets/patterns/doc-style-write.md +62 -2
- package/assets/patterns/git-workflow-commit.github.md +33 -5
- package/assets/patterns/git-workflow-docker.md +22 -0
- package/assets/patterns/git-workflow-freshness.md +87 -0
- package/assets/patterns/git-workflow-merge.md +41 -0
- package/assets/patterns/git-workflow-migration.md +11 -0
- package/assets/patterns/git-workflow-pr.github.md +12 -1
- package/assets/patterns/git-workflow-restart.md +18 -0
- package/assets/patterns/git-workflow-secrets.md +14 -0
- package/assets/patterns/git-workflow-stack.md +93 -1
- package/assets/patterns/lib-layers-move.md +4 -0
- package/assets/patterns/spec-driven-domain.md +47 -2
- package/assets/patterns/spec-driven-rule.md +16 -4
- package/assets/patterns/spec-driven-sweep.md +57 -0
- package/assets/patterns/status-report-table.github.md +1 -1
- package/assets/patterns/task-flow-archive.md +58 -16
- package/assets/patterns/task-flow-close.md +106 -23
- package/assets/patterns/task-flow-handoff.md +14 -2
- package/assets/patterns/task-flow-resume.md +35 -8
- package/assets/patterns/task-flow-start.md +60 -22
- package/assets/patterns/testing-e2e.md +23 -0
- package/assets/patterns/turn-entry-map.md +1 -1
- package/assets/pitfalls/agent-kit.md +71 -3
- package/assets/pitfalls/doc-style.md +15 -0
- package/assets/pitfalls/git-workflow.github.md +88 -0
- package/assets/pitfalls/spec-driven.md +22 -0
- package/assets/pitfalls/task-flow.md +113 -0
- package/assets/pitfalls/testing.md +6 -0
- package/assets/pitfalls/turn-conduct.md +49 -0
- package/assets/rules/browser-verification.md +58 -0
- package/assets/rules/deploy-flow.azure.md +8 -0
- package/assets/rules/deploy-flow.github.md +27 -0
- package/assets/rules/deploy-flow.gitlab.md +8 -0
- package/assets/rules/doc-style.md +20 -0
- package/assets/rules/git-workflow.azure.md +22 -2
- package/assets/rules/git-workflow.github.md +127 -118
- package/assets/rules/git-workflow.gitlab.md +17 -4
- package/assets/rules/lists.md +5 -0
- package/assets/rules/observability.needs-app.md +4 -0
- package/assets/rules/reuse-first.md +14 -0
- package/assets/rules/shared-code.md +5 -0
- package/assets/rules/spec-driven.md +33 -15
- package/assets/rules/task-flow.md +132 -126
- package/assets/rules/testing.md +41 -2
- package/assets/rules/turn-conduct.md +73 -57
- package/assets/rules/turn-entry.md +6 -0
- package/assets/samples/tasks/_template/grill.md +5 -0
- package/assets/samples/tasks/_template/plan.md +3 -0
- package/assets/skills/agent-kit.md +108 -76
- package/assets/templates/postmortem.md +5 -1
- package/bin/agent-kit.d.ts.map +1 -1
- package/bin/agent-kit.js +30 -6
- package/bin/agent-kit.js.map +1 -1
- package/lib/catalog.d.ts.map +1 -1
- package/lib/catalog.js +2 -1
- package/lib/catalog.js.map +1 -1
- package/lib/commands.d.ts.map +1 -1
- package/lib/commands.js +96 -7
- package/lib/commands.js.map +1 -1
- package/lib/hooks-map.d.ts +26 -0
- package/lib/hooks-map.d.ts.map +1 -1
- package/lib/hooks-map.js +58 -2
- package/lib/hooks-map.js.map +1 -1
- package/lib/sections.d.ts +6 -0
- package/lib/sections.d.ts.map +1 -1
- package/lib/sections.js +19 -0
- package/lib/sections.js.map +1 -1
- package/lib/shipment.d.ts +2 -0
- package/lib/shipment.d.ts.map +1 -1
- package/lib/shipment.fixture.d.ts +5 -0
- package/lib/shipment.fixture.d.ts.map +1 -1
- package/lib/shipment.fixture.js +7 -0
- package/lib/shipment.fixture.js.map +1 -1
- package/lib/shipment.js +13 -1
- package/lib/shipment.js.map +1 -1
- package/lib/sync.d.ts +35 -3
- package/lib/sync.d.ts.map +1 -1
- package/lib/sync.js +59 -8
- package/lib/sync.js.map +1 -1
- package/package.json +1 -1
- package/rt-tools-agent-kit-0.18.0.tgz +0 -0
- package/rt-tools-agent-kit-0.16.1.tgz +0 -0
|
@@ -12,14 +12,22 @@ description: Паттерн правила task-flow. Брать при дове
|
|
|
12
12
|
|
|
13
13
|
## Когда брать
|
|
14
14
|
|
|
15
|
-
- Этапы замысла
|
|
15
|
+
- Этапы замысла закрыты.
|
|
16
16
|
- `npm run check:specs` перечислил договорённость в разделе «Пора вливать».
|
|
17
|
+
- Спек меряется длиной сразу после вливания: выросший делится тем же коммитом.
|
|
17
18
|
- Тексты домена приводятся к тому, что работа сделала.
|
|
19
|
+
- Набор гейта прогнан целиком — после вливания и приведения текстов, а не до них.
|
|
18
20
|
- Папка задачи разобрана, и заявка открывается черновиком.
|
|
19
21
|
- Прогон на вершине зелёный, и с заявки снимается черновик.
|
|
20
22
|
|
|
21
23
|
Разбор самой папки сюда не относится — это паттерн `task-flow-archive`. Он стоит между
|
|
22
|
-
|
|
24
|
+
прогоном набора и открытием заявки: заявка открывается уже за убранной работой.
|
|
25
|
+
|
|
26
|
+
**Прогон стоит после вливания договорённости и приведения текстов, а не перед ними.** Оба этих
|
|
27
|
+
шага стоят минуты, а прогон — окно захода: заход, потративший его на прогон, упирался в порог
|
|
28
|
+
заполнения на четырёх строках привязки, и дописать их было уже нечем. Второй довод сильнее
|
|
29
|
+
первого — прогон, идущий после вливания, проверяет и само вливание; идущий до него, он смотрит
|
|
30
|
+
то состояние дерева, которое в главную ветку не поедет.
|
|
23
31
|
|
|
24
32
|
## Состояние `этапы-кончились`: договорённость вливается в спек домена
|
|
25
33
|
|
|
@@ -30,11 +38,19 @@ description: Паттерн правила task-flow. Брать при дове
|
|
|
30
38
|
npm run check:specs # раздел «Пора вливать» называет готовые директории
|
|
31
39
|
```
|
|
32
40
|
|
|
41
|
+
**Спек меряется длиной тем же ходом.** Вливание — известное движение, растящее спек: одно
|
|
42
|
+
довело его до 572 строк при пределе 500, и узнал об этом исполнитель отказом гарда пуша, то
|
|
43
|
+
есть после коммита. Выросший делится на поддомены здесь же, а не на пуше.
|
|
44
|
+
|
|
33
45
|
Порядок переезда:
|
|
34
46
|
|
|
35
47
|
- правила из `proposed/<фича>/spec.md` дописываются в `spec.md` домена, в его разделы;
|
|
36
48
|
- сценарии переезжают в `scenarios.md` домена **с прежними номерами**: на них ссылаются
|
|
37
49
|
заголовки тестов, и пересчёт рвёт сверку;
|
|
50
|
+
- сценарии, у которых работа переписала обещание, правятся на месте: номер прежний, текст
|
|
51
|
+
новый, заголовок теста правится тем же коммитом. Работа, снимающая приём, переписывает уже
|
|
52
|
+
записанное обещание чаще, чем заводит новое, а список, перечисляющий одну допись, эту правку
|
|
53
|
+
не называет вовсе;
|
|
38
54
|
- привязки из `proposed/<фича>/implementation.md` дописываются в `implementation.md` домена
|
|
39
55
|
и проставляются на код, который теперь есть;
|
|
40
56
|
- законы, объявленные фичей в шапке, дописываются в шапку спека домена;
|
|
@@ -103,11 +119,60 @@ grep -rn -A3 "Чего из закона здесь нет" <каталог пр
|
|
|
103
119
|
работа ждёт владельца, а не машину, и заход на этом не кончается: следующая задача берётся тем
|
|
104
120
|
же движением, паттерн `task-flow-resume`.
|
|
105
121
|
|
|
122
|
+
**Готовность меряется рассказанностью, а не пройденностью.** Перечень того, что сделано к
|
|
123
|
+
открытию, читается как список обязательных проверок, и границы у него не видно. Она есть:
|
|
124
|
+
проверка, которую исполнитель не может пройти по причине вне работы — отбитое разрешение,
|
|
125
|
+
недоступная среда, ключ у человека, — готовность не отменяет. Она попадает в «Не гонялось» и в
|
|
126
|
+
«Оставшийся шаг», названная вместе с причиной; умолчание о ней читается как пройденная.
|
|
127
|
+
|
|
106
128
|
Состояния на диске уже нет — ход работы уехал вместе с папкой. Это цена того, что уборка стоит
|
|
107
129
|
до заявки: хвост из четырёх шагов — открыть заявку, дождаться прогона, снять черновик, попросить
|
|
108
130
|
влить — держится этим паттерном, а не строкой в файле. Гард признаёт работу отданной по истории
|
|
109
131
|
ветки: папка, снятая её коммитом, и есть признак.
|
|
110
132
|
|
|
133
|
+
### Раздел об оставшемся шаге пишется в теле заявки, а не дописывается потом
|
|
134
|
+
|
|
135
|
+
Он стоит там с минуты открытия. Сказанного вслух мало, и одним этим требование не держится:
|
|
136
|
+
реплика живёт до следующей реплики, а решение о слиянии принимается на странице заявки — там
|
|
137
|
+
переписки нет вовсе. Владелец вливает, как только видит зелёное, и заявка, открытая без раздела,
|
|
138
|
+
уезжает в главную ветку раньше, чем раздел успевают дописать: так папка задачи однажды и уехала
|
|
139
|
+
неразобранной, пока шёл прогон. Раздел стоит последним и говорит ровно одно: осталось ли что-то
|
|
140
|
+
до слияния.
|
|
141
|
+
|
|
142
|
+
```markdown
|
|
143
|
+
## Оставшийся шаг
|
|
144
|
+
|
|
145
|
+
Папка задачи разобрана коммитом `<sha>` — за работой убрано. Осталось дождаться прогона и снять
|
|
146
|
+
черновик; до этого кнопка слияния заблокирована хостингом.
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Черновик снят — раздел переписывается тем же вызовом, которым правится тело:
|
|
150
|
+
|
|
151
|
+
```markdown
|
|
152
|
+
## Оставшийся шаг
|
|
153
|
+
|
|
154
|
+
Не осталось: прогон зелёный, черновик снят. Можно вливать.
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Заголовок раздела и слова обоих образцов пишутся языком заявки, а не языком паттерна. Образцы
|
|
158
|
+
набраны тем языком, которым написан сам паттерн, и переносятся целиком — порядок мыслей,
|
|
159
|
+
формулировки и заголовок, заголовок последним: он выглядит частью формы, а не частью текста.
|
|
160
|
+
То же верно и для двух сообщений владельцу ниже: они образцы того, **что** сказано, а не того,
|
|
161
|
+
какими словами.
|
|
162
|
+
|
|
163
|
+
Пустым раздел не оставляется и не удаляется вовсе: отсутствие раздела и «шагов не осталось»
|
|
164
|
+
читаются одинаково, а значат разное. Образец тела заявки целиком — в паттерне заведения коммита
|
|
165
|
+
и заявки, если дерево его разложило.
|
|
166
|
+
|
|
167
|
+
Держит это гард поставки, а не память пишущего: он читает тело прямо из команды открытия —
|
|
168
|
+
доводом оно передано или файлом — и отбивает вызов вместе с остальным несошедшимся. Образец
|
|
169
|
+
заголовка при этом называет дерево, потому что заголовок пишется языком заявки, а пакет чужих
|
|
170
|
+
слов не знает; не названный, раздел не судится вовсе. Сверка очереди работ тела по-прежнему не
|
|
171
|
+
читает: промах ловится в минуту открытия, то есть там, где он ещё исправим одним вызовом.
|
|
172
|
+
|
|
173
|
+
Разница между разделом и сказанным вслух одна, и она вся: реплику владелец прочитает, только
|
|
174
|
+
если вернётся в переписку, а раздел он видит там, куда смотрит, нажимая кнопку.
|
|
175
|
+
|
|
111
176
|
### Два сообщения владельцу, и между ними — прогон
|
|
112
177
|
|
|
113
178
|
Оба обязательны, и порядок между ними один. Ни одно не заменяется другим: первое говорит, что
|
|
@@ -175,6 +240,12 @@ PR #<номер> готов к слиянию: прогон зелёный, че
|
|
|
175
240
|
читаются одинаково, а значат разное. Образец тела заявки целиком — в паттерне заведения коммита
|
|
176
241
|
и заявки, если дерево его разложило.
|
|
177
242
|
|
|
243
|
+
Открытая заявка перечитывается той записью, которая будет её вливать, а не той, что её открыла.
|
|
244
|
+
Ответ хостинга автору говорит лишь, что вызов прошёл: право на открытие и видимость открытого —
|
|
245
|
+
разные вещи, и вторая проверяется только со стороны читателя. Невидимая заявка ничем себя не
|
|
246
|
+
выдаёт — она есть в ответе своему автору, у неё стоят метки, а очередь разбора у владельца просто
|
|
247
|
+
пуста.
|
|
248
|
+
|
|
178
249
|
Проверить это машиной нечем, и проверки не будет: тело заявки не читает ни одна сверка, а
|
|
179
250
|
хостинг не спрашивает ни о чём, кроме заголовка. Требование держится тем же, чем и слова
|
|
180
251
|
вслух, — тем, кто пишет тело. Разница между ними одна, и она вся: реплику владелец прочитает,
|
|
@@ -186,29 +257,41 @@ PR #<номер> готов к слиянию: прогон зелёный, че
|
|
|
186
257
|
нет, и собирать папку заново не надо: гард хода работы пропускает правку по признаку из истории
|
|
187
258
|
ветки. Что именно чинится, берётся из замечания, а не из замысла.
|
|
188
259
|
|
|
260
|
+
Главная ветка, влитая ради того, чтобы что-то посмотреть, — такая же правка, как влитая ради
|
|
261
|
+
работы, и уезжает тем же ходом. Слияние, оставшееся в рабочей копии, либо пушится тем же ходом,
|
|
262
|
+
либо не делается — иначе владелец видит прежнее состояние и решает по нему.
|
|
263
|
+
|
|
189
264
|
**Следующее движение:** прогон зелёный и замечаний нет — черновик снимается, и владельцу
|
|
190
265
|
говорится, что работа готова.
|
|
191
266
|
|
|
192
|
-
##
|
|
193
|
-
|
|
194
|
-
- **Тексты правятся до разбора
|
|
195
|
-
|
|
196
|
-
-
|
|
197
|
-
|
|
198
|
-
|
|
267
|
+
## Частые промахи
|
|
268
|
+
|
|
269
|
+
- **Тексты правятся до разбора папки:** список того, что перечитывать, лежит в замысле, а разбор
|
|
270
|
+
папки его удаляет.
|
|
271
|
+
- **Запись раздела решений, повторяющая статью правила слово в слово, доводом при ней не
|
|
272
|
+
считается.** Правило приходит в контекст само, спек — только когда его открыли; пара расходится
|
|
273
|
+
молча. Такая запись уезжает целиком, даже если раздел пустеет; довод, в статье не сказанный,
|
|
274
|
+
дописывается в статью.
|
|
275
|
+
- **Тело заявки остаётся старше разбора папки.** Разбор — последний коммит ветки, и он делает
|
|
276
|
+
неправдой всё, что тело обещало сделать до слияния. Ревьювер читает список оставшегося как
|
|
277
|
+
оставшееся, поэтому тело правится тем же ходом.
|
|
278
|
+
- **Утверждение правила снимается вместе со строкой привязки.** Связь идёт по тексту: строка без
|
|
279
|
+
утверждения и утверждение без строки одинаково краснят сверку спеков.
|
|
199
280
|
- **Раздел «Чего из закона здесь нет» читается глазами, греп тут не помогает.** Искать
|
|
200
|
-
приходится не то слово, которое ждёшь: правило ссылалось на
|
|
201
|
-
|
|
202
|
-
- **Сказать «сверено», не открыв файл, нельзя.** Правило читается
|
|
203
|
-
|
|
281
|
+
приходится не то слово, которое ждёшь: правило ссылалось на статью, которой в законе нет, и по
|
|
282
|
+
слову своей темы эта строка находилась — а неправда была в другом.
|
|
283
|
+
- **Сказать «сверено», не открыв файл, нельзя.** Правило читается целиком: устаревшее утверждение
|
|
284
|
+
стоит среди верных и ничем от них не отличается.
|
|
204
285
|
- **Вливание после мержа не делается.** В главной ветке тогда лежит раздел «предложено, но не
|
|
205
|
-
выкачено» с тем, что работает
|
|
206
|
-
- **Номера сценариев при вливании не пересчитываются.** Идентификатор — ключ связи с
|
|
207
|
-
сдвиг рвёт сверку у
|
|
208
|
-
- **«Что не входит» после вливания читается целиком, а не дописывается.**
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
-
|
|
214
|
-
|
|
286
|
+
выкачено» с тем, что работает месяц: беззвучная ложь, тем убедительнее, чем старше.
|
|
287
|
+
- **Номера сценариев при вливании не пересчитываются.** Идентификатор — ключ связи с тестами, и
|
|
288
|
+
сдвиг рвёт сверку у соседей.
|
|
289
|
+
- **«Что не входит» после вливания читается целиком, а не дописывается.** Границы фичи ложатся
|
|
290
|
+
рядом с границами домена: половина повторяет стоявшее другими словами, а строка «этого раздела
|
|
291
|
+
ещё нет» становится ложью той работой, которая её вливает. Сверка спеков туда не смотрит.
|
|
292
|
+
- **Своя строка сверки очереди ищется по имени** — по номеру задачи и имени ветки: сверка
|
|
293
|
+
отвечает про всё дерево, и на одном закрытии чужих папок было восемь при одной своей.
|
|
294
|
+
- **Пара «метка объёма и строка в замысле эпика» рвётся с двух сторон:** задача по следу закрытой
|
|
295
|
+
наследует метку без строки о заходах, а закрытый эпик уносит строку у всех, кто её несёт.
|
|
296
|
+
- **Правило без привязки в спек домена не въезжает.** Кода, который его исполняет, нет — значит
|
|
297
|
+
это намерение, и место ему в открытых вопросах домена.
|
|
@@ -89,6 +89,8 @@ mkdir -p <каталог передачи>
|
|
|
89
89
|
```markdown
|
|
90
90
|
Работа: <КЛЮЧ>-<номер> «<название задачи>». Рабочее дерево — <полный путь>, ветка
|
|
91
91
|
<КЛЮЧ>-<номер>-<slug> (заведена, в работе).
|
|
92
|
+
Заявка: #<номер>, открыта, ждёт разбора владельцем. Свежесть её основания здесь не записана
|
|
93
|
+
намеренно — она протухает; спрашивается она у хранилища первым делом нового захода.
|
|
92
94
|
|
|
93
95
|
Ход работы и замысел придут на запуске сессии хуком — перечитывать их файлами не надо. Разбор
|
|
94
96
|
просьбы владельца лежит в папке задачи и читается, когда непонятна причина решения.
|
|
@@ -128,7 +130,8 @@ mkdir -p <каталог передачи>
|
|
|
128
130
|
|
|
129
131
|
Разделы фиксированы, и порядок у них тот же:
|
|
130
132
|
|
|
131
|
-
1. **Работа** — номер задачи, её название, рабочее дерево полным путём, ветка и её
|
|
133
|
+
1. **Работа** — номер задачи, её название, рабочее дерево полным путём, ветка и её состояние; у
|
|
134
|
+
отданной работы — номер открытой заявки и то, чего она ждёт.
|
|
132
135
|
2. **Где искать** — что придёт хуком само, а что читается по надобности.
|
|
133
136
|
3. **Эпик** — таблица положения; у работы вне эпика раздела нет.
|
|
134
137
|
4. **Сделано и следующий шаг** — одной строкой каждое; подробности уже в ходе работы.
|
|
@@ -142,14 +145,23 @@ mkdir -p <каталог передачи>
|
|
|
142
145
|
заход одной вставкой. Пересказывать содержание передачи в ответе не надо: владелец её и так
|
|
143
146
|
прочитает, а место на неё уже потрачено.
|
|
144
147
|
|
|
145
|
-
##
|
|
148
|
+
## Частые промахи
|
|
146
149
|
|
|
147
150
|
- **Заход закрывается на втором пороге, а не начинает на нём новый этап.** Напоминание на
|
|
148
151
|
первом — это уже сигнал выбирать точку, а не работать дальше, пока не отобьют.
|
|
149
152
|
- **Передача пишется как пересказ переписки.** В неё идёт то, чего нет ни в ходе работы, ни в
|
|
150
153
|
правилах: дерево, ветка, состояние стендов. Всё остальное следующий заход прочитает сам.
|
|
154
|
+
- **Утверждение о состоянии работы берётся в тот же ход, а не вспоминается.** Родитель задачи,
|
|
155
|
+
её колонка, открытая заявка, влитая ветка, поднятые стенды живут вне захода и меняются без
|
|
156
|
+
него, а передача читается первой и не оспаривается: заход исполняет её указание, а не проверяет
|
|
157
|
+
его. Правдоподобие подтверждением не считается — «ветка не влита, значит и родителя нет» это
|
|
158
|
+
вывод, а не замер. Спросить нечем — так и пишется вопросом: «родитель не проверен, проверить
|
|
159
|
+
перед заявкой».
|
|
151
160
|
- **Состояние работы в передачу не переезжает.** Сделанное отмечается в ходе работы — одной
|
|
152
161
|
записью; передача его пересказывает, но не заменяет и в дерево не коммитится.
|
|
162
|
+
- **В передачу записано состояние, которое живёт часами.** Отставание от главной ветки, ход
|
|
163
|
+
прогона и «проверки зелёные» новый заход читает как верное сегодня. В передачу идёт то, что не
|
|
164
|
+
меняется без участия исполнителя: дерево, ветка, номер заявки, что не закоммичено.
|
|
153
165
|
- **Незакоммиченное не названо.** Работа живёт в дереве неделями, и строка «что лежит
|
|
154
166
|
несохранённым и почему» — единственное, по чему это видно.
|
|
155
167
|
- **Заход, кончившийся ничем, тоже пишет передачу.** «Пробовали так — не вышло, потому что» —
|
|
@@ -27,11 +27,21 @@ description: Паттерн правила task-flow. Брать при возв
|
|
|
27
27
|
образца, а `progress.md` заполняется по тому, что видно в дереве и в истории ветки, а не по
|
|
28
28
|
расспросам владельца.
|
|
29
29
|
|
|
30
|
+
Пришло «РАБОТА ЗАКРЫВАЕТСЯ» — папку разобрала сама ветка перед заявкой, и собирать её заново не
|
|
31
|
+
надо: состояние работы читается у заявки и в передаче захода. Понадобилась правка кода по
|
|
32
|
+
замечаниям разбора — папка восстанавливается на время правки, а разбор повторяется тем же
|
|
33
|
+
коммитом.
|
|
34
|
+
|
|
30
35
|
## Чего не делать
|
|
31
36
|
|
|
32
37
|
- **Не спрашивать владельца о том, что записано.** Ради этого всё и заведено.
|
|
33
38
|
- **Не начинать заново то, что отмечено сделанным.** Отметка стоит в ходе работы; сомнение в
|
|
34
39
|
ней проверяется деревом — сборкой, тестами, чтением файла, — а не вопросом.
|
|
40
|
+
- **Не выводить записанное заново из кода.** Запрет на вопрос этого не покрывает: решение,
|
|
41
|
+
выведенное из кода и поданное находкой, обходится дороже лишнего вопроса — владельцу
|
|
42
|
+
предлагают принять заново то, что он уже принял, и список вариантов звучит убедительнее
|
|
43
|
+
записи, которой он не видит. Прежде чем выводить, ищут в разборе просьбы, в ходе работы и в
|
|
44
|
+
замысле.
|
|
35
45
|
- **Не править замысел.** С ним сверяют результат; пересмотр идёт записью в ходе работы.
|
|
36
46
|
|
|
37
47
|
## Вход из передачи захода
|
|
@@ -134,19 +144,25 @@ git log --oneline origin/main..HEAD
|
|
|
134
144
|
Берётся, а не выбирается: порядок назначен на планировании и лежит в замысле эпика. Выбор,
|
|
135
145
|
предложенный владельцу при назначенном порядке, — просьба назначить его заново.
|
|
136
146
|
|
|
147
|
+
У работы вне эпика замысла с порядком нет, и следующая берётся из очереди работ — тем же
|
|
148
|
+
движением и с тем же запретом на выбор вслух: очередь спрашивается командой, а не памятью о том,
|
|
149
|
+
что заводил сам исполнитель. Пусто в очереди — это утверждение о дереве, и подтверждается оно
|
|
150
|
+
выводом команды.
|
|
151
|
+
|
|
137
152
|
```bash
|
|
138
153
|
# что назначено следующим — читается в замысле эпика, а не спрашивается
|
|
139
154
|
# состояние задач — в очереди работ: замысел о закрытом не знает
|
|
140
155
|
```
|
|
141
156
|
|
|
142
157
|
Останавливает заход только предел заполнения окна — тогда идёт передача, паттерн
|
|
143
|
-
`task-flow-handoff`.
|
|
144
|
-
что кончился именно эпик, а не одна его
|
|
158
|
+
`task-flow-handoff`. Кончившийся эпик поводом остановиться не бывает: работа берётся вне его —
|
|
159
|
+
из очереди работ, — а владельцу тем же ходом называется, что кончился именно эпик, а не одна его
|
|
160
|
+
задача. Он называется вместе со взятой работой, а не вместо неё.
|
|
145
161
|
|
|
146
162
|
**Следующее движение:** по следующей задаче делается действие — заведена задача, ветка или
|
|
147
163
|
папка. Ход кончается после него, а не после слов о нём.
|
|
148
164
|
|
|
149
|
-
##
|
|
165
|
+
## Частые промахи
|
|
150
166
|
|
|
151
167
|
- **Заход, кончившийся ничем, тоже записывается.** Иначе следующий пойдёт той же дорогой:
|
|
152
168
|
«пробовали так — не вышло, потому что» стоит одной строки и экономит целый заход.
|
|
@@ -154,10 +170,21 @@ git log --oneline origin/main..HEAD
|
|
|
154
170
|
несохранённым и почему» — единственное, по чему это видно, пока PR нет.
|
|
155
171
|
- **Подтверждение — вывод команды или замер, а не пересказ.** «Проверил, работает» через
|
|
156
172
|
заход неотличимо от «казалось, что работает».
|
|
157
|
-
- **Число из передачи пересчитывается
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
173
|
+
- **Число из передачи и из «Где стоим» пересчитывается перед тем, как попасть в любой новый
|
|
174
|
+
текст.** Не только перед делением работы: перенесённое в разбор просьбы или в ход работы, оно
|
|
175
|
+
читается следующими заходами как замер и не проверяется больше никем. Передача описывает
|
|
176
|
+
день, когда её писали, лежит вне дерева, и не читает её ни одна проверка. Счёт, взятый
|
|
177
|
+
непересчитанным, разошёлся с деревом на восемь и нашёлся сценарием подсчёта, а не чтением; та
|
|
178
|
+
же цена у оценки «работы вдвое больше предыдущей» — на текущем коммите объёмы оказались почти
|
|
179
|
+
равны. Пересчёт стоит одной команды, и в текст едет своё число.
|
|
162
180
|
- **Доэтапное отделяется от своего.** Красное, найденное по дороге и не этой работой
|
|
163
181
|
сделанное, помечается таковым сразу: иначе следующий заход примет его за свою поломку.
|
|
182
|
+
- **Разбор, написанный этим заходом, требованием для него не становится.** Запись объясняет
|
|
183
|
+
механизм, а исполняется он тем же, чем исполнялось прежнее, — вниманием того, кто ведёт ход:
|
|
184
|
+
через один ход после записи механизм повторился в той же форме. Поэтому разбор кончается не
|
|
185
|
+
текстом, а тем, что из него вышло: правкой ресурса, гардом или предложением с адресом. Заход,
|
|
186
|
+
дописавший разбор и вернувшийся к работе прежним, платит за него дважды.
|
|
187
|
+
- **Число находок, написанное словом, устаревает к следующему абзацу.** Счёт растёт заходами, а
|
|
188
|
+
слово стоит на месте: «семь» простояло над восемью перечисленными до самого итога и поехало бы
|
|
189
|
+
дальше — в отчёт и в замысел эпика. Пишется либо перечень без числа, либо число, посчитанное
|
|
190
|
+
тем же ходом, каким пишется итог.
|
|
@@ -12,7 +12,8 @@ description: Паттерн правила task-flow. Брать в начале
|
|
|
12
12
|
|
|
13
13
|
## Когда брать
|
|
14
14
|
|
|
15
|
-
- Владелец просит что-то
|
|
15
|
+
- Владелец просит что-то сделать; размер просьбы значения не имеет — папка заводится под любую
|
|
16
|
+
работу.
|
|
16
17
|
- Замеченный по ходу дефект становится задачей.
|
|
17
18
|
|
|
18
19
|
## Порядок
|
|
@@ -33,21 +34,30 @@ Agent(subagent_type: "Explore", prompt: "<тема просьбы>: что по
|
|
|
33
34
|
|
|
34
35
|
Находки складываются в раздел «Что уже есть в дереве» разбора.
|
|
35
36
|
|
|
37
|
+
Дерево — не единственное место, где может лежать ответ. Решение, принятое прошлым заходом и
|
|
38
|
+
никуда не записанное, живёт только в записи того захода: записи заходов лежат в каталоге заходов
|
|
39
|
+
агента, и поиск по ним словом темы стоит одной команды. Найденное там ответом не остаётся на
|
|
40
|
+
месте — тем же ходом оно переписывается в дерево: в замысел эпика, если связывает задачи, и в
|
|
41
|
+
ход работы, если касается одной.
|
|
42
|
+
|
|
43
|
+
Разведка, не нашедшая ничего, разрешением спрашивать не становится. Сначала называется, где
|
|
44
|
+
искали, потом добираются места, которых в списке не было: замысел эпика, описание прошлого,
|
|
45
|
+
записи прошлых заходов. Одно место отрицанием не является: «в таком-то месте не нашёл» говорит о
|
|
46
|
+
месте, а не о дереве, и вопрос называет оба способа, которыми искали.
|
|
47
|
+
|
|
36
48
|
Разведка кончается не ощущением, а выводом команд. До первого вопроса владельцу исполнитель
|
|
37
49
|
знает: как устроен репозиторий (корневая памятка), что лежит в каталоге, о котором пойдёт речь
|
|
38
|
-
(`ls`), и есть ли уже написанное по теме (поиск по документации и правилам).
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
50
|
+
(`ls`), и есть ли уже написанное по теме (поиск по документации и правилам). «Не знаю»
|
|
51
|
+
проверяемым не бывает. Без списка того, что считается сделанным, разведка исполняется как
|
|
52
|
+
настроение: прочитанный переданный текст сходит за неё, и по текущему дереву не запускается ни
|
|
53
|
+
одной команды.
|
|
42
54
|
|
|
43
55
|
Разведка по заведённой задаче кончается воспроизведённым симптомом, а не найденным файлом. Тело
|
|
44
|
-
задачи описывает дерево на день заведения, и
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
исход: чинить нечего, а зелёные проверки после такой правки говорят ровно об этом и ни о чём
|
|
50
|
-
больше.
|
|
56
|
+
задачи описывает дерево на день заведения, и чужие правки въезжают в главную ветку между
|
|
57
|
+
заведением и работой: разведка по именам из тела подтверждает, что файлы на месте, — и отпавшая
|
|
58
|
+
задача от живой не отличается ничем. Прежде первой своей правки разведка повторяет то, на что
|
|
59
|
+
задача жалуется: зовёт процедуру, читает ответ, гоняет молчавшую проверку. Симптом не
|
|
60
|
+
воспроизвёлся — задача закрывается отпавшей, и это законный её исход.
|
|
51
61
|
|
|
52
62
|
**Следующее движение:** находки ложатся в разбор, и тем же ходом владельцу уходит первый из
|
|
53
63
|
шести вопросов. Разведка кончилась — состояние осталось прежним, ход тоже.
|
|
@@ -68,9 +78,21 @@ Agent(subagent_type: "Explore", prompt: "<тема просьбы>: что по
|
|
|
68
78
|
| Чем будет видно, что задача закрыта | «работает» признаком не является |
|
|
69
79
|
| Есть ли образец, с которого снимается подход | разведка найдёт похожее, а не то |
|
|
70
80
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
81
|
+
Список шести — набор того, что должно быть закрыто к началу работы, а не набор реплик, которые
|
|
82
|
+
надо произнести. Обязательный вопрос, ответ на который владелец уже дал, отмечается закрытым, а
|
|
83
|
+
не задаётся: ответ ищется в двух местах — в документации и в том, что владелец сказал в этом же
|
|
84
|
+
заходе, включая исходную просьбу. Слово, повторённое в просьбе несколько раз, ответом является.
|
|
85
|
+
Закрытый вопрос отмечается в разборе просьбы вместе с тем, чем он закрыт.
|
|
86
|
+
|
|
87
|
+
Закрыть его можно и допущением, когда ответ очевиден: в разборе стоит строка «вопрос закрыт
|
|
88
|
+
допущением: <что принято>». Неверное допущение стоит правки, вопрос ради очевидного — захода.
|
|
89
|
+
|
|
90
|
+
Объём работы основанием для вопроса о границах не бывает: «это большая работа» решает
|
|
91
|
+
исполнитель, «делать ли её целиком» — владелец, и решает раньше, чем работа началась. Вопрос о
|
|
92
|
+
границах задаётся, когда владелец их не назвал, а не когда названные оказались широкими.
|
|
93
|
+
|
|
94
|
+
Форму вопроса задают настройки владельца: где требуют меню, спрашивается меню, и к каждому
|
|
95
|
+
вопросу добавляется свободный вариант — у закрытого набора нет строки «вопрос не тот».
|
|
74
96
|
|
|
75
97
|
**Рамка переданного текста на текущее дерево не переносится.** Передача захода, файл
|
|
76
98
|
предложений и спек описывают то дерево, в котором писались. Про текущее знает только текущее:
|
|
@@ -121,6 +143,11 @@ Workflow(name: "plan", args: "docs/tasks/_draft-<slug>")
|
|
|
121
143
|
«не входит». Находка критика, расходящаяся с ответом владельца, относится владельцу — она не
|
|
122
144
|
исполняется молча и не считается закрытой правкой текста.
|
|
123
145
|
|
|
146
|
+
Ход на этой границе не кончается. Закрытый разбор выглядит законченным куском: ответы владельца
|
|
147
|
+
лежат на диске, файл закоммичен, отчитаться есть чем — и отчёт встаёт ровно на то место, которое
|
|
148
|
+
должна была занять договорённость. Пишется она тем же ходом, конвейером ролей или рукой
|
|
149
|
+
исполнителя, и разницы между этими двумя случаями для конца хода нет.
|
|
150
|
+
|
|
124
151
|
**Следующее движение:** сверенная с разбором договорённость коммитится, и тем же ходом
|
|
125
152
|
заводятся задача, ветка и папка — а вышла из разбора серия, сперва объявляется эпик.
|
|
126
153
|
|
|
@@ -155,6 +182,13 @@ Workflow(name: "plan", args: "docs/tasks/_draft-<slug>")
|
|
|
155
182
|
таблицы, с меткой эпика. Выданные номера возвращаются в ту же таблицу — колонкой или приставкой
|
|
156
183
|
к названию, — и с этой минуты «взять следующую» отвечает номером, а не названием.
|
|
157
184
|
|
|
185
|
+
Задача, заведённая под эпик, называет его в своём теле: номер карточки эпика и путь к замыслу —
|
|
186
|
+
одной строкой. Замысел называет задачу со своей стороны, и односторонняя привязка выглядит целой
|
|
187
|
+
ровно так же, как двусторонняя — читатель приходит то от линии работ, то от карточки, и вторая
|
|
188
|
+
сторона существует только для одного из них. Держалась она подражанием: пока тело писалось с
|
|
189
|
+
образца соседней задачи того же эпика, строка копировалась вместе с формой, а задача, заведённая
|
|
190
|
+
посреди работы находкой сверки, писалась не с образца.
|
|
191
|
+
|
|
158
192
|
**Следующее движение:** объявленный эпик коммитится вместе с номерами задач, и тем же ходом
|
|
159
193
|
берётся первая его задача — заведением ветки и папки.
|
|
160
194
|
|
|
@@ -208,6 +242,13 @@ cp docs/tasks/_template/progress.md docs/tasks/<КЛЮЧ>-<номер>-<slug>/pr
|
|
|
208
242
|
**Поведение:** меняется
|
|
209
243
|
```
|
|
210
244
|
|
|
245
|
+
Дерево, у которого каталога «предложено» нет, называет договорённость самим спеком домена — там
|
|
246
|
+
она пишется прямо в него, и переезжать при закрытии работы нечему:
|
|
247
|
+
|
|
248
|
+
```markdown
|
|
249
|
+
**Спек:** `docs/specs/bookings/spec.md`
|
|
250
|
+
```
|
|
251
|
+
|
|
211
252
|
Работа, не задевающая `apps/**` и `libs/**`, договорённости не требует:
|
|
212
253
|
|
|
213
254
|
```markdown
|
|
@@ -242,19 +283,16 @@ cp docs/tasks/_template/progress.md docs/tasks/<КЛЮЧ>-<номер>-<slug>/pr
|
|
|
242
283
|
**Следующее движение:** первый этап делается тем же ходом, а закрытым он объявляется после
|
|
243
284
|
того, как прошла его команда из строки «Чем проверяется».
|
|
244
285
|
|
|
245
|
-
##
|
|
286
|
+
## Частые промахи
|
|
246
287
|
|
|
247
288
|
- **Номер не бывает первым.** До конца разбора неизвестно даже, сколько задач из него выйдет:
|
|
248
289
|
заведённая заранее задача после разбивки закрывается и остаётся мусором в очереди работ.
|
|
249
290
|
- **Разбор пишется на диск сразу, а не копится в переписке.** Сессия обрывается, и разбор,
|
|
250
291
|
прожитый в разговоре, восстанавливается только пересказом владельца.
|
|
251
292
|
- **Из одного разбора вышло несколько задач — общее уезжает в замысел эпика.** Папка задачи
|
|
252
|
-
умирает с мержем, а порядок задач
|
|
253
|
-
замысла называет компаньон правила.
|
|
293
|
+
умирает с мержем, а порядок задач его переживает; каталог называет компаньон правила.
|
|
254
294
|
- **Задача заводится командой, а не четырьмя вызовами подряд.** Борда к репозиторию не
|
|
255
295
|
привязана, и задача попадает на неё только явным добавлением.
|
|
256
296
|
- **Slug ветки берётся из терминологии договорённости, а не из слов просьбы.** Договорённость
|
|
257
|
-
пишется раньше ветки и как раз там отказывается от слова
|
|
258
|
-
|
|
259
|
-
отвергнутым. Заголовок задачи и PR поправить можно, имя ветки после открытия PR —
|
|
260
|
-
уже нет.
|
|
297
|
+
пишется раньше ветки и как раз там отказывается от слова владельца. Заголовок задачи и PR
|
|
298
|
+
поправить можно, имя ветки после открытия PR — уже нет.
|
|
@@ -58,6 +58,13 @@ const ALLOW_RENAME: boolean = process.env['E2E_ALLOW_SLUG_RENAME'] === '1';
|
|
|
58
58
|
test.skip(!ALLOW_RENAME, 'меняет живой адрес объекта: включается E2E_ALLOW_SLUG_RENAME=1');
|
|
59
59
|
```
|
|
60
60
|
|
|
61
|
+
Выключатели бывают двух родов, и покрытием считается только первый. **Выключатель по состоянию
|
|
62
|
+
стенда** пропускает случай, которого на этом стенде не бывает по устройству, — сценарий закрыт,
|
|
63
|
+
и отметки он не требует. **Выключатель по переменной окружения** оставляет тест невыполненным:
|
|
64
|
+
сценарий за ним числится покрытым, а не проверен ничем, и такой сценарий несёт отметку
|
|
65
|
+
частичного покрытия с причиной. Из трёх ниже к первому роду не относится ни один: все три
|
|
66
|
+
управляются переменной.
|
|
67
|
+
|
|
61
68
|
- Спека, необратимо меняющая данные стенда, по умолчанию пропускается и включается своей
|
|
62
69
|
переменной.
|
|
63
70
|
- `BEHIND_NGINX` в `home.smoke.spec.ts` — это `!!process.env['BASE_URL']`: вместе с ним
|
|
@@ -67,6 +74,22 @@ test.skip(!ALLOW_RENAME, 'меняет живой адрес объекта: в
|
|
|
67
74
|
- `playwright/no-skipped-test` выключен в `eslint.config.mjs`: выключатель теста здесь —
|
|
68
75
|
приём, а не забытый `test.skip`.
|
|
69
76
|
|
|
77
|
+
## Код перехода проверяется ответом, а не переходом по нему
|
|
78
|
+
|
|
79
|
+
Переход браузер проходит сам, и код после него — код конечной страницы: спека, названная
|
|
80
|
+
«отвечает 301», утверждала 200 и не заметила бы подмены постоянного перехода на временный.
|
|
81
|
+
Спрашивается сам ответ, без хождения по нему:
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
const answer = await request.get('/старый-адрес', { maxRedirects: 0 });
|
|
85
|
+
|
|
86
|
+
expect(answer.status()).toBe(301);
|
|
87
|
+
expect(answer.headers()['location']).toBe('/новый-адрес');
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Отличать постоянный переход от временного нужно там, где на нём стоит договорённость: поисковые
|
|
91
|
+
роботы и браузер запоминают только постоянный, и разница между 301 и 302 видна лишь в ответе.
|
|
92
|
+
|
|
70
93
|
## Частые промахи
|
|
71
94
|
|
|
72
95
|
- **Порт {{ssrPort}} занимать осторожно:** стенд разработчика на {{sitePort}} ходит по тому же имени
|
|
@@ -70,7 +70,7 @@ node tools/check-turn-map.mjs # размер, полнота состояни
|
|
|
70
70
|
без передачи, без карты, без обеих. Последний случай обязан дать пустой вывод и нулевой код —
|
|
71
71
|
хук, промолчавший с ненулевым кодом, читается как отбитый запуск.
|
|
72
72
|
|
|
73
|
-
##
|
|
73
|
+
## Частые промахи
|
|
74
74
|
|
|
75
75
|
- **Предел размера назначается замером, а не на глаз.** Первое число выбрали «вдвое больше
|
|
76
76
|
нынешней карты» — и проверка покраснела на собственном тексте в первом же прогоне: карта в
|