@rt-tools/agent-kit 0.20.0 → 0.22.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/check-reuse.mjs +11 -1
- package/assets/checks/check-specs.mjs +8 -23
- package/assets/checks/signals/core.json +12 -2
- package/assets/checks/signals.mjs +17 -0
- package/assets/checks/spec-proposed.mjs +122 -0
- package/assets/hooks/browser-guard-device-id.sh +3 -0
- package/assets/hooks/browser-guard-no-asking.sh +3 -0
- package/assets/hooks/browser-guard-no-listing.sh +3 -0
- package/assets/hooks/browser-guard-no-other-drivers.sh +3 -0
- package/assets/hooks/browser-guard-require-select.sh +3 -0
- package/assets/hooks/claim-guard.sh +4 -0
- package/assets/hooks/conscience-guard.sh +4 -0
- package/assets/hooks/deny-tail.sh +12 -0
- package/assets/hooks/dev-server-guard.sh +3 -0
- package/assets/hooks/docs-guard.sh +4 -11
- package/assets/hooks/exam-guard.sh +3 -0
- package/assets/hooks/git-guard-delivery.sh +4 -4
- package/assets/hooks/git-guard-main.sh +4 -9
- package/assets/hooks/git-guard-push-tests.sh +3 -0
- package/assets/hooks/grill-gate.sh +5 -0
- package/assets/hooks/guard-note.sh +45 -0
- package/assets/hooks/handoff-entry-guard.sh +3 -0
- package/assets/hooks/handoff-write.sh +58 -7
- package/assets/hooks/hook-input.sh +1 -0
- package/assets/hooks/override-write-guard.sh +4 -4
- package/assets/hooks/postmortem-guard.sh +4 -0
- package/assets/hooks/proposal-guard.sh +11 -0
- package/assets/hooks/prose-style-guard.sh +3 -0
- package/assets/hooks/qa-dataid-guard.sh +3 -0
- package/assets/hooks/rerun-guard.sh +3 -0
- package/assets/hooks/reuse-first-guard.sh +3 -0
- package/assets/hooks/rule-article.sh +1 -1
- package/assets/hooks/rule-source-guard.sh +4 -4
- package/assets/hooks/sql-guard.sh +3 -0
- package/assets/hooks/task-context-load.sh +1 -1
- package/assets/hooks/task-flow-draft-guard.sh +3 -0
- package/assets/hooks/task-flow-guard.sh +3 -0
- package/assets/hooks/turn-entry-load.sh +27 -2
- package/assets/hooks/turn-exit-guard.sh +4 -0
- package/assets/hooks/waiting-turn-guard.sh +32 -10
- package/assets/hooks/window-fill-guard.sh +3 -0
- package/assets/hooks/work-start-guard.sh +5 -0
- package/assets/hooks/write-targets.sh +59 -10
- package/assets/laws/delivery.md +5 -0
- package/assets/laws/frontend-application.md +10 -0
- package/assets/laws/work-conduct.md +8 -0
- package/assets/patterns/browser-verification-stand.md +24 -9
- package/assets/patterns/git-workflow-pr.github.md +29 -22
- package/assets/patterns/spec-driven-domain.md +5 -0
- package/assets/patterns/spec-driven-rule.md +41 -1
- package/assets/patterns/task-flow-archive.md +12 -0
- package/assets/patterns/task-flow-handoff.md +14 -1
- package/assets/patterns/task-flow-resume.md +11 -0
- package/assets/patterns/task-flow-start.md +40 -40
- package/assets/patterns/testing-e2e.md +15 -0
- package/assets/patterns/testing-unit.md +13 -0
- package/assets/pitfalls/git-workflow.github.md +13 -0
- package/assets/pitfalls/spec-driven.md +20 -0
- package/assets/pitfalls/task-flow.md +78 -48
- package/assets/rules/git-workflow.azure.md +5 -0
- package/assets/rules/git-workflow.github.md +26 -23
- package/assets/rules/git-workflow.gitlab.md +5 -0
- package/assets/rules/spec-driven.md +23 -24
- package/assets/rules/turn-conduct.md +13 -15
- package/assets/rules/turn-entry.md +6 -4
- package/assets/rules/typescript-conventions.md +7 -0
- package/assets/skills/agent-kit-extend.md +11 -0
- package/assets/skills/agent-kit.md +12 -2
- package/lib/commands.d.ts.map +1 -1
- package/lib/commands.js +36 -1
- package/lib/commands.js.map +1 -1
- package/lib/observations.d.ts +13 -1
- package/lib/observations.d.ts.map +1 -1
- package/lib/observations.js +7 -1
- package/lib/observations.js.map +1 -1
- package/package.json +1 -1
- package/rt-tools-agent-kit-0.22.0.tgz +0 -0
- package/rt-tools-agent-kit-0.20.0.tgz +0 -0
|
@@ -26,6 +26,16 @@
|
|
|
26
26
|
рабочим и молча ничего не делает.
|
|
27
27
|
- **Набор записей приходит с сервера страницей, а не целиком.** Список, растущий вместе с
|
|
28
28
|
данными, однажды перестаёт открываться, и заметно это становится уже у пользователя.
|
|
29
|
+
- **У значения, положенного приложением в браузер, есть род: устройство либо вошедший.**
|
|
30
|
+
Хранилище браузера переживает и перезагрузку, и выход, и смену того, кто вошёл; род решает,
|
|
31
|
+
снимается ли значение при выходе. По имени ключа он не виден: язык интерфейса принадлежит
|
|
32
|
+
устройству, выбранная рабочая область — вошедшему, и по именам они неразличимы. Умолчания у
|
|
33
|
+
рода нет тоже: оставленное значение сеанса отдаёт следующему вошедшему чужой выбор, а снятая
|
|
34
|
+
настройка устройства заставляет выбирать язык при каждом входе. Значит род называет человек, и
|
|
35
|
+
называет до того, как ключ заведён.
|
|
36
|
+
- **Значения сеанса снимает то же место, которое снимает вход.** Уход по истёкшему входу идёт
|
|
37
|
+
мимо кнопки выхода, и ключ, снятый своим экраном, остаётся лежать — то есть достаётся
|
|
38
|
+
следующему вошедшему на этом устройстве.
|
|
29
39
|
- **Окружение, которого нет на сервере, приходит экрану извне, а не берётся у среды.**
|
|
30
40
|
Взятое напрямую, оно компилируется и падает при отдаче страницы сервером — то есть у гостя,
|
|
31
41
|
а не у того, кто это написал. Места, где иначе нельзя, названы поимённо.
|
|
@@ -32,6 +32,11 @@
|
|
|
32
32
|
«здесь нет», «этого не заводили», «такого файла не бывает» — произносится только как вывод
|
|
33
33
|
команды. Не проверенное отрицание опаснее вопроса: вопрос владелец поправит, а факт от
|
|
34
34
|
исполнителя примет на веру, потому что тот в дерево смотрит.
|
|
35
|
+
- **Пустой вывод утверждением не бывает.** Он значит либо «ноль строк», либо «спрошено не то», и
|
|
36
|
+
различает эти два только повторный вызов — без конвейера и без глушения потока ошибок: в
|
|
37
|
+
конвейере код возврата принадлежит последнему звену, а заглушённый поток уносит текст промаха.
|
|
38
|
+
Пока такой вызов не сделан, о дереве не сказано ничего, а «ничего нет» — самая дорогая из
|
|
39
|
+
возможных ошибок: она отменяет работу, которую владелец велел сделать.
|
|
35
40
|
- **Отрицание, полученное одним источником, отрицанием не является.** Ответ «не найдено», отказ в
|
|
36
41
|
доступе и пустой список говорят о правах спрашивающего, а не о предмете: тот же вопрос, заданный
|
|
37
42
|
оттуда, где предмет виден, отвечает обратным. Сказать «этого нет» можно только после второго
|
|
@@ -50,6 +55,9 @@
|
|
|
50
55
|
просьбы, даже когда свой даёт тот же ответ: равноценность инструментов решает тот, кто просит.
|
|
51
56
|
Одинаковый результат равноценностью не является — у названного инструмента бывает видно то,
|
|
52
57
|
чего у заменителя нет вовсе.
|
|
58
|
+
- **Случившаяся подмена называется в том же докладе.** Чем сделано вместо названного и почему —
|
|
59
|
+
двумя словами, рядом с ответом на просьбу. Без этой строки владелец узнаёт о подмене, повторяя
|
|
60
|
+
указание: к той минуте работа по нему уже сделана не тем, и заплачено за неё дважды.
|
|
53
61
|
- **Понимание записано там, где идёт работа.** Оставленное в переписке живёт у одного участника и
|
|
54
62
|
до следующего дня; работу продолжает тот, у кого этой переписки нет.
|
|
55
63
|
- **Сказанное владельцем записывается его словами и задним числом не переписывается.** Пересказ
|
|
@@ -54,15 +54,26 @@ npx nx build admin --base-href=/
|
|
|
54
54
|
Angular DevTools, нужна ещё и dev-конфигурация (`--configuration=development`): прод-сборка не
|
|
55
55
|
публикует `window.ng`. Выводы о размере бандла и минификации на такой сборке делать нельзя.
|
|
56
56
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
57
|
+
Собранное отдаётся прокси дерева с его настоящим конфигом, а не статическим сервером. Причин
|
|
58
|
+
две, и обе всплывают в первую минуту: приложение ходит за процедурами на свой же origin, а по
|
|
59
|
+
глубокой ссылке статический сервер отвечает `404` — маршрутов одностраничного приложения он не
|
|
60
|
+
знает и на его точку входа не откатывается. Гард дев-серверов такой сервер отбивает наравне с
|
|
61
|
+
`nx serve`, и это указание на верный ход, а не помеха: готовый вызов — раздел «Стенд под
|
|
62
|
+
настоящим nginx» ниже, он и отдаёт собранное, и проксирует процедуры.
|
|
63
|
+
|
|
64
|
+
Вход делается формой, как у человека. Учётная запись местной базы разработки — не секрет
|
|
65
|
+
владельца: её кладёт туда засев того же дерева, а пароль лежит в файле окружения рядом.
|
|
66
|
+
Разрешения на неё не спрашивают — спрашивают про боевую запись, а её на местном стенде не
|
|
67
|
+
бывает вовсе. Там, где приёмника рядом нет, ответ входа подменяет сам стенд: путь у приложения
|
|
68
|
+
остаётся тот же, что у человека.
|
|
69
|
+
|
|
70
|
+
Токен руками не подписывается и в хранилище браузера руками не кладётся: положенный так, он
|
|
71
|
+
проверяет экран, миновав живой путь входа, — то есть отвечает не на тот вопрос. Просьба к
|
|
72
|
+
человеку набрать пароль, открыть вкладку или нажать кнопку означает неверно выбранный путь, а
|
|
73
|
+
не нехватку прав у исполнителя.
|
|
74
|
+
|
|
75
|
+
Стенд владельца запасным путём не бывает: он собирает главную ветку и о правке в рабочем дереве
|
|
76
|
+
не говорит ничего.
|
|
66
77
|
|
|
67
78
|
## Стенд API
|
|
68
79
|
|
|
@@ -163,6 +174,10 @@ done
|
|
|
163
174
|
это по её длительности.
|
|
164
175
|
- Свой дев-сервер не поднимать: сайт на {{sitePort}}, админка на {{adminPort}}, API на {{apiPort}} уже подняты
|
|
165
176
|
владельцем, и второй экземпляр отбивается гардом.
|
|
177
|
+
- **Отбитый статический сервер читается как запрет проверки, а он указание на верный ход.**
|
|
178
|
+
Отдавать собранное им нельзя не из осторожности: приложение ходит на свой origin, а глубокая
|
|
179
|
+
ссылка отвечает `404`. Отсюда идут не к обходу гарда, а к прокси дерева с его настоящим
|
|
180
|
+
конфигом.
|
|
166
181
|
- **Дев-сервер владельца — место, где смотрят, а не место, где проверяют.** Вывод о том, что
|
|
167
182
|
экран верен, делается на прод-сборке за настоящим прокси: разметка от сервера, локали, кэш,
|
|
168
183
|
перенаправления и заголовки на дев-сервере либо другие, либо отсутствуют вовсе. Взгляд на
|
|
@@ -94,10 +94,14 @@ GH_TOKEN="$TOKEN" gh pr create --title '[<КЛЮЧ>-86] Письмо владе
|
|
|
94
94
|
/opt/homebrew/bin/gh issue view 86 --json labels --jq '.labels | map(.name) | join(",")'
|
|
95
95
|
```
|
|
96
96
|
|
|
97
|
-
Строка `Closes #<номер>` обязательна: без неё PR не прикрепляется к задаче, и сверка очереди
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
97
|
+
Строка `Closes #<номер>` обязательна: без неё PR не прикрепляется к задаче, и сверка очереди это
|
|
98
|
+
находит. Она же означает, что задача закрывается целиком — половину задачи одним PR не выкатывают:
|
|
99
|
+
работа, которая в одну ветку не влезает, делится на задачи до того, как ветка заводится.
|
|
100
|
+
|
|
101
|
+
Отказ о превышенной квоте языка запросов (`API rate limit already exceeded`) заявки не заводит
|
|
102
|
+
вовсе; открытие идёт тогда вызовом REST — `$GH api -X POST "repos/$REPO/pulls" -f head=… -f
|
|
103
|
+
base=… -f title=… -F body=@<файл>`, — а метки и ревьювер ставятся следом. Текст такого отказа
|
|
104
|
+
читается как временный, но квота у записи не исчерпана, а равна нулю: ждать нечего.
|
|
101
105
|
|
|
102
106
|
У уже открытого PR то же ставится тремя вызовами REST. `gh pr edit` здесь не годится: он
|
|
103
107
|
запрашивает карточки Projects (classic), получает отказ о снятом API и до правки не доходит.
|
|
@@ -177,11 +181,10 @@ $GH api "repos/$REPO/pulls/321" \
|
|
|
177
181
|
назначить автора ревьювером нельзя, а отказа на такой запрос не приходит. Владельцу называют
|
|
178
182
|
то, что прочитали, а не то, что заказывали.
|
|
179
183
|
|
|
180
|
-
Прочитанное расхождение имеет назначенное
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
означает, что порядок поставки прочитан и не исполнен: ход отсюда один.
|
|
184
|
+
Прочитанное расхождение имеет назначенное действие: автора у заявки не сменить, и она
|
|
185
|
+
закрывается и открывается заново токеном машинной записи — с переносом тела, меток, ревьювера и
|
|
186
|
+
исполнителя. Номер сменится, и ссылки на прежний переписываются тем же ходом. Развилка, вынесенная
|
|
187
|
+
тут владельцу, означает, что порядок поставки прочитан и не исполнен.
|
|
185
188
|
|
|
186
189
|
Учётная запись, из-под которой пришлось пушить, в этот вызов не переносится: пуш и авторство
|
|
187
190
|
PR выбираются отдельно, и `GH_TOKEN` для публикации — всегда токен бота.
|
|
@@ -191,10 +194,16 @@ PR выбираются отдельно, и `GH_TOKEN` для публикац
|
|
|
191
194
|
фразой владелец успевает влить PR, и всё сказанное о нём после этого — про вчерашний день. Так
|
|
192
195
|
владельцу и было предложено влить то, что он влил часом раньше.
|
|
193
196
|
|
|
194
|
-
Читается состояние и перед пушем в ветку, у которой есть
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
197
|
+
Читается состояние и перед пушем в ветку, у которой есть заявка. Влитая заявка означает, что
|
|
198
|
+
ветки на сервере уже нет: пуш её не обновит, а заведёт заново, и вклад останется вне главной
|
|
199
|
+
ветки. Ответ пуша говорит это отметкой о новой ветке вместо перечня коммитов — на удачную
|
|
200
|
+
отправку он похож целиком.
|
|
201
|
+
|
|
202
|
+
**Итог прогона читается отдельным вызовом, а не кодом возврата ожидания.** Команда клиента,
|
|
203
|
+
которая ждёт конца прогона, возвращает ноль и на красном: дождалась она конца, а не успеха.
|
|
204
|
+
Прочитанный как исход, этот ноль делает зелёным то, что упало, и сказанное владельцу о зелёном
|
|
205
|
+
прогоне оказывается про красный. Состояние и заключение прогона спрашивают своим вызовом — тем
|
|
206
|
+
же, каким читают состояние заявки.
|
|
198
207
|
|
|
199
208
|
Открытый PR означает, что задача ждёт разбора, — колонка переставляется тем же движением:
|
|
200
209
|
|
|
@@ -212,13 +221,11 @@ npm run task:move -- 86 in-review
|
|
|
212
221
|
гоняет ничего. Линтеры, юниты и сценарии хуков снимает гейт пуша — ниже то, чего он не знает.
|
|
213
222
|
|
|
214
223
|
1. **Главная ветка влита в эту ветку** — `git fetch origin && git merge origin/main`.
|
|
215
|
-
Свежесть основания между ветками одного захода не наследуется: вторая и третья
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
показывает ревьюверу правку вперемешку с чужой. Порядок и разбор конфликта — паттерн
|
|
221
|
-
`git-workflow-merge`.
|
|
224
|
+
Свежесть основания между ветками одного захода не наследуется: вторая и третья отводятся
|
|
225
|
+
после своего `fetch`, а не от ссылки под первую. Пока идёт работа, главная уходит вперёд —
|
|
226
|
+
чаще всего собственным PR того же исполнителя. Всё, что проверяется ниже, проверяется от
|
|
227
|
+
этого основания: PR с разошедшейся ветки показывает ревьюверу правку вперемешку с чужой.
|
|
228
|
+
Порядок и разбор конфликта — паттерн `git-workflow-merge`.
|
|
222
229
|
2. **В ветке только та правка, за которой её заводили** — `git diff main...HEAD --stat`. Чужой
|
|
223
230
|
домен в списке файлов означает, что правка расползлась, и её надо вернуть в свои границы.
|
|
224
231
|
3. **Ни мока, ни подменённого ответа, ни отладочной строки** — `git diff main...HEAD` читается
|
|
@@ -281,8 +288,8 @@ in-review`, — и `npm run check:board` прогоняется ещё раз:
|
|
|
281
288
|
- Второй строкой `Closes` в одном PR задача больше не закрывается: две задачи в одной ветке
|
|
282
289
|
откатываются только вместе. Либо это одна задача — и вторая поглощается, — либо две ветки.
|
|
283
290
|
- Половина задачи, уехавшая своим PR, тоже промах: тело такого PR начинается со слов «Часть
|
|
284
|
-
#<номер>» вместо `Closes`, задача остаётся
|
|
285
|
-
|
|
291
|
+
#<номер>» вместо `Closes`, и задача остаётся открытой. Работа, которая в одну ветку не
|
|
292
|
+
влезает, делится на задачи до того, как ветка заводится.
|
|
286
293
|
- PR открыт без ревьювера: он не попадает во входящие владельца вовсе, и очередь стоит,
|
|
287
294
|
выглядя работающей. Так шестнадцать PR ждали разбора, которого никто не запрашивал.
|
|
288
295
|
- Метки поставлены по названию PR, а не прочитаны у задачи: область теряется, и по борде не
|
|
@@ -108,6 +108,11 @@ docs/specs/<домен>/
|
|
|
108
108
|
Тогда отказ подаётся владельцу как занятые даты, а не как ошибка базы
|
|
109
109
|
```
|
|
110
110
|
|
|
111
|
+
**«Тогда» называет один исход.** Формулировка через «либо» описывает два устройства сразу, и
|
|
112
|
+
какое из них работает, по сценарию не узнать: сценарий зелен при любом. Развилка описывается
|
|
113
|
+
двумя сценариями с разным «Дано» — тогда смена поведения роняет ровно тот из них, который
|
|
114
|
+
перестал быть верным, а не проходит молча.
|
|
115
|
+
|
|
111
116
|
Идентификатор ставится в начало заголовка теста, через тире. Сценарий без теста помечается
|
|
112
117
|
`Не покрыто: <причина>`, сценарий с неполным тестом — `Покрытие: частичное — <чего не
|
|
113
118
|
хватает>`.
|
|
@@ -86,6 +86,11 @@ description: Правило под «Закон о поставке». Брат
|
|
|
86
86
|
пустой она не бывает. Выводить требование из фразы в тексте нельзя: разложено у потребителя не
|
|
87
87
|
всё, и текст, сказавший «правку отбивает гард», врёт в дереве, где гарда нет.
|
|
88
88
|
|
|
89
|
+
Читается строка списком идентификаторов ресурсов, поэтому проза в ней превращается в требования,
|
|
90
|
+
которых нет: «требует команду строки запуска и токен дерева» раскладка разбирает на два имени и
|
|
91
|
+
печатает оба неотвеченными — в её выводе такие строки неотличимы от настоящей нехватки.
|
|
92
|
+
Требование объявляется идентификатором ресурса либо не объявляется вовсе.
|
|
93
|
+
|
|
89
94
|
Разделы: `## Как это называется здесь` · `## Где это лежит` · `## Как закон применяется
|
|
90
95
|
здесь` · `## Чего из закона здесь нет` · `## Паттерны` · `## Ловушки`.
|
|
91
96
|
|
|
@@ -114,7 +119,26 @@ description: Паттерн правила git-workflow. Брать … Не б
|
|
|
114
119
|
---
|
|
115
120
|
```
|
|
116
121
|
|
|
117
|
-
Разделы: `## Когда брать` · готовый код · `##
|
|
122
|
+
Разделы: `## Когда брать` · готовый код · `## Как пишется сама статья
|
|
123
|
+
|
|
124
|
+
**Довод при статье называет устройство, на котором он верен.** Довод стареет вместе с тем, что
|
|
125
|
+
его вызвало: запрет писать в чужую настройку стоял на том, что слияние JSON молча теряет
|
|
126
|
+
несовпавшее, — и был верен, пока куском была карта из двух десятков объявлений. Пришёл
|
|
127
|
+
диспетчер, кусок стал строкой на событие, довод перестал быть верным, а стоял ещё две редакции
|
|
128
|
+
и читался действующим запретом. Названное устройство — то, по чему при следующей правке видно,
|
|
129
|
+
что довод пора перечитать.
|
|
130
|
+
|
|
131
|
+
**Требование к шагу стоит в том разделе, который этот шаг ведёт.** Написанное ниже читается
|
|
132
|
+
после шага: раздел об оставшемся шаге требовался и прежде, и образцы стояли готовые, — но само
|
|
133
|
+
требование лежало ниже описания открытия заявки. Читающий доходил до открытия, открывал заявку
|
|
134
|
+
и требования ещё не видел; выглядит это забывчивостью, а не порядком текста.
|
|
135
|
+
|
|
136
|
+
**Статья о непроверяемом называет, какое именно средство её не берёт.** «Проверить машиной
|
|
137
|
+
нечем» стареет вместе с тем, чем проверяли: тело заявки не читает сверка очереди работ — и это
|
|
138
|
+
было записано как «не читает никто», хотя гард поставки разбирает ту же строку команды и по ней
|
|
139
|
+
судит заголовок. Названное средство даёт следующей правке точку, от которой отсчитывать.
|
|
140
|
+
|
|
141
|
+
## Частые промахи`. Привязки у паттерна нет:
|
|
118
142
|
проверка его не сверяет, потому что сверять готовый код с ним самим нечем.
|
|
119
143
|
|
|
120
144
|
## Описание: триста знаков и один вопрос
|
|
@@ -183,6 +207,19 @@ description: Паттерн правила git-workflow. Брать … Не б
|
|
|
183
207
|
|
|
184
208
|
## Частые промахи
|
|
185
209
|
|
|
210
|
+
- Проверка требования «шаг делается» поставлена на вызов самого шага. Гард, привязанный к
|
|
211
|
+
вызову, ловит форму сделанного и не видит несделанного вовсе: снятие черновика, которого не
|
|
212
|
+
было, не даёт ему ни одного события. У такого требования проверка стоит на завершении хода —
|
|
213
|
+
там видно, чего за ход не случилось.
|
|
214
|
+
- Привязка называет одно место исполнения, а исполняют утверждение несколько сторон. Сверка
|
|
215
|
+
смотрит наличие строки, а не полноту списка: договорённость обещала объявление нескольких
|
|
216
|
+
событий, привязка вела в сборку настройки, а диспетчер читал одно — и молчали обе стороны.
|
|
217
|
+
Статья, чьё утверждение исполняют несколько мест, называет их все.
|
|
218
|
+
- Список, названный деревом, лежит в компаньоне, а общий довод — в самом правиле. В контекст
|
|
219
|
+
общий довод приходит всегда, а список — только когда его прочитали, и проигрывает он в ту же
|
|
220
|
+
минуту, когда решение принимают по памяти. Всякий раз, когда правило требует «список назван
|
|
221
|
+
деревом», оно требует и того, чтобы список читали раньше общих слов, — и говорит это прямо.
|
|
222
|
+
|
|
186
223
|
- Закон назвал файл проекта — проверка отбивает. Путям место в правиле.
|
|
187
224
|
- Спутник с привязкой лежит рядом с законом: он привязывает закон к этому проекту, а зелёная
|
|
188
225
|
проверка это утвердит, потому что структура совпадёт с тем, чего проверка сама и ждёт.
|
|
@@ -190,6 +227,9 @@ description: Паттерн правила git-workflow. Брать … Не б
|
|
|
190
227
|
правку сущности оказались привязаны к механике, которую не зовёт ни один экран.
|
|
191
228
|
- Утверждение переформулировали, а строку в привязке не тронули: связь идёт по тексту, и
|
|
192
229
|
проверка перестанет её находить.
|
|
230
|
+
- Пустая привязка отбивается сверкой спеков, и вердикт для неё нужен дословный: принимаются
|
|
231
|
+
«Не исполняется», «Не применимо», «Не проверяется». Фраза своими словами — «держится текстом»,
|
|
232
|
+
«проверяется глазами» — вердиктом не считается, и узнаётся это отказом сверки.
|
|
193
233
|
- Строка привязки дописана в конец компаньона, а не вставлена в таблицу. После таблицы там идут
|
|
194
234
|
ещё разделы — «Чем это проверяется», «Что ещё стоит знать при чтении кода», — и приписанная в
|
|
195
235
|
конец строка в таблицу не попадает вовсе: утверждение читается непривязанным, а сверка спеков
|
|
@@ -199,6 +199,18 @@ npm run cargo:mark -- --state fixed \
|
|
|
199
199
|
правит ссылки во всех текстах, которые на неё смотрят, ради ровного ряда имён. Порядок между
|
|
200
200
|
частями не нужен — находки друг друга не продолжают, и владелец читает их разом.
|
|
201
201
|
|
|
202
|
+
**Строка находки, закрытой другой работой, помечается номером той работы.** Починенная по
|
|
203
|
+
частям находка со стороны списка неотличима от несделанной: оба её промаха были закрыты своими
|
|
204
|
+
задачами и записаны предметно, каждый при своём поддомене, — а разбор ушёл на то, чтобы
|
|
205
|
+
выяснить, что чинить нечего. Номер стоит в самой строке, и следующий читатель этого пути не
|
|
206
|
+
проходит.
|
|
207
|
+
|
|
208
|
+
**Пункт сборной находки проверяется на живость до того, как берётся в работу.** Мелочи,
|
|
209
|
+
списанные в один пункт, не стареют вместе: из четырёх промахов живыми оказались два, один был
|
|
210
|
+
закрыт другой работой, четвёртый не воспроизводился — и разведка этого заняла больше времени,
|
|
211
|
+
чем сами правки. Сборная задача поэтому стоит ровно столько, сколько разведка её состава, и
|
|
212
|
+
это говорится владельцу до того, как её берут.
|
|
213
|
+
|
|
202
214
|
**Наружу без слова владельца уезжает только сводка наблюдений.** Она говорит, чем пользовались
|
|
203
215
|
и чем не пользовались ни разу, — это факт, и мнением он не станет. Предложение — другое дело:
|
|
204
216
|
это заготовка правки чужого дерева, и часть заготовок отпадает при первом же чтении. Уехавшая
|
|
@@ -59,13 +59,26 @@ description: Паттерн правила turn-conduct. Брать, когда
|
|
|
59
59
|
|
|
60
60
|
### Передача
|
|
61
61
|
|
|
62
|
-
Кладётся
|
|
62
|
+
Кладётся разделом `## Передача захода` в ход работы задачи — в тот же файл, где стоит «Где
|
|
63
|
+
стоим». Он коммитится и едет в ветку, поэтому передача переживает переход на другую машину:
|
|
64
|
+
работу, оборванную заполнением окна, подхватывают там, где её продолжают. Коммитит и пушит
|
|
65
|
+
раздел исполнитель, тем же ходом, что и остальную запись работы.
|
|
66
|
+
|
|
67
|
+
Раздел один: второе сжатие переписывает прежний, а не дописывает второй — две правды об одной
|
|
68
|
+
работе в одном файле хуже одной устаревшей. Заголовки внутри него идут третьим уровнем, чтобы
|
|
69
|
+
не сталкиваться с разделами самого хода работы.
|
|
70
|
+
|
|
71
|
+
У работы без папки задачи — отсоединённая голова, ветка без заведённой задачи — разделу лечь
|
|
72
|
+
некуда, и передача уезжает файлом вне дерева; каталог называет профиль:
|
|
63
73
|
|
|
64
74
|
```bash
|
|
65
75
|
mkdir -p <каталог передачи>
|
|
66
76
|
# файл — <каталог передачи>/<ветка>.md
|
|
67
77
|
```
|
|
68
78
|
|
|
79
|
+
Это запасной путь, а не второе законное место: у ветки с папкой задачи такой файл не заводится
|
|
80
|
+
вовсе, и читающая сторона его не смотрит, найдя раздел.
|
|
81
|
+
|
|
69
82
|
**Черновик передачи пишет хук, а не рука.** Перед сжатием контекста он кладёт по тому же
|
|
70
83
|
адресу то, что есть на диске: ветку, состояние работы, следующий шаг, незакоммиченное, коммиты
|
|
71
84
|
сверх главной. Сжатие приходит и тогда, когда напомнить некому — ночью или посреди длинного
|
|
@@ -32,6 +32,17 @@ description: Паттерн правила task-flow. Брать при возв
|
|
|
32
32
|
замечаниям разбора — папка восстанавливается на время правки, а разбор повторяется тем же
|
|
33
33
|
коммитом.
|
|
34
34
|
|
|
35
|
+
## Признак этапа проверяется прогоном, а не перечислением по чтению
|
|
36
|
+
|
|
37
|
+
Пересчитанное глазами расходится с тем, что есть: читая проверку, исполнитель насчитал четыре
|
|
38
|
+
выхода пропуском, а их было пять — пятый лежал за отдельной функцией внутри обвязки клиента
|
|
39
|
+
базы и в перечень не попал. Нашёлся он прогоном, и спасла работу именно та строка замысла,
|
|
40
|
+
которая требовала проверить каждый случай командой.
|
|
41
|
+
|
|
42
|
+
Отсюда форма признака: он называет команду и то, что в её выводе означает «сошлось», — а не
|
|
43
|
+
перечень, собранный чтением. Перечень годится, чтобы понять, где смотреть; закрытым этап
|
|
44
|
+
делает вывод команды.
|
|
45
|
+
|
|
35
46
|
## Чего не делать
|
|
36
47
|
|
|
37
48
|
- **Не спрашивать владельца о том, что записано.** Ради этого всё и заведено.
|
|
@@ -45,12 +45,11 @@ Agent(subagent_type: "Explore", prompt: "<тема просьбы>: что по
|
|
|
45
45
|
записи прошлых заходов. Одно место отрицанием не является: «в таком-то месте не нашёл» говорит о
|
|
46
46
|
месте, а не о дереве, и вопрос называет оба способа, которыми искали.
|
|
47
47
|
|
|
48
|
-
Разведка кончается не ощущением, а выводом команд. До первого вопроса владельцу исполнитель
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
одной команды.
|
|
48
|
+
Разведка кончается не ощущением, а выводом команд. До первого вопроса владельцу исполнитель знает:
|
|
49
|
+
как устроен репозиторий (корневая памятка), что лежит в каталоге, о котором пойдёт речь (`ls`), и
|
|
50
|
+
есть ли уже написанное по теме (поиск по документации и правилам). Без списка того, что считается
|
|
51
|
+
сделанным, разведка исполняется как настроение: прочитанный переданный текст сходит за неё, и по
|
|
52
|
+
дереву не запускается ни одной команды.
|
|
54
53
|
|
|
55
54
|
Разведка по заведённой задаче кончается воспроизведённым симптомом, а не найденным файлом. Тело
|
|
56
55
|
задачи описывает дерево на день заведения, и чужие правки въезжают в главную ветку между
|
|
@@ -94,11 +93,10 @@ Agent(subagent_type: "Explore", prompt: "<тема просьбы>: что по
|
|
|
94
93
|
Форму вопроса задают настройки владельца: где требуют меню, спрашивается меню, и к каждому
|
|
95
94
|
вопросу добавляется свободный вариант — у закрытого набора нет строки «вопрос не тот».
|
|
96
95
|
|
|
97
|
-
**Рамка переданного текста на текущее дерево не переносится.** Передача захода, файл
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
дерева, которое пакет и пишет, и ставит.
|
|
96
|
+
**Рамка переданного текста на текущее дерево не переносится.** Передача захода, файл предложений
|
|
97
|
+
и спек описывают то дерево, в котором писались; про текущее знает только текущее, и утверждение о
|
|
98
|
+
раскладке проверяется командой здесь. Подтверждение находится само — признаки дерева, только
|
|
99
|
+
ставящего пакет, стоят и у того, которое пакет пишет и ставит.
|
|
102
100
|
|
|
103
101
|
Сообщение, которым исполнитель останавливается, начинается с того, чего он ждёт:
|
|
104
102
|
|
|
@@ -108,12 +106,12 @@ Agent(subagent_type: "Explore", prompt: "<тема просьбы>: что по
|
|
|
108
106
|
```
|
|
109
107
|
|
|
110
108
|
Под вопросом идёт таблица положения эпика — та же, что в передаче. Под, а не над: остановка
|
|
111
|
-
называется первой строкой,
|
|
112
|
-
|
|
109
|
+
называется первой строкой, а положение эпика — то, из чего владелец решает. Работа вне эпика
|
|
110
|
+
таблицы не несёт.
|
|
113
111
|
|
|
114
|
-
Замеры, находки ролей и список решений к этому моменту
|
|
115
|
-
|
|
116
|
-
|
|
112
|
+
Замеры, находки ролей и список решений к этому моменту записаны в ход работы, и в сообщении
|
|
113
|
+
владельцу они лишние: отчёт, в конце которого стоит вопрос, выглядит добросовестно ровно
|
|
114
|
+
настолько, насколько надёжно вопрос в нём тонет.
|
|
117
115
|
|
|
118
116
|
Ответы пишутся в `docs/tasks/_draft-<slug>/grill.md` — папка ещё черновик, номера нет.
|
|
119
117
|
|
|
@@ -153,9 +151,9 @@ Workflow(name: "plan", args: "docs/tasks/_draft-<slug>")
|
|
|
153
151
|
|
|
154
152
|
### Состояние `договорённость-записана`: серия задач объявляется эпиком
|
|
155
153
|
|
|
156
|
-
Разбор кончился одной задачей — шаг пропускается. Вышло несколько, и порядок между ними
|
|
157
|
-
|
|
158
|
-
|
|
154
|
+
Разбор кончился одной задачей — шаг пропускается. Вышло несколько, и порядок между ними значим —
|
|
155
|
+
эпик объявляется здесь, до первой из них, и дважды: карточкой в очереди работ с меткой эпика и
|
|
156
|
+
замыслом рядом с ней.
|
|
159
157
|
|
|
160
158
|
Замысел эпика называет три вещи, и ни одна не выводится из остальных:
|
|
161
159
|
|
|
@@ -171,12 +169,11 @@ Workflow(name: "plan", args: "docs/tasks/_draft-<slug>")
|
|
|
171
169
|
```
|
|
172
170
|
|
|
173
171
|
Состав без порядка порядком не является: две задачи, у которых он держался пониманием, ушли в
|
|
174
|
-
работу наоборот, и вторая переделывалась под первую. Назначенный
|
|
175
|
-
|
|
176
|
-
вызвала.
|
|
172
|
+
работу наоборот, и вторая переделывалась под первую. Назначенный порядок держится до конца эпика;
|
|
173
|
+
пересмотр — решение владельца, и пишется он в ход работы той задачи, которая его вызвала.
|
|
177
174
|
|
|
178
|
-
Лежит замысел вне папки задачи: та умирает с мержем первой
|
|
179
|
-
|
|
175
|
+
Лежит замысел вне папки задачи: та умирает с мержем первой же. Каталог для него называет компаньон
|
|
176
|
+
правила — у пакета своего пути нет.
|
|
180
177
|
|
|
181
178
|
Карточки заводятся на все задачи разом, здесь же: по вызову заведения задачи на каждую строку
|
|
182
179
|
таблицы, с меткой эпика. Выданные номера возвращаются в ту же таблицу — колонкой или приставкой
|
|
@@ -200,20 +197,24 @@ git checkout -b <КЛЮЧ>-<номер>-<slug>
|
|
|
200
197
|
npm run task:move -- <номер> in-progress
|
|
201
198
|
```
|
|
202
199
|
|
|
200
|
+
Тело приходит файлом и пустым не бывает: заведённая пустой задача не говорит ничего ни
|
|
201
|
+
исполнителю, ни владельцу, а дописать её потом можно только со слова владельца — и заводится
|
|
202
|
+
пустое молча, номером наравне с полным.
|
|
203
|
+
|
|
203
204
|
`task:new` переименовывает `_draft-<slug>` в `<КЛЮЧ>-<номер>-<slug>` и проставляет шапку замысла.
|
|
204
205
|
Ветка заводится вторым вызовом: составную «завести и сразу коммитить» гард главной ветки
|
|
205
206
|
отклоняет целиком.
|
|
206
207
|
|
|
207
|
-
Номер уже выдан — черновика нет и не заводится: папка
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
заведённой нельзя работать.
|
|
208
|
+
Номер уже выдан — черновика нет и не заводится: папка открывается сразу под именем ветки, а
|
|
209
|
+
разбор пишется в неё же. Так начинается половина работ: номер приходит прошлым заходом,
|
|
210
|
+
замеченным дефектом или соседней задачей, и шаг с черновиком тогда неисполним — переименовывать
|
|
211
|
+
нечего. Ловушка «номер не бывает первым» сюда не относится: она про то, что задачу не заводят до
|
|
212
|
+
разбора, а не про то, что с уже заведённой нельзя работать.
|
|
213
213
|
|
|
214
|
-
Остальные два файла пишутся, а не кладутся образцом впрок: пустой `plan.md`
|
|
215
|
-
|
|
216
|
-
|
|
214
|
+
Остальные два файла пишутся, а не кладутся образцом впрок: пустой `plan.md` неотличим от
|
|
215
|
+
замысла без этапов, а следующий заход доверяет папке задачи. Образец открывается тем же
|
|
216
|
+
движением, которым заполняется, и шапку раскладки с копии снимают тут же — иначе правку отобьёт
|
|
217
|
+
гард, а ловушка при правиле объясняет почему:
|
|
217
218
|
|
|
218
219
|
```bash
|
|
219
220
|
cp docs/tasks/_template/plan.md docs/tasks/<КЛЮЧ>-<номер>-<slug>/plan.md # и сразу пишется
|
|
@@ -229,8 +230,8 @@ cp docs/tasks/_template/progress.md docs/tasks/<КЛЮЧ>-<номер>-<slug>/pr
|
|
|
229
230
|
Пока не объявлено состояние, в котором код правится, гард отбивает правку и называет
|
|
230
231
|
обязательное действие того состояния, которое стоит в строке.
|
|
231
232
|
|
|
232
|
-
**Следующее движение:** объявив состояние, тот же ход берётся за замысел
|
|
233
|
-
|
|
233
|
+
**Следующее движение:** объявив состояние, тот же ход берётся за замысел с его шапки. Заведённая
|
|
234
|
+
папка ходом не кончается: написанного файла в ней ещё нет ни одного.
|
|
234
235
|
|
|
235
236
|
### Состояние `задача-взята`: шапка замысла
|
|
236
237
|
|
|
@@ -270,11 +271,10 @@ cp docs/tasks/_template/progress.md docs/tasks/<КЛЮЧ>-<номер>-<slug>/pr
|
|
|
270
271
|
- **Этап:** 1 из 3 — <название первого этапа из замысла>
|
|
271
272
|
```
|
|
272
273
|
|
|
273
|
-
Ход на этой границе не кончается. Написанный замысел выглядит законченным куском: этапы
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
двух процентов.
|
|
274
|
+
Ход на этой границе не кончается. Написанный замысел выглядит законченным куском: этапы разложены,
|
|
275
|
+
файл закоммичен, отчитаться есть чем — и отчёт встаёт ровно на то место, которое должна была
|
|
276
|
+
занять работа. Владелец читает его как сделанное, а сделано ничего: 21 августа заход кончился
|
|
277
|
+
строкой «следующий шаг — такой-то» при заполнении окна около двух процентов.
|
|
278
278
|
|
|
279
279
|
Кончают ход четыре вещи, и они те же, что у остальных состояний: предел заполнения окна, отказ
|
|
280
280
|
гарда, вопрос владельцу и отданная работа, по которой начата следующая. Дочитанный до конца
|
|
@@ -90,6 +90,21 @@ expect(answer.headers()['location']).toBe('/новый-адрес');
|
|
|
90
90
|
Отличать постоянный переход от временного нужно там, где на нём стоит договорённость: поисковые
|
|
91
91
|
роботы и браузер запоминают только постоянный, и разница между 301 и 302 видна лишь в ответе.
|
|
92
92
|
|
|
93
|
+
## Состояние экрана после действия ждётся опросом, а не читается следующей строкой
|
|
94
|
+
|
|
95
|
+
Между нажатием и новым содержимым лежит сеть: отбор уходит в адрес нажатием, а строки приезжают
|
|
96
|
+
ответом сервера, и прочитанные сразу — ещё прежние. Спека, читающая столбец следующей строкой,
|
|
97
|
+
проходит на своей машине и краснеет в конвейере: там ответ приходит позже, и разница между
|
|
98
|
+
машинами решает исход.
|
|
99
|
+
|
|
100
|
+
Ждётся поэтому само состояние — опросом до совпадения с ожидаемым, а не одним чтением и не
|
|
101
|
+
паузой на время. Пауза проверяет машину: на свободной её хватает всегда, на занятой не хватает,
|
|
102
|
+
и какая именно спека не успела, оказывается делом случая.
|
|
103
|
+
|
|
104
|
+
Знание это заводится в правиле, а не в общем модуле набора: записанное только кодом, оно
|
|
105
|
+
известно тому, кто его писал, — следующая спека повторяет промах, потому что читает не код, а
|
|
106
|
+
правило.
|
|
107
|
+
|
|
93
108
|
## Частые промахи
|
|
94
109
|
|
|
95
110
|
- **Порт {{ssrPort}} занимать осторожно:** стенд разработчика на {{sitePort}} ходит по тому же имени
|
|
@@ -106,6 +106,19 @@ globalThis.fetch = (): Promise<Response> => Promise.resolve(Response.json({ succ
|
|
|
106
106
|
заголовке и едет в ветке. Признак временного файла — его заголовок не называет ни одного
|
|
107
107
|
сценария.
|
|
108
108
|
|
|
109
|
+
## Зелёное, которое ничего не проверяет
|
|
110
|
+
|
|
111
|
+
**Проба, ждущая молчания, идёт в паре с пробой, ждущей отказа.** Молчание наступает и тогда,
|
|
112
|
+
когда проверять было нечем: приставка перед командой в конвейере действует на одно звено, и
|
|
113
|
+
хук, получивший пустое значение, молчит ровно так же, как хук, которому нечего отбивать. Две
|
|
114
|
+
пробы из трёх при этом зелены — они и ждали молчания, — и промах виден только по третьей,
|
|
115
|
+
которая ждёт отказа.
|
|
116
|
+
|
|
117
|
+
**Проба на мину, которая не срабатывает, зелена и без починки.** Сценарий на таблицу кодов
|
|
118
|
+
отказа у спека без процедур проходил бы и до правки: читать эту таблицу сверке не приходится
|
|
119
|
+
вовсе. Проверяется такая проба обеими сторонами — прежнее состояние возвращается на минуту и
|
|
120
|
+
прогоняется: не покраснело, значит проба ничего не сторожит.
|
|
121
|
+
|
|
109
122
|
## Частые промахи
|
|
110
123
|
|
|
111
124
|
- Либа без своего `vitest.config.mts`: `nx test <проект>` пройдёт зелёным, не запустив ни
|
|
@@ -219,8 +219,21 @@
|
|
|
219
219
|
ни статус, ни сверка, а команда, прошедшая между прятаньем и возвратом, пишет в те же файлы —
|
|
220
220
|
и возврат встаёт конфликтом. Так ушли в прятанье восемь незакоммиченных файлов при живом
|
|
221
221
|
запрете на эту команду: запрет читался в начале захода, а команда набиралась через сорок ходов.
|
|
222
|
+
- **Вывод команды, которой нужен репозиторий, собирается в каталоге репозитория.**
|
|
223
|
+
Перенаправление создаёт файл раньше, чем команда успевает отказать: клиент хостинга, позванный
|
|
224
|
+
из каталога временных файлов, падает строкой о том, что это не репозиторий, а пустой файл к
|
|
225
|
+
этой минуте уже записан. Уехав дальше — в тело заявки, в замысел, в правило, — он стирает
|
|
226
|
+
написанное, и восстанавливается это только историей правок на стороне хостинга. Файл вывода
|
|
227
|
+
поэтому кладётся в дереве, а записанное проверяется до того, как его куда-то отправят.
|
|
228
|
+
|
|
222
229
|
- **Очередь конвейера, заведённая на всё дерево, снимает ждущего чужим пушем.** Группа
|
|
223
230
|
одновременности с отменой уже идущего экономит машину ровно до первого соседа: его пуш снимает
|
|
224
231
|
прогон чужой ветки, и та остаётся с вершиной без единого прогона — заявка при этом выглядит
|
|
225
232
|
непроверенной, а прогонять её заново некому. Группа поэтому заводится своя на ветку, и общей
|
|
226
233
|
остаётся только у шагов, которым нужен стенд: их и правда нельзя гнать вдвоём на одной машине.
|
|
234
|
+
|
|
235
|
+
- **Команды дерева зовутся из его корня, а не из каталога пакета.** В подкаталоге со своим
|
|
236
|
+
манифестом запуск берёт его, а не корневой, и отвечает «такой команды нет» — при том что в
|
|
237
|
+
дереве она есть и написана верно. Читается это как поломка команды, а лечится каталогом: путь
|
|
238
|
+
до неё называется от корня, и звать её оттуда.
|
|
239
|
+
|