@rt-tools/agent-kit 0.17.0 → 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.github.mjs +77 -73
- package/assets/checks/check-board.github.mjs +39 -3
- package/assets/checks/check-hook-scope.mjs +126 -0
- package/assets/checks/check-profile-drift.mjs +195 -0
- 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/defaults/project.sh +21 -117
- package/assets/defaults/shell.sh +139 -0
- 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-signature.sh +14 -5
- package/assets/hooks/git-guard-delivery.sh +15 -2
- package/assets/hooks/grill-gate.sh +63 -6
- package/assets/hooks/proposal-guard.sh +11 -4
- package/assets/hooks/rule-source-guard.sh +8 -13
- package/assets/hooks/task-context-load.sh +22 -0
- package/assets/hooks/task-flow-context.sh +9 -0
- package/assets/hooks/task-flow-draft-guard.sh +17 -0
- package/assets/hooks/turn-exit-guard.sh +45 -87
- package/assets/hooks/waiting-turn-guard.sh +65 -2
- package/assets/hooks/work-start-guard.sh +166 -0
- package/assets/hooks/write-targets.sh +24 -0
- package/assets/laws/verifiability.md +23 -0
- package/assets/patterns/browser-verification-measure.md +3 -1
- package/assets/patterns/browser-verification-stand.md +10 -2
- package/assets/patterns/doc-style-write.md +21 -1
- package/assets/patterns/git-workflow-commit.github.md +18 -3
- package/assets/patterns/git-workflow-docker.md +8 -0
- package/assets/patterns/git-workflow-freshness.md +87 -0
- package/assets/patterns/git-workflow-merge.md +23 -0
- package/assets/patterns/git-workflow-pr.github.md +6 -0
- package/assets/patterns/git-workflow-restart.md +18 -0
- package/assets/patterns/git-workflow-stack.md +30 -0
- package/assets/patterns/lib-layers-move.md +4 -0
- package/assets/patterns/spec-driven-domain.md +13 -1
- package/assets/patterns/spec-driven-rule.md +5 -4
- package/assets/patterns/spec-driven-sweep.md +1 -1
- package/assets/patterns/status-report-table.github.md +1 -1
- package/assets/patterns/task-flow-archive.md +12 -2
- package/assets/patterns/task-flow-close.md +31 -24
- package/assets/patterns/task-flow-handoff.md +14 -2
- package/assets/patterns/task-flow-resume.md +18 -3
- package/assets/patterns/task-flow-start.md +23 -23
- package/assets/patterns/testing-e2e.md +23 -0
- package/assets/patterns/turn-entry-map.md +1 -1
- package/assets/pitfalls/agent-kit.md +4 -6
- package/assets/pitfalls/doc-style.md +10 -0
- package/assets/pitfalls/git-workflow.github.md +20 -0
- package/assets/pitfalls/spec-driven.md +6 -0
- package/assets/pitfalls/task-flow.md +20 -0
- package/assets/pitfalls/testing.md +6 -0
- package/assets/pitfalls/turn-conduct.md +35 -0
- package/assets/rules/browser-verification.md +19 -0
- package/assets/rules/deploy-flow.github.md +9 -0
- package/assets/rules/doc-style.md +6 -0
- package/assets/rules/git-workflow.azure.md +17 -2
- package/assets/rules/git-workflow.github.md +89 -90
- package/assets/rules/git-workflow.gitlab.md +12 -4
- package/assets/rules/lists.md +5 -0
- package/assets/rules/observability.needs-app.md +4 -0
- package/assets/rules/reuse-first.md +6 -0
- package/assets/rules/spec-driven.md +29 -25
- package/assets/rules/task-flow.md +52 -46
- package/assets/rules/testing.md +27 -1
- package/assets/rules/turn-conduct.md +46 -43
- package/assets/skills/agent-kit.md +9 -0
- package/package.json +1 -1
- package/rt-tools-agent-kit-0.18.0.tgz +0 -0
- package/rt-tools-agent-kit-0.17.0.tgz +0 -0
|
@@ -54,6 +54,18 @@ docs/specs/<домен>/
|
|
|
54
54
|
такой спек по строкам бесполезно, потому что делится в нём не описание домена, а ненаписанное
|
|
55
55
|
правило.
|
|
56
56
|
|
|
57
|
+
**Заголовок записи раздела решений датой не называется.** Дата говорит, когда решение приняли, а
|
|
58
|
+
раздел отвечает на «почему так, а не иначе»: по дате решение не отобрать и не найти, зато
|
|
59
|
+
названная ею запись читается описанием прошлого и остаётся в спеке навсегда. Запись начинается с
|
|
60
|
+
самого решения.
|
|
61
|
+
|
|
62
|
+
**Утверждение, стоящее в другом разделе того же спека, вторым пунктом правил не заводится.**
|
|
63
|
+
Устройство записи живёт в разделе данных, порядок вызовов — в разделе контракта, причина
|
|
64
|
+
существования домена — в разделе «Зачем»: все три говорят о том же, о чём говорило бы правило.
|
|
65
|
+
Второй экземпляр расходится с первым молча, и заметить это нечем — сверка знает пункт правила
|
|
66
|
+
против якоря, а два утверждения об одном не сравнивает никто. Решение при этом из раздела решений
|
|
67
|
+
уезжает целиком: место, где требование живёт, найдено.
|
|
68
|
+
|
|
57
69
|
Шапка несёт статус, дату ревизии, префикс сценариев, зависимости от других доменов, строку
|
|
58
70
|
`**Законы:**` — законы, которые домен применяет, — и строку `**Процедуры:**` — корни либ, чьи
|
|
59
71
|
процедуры домен обслуживает.
|
|
@@ -84,7 +96,7 @@ docs/specs/<домен>/
|
|
|
84
96
|
```
|
|
85
97
|
|
|
86
98
|
Правило, которому места в коде не нашлось, — намерение: ему место в «Открытых вопросах» как
|
|
87
|
-
`Q
|
|
99
|
+
`Q-<буква закона>-<номер>`, а не формальный якорь.
|
|
88
100
|
|
|
89
101
|
## Сценарий
|
|
90
102
|
|
|
@@ -33,7 +33,10 @@ description: Паттерн правила spec-driven. Брать при зав
|
|
|
33
33
|
вопрос есть, и стираются вместе с последним закрытым: закрытый вопрос из закона убирается, а
|
|
34
34
|
не превращается в пустой раздел.
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
Даты в законе тоже нет: у одного закона из семнадцати она стояла, у остальных не появлялась
|
|
37
|
+
никогда, а прочитанная как срок годности — старит верный текст, которого никто не трогал, потому
|
|
38
|
+
что трогать было нечего. Ни истории правок, ни доводов о том, почему когда-то выбрали так, в
|
|
39
|
+
законе нет. Историю
|
|
37
40
|
держит система контроля версий, а довод с отвергнутой альтернативой — свойство работы, а не
|
|
38
41
|
продукта: ему место в «Ловушках» правила под этим законом, где и путям к файлам можно.
|
|
39
42
|
Утверждение, которое нельзя написать как «верно всегда», статьёй не становится вовсе.
|
|
@@ -43,8 +46,6 @@ description: Паттерн правила spec-driven. Брать при зав
|
|
|
43
46
|
|
|
44
47
|
Как правка доезжает до работающего приложения. …
|
|
45
48
|
|
|
46
|
-
**Ревизия:** 2026-08-05
|
|
47
|
-
|
|
48
49
|
## Статьи
|
|
49
50
|
|
|
50
51
|
- **Выкатывается образ того коммита, который выкатывают.** Умолчание «последний» отстаёт от
|
|
@@ -98,7 +99,7 @@ description: Правило под «Закон о поставке». Брат
|
|
|
98
99
|
```
|
|
99
100
|
|
|
100
101
|
Утверждение, которому места в коде не нашлось, в этот раздел не ставится: оно уходит прозой в
|
|
101
|
-
«Ловушки» или вопросом `Q
|
|
102
|
+
«Ловушки» или вопросом `Q-<буква закона>-<номер>` в закон.
|
|
102
103
|
|
|
103
104
|
## Паттерн
|
|
104
105
|
|
|
@@ -47,7 +47,7 @@ description: Паттерн правила spec-driven. Брать при спл
|
|
|
47
47
|
тридцати шести строк расхождений не оказалось ни одной. Поэтому число находок прошлого домена на
|
|
48
48
|
следующий не переносится — переносится только сам порядок проходов.
|
|
49
49
|
|
|
50
|
-
##
|
|
50
|
+
## Частые промахи
|
|
51
51
|
|
|
52
52
|
- **Урожайность прохода обещана фактом.** «Проход даст столько-то» — оценка, и по чужому слою она
|
|
53
53
|
промахивается целиком. Разбор просьбы называет проходы, а не число находок.
|
|
@@ -57,7 +57,7 @@ gh api repos/:owner/:repo/issues/<номер> --jq '{t:.title,s:.state,labels:[.
|
|
|
57
57
|
имя команды в оболочке бывает занято чужим псевдонимом, и тогда вызов уходит в интерактивный
|
|
58
58
|
вход вместо ответа.
|
|
59
59
|
|
|
60
|
-
##
|
|
60
|
+
## Частые промахи
|
|
61
61
|
|
|
62
62
|
- **Задача на борде читается запросом, а не подкомандой просмотра.** Подкоманда тянет за собой
|
|
63
63
|
доски старого образца, хостинг отвечает отказом о них, и вызов краснеет целиком, ничего не
|
|
@@ -46,7 +46,17 @@ description: Паттерн правила task-flow. Брать, когда т
|
|
|
46
46
|
| `grill.md` | в `docs/archive/` — ответы владельца невосстановимы, и это единственная запись о том, почему задача поставлена так |
|
|
47
47
|
| `progress.md` | в `docs/archive/`, если в нём есть решения по ходу с причинами; иначе удаляется |
|
|
48
48
|
| `plan.md` | удаляется — после выкатки на его вопрос отвечает код, а на «как работает» отвечает спек домена |
|
|
49
|
-
| находки разбора |
|
|
49
|
+
| находки разбора | пишутся сразу рядом с замыслом эпика — не переезжают отсюда; работа вне эпика показывает их владельцу тем же ходом |
|
|
50
|
+
|
|
51
|
+
Находки в папке задачи не живут вовсе. Разбор идёт фоном, и когда он кончится, не знает никто:
|
|
52
|
+
папка к этой минуте разобрана, а ветка бывает уже влита и снята. Оба срока назначает не
|
|
53
|
+
исполнитель, поэтому переезд «из папки к замыслу эпика» держался бы на совпадении, которого может
|
|
54
|
+
и не случиться. Тем же местом пользуется находка, замеченная не разбором, а по ходу работы.
|
|
55
|
+
|
|
56
|
+
Находки, вернувшиеся после того, как ветка ушла, едут веткой следующей задачи: пуш в снятую ветку
|
|
57
|
+
её не обновляет, а заводит заново, и коммит остаётся вне главной. Следующая задача к этой минуте
|
|
58
|
+
уже взята — её веткой уборка за предыдущей и едет, тем же порядком, каким разбирают чужую папку
|
|
59
|
+
задачи. Эпик кончился и следующей задачи нет — находки уезжают своей задачей.
|
|
50
60
|
|
|
51
61
|
Уезжающее складывается одним файлом с говорящим именем, а не папкой из трёх:
|
|
52
62
|
|
|
@@ -187,7 +197,7 @@ npm run cargo:mark -- --state fixed \
|
|
|
187
197
|
котором владелец сказал вслух, уходит наружу в тот же ход: написанное и не отправленное лежит в
|
|
188
198
|
дереве неотличимо от отправленного.
|
|
189
199
|
|
|
190
|
-
##
|
|
200
|
+
## Частые промахи
|
|
191
201
|
|
|
192
202
|
- **Папку разбирают до открытия заявки — потом о ней уже никто не вспомнит.** Сверка очереди
|
|
193
203
|
считает задачу закрытой по слиянию: после него за папку никто не отвечает — работа перешла к
|
|
@@ -258,33 +258,40 @@ PR #<номер> готов к слиянию: прогон зелёный, че
|
|
|
258
258
|
ветки. Что именно чинится, берётся из замечания, а не из замысла.
|
|
259
259
|
|
|
260
260
|
Главная ветка, влитая ради того, чтобы что-то посмотреть, — такая же правка, как влитая ради
|
|
261
|
-
работы, и уезжает тем же ходом.
|
|
262
|
-
|
|
263
|
-
владелец видит прежнее состояние и решает по нему.
|
|
261
|
+
работы, и уезжает тем же ходом. Слияние, оставшееся в рабочей копии, либо пушится тем же ходом,
|
|
262
|
+
либо не делается — иначе владелец видит прежнее состояние и решает по нему.
|
|
264
263
|
|
|
265
264
|
**Следующее движение:** прогон зелёный и замечаний нет — черновик снимается, и владельцу
|
|
266
265
|
говорится, что работа готова.
|
|
267
266
|
|
|
268
|
-
##
|
|
269
|
-
|
|
270
|
-
- **Тексты правятся до разбора
|
|
271
|
-
|
|
272
|
-
-
|
|
273
|
-
|
|
274
|
-
|
|
267
|
+
## Частые промахи
|
|
268
|
+
|
|
269
|
+
- **Тексты правятся до разбора папки:** список того, что перечитывать, лежит в замысле, а разбор
|
|
270
|
+
папки его удаляет.
|
|
271
|
+
- **Запись раздела решений, повторяющая статью правила слово в слово, доводом при ней не
|
|
272
|
+
считается.** Правило приходит в контекст само, спек — только когда его открыли; пара расходится
|
|
273
|
+
молча. Такая запись уезжает целиком, даже если раздел пустеет; довод, в статье не сказанный,
|
|
274
|
+
дописывается в статью.
|
|
275
|
+
- **Тело заявки остаётся старше разбора папки.** Разбор — последний коммит ветки, и он делает
|
|
276
|
+
неправдой всё, что тело обещало сделать до слияния. Ревьювер читает список оставшегося как
|
|
277
|
+
оставшееся, поэтому тело правится тем же ходом.
|
|
278
|
+
- **Утверждение правила снимается вместе со строкой привязки.** Связь идёт по тексту: строка без
|
|
279
|
+
утверждения и утверждение без строки одинаково краснят сверку спеков.
|
|
275
280
|
- **Раздел «Чего из закона здесь нет» читается глазами, греп тут не помогает.** Искать
|
|
276
|
-
приходится не то слово, которое ждёшь: правило ссылалось на
|
|
277
|
-
|
|
278
|
-
- **Сказать «сверено», не открыв файл, нельзя.** Правило читается
|
|
279
|
-
|
|
281
|
+
приходится не то слово, которое ждёшь: правило ссылалось на статью, которой в законе нет, и по
|
|
282
|
+
слову своей темы эта строка находилась — а неправда была в другом.
|
|
283
|
+
- **Сказать «сверено», не открыв файл, нельзя.** Правило читается целиком: устаревшее утверждение
|
|
284
|
+
стоит среди верных и ничем от них не отличается.
|
|
280
285
|
- **Вливание после мержа не делается.** В главной ветке тогда лежит раздел «предложено, но не
|
|
281
|
-
выкачено» с тем, что работает
|
|
282
|
-
- **Номера сценариев при вливании не пересчитываются.** Идентификатор — ключ связи с
|
|
283
|
-
сдвиг рвёт сверку у
|
|
284
|
-
- **«Что не входит» после вливания читается целиком, а не дописывается.**
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
-
|
|
290
|
-
|
|
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,6 +27,11 @@ description: Паттерн правила task-flow. Брать при возв
|
|
|
27
27
|
образца, а `progress.md` заполняется по тому, что видно в дереве и в истории ветки, а не по
|
|
28
28
|
расспросам владельца.
|
|
29
29
|
|
|
30
|
+
Пришло «РАБОТА ЗАКРЫВАЕТСЯ» — папку разобрала сама ветка перед заявкой, и собирать её заново не
|
|
31
|
+
надо: состояние работы читается у заявки и в передаче захода. Понадобилась правка кода по
|
|
32
|
+
замечаниям разбора — папка восстанавливается на время правки, а разбор повторяется тем же
|
|
33
|
+
коммитом.
|
|
34
|
+
|
|
30
35
|
## Чего не делать
|
|
31
36
|
|
|
32
37
|
- **Не спрашивать владельца о том, что записано.** Ради этого всё и заведено.
|
|
@@ -139,19 +144,25 @@ git log --oneline origin/main..HEAD
|
|
|
139
144
|
Берётся, а не выбирается: порядок назначен на планировании и лежит в замысле эпика. Выбор,
|
|
140
145
|
предложенный владельцу при назначенном порядке, — просьба назначить его заново.
|
|
141
146
|
|
|
147
|
+
У работы вне эпика замысла с порядком нет, и следующая берётся из очереди работ — тем же
|
|
148
|
+
движением и с тем же запретом на выбор вслух: очередь спрашивается командой, а не памятью о том,
|
|
149
|
+
что заводил сам исполнитель. Пусто в очереди — это утверждение о дереве, и подтверждается оно
|
|
150
|
+
выводом команды.
|
|
151
|
+
|
|
142
152
|
```bash
|
|
143
153
|
# что назначено следующим — читается в замысле эпика, а не спрашивается
|
|
144
154
|
# состояние задач — в очереди работ: замысел о закрытом не знает
|
|
145
155
|
```
|
|
146
156
|
|
|
147
157
|
Останавливает заход только предел заполнения окна — тогда идёт передача, паттерн
|
|
148
|
-
`task-flow-handoff`.
|
|
149
|
-
что кончился именно эпик, а не одна его
|
|
158
|
+
`task-flow-handoff`. Кончившийся эпик поводом остановиться не бывает: работа берётся вне его —
|
|
159
|
+
из очереди работ, — а владельцу тем же ходом называется, что кончился именно эпик, а не одна его
|
|
160
|
+
задача. Он называется вместе со взятой работой, а не вместо неё.
|
|
150
161
|
|
|
151
162
|
**Следующее движение:** по следующей задаче делается действие — заведена задача, ветка или
|
|
152
163
|
папка. Ход кончается после него, а не после слов о нём.
|
|
153
164
|
|
|
154
|
-
##
|
|
165
|
+
## Частые промахи
|
|
155
166
|
|
|
156
167
|
- **Заход, кончившийся ничем, тоже записывается.** Иначе следующий пойдёт той же дорогой:
|
|
157
168
|
«пробовали так — не вышло, потому что» стоит одной строки и экономит целый заход.
|
|
@@ -173,3 +184,7 @@ git log --oneline origin/main..HEAD
|
|
|
173
184
|
через один ход после записи механизм повторился в той же форме. Поэтому разбор кончается не
|
|
174
185
|
текстом, а тем, что из него вышло: правкой ресурса, гардом или предложением с адресом. Заход,
|
|
175
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
|
## Порядок
|
|
@@ -41,23 +42,22 @@ Agent(subagent_type: "Explore", prompt: "<тема просьбы>: что по
|
|
|
41
42
|
|
|
42
43
|
Разведка, не нашедшая ничего, разрешением спрашивать не становится. Сначала называется, где
|
|
43
44
|
искали, потом добираются места, которых в списке не было: замысел эпика, описание прошлого,
|
|
44
|
-
записи прошлых заходов.
|
|
45
|
+
записи прошлых заходов. Одно место отрицанием не является: «в таком-то месте не нашёл» говорит о
|
|
46
|
+
месте, а не о дереве, и вопрос называет оба способа, которыми искали.
|
|
45
47
|
|
|
46
48
|
Разведка кончается не ощущением, а выводом команд. До первого вопроса владельцу исполнитель
|
|
47
49
|
знает: как устроен репозиторий (корневая памятка), что лежит в каталоге, о котором пойдёт речь
|
|
48
|
-
(`ls`), и есть ли уже написанное по теме (поиск по документации и правилам).
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
(`ls`), и есть ли уже написанное по теме (поиск по документации и правилам). «Не знаю»
|
|
51
|
+
проверяемым не бывает. Без списка того, что считается сделанным, разведка исполняется как
|
|
52
|
+
настроение: прочитанный переданный текст сходит за неё, и по текущему дереву не запускается ни
|
|
53
|
+
одной команды.
|
|
52
54
|
|
|
53
55
|
Разведка по заведённой задаче кончается воспроизведённым симптомом, а не найденным файлом. Тело
|
|
54
|
-
задачи описывает дерево на день заведения, и
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
исход: чинить нечего, а зелёные проверки после такой правки говорят ровно об этом и ни о чём
|
|
60
|
-
больше.
|
|
56
|
+
задачи описывает дерево на день заведения, и чужие правки въезжают в главную ветку между
|
|
57
|
+
заведением и работой: разведка по именам из тела подтверждает, что файлы на месте, — и отпавшая
|
|
58
|
+
задача от живой не отличается ничем. Прежде первой своей правки разведка повторяет то, на что
|
|
59
|
+
задача жалуется: зовёт процедуру, читает ответ, гоняет молчавшую проверку. Симптом не
|
|
60
|
+
воспроизвёлся — задача закрывается отпавшей, и это законный её исход.
|
|
61
61
|
|
|
62
62
|
**Следующее движение:** находки ложатся в разбор, и тем же ходом владельцу уходит первый из
|
|
63
63
|
шести вопросов. Разведка кончилась — состояние осталось прежним, ход тоже.
|
|
@@ -84,14 +84,15 @@ Agent(subagent_type: "Explore", prompt: "<тема просьбы>: что по
|
|
|
84
84
|
заходе, включая исходную просьбу. Слово, повторённое в просьбе несколько раз, ответом является.
|
|
85
85
|
Закрытый вопрос отмечается в разборе просьбы вместе с тем, чем он закрыт.
|
|
86
86
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
работа началась. Вопрос о границах задаётся тогда, когда владелец границ не назвал, — а не
|
|
90
|
-
тогда, когда названные оказались широкими.
|
|
87
|
+
Закрыть его можно и допущением, когда ответ очевиден: в разборе стоит строка «вопрос закрыт
|
|
88
|
+
допущением: <что принято>». Неверное допущение стоит правки, вопрос ради очевидного — захода.
|
|
91
89
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
90
|
+
Объём работы основанием для вопроса о границах не бывает: «это большая работа» решает
|
|
91
|
+
исполнитель, «делать ли её целиком» — владелец, и решает раньше, чем работа началась. Вопрос о
|
|
92
|
+
границах задаётся, когда владелец их не назвал, а не когда названные оказались широкими.
|
|
93
|
+
|
|
94
|
+
Форму вопроса задают настройки владельца: где требуют меню, спрашивается меню, и к каждому
|
|
95
|
+
вопросу добавляется свободный вариант — у закрытого набора нет строки «вопрос не тот».
|
|
95
96
|
|
|
96
97
|
**Рамка переданного текста на текущее дерево не переносится.** Передача захода, файл
|
|
97
98
|
предложений и спек описывают то дерево, в котором писались. Про текущее знает только текущее:
|
|
@@ -282,15 +283,14 @@ cp docs/tasks/_template/progress.md docs/tasks/<КЛЮЧ>-<номер>-<slug>/pr
|
|
|
282
283
|
**Следующее движение:** первый этап делается тем же ходом, а закрытым он объявляется после
|
|
283
284
|
того, как прошла его команда из строки «Чем проверяется».
|
|
284
285
|
|
|
285
|
-
##
|
|
286
|
+
## Частые промахи
|
|
286
287
|
|
|
287
288
|
- **Номер не бывает первым.** До конца разбора неизвестно даже, сколько задач из него выйдет:
|
|
288
289
|
заведённая заранее задача после разбивки закрывается и остаётся мусором в очереди работ.
|
|
289
290
|
- **Разбор пишется на диск сразу, а не копится в переписке.** Сессия обрывается, и разбор,
|
|
290
291
|
прожитый в разговоре, восстанавливается только пересказом владельца.
|
|
291
292
|
- **Из одного разбора вышло несколько задач — общее уезжает в замысел эпика.** Папка задачи
|
|
292
|
-
умирает с мержем, а порядок задач
|
|
293
|
-
замысла называет компаньон правила.
|
|
293
|
+
умирает с мержем, а порядок задач его переживает; каталог называет компаньон правила.
|
|
294
294
|
- **Задача заводится командой, а не четырьмя вызовами подряд.** Борда к репозиторию не
|
|
295
295
|
привязана, и задача попадает на неё только явным добавлением.
|
|
296
296
|
- **Slug ветки берётся из терминологии договорённости, а не из слов просьбы.** Договорённость
|
|
@@ -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
|
нынешней карты» — и проверка покраснела на собственном тексте в первом же прогоне: карта в
|
|
@@ -26,6 +26,10 @@
|
|
|
26
26
|
надстройка, которую она закрыла, не сопоставляются ничем, и надстройка остаётся замещать уже
|
|
27
27
|
исправленный раздел.
|
|
28
28
|
|
|
29
|
+
Скопированная пакетная строка правится в источнике пакета, а не в копии: правка внутри
|
|
30
|
+
надстройки расходится с исходником молча, и видно её только там, где сам текст служит ключом
|
|
31
|
+
связи — в статье, у которой есть привязка. Перед правкой строки в надстройке она ищется в
|
|
32
|
+
источнике; не нашлась — строка своя, и правится на месте.
|
|
29
33
|
- **Готовый код пакета не называет имён одного дерева.** Префикс директив кита, ключи подписей
|
|
30
34
|
и имена сущностей принадлежат тому дереву, где паттерн писали; разложенные в соседнем, они
|
|
31
35
|
учат звать то, чего там нет вовсе. Имя директивы при этом отличается от имени в примере: по
|
|
@@ -42,12 +46,6 @@
|
|
|
42
46
|
отдельным шагом, отбивается как неиспользуемый ещё до того, как появится строка, которая его
|
|
43
47
|
зовёт, и работа встаёт на половине. Правка делается одним вызовом либо в порядке «сначала
|
|
44
48
|
использование, потом импорт».
|
|
45
|
-
- **Прогонять сценарии гардов можно, ничего не раскладывая, — но только там, где сам пакет живёт
|
|
46
|
-
исходниками.** Обвязка набора принимает каталог гардов переменной, и пакетную редакцию гоняют
|
|
47
|
-
по сценариям дерева до установки. Заход, потраченный на диагноз по последствиям, стоил ровно
|
|
48
|
-
этой строки. В поставке ни обвязки, ни каталога сценариев нет: они живут в репозитории пакета,
|
|
49
|
-
и дерево-потребитель, поверившее совету, ищет у себя то, чего ему не отгружали.
|
|
50
|
-
|
|
51
49
|
- **Прогонять сценарии гардов можно, ничего не раскладывая, — там, где эти сценарии есть.**
|
|
52
50
|
Обвязка набора принимает каталог гардов переменной, и пакетную редакцию гоняют до установки.
|
|
53
51
|
Живёт она в репозитории самого пакета: в поставку едут ресурсы, строка запуска и библиотека, а
|
|
@@ -88,3 +88,13 @@
|
|
|
88
88
|
строки. Отличить это от применённой правки по коду возврата нечем — видно только по самому
|
|
89
89
|
файлу, и обычно позже, по заголовкам собранного текста. Текст правится инструментом правки; а
|
|
90
90
|
если замену всё же зовут, место, которое она обещала изменить, перечитывают сразу после неё.
|
|
91
|
+
- **Число, полученное командой, замером ещё не является.** Требование пересчитывать число
|
|
92
|
+
командой соблюдается буквально — команда была, — а мерила ли она предмет числа, не спрашивает
|
|
93
|
+
никто. Вывод бывает ложным по-разному и молча: `grep -E` с границей слова `\b` на BSD часть
|
|
94
|
+
образца игнорирует и об этом не сообщает («278 вхождений» оказались 79, и двенадцать из них о
|
|
95
|
+
другом), регулярка не видит, где кончается блок, и приписывает найденное соседу, а память
|
|
96
|
+
возвращает число, не помня его происхождения, — от замера оно неотличимо. Число пишется той
|
|
97
|
+
командой, которая мерит его предмет, и тем же ходом, каким пишется текст.
|
|
98
|
+
- **Границу слова спрашивают у той команды, которая её знает.** `grep -w`, `rg` и `python3` с
|
|
99
|
+
`re` её реализуют, BSD `grep -E` — нет; проверка стоит одной команды и делается до того, как
|
|
100
|
+
число уедет в текст.
|
|
@@ -7,6 +7,21 @@
|
|
|
7
7
|
|
|
8
8
|
## Ловушки
|
|
9
9
|
|
|
10
|
+
- **Непосчитанная сливаемость конфликтом не бывает.** Хостинг считает её заново после каждой
|
|
11
|
+
правки главной ветки и до конца счёта отвечает неопределённостью. Прочитанная как конфликт,
|
|
12
|
+
она отбивает работу на каждой свежей вершине — то есть ровно там, где отбивать нечего.
|
|
13
|
+
Поэтому и гард, и сверка судят только прямое «конфликтует», а молчание опроса пропускают.
|
|
14
|
+
- **Силовая отправка ветки, стоящей под другой в стопке, закрывает её заявку как слитую.**
|
|
15
|
+
Хостинг считает заявку слитой, когда вершина её ветки достижима из базы; состояние лживое — в
|
|
16
|
+
главной ветке правки нет, а задача остаётся открытой. Требование, из которого это следует, —
|
|
17
|
+
статья правила о том, что нижняя ветка череды историю не переписывает.
|
|
18
|
+
- **Ветка, догнанная в рабочем дереве и не отправленная, работой не считается.** Человек видит
|
|
19
|
+
прежнее состояние и читает его как «не сделано ничего», а сделанное лежит там, где его не
|
|
20
|
+
видит никто. Про неотправленный разрешённый конфликт статья правила это говорит, но догнанная
|
|
21
|
+
ветка без единого спора под неё не подпадает вовсе.
|
|
22
|
+
- **`UNKNOWN` в поле сливаемости означает «ещё не посчитано», а не «конфликтов нет».** Хостинг
|
|
23
|
+
считает её после каждого чужого слияния, и заявка, прочитанная в эту секунду, выглядит
|
|
24
|
+
здоровой.
|
|
10
25
|
- **Одна работа — одна задача, сколько бы файлов она ни задела.** Числа, за которым правка
|
|
11
26
|
становится второй задачей, здесь нет: делится то, что придётся откатывать порознь. Сплошная
|
|
12
27
|
правка текстов дерева была заведена тремя задачами «по объёму» — пришлось стирать две,
|
|
@@ -199,3 +214,8 @@
|
|
|
199
214
|
хостинг, заявка стоит конфликтующей при разрешённом на месте расхождении.
|
|
200
215
|
- **Сверки раскладки нет в конвейере, поэтому шага, который она бы закрывала, там тоже нет.**
|
|
201
216
|
Правка мимо источника в день, когда её делают, не ломает ничего.
|
|
217
|
+
- **Рабочее дерево не опустошается ради прогона инструмента.** Вопрос «этот долг был до моих
|
|
218
|
+
правок или от них» решается второй копией дерева, а не прятаньем работы: спрятанного не видит
|
|
219
|
+
ни статус, ни сверка, а команда, прошедшая между прятаньем и возвратом, пишет в те же файлы —
|
|
220
|
+
и возврат встаёт конфликтом. Так ушли в прятанье восемь незакоммиченных файлов при живом
|
|
221
|
+
запрете на эту команду: запрет читался в начале захода, а команда набиралась через сорок ходов.
|
|
@@ -50,3 +50,9 @@
|
|
|
50
50
|
и число это падает по мере того, как их читают. Счёт при этом грубый: строка, показанная
|
|
51
51
|
образцом внутри ограды, считается наравне с настоящей — тот, кто учит её писать, попадает
|
|
52
52
|
в число объявивших.
|
|
53
|
+
- **Привязка пишется по тексту статьи, а не по смыслу имени гарда.** Гард, чьё имя звучит про то
|
|
54
|
+
же самое, статью не закрывает: статья перечисляла шесть действий по отдельному слову владельца
|
|
55
|
+
— коммит, пуш, открытие заявки, запись в вики, заведение задачи, правка закона, — а
|
|
56
|
+
поставленный ей гард не держит ни одного из них и отправки предложения среди перечисленного
|
|
57
|
+
нет вовсе. Читается текст статьи целиком, и в привязке называется то место, которое держит
|
|
58
|
+
названное ею, а не соседнее по смыслу.
|
|
@@ -7,6 +7,20 @@
|
|
|
7
7
|
|
|
8
8
|
## Ловушки
|
|
9
9
|
|
|
10
|
+
- **Разрешение владельца, оставленное в репозитории, теряется на каждой новой ветке.** Оно
|
|
11
|
+
записано номером в файл ветки, а следующая ветка отводится от главной и его не несёт: гард
|
|
12
|
+
отбивает работу, которую владелец разрешил, — и повторяется это ровно столько раз, сколько
|
|
13
|
+
веток заведут до слияния разрешившего коммита. Отказ гарда при этом называет файл и молчит о
|
|
14
|
+
том, что запись принадлежит ветке: из его текста это читается как настройка дерева. Пока
|
|
15
|
+
разрешение живёт в репозитории, номер дописывается заново в каждую новую ветку.
|
|
16
|
+
- **Имя чужого дерева в файлы репозитория не пишется, а путь к образцу — пишется.** Обе вещи
|
|
17
|
+
живут рядом с передачей захода именно поэтому: там законен полный путь, а в репозитории —
|
|
18
|
+
только ссылка без имени.
|
|
19
|
+
- **Строка «Ждём владельца» в ходе работы живёт дольше причины, по которой её написали.** Она
|
|
20
|
+
лежит на диске, приходит в контекст следующим заходом и читается как действующее состояние —
|
|
21
|
+
поэтому снимается тем же ходом, которым владелец ответил. Иначе ожидание подтверждает себя
|
|
22
|
+
само: три указания владельца подряд не пересилили одной строки на диске.
|
|
23
|
+
|
|
10
24
|
- **Папка называется именем ветки, один в один.** Хук запуска ищет её по
|
|
11
25
|
`git branch --show-current`, и папка, названная иначе, не находится ничем: работа идёт с
|
|
12
26
|
пустым контекстом, а владельца просят пересказать то, что уже записано.
|
|
@@ -181,3 +195,9 @@
|
|
|
181
195
|
- **Прогон, поставленный первым шагом закрытия, съедает окно захода.** Он стоит дороже всех
|
|
182
196
|
остальных шагов вместе, и потративший его на прогон упирался в порог заполнения на четырёх
|
|
183
197
|
строках привязки — то есть на работе, которая стоила бы минуты, если бы шла первой.
|
|
198
|
+
- **Разрешение работать вне назначенного эпика принадлежит рабочему дереву, а не ветке.**
|
|
199
|
+
Записанное в файл репозитория, оно уезжает вместе с веткой: из соседней его не видно, и гард
|
|
200
|
+
эпика отбивает ровно ту работу, которую владелец разрешил. За один заход это случилось дважды
|
|
201
|
+
— сперва на отказе конца хода, потом на переводе колонки, и оба раза номер дописывался заново.
|
|
202
|
+
Место такому разрешению там же, где передача захода: оно не откатывается вместе с правкой и не
|
|
203
|
+
принадлежит ни одной задаче.
|
|
@@ -7,6 +7,12 @@
|
|
|
7
7
|
|
|
8
8
|
## Ловушки
|
|
9
9
|
|
|
10
|
+
- **Зелёный тест чистой функции молчит о ряде, которого рабочий путь не порождает.** Функция
|
|
11
|
+
верна на том, что ей подали, а подаёт ей ввод сам тест: ряд, собранный ради удобства
|
|
12
|
+
проверки, доказывает поведение на случае, которого в работе не бывает. Так стояли два зелёных
|
|
13
|
+
теста решения об оповещении, а предохранитель, ради которого решение писали, не сработал ни
|
|
14
|
+
разу. Форма ввода берётся с той границы, откуда решение зовут, — у процедуры, у службы, у
|
|
15
|
+
обработчика, — и сверяется с ней, а не выдумывается рядом с проверкой.
|
|
10
16
|
- **Зелёный `nx test <проект>` не значит, что хоть один файл исполнялся.** Либа без своего
|
|
11
17
|
`vitest.config.mts` не запускает ничего — так тесты домена броней не запускались ни разу.
|
|
12
18
|
Либа с конфигом, но без единого `*.spec.ts`, проходит зелёной из-за `passWithNoTests: true`,
|