@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
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: git-workflow-stack
|
|
3
3
|
kind: pattern
|
|
4
4
|
rule: git-workflow
|
|
5
|
-
description: Паттерн правила git-workflow. Брать, когда из одного основания заведено больше двух
|
|
5
|
+
description: Паттерн правила git-workflow. Брать, когда работы идут одна за другой либо когда из одного основания уже заведено больше двух веток: ветвление чередой от предыдущей, основание заявки, порядок вливания снизу вверх, перевливание главной по факту конфликта. Один конфликт — паттерн git-workflow-merge.
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Стопка заявок из одного основания
|
|
@@ -11,12 +11,70 @@ description: Паттерн правила git-workflow. Брать, когда
|
|
|
11
11
|
`docs/constitution/delivery.md`. Разбор одного конфликта — паттерн `git-workflow-merge`,
|
|
12
12
|
открытие одной заявки — `git-workflow-pr`.
|
|
13
13
|
|
|
14
|
+
**Вызовы здесь даны клиентом GitHub.** Дерево на другом хостинге читает их как форму, а команду
|
|
15
|
+
берёт у своего клиента: имена полей и подкоманд у клиентов разные, а спрашиваемое — одно.
|
|
16
|
+
Соответствие называет редакция правила поставки, разложенная в этом дереве.
|
|
17
|
+
|
|
14
18
|
## Когда брать
|
|
15
19
|
|
|
16
20
|
- Из одного основания заведено больше двух веток, и все ждут слияния.
|
|
17
21
|
- За заход сделано несколько работ, и они лежат в дереве невыложенными.
|
|
18
22
|
- Решается, в каком порядке отдавать накопленное владельцу.
|
|
19
23
|
|
|
24
|
+
## Череда: ветвиться от предыдущей, а не от главной
|
|
25
|
+
|
|
26
|
+
Стопка из одного основания — то, чего надо избежать. Работы, идущие подряд, ветвятся подряд:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
# первая работа череды — от главной, как обычно
|
|
30
|
+
git checkout -b <КЛЮЧ>-<номер>-<slug> origin/main
|
|
31
|
+
|
|
32
|
+
# каждая следующая — от предыдущей ветки, а не от origin/main
|
|
33
|
+
git checkout -b <КЛЮЧ>-<следующий>-<slug> <КЛЮЧ>-<номер>-<slug>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Правка предыдущей лежит тогда в общем предке, и сводить два разных изменения одного файла не
|
|
37
|
+
приходится вовсе. Расхождение всплывает при ветвлении — у того, у кого обе правки свои и под
|
|
38
|
+
рукой, — а не при слиянии, у владельца, у которого нет ни одной.
|
|
39
|
+
|
|
40
|
+
От главной ветвится первая работа череды и всякая, которая предыдущей не касается: череда — это
|
|
41
|
+
про соседние работы, а не про все подряд.
|
|
42
|
+
|
|
43
|
+
## Заявка череды стоит на предыдущей ветке
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
gh pr create --base <предыдущая ветка> --title '[<КЛЮЧ>-<номер>] <что сделано>' --body-file <файл>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Основанием главная не ставится: разбор тогда показывает свою правку вперемешку со всем, что под
|
|
50
|
+
ней. Влитую нижнюю хостинг переносит сам — базой её заявки-наследницы становится главная.
|
|
51
|
+
|
|
52
|
+
Порядок вливания стоит в теле каждой заявки строкой «стоит на #<номер>, вливать после него»:
|
|
53
|
+
владелец вливает по списку, а родство веток по списку не видно.
|
|
54
|
+
|
|
55
|
+
**Конвейер дерева проверяется на то, слушает ли он заявку с таким основанием.** Событие заявки
|
|
56
|
+
хостинг шлёт с фильтром по базе, и дерево, оставившее в фильтре одну главную ветку, всей череде
|
|
57
|
+
прогонов не даёт вовсе: заявка стоит зелёно-пустой, а вернуть событие нечем — ни новый коммит,
|
|
58
|
+
ни перезакрытие заявки базы не меняют. Спрашивается это до того, как череду заводить: у
|
|
59
|
+
настройки конвейера, а не у страницы заявки, где отсутствие прогона выглядит так же, как его
|
|
60
|
+
ожидание.
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
# порядок череды целиком — снизу вверх
|
|
64
|
+
gh pr list --state open --json number,headRefName,baseRefName \
|
|
65
|
+
--jq '.[] | "\(.number)\t\(.headRefName)\tна \(.baseRefName)"'
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Чего в череде не делают
|
|
69
|
+
|
|
70
|
+
- **Историю нижней ветки не переписывают.** Ни `rebase`, ни силовая отправка: вершина верхней
|
|
71
|
+
становится достижимой из её основания, и хостинг закрывает заявку верхней как слитую — при том
|
|
72
|
+
что в главной её правок нет. Отставшая нижняя чинится вливанием главной в неё и дальше вверх.
|
|
73
|
+
- **Череду не вливают из середины.** Влитая не по порядку тащит за собой всё, что под ней, — и
|
|
74
|
+
разбор той работы уже не состоится.
|
|
75
|
+
- **Готовые ветки не копят.** Череда не отменяет того, что единица работы — влитая заявка: она
|
|
76
|
+
лишь делает безопасной ту длину, которая всё же накопилась.
|
|
77
|
+
|
|
20
78
|
## Единица работы — влитая заявка, а не открытая
|
|
21
79
|
|
|
22
80
|
Открытый черновик работой не является: кнопка слияния у него заблокирована, в главной ветке его
|
|
@@ -65,6 +123,21 @@ docs/archive/README.md merge=union
|
|
|
65
123
|
Сложение ставится только на указатели, где правка всегда добавляющая. На текст, который
|
|
66
124
|
переписывают, оно оставит в файле обе редакции.
|
|
67
125
|
|
|
126
|
+
**Сложение сторон метку сливаемости не снимает, и вливать главную по ней нельзя.** Хостинг
|
|
127
|
+
считает сливаемость своим приёмом и настроек слияния не читает: ветка, тронувшая сложенный
|
|
128
|
+
указатель, помечается конфликтующей всё равно. Спрошенная у него стопка отвечает «конфликтует»
|
|
129
|
+
целиком, и вливание по этому ответу — то же вливание во все ветки, что и без сложения: раздел
|
|
130
|
+
ниже велит вливать главную по факту конфликта, а факт этот хостинг называет про каждую ветку
|
|
131
|
+
стопки. Пятнадцать заявок разом простояли так за один заход. Проверяется одной командой: то же
|
|
132
|
+
слияние без драйвера даёт конфликтный маркер, с драйвером идёт чисто — значит метку держит
|
|
133
|
+
указатель, а не правка.
|
|
134
|
+
|
|
135
|
+
**Указатель, куда дописывает каждая ветка стопки, из стопки убирается, а не складывается.**
|
|
136
|
+
Сложение — починка проявления: конфликта нет, метка есть, вливать по-прежнему приходится.
|
|
137
|
+
Спрашивается это до заведения веток: отвечает ли указатель на вопрос, которого не закрывает
|
|
138
|
+
обход каталога. Не отвечает — он снимается, и площадь пересечения стопки падает до настоящих
|
|
139
|
+
общих файлов.
|
|
140
|
+
|
|
68
141
|
## Порядок вливания задаётся заранее и называется владельцу
|
|
69
142
|
|
|
70
143
|
Порядок считается до открытия заявок — по тому, кто какие файлы правит:
|
|
@@ -79,6 +152,25 @@ done | sort | uniq -c | sort -rn | head
|
|
|
79
152
|
конфликт там, где подряд его бы не было. Порядок называется владельцу в теле заявки — кнопки
|
|
80
153
|
нажимает он, а о родстве веток не знает.
|
|
81
154
|
|
|
155
|
+
## Волна веток проверяется пробным слиянием
|
|
156
|
+
|
|
157
|
+
Ветка, лежащая невлитой рядом с соседками, зелена сама по себе: линт, тесты, сборки и сверки
|
|
158
|
+
она проходит одна. Сталкивается она с ними тем, чего на отдельной ветке не видит ни одна
|
|
159
|
+
проверка — тот же следующий свободный номер сценария, тот же заведённый новым файл, та же
|
|
160
|
+
правленная строка отметки. После слияния первые два чинятся уже в главной и стоят отдельной
|
|
161
|
+
работы.
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
git fetch origin
|
|
165
|
+
git checkout -b probe-merge origin/main
|
|
166
|
+
for b in <ветка-1> <ветка-2> <ветка-3>; do git merge --no-edit "origin/$b" || break; done
|
|
167
|
+
npm run check:all
|
|
168
|
+
git checkout - && git branch -D probe-merge
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Ветка пробы удаляется, а находки и порядок слияния записываются туда, где живёт замысел линии
|
|
172
|
+
работ: пробное слияние отвечает на «что столкнётся», а не заменяет собой отдачу.
|
|
173
|
+
|
|
82
174
|
## Частые промахи
|
|
83
175
|
|
|
84
176
|
- Открыты все заявки разом, потому что ветки были готовы. Готовность ветки признаком того, что
|
|
@@ -77,6 +77,10 @@ grep -rn "@<область>/<семья>/<домен>" libs/ apps/ | sed 's/:.*/
|
|
|
77
77
|
npx nx run-many -t lint --projects=<список по изменённым файлам>
|
|
78
78
|
```
|
|
79
79
|
|
|
80
|
+
Этот прогон — быстрый, по горячим следам переноса, и набором перед пушем он не бывает:
|
|
81
|
+
набор, собранный по изменённым файлам, пропускает то, до чего правка дошла связями. Перед
|
|
82
|
+
пушем идёт тот же набор, что гоняет конвейер, и теми же командами.
|
|
83
|
+
|
|
80
84
|
## Проверить
|
|
81
85
|
|
|
82
86
|
```bash
|
|
@@ -33,6 +33,11 @@ docs/specs/<домен>/
|
|
|
33
33
|
та же связь сценариев с тестами. Домен, у которого половина поддоменов описана, а половина
|
|
34
34
|
заведена пустыми каталогами, зелёным не бывает.
|
|
35
35
|
|
|
36
|
+
Работа, задевшая домен и его поддомен, пишет две договорённости, а не одну. Префикс сценариев у
|
|
37
|
+
поддомена свой, а второго префикса одному спеку сверка не даёт: сценарии такой работы
|
|
38
|
+
разъезжаются по двум нумерациям — по одной на каждый спек, в который вольются. Замысел называет
|
|
39
|
+
обе, и вливаются они порознь, каждая в свой спек.
|
|
40
|
+
|
|
36
41
|
## Обязательные разделы
|
|
37
42
|
|
|
38
43
|
`## Зачем` · `## Терминология` с подразделом `### Как это называется в интерфейсе` ·
|
|
@@ -49,6 +54,18 @@ docs/specs/<домен>/
|
|
|
49
54
|
такой спек по строкам бесполезно, потому что делится в нём не описание домена, а ненаписанное
|
|
50
55
|
правило.
|
|
51
56
|
|
|
57
|
+
**Заголовок записи раздела решений датой не называется.** Дата говорит, когда решение приняли, а
|
|
58
|
+
раздел отвечает на «почему так, а не иначе»: по дате решение не отобрать и не найти, зато
|
|
59
|
+
названная ею запись читается описанием прошлого и остаётся в спеке навсегда. Запись начинается с
|
|
60
|
+
самого решения.
|
|
61
|
+
|
|
62
|
+
**Утверждение, стоящее в другом разделе того же спека, вторым пунктом правил не заводится.**
|
|
63
|
+
Устройство записи живёт в разделе данных, порядок вызовов — в разделе контракта, причина
|
|
64
|
+
существования домена — в разделе «Зачем»: все три говорят о том же, о чём говорило бы правило.
|
|
65
|
+
Второй экземпляр расходится с первым молча, и заметить это нечем — сверка знает пункт правила
|
|
66
|
+
против якоря, а два утверждения об одном не сравнивает никто. Решение при этом из раздела решений
|
|
67
|
+
уезжает целиком: место, где требование живёт, найдено.
|
|
68
|
+
|
|
52
69
|
Шапка несёт статус, дату ревизии, префикс сценариев, зависимости от других доменов, строку
|
|
53
70
|
`**Законы:**` — законы, которые домен применяет, — и строку `**Процедуры:**` — корни либ, чьи
|
|
54
71
|
процедуры домен обслуживает.
|
|
@@ -79,7 +96,7 @@ docs/specs/<домен>/
|
|
|
79
96
|
```
|
|
80
97
|
|
|
81
98
|
Правило, которому места в коде не нашлось, — намерение: ему место в «Открытых вопросах» как
|
|
82
|
-
`Q
|
|
99
|
+
`Q-<буква закона>-<номер>`, а не формальный якорь.
|
|
83
100
|
|
|
84
101
|
## Сценарий
|
|
85
102
|
|
|
@@ -95,11 +112,17 @@ docs/specs/<домен>/
|
|
|
95
112
|
`Не покрыто: <причина>`, сценарий с неполным тестом — `Покрытие: частичное — <чего не
|
|
96
113
|
хватает>`.
|
|
97
114
|
|
|
115
|
+
Сценарий, который проверить нечем в принципе, не заводится вовсе. Пометка о непокрытом говорит
|
|
116
|
+
«теста ещё нет» и обещает, что он появится; там, где проверки не существует, обещания нет, а
|
|
117
|
+
помеченный сценарий висит в наборе вечно, читается как долг и заставляет каждого следующего
|
|
118
|
+
заново выяснять, не пора ли его закрыть. Правило, ради которого сценарий хотели завести,
|
|
119
|
+
остаётся правилом: его держат строка в компаньоне и запись в истории изменений, и этого довольно.
|
|
120
|
+
|
|
98
121
|
Номер в идентификаторе живёт так:
|
|
99
122
|
|
|
100
123
|
| Что случилось | Что делается с номером |
|
|
101
124
|
| ----------------------- | ---------------------------------------------------------------------------------------------------- |
|
|
102
|
-
| сценарий добавили | берётся следующий свободный — наибольший выданный
|
|
125
|
+
| сценарий добавили | берётся следующий свободный — наибольший выданный **во всех ветках** плюс один, а не дырка в середине |
|
|
103
126
|
| обещание изменили | номер тот же, заголовок теста правится тем же коммитом |
|
|
104
127
|
| сценарий удалили | номер остаётся пустым и новому сценарию не отдаётся; тест удаляется вместе со сценарием |
|
|
105
128
|
| номера захотелось сжать | не пересчитываются: связь с тестами держит только номер, а прогон остаётся зелёным при обеих правках |
|
|
@@ -107,6 +130,15 @@ docs/specs/<домен>/
|
|
|
107
130
|
Номер записывается так же, как у соседей в этом же файле: сверка ищет его шаблоном, и номер,
|
|
108
131
|
записанный иначе, не совпадёт ни в спеке, ни в заголовке теста.
|
|
109
132
|
|
|
133
|
+
**Свободный номер ищется во всех ветках, а не в одной главной.** Соседняя работа держит свои
|
|
134
|
+
номера на диске и в главную ещё не въехала: шесть номеров так раздали дважды, и двигаться
|
|
135
|
+
пришлось той работе, чья договорённость не влита. Номер — единственное, чем сценарий связан с
|
|
136
|
+
тестом, и отданный второй раз он оставляет старую ссылку правильной на вид и ведущей не туда.
|
|
137
|
+
|
|
138
|
+
Спрашивается это командой дерева, если дерево её завело: она читает заголовки сценариев во всех
|
|
139
|
+
ветках — своих и удалённых — и печатает первый свободный за наибольшим занятым. Имя команды
|
|
140
|
+
называет компаньон правила.
|
|
141
|
+
|
|
110
142
|
## Порядок работы
|
|
111
143
|
|
|
112
144
|
1. Задача заводится сценариями: что станет верно, когда работа закончится.
|
|
@@ -115,6 +147,10 @@ docs/specs/<домен>/
|
|
|
115
147
|
4. `npm run check:specs` — до пуша.
|
|
116
148
|
5. Приёмка идёт по сценариям, а не по пересказу правки.
|
|
117
149
|
|
|
150
|
+
Правило, обещающее человеку видимый результат, подтверждается на работающем приложении, а не
|
|
151
|
+
выводом из графа вызовов. Чтением подтверждаются заголовки, связь с привязками и форма данных;
|
|
152
|
+
правило, которое подтвердить не на чем, уезжает открытым вопросом и утверждением не пишется.
|
|
153
|
+
|
|
118
154
|
## Частые промахи
|
|
119
155
|
|
|
120
156
|
- Выросший домен делят на новые домены, а не на поддомены: новый домен приходится заводить в
|
|
@@ -139,10 +175,19 @@ docs/specs/<домен>/
|
|
|
139
175
|
- Закон, названный в тексте, но забытый в строке `**Законы:**`: по закону тогда не узнать,
|
|
140
176
|
какие домены на нём стоят.
|
|
141
177
|
- Правка `.proto` без спеков задетых доменов: `docs-guard` отбивает такой коммит.
|
|
178
|
+
- **Правило, выведенное из графа вызовов, ошибается беззвучно.** Читается оно так же уверенно,
|
|
179
|
+
как замеренное, и сверка привязки его пропускает — символ на месте, просто описывает он не то.
|
|
180
|
+
Два правила одного спека оказались перевёрнутыми: связь шла не между хранилищами, а через
|
|
181
|
+
слушающий их компонент, — и оба чуть не стали задачей на дефект, которого нет.
|
|
182
|
+
|
|
142
183
|
- **Выросший домен делится на поддомены, а не на новые домены.** Новый домен пришлось бы
|
|
143
184
|
заводить в указателе, сверять с кодом отдельно и объяснять, чем он соседу не поддомен;
|
|
144
185
|
поддомен остаётся в своём домене и наследует его контракт. Соседний домен заводится только
|
|
145
186
|
тогда, когда предмет живёт своей сущностью.
|
|
187
|
+
- **Наибольший выданный номер ищется по всему домену командой, а не глазами по хвосту файла.**
|
|
188
|
+
Номера в файле сценариев идут не по порядку: правки вставляли их к соседям по смыслу, и
|
|
189
|
+
последняя строка максимума не показывает. Шесть новых номеров из одиннадцати легли на занятые
|
|
190
|
+
— поймала это сверка спеков, а не чтение, и переписывать пришлось заодно заголовки тестов.
|
|
146
191
|
- **Границу между доменами проводит владелец, а не автор очередной правки.** Автор видит свою
|
|
147
192
|
правку, а не то, чем предмет обрастёт: домен, заведённый по ходу дела, через месяц оказывается
|
|
148
193
|
половиной соседнего, и разводить их приходится вместе с номерами сценариев.
|
|
@@ -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
|
- **Выкатывается образ того коммита, который выкатывают.** Умолчание «последний» отстаёт от
|
|
@@ -74,6 +75,17 @@ description: Правило под «Закон о поставке». Брат
|
|
|
74
75
|
---
|
|
75
76
|
```
|
|
76
77
|
|
|
78
|
+
Под шапкой стоит строка требования к соседним ресурсам — тем, без которых статьи правила не
|
|
79
|
+
исполняются:
|
|
80
|
+
|
|
81
|
+
```markdown
|
|
82
|
+
**Требует:** `hooks/<гард>.sh`, `checks/<проверка>.mjs`
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Ресурсы называются именами пакета, а не путями дерева. Строки нет — правило не требует ничего;
|
|
86
|
+
пустой она не бывает. Выводить требование из фразы в тексте нельзя: разложено у потребителя не
|
|
87
|
+
всё, и текст, сказавший «правку отбивает гард», врёт в дереве, где гарда нет.
|
|
88
|
+
|
|
77
89
|
Разделы: `## Как это называется здесь` · `## Где это лежит` · `## Как закон применяется
|
|
78
90
|
здесь` · `## Чего из закона здесь нет` · `## Паттерны` · `## Ловушки`.
|
|
79
91
|
|
|
@@ -87,7 +99,7 @@ description: Правило под «Закон о поставке». Брат
|
|
|
87
99
|
```
|
|
88
100
|
|
|
89
101
|
Утверждение, которому места в коде не нашлось, в этот раздел не ставится: оно уходит прозой в
|
|
90
|
-
«Ловушки» или вопросом `Q
|
|
102
|
+
«Ловушки» или вопросом `Q-<буква закона>-<номер>` в закон.
|
|
91
103
|
|
|
92
104
|
## Паттерн
|
|
93
105
|
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: spec-driven-sweep
|
|
3
|
+
kind: pattern
|
|
4
|
+
rule: spec-driven
|
|
5
|
+
description: Паттерн правила spec-driven. Брать при сплошном разборе привязки домена — пять проходов, три из которых делает машина, разбор срабатываний чтением и доля ложных по слоям. Не брать для заведения спека домена — это паттерн spec-driven-domain.
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Сплошной разбор привязки домена
|
|
9
|
+
|
|
10
|
+
Паттерн правила `spec-driven`. Что при этом должно быть верно — закон о документации проекта.
|
|
11
|
+
|
|
12
|
+
## Когда брать
|
|
13
|
+
|
|
14
|
+
- Привязка домена разбирается целиком: каждое утверждение против кода, на который оно указывает.
|
|
15
|
+
- Тексты дерева сверяются с деревом задачей, а не по ходу другой работы.
|
|
16
|
+
|
|
17
|
+
## Проходов пять, и порядок у них один
|
|
18
|
+
|
|
19
|
+
Три первых делает машина по всему домену разом, два последних — чтение. Порядок не
|
|
20
|
+
переставляется: чтение идёт по строкам, которые машина уже отобрала, иначе читается весь домен.
|
|
21
|
+
|
|
22
|
+
1. **Мёртвый адрес.** Названного файла нет в дереве, или символа нет нигде. Даёт ноль на домене,
|
|
23
|
+
который уже разбирали, и целую пачку на том, откуда недавно уезжал код.
|
|
24
|
+
2. **Якорь, живущий только в пояснении.** Символ встречается в дереве лишь в комментариях.
|
|
25
|
+
Проверка привязки комментарий засчитывает наравне с кодом, поэтому такому якорю она зелёная, а
|
|
26
|
+
места исполнения за ним нет.
|
|
27
|
+
3. **Символ не объявлен в названном файле.** Файл его импортирует и зовёт, а объявление лежит в
|
|
28
|
+
другом месте. Самый урожайный проход и самый шумный.
|
|
29
|
+
4. **Обещание против кода.** Читается код по адресу: делает ли он то, что утверждает правило.
|
|
30
|
+
Машине этот проход не даётся вовсе — расхождение здесь обычно в условии и в порядке шагов.
|
|
31
|
+
5. **Число, код отказа и ключ словаря — поимённо.** Каждое число из текста ищется в дереве,
|
|
32
|
+
каждый названный код отказа — в месте, где он бросается, каждый ключ словаря — во всех
|
|
33
|
+
локалях. Расхождение тут выглядит опечаткой и живёт годами.
|
|
34
|
+
|
|
35
|
+
## Срабатывание — очередь на чтение, а не список дефектов
|
|
36
|
+
|
|
37
|
+
Проход выдаёт строки, находкой становится подтверждённая чтением. Разница не словесная: строки
|
|
38
|
+
третьего прохода на треть законны у любого домена, и записанные находками они превращают разбор в
|
|
39
|
+
правку верного кода. В ход работы идут оба числа — сколько строк дал проход и сколько из них
|
|
40
|
+
оказались расхождениями.
|
|
41
|
+
|
|
42
|
+
## Доля ложных зависит от слоя
|
|
43
|
+
|
|
44
|
+
Там, где правило живёт в процедуре, место исполнения одно и оно публично: срабатывание третьего
|
|
45
|
+
прохода чаще оказывается расхождением — из четырнадцати строк шесть. Там, где правило живёт в
|
|
46
|
+
компоненте или службе, местом исполнения законно бывает приватное поле или приватный метод: из
|
|
47
|
+
тридцати шести строк расхождений не оказалось ни одной. Поэтому число находок прошлого домена на
|
|
48
|
+
следующий не переносится — переносится только сам порядок проходов.
|
|
49
|
+
|
|
50
|
+
## Частые промахи
|
|
51
|
+
|
|
52
|
+
- **Урожайность прохода обещана фактом.** «Проход даст столько-то» — оценка, и по чужому слою она
|
|
53
|
+
промахивается целиком. Разбор просьбы называет проходы, а не число находок.
|
|
54
|
+
- **Проход, давший ноль, не записан.** Следующий заход гоняет его заново по тому же домену. Ноль
|
|
55
|
+
— такой же результат, и он пишется вместе с остальными.
|
|
56
|
+
- **Счёт сторон принят за разбор.** Зелёная проверка привязки говорит, что у каждого утверждения
|
|
57
|
+
есть строка, а куда эта строка ведёт — не говорит ничего.
|
|
@@ -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
|
|
|
@@ -117,18 +127,50 @@ npm run check:docs # пути, названные в текстах, суще
|
|
|
117
127
|
3. **Вернувшиеся находки принимают одним ходом** — записать и вернуться к прежнему. Разбор,
|
|
118
128
|
отложенный «до удобного момента», не случается вовсе: заход кончается раньше.
|
|
119
129
|
|
|
120
|
-
|
|
121
|
-
|
|
130
|
+
### Записи груза переводятся в «готово» тем же ходом
|
|
131
|
+
|
|
132
|
+
Работа, начатая с приехавшего груза, кончается здесь, а не на разборе папки: до слияния правки в
|
|
133
|
+
дереве нет, и отметка утверждала бы то, чего в главной ветке ещё не лежит. Это единственное
|
|
134
|
+
состояние, где слияние уже случилось, а ход о задаче ещё идёт.
|
|
135
|
+
|
|
136
|
+
Ключи берутся из описания прошлого — папки задачи на диске к этой минуте нет, — и подставляются
|
|
137
|
+
полными, как их печатает чтение приёма:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
npm run cargo:mark -- --state fixed \
|
|
141
|
+
--proposal <полный ключ> --proposal <полный ключ> \
|
|
142
|
+
--fix '<чем исправлено: статья правила, гард, проверка, правка кода>'
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Приём починки один на вызов, поэтому записи едут пачками по тому, чем закрыты, а не всей задачей
|
|
146
|
+
разом. Ответ читается: «переведено 0» означает, что этот разбор не двинул ничего.
|
|
147
|
+
|
|
148
|
+
**Следующее движение:** пока роль разбирает, тот же ход занят следующей задачей; записи груза
|
|
149
|
+
переводятся в «готово» этим же ходом, вернувшиеся находки принимаются одним ходом — записать и
|
|
150
|
+
продолжить прежнее, а владельцу о них говорится, когда кончился эпик.
|
|
122
151
|
|
|
123
|
-
##
|
|
152
|
+
## Находки разбора ложатся к замыслу эпика и ждут владельца
|
|
124
153
|
|
|
125
|
-
Ответ роли живёт в переписке и умирает вместе с ней, поэтому он сразу ложится на
|
|
126
|
-
|
|
154
|
+
Ответ роли живёт в переписке и умирает вместе с ней, поэтому он сразу ложится на диск. Пишет
|
|
155
|
+
его исполнитель: роль файлов не пишет.
|
|
127
156
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
157
|
+
**Пишутся находки сразу в файл рядом с замыслом эпика, а не в папку задачи.** Разбор идёт
|
|
158
|
+
фоном, и когда он кончится, не знает никто; папка задачи к этому времени бывает уже разобрана,
|
|
159
|
+
а ветка влита и снята. Оба срока назначает не исполнитель, поэтому переезд «из папки к замыслу
|
|
160
|
+
эпика» держится на совпадении, которого может и не случиться. Тем же местом пользуется находка,
|
|
161
|
+
замеченная не разбором, а по ходу работы. Работа вне эпика показывает находки владельцу тем же
|
|
162
|
+
ходом.
|
|
163
|
+
|
|
164
|
+
**Находки, вернувшиеся после того, как ветка ушла, едут веткой следующей задачи.** Пуш в снятую
|
|
165
|
+
ветку её не обновляет, а заводит заново: коммит остаётся вне главной ветки и пропадает вместе
|
|
166
|
+
с ней. Следующая задача к этому времени уже взята — её веткой уборка за предыдущей и едет.
|
|
167
|
+
Эпик кончился и следующей задачи нет — находки уезжают своей задачей.
|
|
168
|
+
|
|
169
|
+
**Накопительный файл находок делится до дописи, а не после.** Длина смотрится одной командой
|
|
170
|
+
перед первой написанной строкой: раздел задачи занимает десятки строк, и предел длины документа
|
|
171
|
+
он переходит молча. Гейт пуша показывает превышение, когда допись уже закоммичена, — тогда
|
|
172
|
+
деление идёт задним числом, вместе с правкой ссылок на файл. Не влезает — заводится следующая
|
|
173
|
+
часть, и раздел пишется сразу в неё.
|
|
132
174
|
|
|
133
175
|
**Наружу без слова владельца уезжает только сводка наблюдений.** Она говорит, чем пользовались
|
|
134
176
|
и чем не пользовались ни разу, — это факт, и мнением он не станет. Предложение — другое дело:
|
|
@@ -155,18 +197,18 @@ npm run check:docs # пути, названные в текстах, суще
|
|
|
155
197
|
котором владелец сказал вслух, уходит наружу в тот же ход: написанное и не отправленное лежит в
|
|
156
198
|
дереве неотличимо от отправленного.
|
|
157
199
|
|
|
158
|
-
|
|
159
|
-
владельцу о них говорится, когда кончился эпик.
|
|
160
|
-
|
|
161
|
-
## Ловушки
|
|
200
|
+
## Частые промахи
|
|
162
201
|
|
|
163
202
|
- **Папку разбирают до открытия заявки — потом о ней уже никто не вспомнит.** Сверка очереди
|
|
164
203
|
считает задачу закрытой по слиянию: после него за папку никто не отвечает — работа перешла к
|
|
165
204
|
следующей задаче, и находка достанется чужому заходу. Держит это гард поставки:
|
|
166
205
|
открытие заявки отбивается, пока папка лежит в ветке.
|
|
167
206
|
- **Разбор папки идёт последним коммитом, после того как гейт пуша прошёл целиком.** Порядок
|
|
168
|
-
один: мерж главной ветки,
|
|
169
|
-
|
|
207
|
+
один: мерж главной ветки, вливание договорённости, приведение текстов домена, все линтеры и
|
|
208
|
+
проверки зелёные, разбор папки — и только потом заявка. Дешёвый шаг стоит раньше дорогого:
|
|
209
|
+
заход, потративший окно на прогон, упирался в порог заполнения на четырёх строках привязки, и
|
|
210
|
+
дописать их было уже нечем. Второй довод сильнее: прогон, стоящий после вливания, проверяет и
|
|
211
|
+
само вливание — иначе он смотрит то состояние дерева, которое в главную ветку не поедет.
|
|
170
212
|
- **После разбора замысла на диске нет, и собирать папку заново не надо.** Правку по замечаниям
|
|
171
213
|
разбора и починку красного прогона гард хода работы пропускает по признаку из истории ветки:
|
|
172
214
|
папка, снятая её коммитом, и есть признак отданной работы. Собранная заново папка вернула бы
|