@rt-tools/agent-kit 0.8.1 → 0.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -19
- package/assets/agents/qa-engineer.md +1 -1
- package/assets/checks/board.github.mjs +56 -17
- package/assets/checks/check-board.github.mjs +49 -5
- package/assets/checks/task-new.github.mjs +33 -5
- package/assets/commands/agent-kit-digest.md +10 -5
- package/assets/commands/next-session.md +4 -4
- package/assets/commands/skill-curator.md +11 -9
- package/assets/defaults/gate-map.sh +11 -4
- package/assets/defaults/project.sh +46 -0
- package/assets/docs/GLOSSARY.md +28 -26
- package/assets/hooks/docs-guard.sh +19 -3
- package/assets/hooks/git-guard-delivery.sh +106 -13
- package/assets/hooks/proposal-guard.sh +93 -0
- package/assets/hooks/reuse-first-guard.sh +68 -14
- package/assets/hooks/skill-gate-layers.sh +1 -1
- package/assets/hooks/skill-gate.sh +26 -0
- package/assets/hooks/task-flow-guard.sh +44 -18
- package/assets/hooks/window-fill-guard.sh +1 -1
- package/assets/laws/delivery.md +13 -7
- package/assets/laws/project-documentation.md +21 -0
- package/assets/laws/verifiability.md +6 -1
- package/assets/laws/work-conduct.md +67 -3
- package/assets/patterns/git-workflow-commit.azure.md +10 -2
- package/assets/patterns/git-workflow-commit.github.md +15 -2
- package/assets/patterns/git-workflow-commit.gitlab.md +10 -2
- package/assets/patterns/git-workflow-merge.md +1 -1
- package/assets/patterns/spec-driven-domain.md +7 -1
- package/assets/patterns/spec-driven-rule.md +6 -0
- package/assets/patterns/task-flow-close.md +78 -9
- package/assets/patterns/task-flow-handoff.md +27 -4
- package/assets/patterns/task-flow-resume.md +23 -5
- package/assets/patterns/task-flow-start.md +5 -1
- package/assets/rules/browser-verification.md +10 -1
- package/assets/rules/doc-style.md +13 -5
- package/assets/rules/git-workflow.azure.md +12 -7
- package/assets/rules/git-workflow.github.md +31 -13
- package/assets/rules/git-workflow.gitlab.md +12 -7
- package/assets/rules/spec-driven.md +4 -0
- package/assets/rules/task-flow.md +47 -22
- package/assets/rules/testing.md +19 -0
- package/assets/rules/typescript-conventions.md +12 -0
- package/assets/skills/agent-kit-extend.md +24 -0
- package/assets/skills/agent-kit.md +54 -6
- package/assets/traits.json +14 -0
- package/bin/agent-kit.d.ts.map +1 -1
- package/bin/agent-kit.js +31 -16
- package/bin/agent-kit.js.map +1 -1
- package/index.d.ts +1 -0
- package/index.d.ts.map +1 -1
- package/index.js +1 -0
- package/index.js.map +1 -1
- package/lib/argv.d.ts +17 -0
- package/lib/argv.d.ts.map +1 -0
- package/lib/argv.js +44 -0
- package/lib/argv.js.map +1 -0
- package/lib/cargo.d.ts +88 -0
- package/lib/cargo.d.ts.map +1 -0
- package/lib/cargo.js +16 -0
- package/lib/cargo.js.map +1 -0
- package/lib/catalog.d.ts +18 -1
- package/lib/catalog.d.ts.map +1 -1
- package/lib/catalog.js +12 -2
- package/lib/catalog.js.map +1 -1
- package/lib/commands.d.ts +0 -26
- package/lib/commands.d.ts.map +1 -1
- package/lib/commands.js +78 -122
- package/lib/commands.js.map +1 -1
- package/lib/companion.d.ts +37 -0
- package/lib/companion.d.ts.map +1 -1
- package/lib/companion.js +42 -1
- package/lib/companion.js.map +1 -1
- package/lib/config.d.ts +28 -0
- package/lib/config.d.ts.map +1 -1
- package/lib/config.js +20 -0
- package/lib/config.js.map +1 -1
- package/lib/ship.d.ts +39 -0
- package/lib/ship.d.ts.map +1 -0
- package/lib/ship.js +87 -0
- package/lib/ship.js.map +1 -0
- package/lib/shipment.d.ts +60 -0
- package/lib/shipment.d.ts.map +1 -0
- package/lib/shipment.js +247 -0
- package/lib/shipment.js.map +1 -0
- package/lib/snapshot.d.ts +30 -0
- package/lib/snapshot.d.ts.map +1 -0
- package/lib/snapshot.js +73 -0
- package/lib/snapshot.js.map +1 -0
- package/lib/traits.d.ts +32 -0
- package/lib/traits.d.ts.map +1 -0
- package/lib/traits.js +82 -0
- package/lib/traits.js.map +1 -0
- package/package.json +6 -2
- package/rt-tools-agent-kit-0.8.2.tgz +0 -0
- package/lib/submit.d.ts +0 -24
- package/lib/submit.d.ts.map +0 -1
- package/lib/submit.js +0 -26
- package/lib/submit.js.map +0 -1
- package/rt-tools-agent-kit-0.8.1.tgz +0 -0
- /package/assets/rules/{entity-conventions.md → entity-conventions.needs-admin.md} +0 -0
- /package/assets/rules/{observability.md → observability.needs-app.md} +0 -0
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: task-flow-close
|
|
3
3
|
kind: pattern
|
|
4
4
|
rule: task-flow
|
|
5
|
-
description: Паттерн правила task-flow. Брать при закрытии работы — вливание договорённости в спек домена последним коммитом
|
|
5
|
+
description: Паттерн правила task-flow. Брать при закрытии работы — вливание договорённости в спек домена последним коммитом PR, разбор папки задачи, переезд в архив, сверка очереди работ. Не брать для хода работы — это паттерн task-flow-resume.
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Закрытие работы
|
|
@@ -12,12 +12,12 @@ description: Паттерн правила task-flow. Брать при закр
|
|
|
12
12
|
|
|
13
13
|
## Когда брать
|
|
14
14
|
|
|
15
|
-
- Этапы замысла закрыты, проверки зелёные,
|
|
15
|
+
- Этапы замысла закрыты, проверки зелёные, PR готовится к публикации.
|
|
16
16
|
- `npm run check:specs` перечислил договорённость в разделе «Пора вливать».
|
|
17
17
|
|
|
18
18
|
## 9. Договорённость вливается в спек домена
|
|
19
19
|
|
|
20
|
-
Последним коммитом
|
|
20
|
+
Последним коммитом PR, до слияния. Код к этому моменту написан, поэтому привязки
|
|
21
21
|
`файл:символ` известны — правило въезжает в спек домена сразу проверяемым.
|
|
22
22
|
|
|
23
23
|
```bash
|
|
@@ -78,17 +78,69 @@ grep -rn -A3 "Чего из закона здесь нет" <каталог пр
|
|
|
78
78
|
```
|
|
79
79
|
|
|
80
80
|
**Закон в ветке не правится.** Статья закона — договорённость с владельцем, и меняет её он.
|
|
81
|
-
Работа с ней разошлась — пишется готовый текст статьи: в ход работы и в тело
|
|
81
|
+
Работа с ней разошлась — пишется готовый текст статьи: в ход работы и в тело PR. Файл
|
|
82
82
|
закона правится после ответа. С законами приложения так же: деньги, локали и доступ — та же
|
|
83
83
|
договорённость, только про это приложение.
|
|
84
84
|
|
|
85
|
-
Что сделали на этом шаге, пишется в тело
|
|
85
|
+
Что сделали на этом шаге, пишется в тело PR: что перечитали, что изменили, а если ничего
|
|
86
86
|
не изменили — почему. Форма раздела — паттерн `git-workflow-commit`.
|
|
87
87
|
|
|
88
88
|
## 11. Папка задачи разбирается
|
|
89
89
|
|
|
90
|
+
**Заход, открывший PR, называет владельцу оставшийся шаг вслух:** после одобрения ветка
|
|
91
|
+
получает ещё один коммит — разбор папки, — и только потом вливается. Порядок этот записан
|
|
92
|
+
здесь, а читает его исполнитель; вливает же владелец, и молчание он читает как «работа
|
|
93
|
+
кончена» — видит зелёный PR и мержит его тем же ходом. Промах случается ровно в шов между
|
|
94
|
+
двумя ходами, и стоит он отдельной задачи: после слияния папку разбирать уже некому.
|
|
95
|
+
|
|
96
|
+
### Два сообщения владельцу, и между ними — прогон
|
|
97
|
+
|
|
98
|
+
Оба обязательны, и порядок между ними один. Ни одно не заменяется другим: первое говорит, что
|
|
99
|
+
работа отдана и чего она ждёт, второе — что она готова.
|
|
100
|
+
|
|
101
|
+
Сразу после открытия PR:
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
PR #<номер> открыт. Жду прогона: пока он идёт, о работе известно только то, что она
|
|
105
|
+
запушена. Как закончится — разберу папку задачи последним коммитом и попрошу тебя влить.
|
|
106
|
+
Пока жду, беру задачу #<номер следующей>.
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Прогон зелёный, папка разобрана и запушена:
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
PR #<номер> готов к слиянию: прогон зелёный, папка задачи разобрана, за работой убрано.
|
|
113
|
+
Влей его, пожалуйста.
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Прогон красный — сообщение то же по форме, но говорит о красном и о том, что с ним делается;
|
|
117
|
+
просьбы влить в нём нет. Просьба звучит один раз и только тогда, когда работа готова целиком:
|
|
118
|
+
сказанная заранее, она перестаёт что-либо значить, и владелец возвращается к прежнему —
|
|
119
|
+
вливать по зелёной странице.
|
|
120
|
+
|
|
121
|
+
Между двумя сообщениями исполнитель не ждёт: работа отдана на разбор, и тем же движением
|
|
122
|
+
берётся следующая задача. Возвращается он к PR тем ходом, которым читает конец прогона.
|
|
123
|
+
|
|
124
|
+
Разбор идёт по трём исходам, а не по двум.
|
|
125
|
+
|
|
126
|
+
**Первым отбирается действующее требование.** Всё, что останется верным и завтра, становится
|
|
127
|
+
статьёй закона, пунктом правила или разделом паттерна — по тому, о чём оно говорит. Признак
|
|
128
|
+
отбора один и записан здесь заранее: перестанет ли текст быть верным, если завтра всё
|
|
129
|
+
переделать. Перестанет — это рассказ о состоявшемся; не перестанет — требование, и место ему в
|
|
130
|
+
слое правил. Закон при этом в ветке не правится — его статья приносится владельцу текстом.
|
|
131
|
+
|
|
132
|
+
**Вторым отбирается рассказ о состоявшемся переезде.** Он уезжает в описание прошлого и
|
|
133
|
+
называет для каждого перенесённого решения, куда оно ушло: иначе решение, ставшее правилом, и
|
|
134
|
+
решение, потерянное при переносе, выглядят одинаково — записью, на которую никто не ссылается.
|
|
135
|
+
|
|
136
|
+
**Третьим удаляется остальное.**
|
|
137
|
+
|
|
138
|
+
Порядок именно такой: начав с переезда, исполнитель увозит вместе с ним и действующее — под
|
|
139
|
+
конец работы это дешевле, чем разбирать.
|
|
140
|
+
|
|
90
141
|
Целиком в архив не переносится: `docs/archive/` — место для записей о состоявшемся, которые
|
|
91
|
-
кто-то читает, а не свалка ходов работы.
|
|
142
|
+
кто-то читает, а не свалка ходов работы. Таблица ниже говорит о том, что осталось после
|
|
143
|
+
первого отбора.
|
|
92
144
|
|
|
93
145
|
| Файл | Куда |
|
|
94
146
|
| ------------- | ------------------------------------------------------------------------------------------------------------------ |
|
|
@@ -103,9 +155,26 @@ cat docs/tasks/<КЛЮЧ>-<номер>-<slug>/grill.md > docs/archive/<ЧТО_Р
|
|
|
103
155
|
rm -r docs/tasks/<КЛЮЧ>-<номер>-<slug>
|
|
104
156
|
```
|
|
105
157
|
|
|
106
|
-
Разбор идёт в том же
|
|
158
|
+
Разбор идёт в том же PR, что и работа: папка, оставленная до мержа, попадает в главную
|
|
107
159
|
ветку и читается там как текущая.
|
|
108
160
|
|
|
161
|
+
### Работа, разбирающая чужую папку, разбирает две
|
|
162
|
+
|
|
163
|
+
Своя папка у такой работы есть — она заводится наравне со всеми, исключения из этого нет. Обе
|
|
164
|
+
снимаются последним коммитом, и порядок между ними один: сперва чужая, потом своя. Начав со
|
|
165
|
+
своей, исполнитель теряет замысел на диске, а он ещё нужен — гард отбивает правку без него, а
|
|
166
|
+
правка по замечаниям разбора идёт в ту же ветку.
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
cat docs/tasks/<чужая>/grill.md > docs/archive/<ЧТО_РЕШАЛИ_ТАМ>.md
|
|
170
|
+
rm -r docs/tasks/<чужая>
|
|
171
|
+
cat docs/tasks/<своя>/grill.md > docs/archive/<ЧТО_РЕШАЛИ_ЗДЕСЬ>.md
|
|
172
|
+
rm -r docs/tasks/<своя>
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Две записи в архиве, а не одна: работы разные, и решения в них разные. Сверка очереди работ
|
|
176
|
+
после этого не называет ни одной папки — этим и проверяется, что разобраны обе.
|
|
177
|
+
|
|
109
178
|
## 12. Сверка
|
|
110
179
|
|
|
111
180
|
```bash
|
|
@@ -121,7 +190,7 @@ npm run check:docs # пути, названные в текстах, суще
|
|
|
121
190
|
отвечает — работа перешла к следующей задаче, и находка достанется чужому заходу. Три раза
|
|
122
191
|
подряд папка закрытой задачи так и уехала в главную ветку, в последний раз их набралось
|
|
123
192
|
пять. Теперь это держит гард поставки: слияние отбивается, пока папка лежит в ветке.
|
|
124
|
-
- **Разбирают последним коммитом, а не перед открытием
|
|
193
|
+
- **Разбирают последним коммитом, а не перед открытием PR.** Пока идёт ревью, замысел
|
|
125
194
|
нужен на диске: без него правку по замечаниям не пропустит гард хода работы. Порядок такой:
|
|
126
195
|
правки по ревью, потом разбор папки, потом слияние.
|
|
127
196
|
- **Разбор папки идёт последним, после того как гейт пуша прошёл целиком.** Гард хода работы
|
|
@@ -165,7 +234,7 @@ npm run check:docs # пути, названные в текстах, суще
|
|
|
165
234
|
в нём нет. Паттерн находится по имени правленого символа, а не по теме работы.
|
|
166
235
|
- **Правило без привязки в спек домена не въезжает.** Кода, который его исполняет, нет —
|
|
167
236
|
значит это намерение, и место ему в открытых вопросах домена, а не в правилах.
|
|
168
|
-
- **Замысел
|
|
237
|
+
- **Замысел эпика правят только там, где вписывают «чем кончился».** Границы эпика и
|
|
169
238
|
порядок задач в ней при этом остаются прежними, а работа их уже нарушила: задача, решившая
|
|
170
239
|
читать спеки, оставила над собой границу «спеки — вторая очередь», и следующий исполнитель
|
|
171
240
|
прочитает её как действующую. Границы линии перечитываются целиком тем же заходом, что и
|
|
@@ -26,7 +26,7 @@ description: Паттерн правила task-flow. Брать, когда з
|
|
|
26
26
|
|
|
27
27
|
Пороги сторожит гард заполнения окна; размер окна он берёт из настройки дерева — из записи
|
|
28
28
|
захода тот не выводится. Место между порогами и есть то, на что заход закрывается: дописать ход
|
|
29
|
-
работы, написать передачу, закоммитить и открыть
|
|
29
|
+
работы, написать передачу, закоммитить и открыть PR, если работа кончена.
|
|
30
30
|
|
|
31
31
|
## Точка остановки
|
|
32
32
|
|
|
@@ -54,7 +54,7 @@ description: Паттерн правила task-flow. Брать, когда з
|
|
|
54
54
|
|
|
55
55
|
### Коммит
|
|
56
56
|
|
|
57
|
-
Проверенное коммитится сразу, а не копится до конца задачи. Работа кончена — открывается
|
|
57
|
+
Проверенное коммитится сразу, а не копится до конца задачи. Работа кончена — открывается PR:
|
|
58
58
|
паттерн `git-workflow-commit`.
|
|
59
59
|
|
|
60
60
|
### Передача
|
|
@@ -86,12 +86,35 @@ mkdir -p <каталог передачи>
|
|
|
86
86
|
- <прочее, чего нет ни в правилах, ни в ходе работы>.
|
|
87
87
|
```
|
|
88
88
|
|
|
89
|
+
Третьим разделом идёт «Эпик» — таблица положения. Работа вне эпика этого раздела не несёт:
|
|
90
|
+
таблица из одной строки повторяет раздел «Работа» и читается как эпик из одной задачи.
|
|
91
|
+
|
|
92
|
+
```markdown
|
|
93
|
+
### Эпик <номер> — <возможность, названная замыслом>
|
|
94
|
+
|
|
95
|
+
| № | Задача | Состояние |
|
|
96
|
+
| --- | --------------------------------- | --------- |
|
|
97
|
+
| 1 | <КЛЮЧ>-<номер> — <что делает> | закрыта |
|
|
98
|
+
| 2 | **<КЛЮЧ>-<номер> — <что делает>** | в работе |
|
|
99
|
+
| 3 | <КЛЮЧ>-<номер> — <что делает> | впереди |
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Три колонки, строка на задачу. Заголовок называет номер эпика и возможность — ту, что записана в
|
|
103
|
+
замысле, а не пересказанную заново. `№` — место по порядку: фактическое у закрытых, назначенное
|
|
104
|
+
замыслом у будущих. `Задача` — номер и что она делает, теми же словами, что в замысле.
|
|
105
|
+
`Состояние` — «закрыта», «в работе» или «впереди»; строка текущей задачи выделяется целиком.
|
|
106
|
+
|
|
107
|
+
Состав берётся из замысла эпика, а состояние — из очереди работ: замысел о том, что закрыто, не
|
|
108
|
+
знает, а очередь не знает порядка. Задача, дописанная в эпик после планирования, стоит в очереди
|
|
109
|
+
и в таблице, а в замысле её нет — расхождение называется вслух, а не заглаживается.
|
|
110
|
+
|
|
89
111
|
Разделы фиксированы, и порядок у них тот же:
|
|
90
112
|
|
|
91
113
|
1. **Работа** — номер задачи, её название, рабочее дерево полным путём, ветка и её состояние.
|
|
92
114
|
2. **Где искать** — что придёт хуком само, а что читается по надобности.
|
|
93
|
-
3.
|
|
94
|
-
4.
|
|
115
|
+
3. **Эпик** — таблица положения; у работы вне эпика раздела нет.
|
|
116
|
+
4. **Сделано и следующий шаг** — одной строкой каждое; подробности уже в ходе работы.
|
|
117
|
+
5. **Что учесть** — особенности этого захода, которых нет ни в правилах, ни в ходе работы:
|
|
95
118
|
поднятые стенды, отставшие зависимости, чужие процессы на портах, незакрытые вопросы к
|
|
96
119
|
владельцу.
|
|
97
120
|
|
|
@@ -59,16 +59,16 @@ git log --oneline origin/main..HEAD
|
|
|
59
59
|
- **Следующий шаг:** сценарии обоих хуков, затем подключение в настройках
|
|
60
60
|
- **Незакоммиченное:** всё, ветка пока без коммитов
|
|
61
61
|
- **Ждём владельца:** нет
|
|
62
|
-
-
|
|
62
|
+
- **PR:** ещё не открыт
|
|
63
63
|
```
|
|
64
64
|
|
|
65
|
-
Строка про
|
|
65
|
+
Строка про PR обязательна с той минуты, как этапы кончились: между открытием PR и
|
|
66
66
|
слиянием проходит день и больше, и заход обрывается там чаще всего. Без неё следующий заход
|
|
67
|
-
читает «этап последний, всё зелено» и об открытом
|
|
67
|
+
читает «этап последний, всё зелено» и об открытом PR узнаёт только из истории ветки или у
|
|
68
68
|
владельца — то есть ровно тем пересказом, ради отмены которого всё и заведено:
|
|
69
69
|
|
|
70
70
|
```markdown
|
|
71
|
-
-
|
|
71
|
+
- **PR:** #1396, ждёт разбора · отвечено 3 замечания из 5 · не сделано: разбор папки задачи
|
|
72
72
|
```
|
|
73
73
|
|
|
74
74
|
Решение, принятое по ходу, — вместе с причиной и с тем, что было альтернативой:
|
|
@@ -94,12 +94,30 @@ git log --oneline origin/main..HEAD
|
|
|
94
94
|
- Доэтапное, не этой работы: сверка очереди перечисляет шесть закрытых задач вне борды.
|
|
95
95
|
```
|
|
96
96
|
|
|
97
|
+
## 13. Следующая задача эпика берётся тем же движением
|
|
98
|
+
|
|
99
|
+
Задача закрыта, PR открыт и ждёт владельца — заход на этом не кончается. Отданное на разбор
|
|
100
|
+
ждёт человека, а не машину: пока эпик не кончился, следующая его задача берётся сразу, тем же
|
|
101
|
+
движением, которым предыдущая ушла на разбор.
|
|
102
|
+
|
|
103
|
+
Берётся, а не выбирается: порядок назначен на планировании и лежит в замысле эпика. Выбор,
|
|
104
|
+
предложенный владельцу при назначенном порядке, — просьба назначить его заново.
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
# что назначено следующим — читается в замысле эпика, а не спрашивается
|
|
108
|
+
# состояние задач — в очереди работ: замысел о закрытом не знает
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Останавливает заход только предел заполнения окна — тогда идёт передача, паттерн
|
|
112
|
+
`task-flow-handoff`. Эпик кончился — заход закрывается тем же порядком, и владельцу называется,
|
|
113
|
+
что кончился именно эпик, а не одна его задача.
|
|
114
|
+
|
|
97
115
|
## Ловушки
|
|
98
116
|
|
|
99
117
|
- **Заход, кончившийся ничем, тоже записывается.** Иначе следующий пойдёт той же дорогой:
|
|
100
118
|
«пробовали так — не вышло, потому что» стоит одной строки и экономит целый заход.
|
|
101
119
|
- **Незакоммиченное называется явно.** Работа живёт в дереве неделями; строка «что лежит
|
|
102
|
-
несохранённым и почему» — единственное, по чему это видно, пока
|
|
120
|
+
несохранённым и почему» — единственное, по чему это видно, пока PR нет.
|
|
103
121
|
- **Подтверждение — вывод команды или замер, а не пересказ.** «Проверил, работает» через
|
|
104
122
|
заход неотличимо от «казалось, что работает».
|
|
105
123
|
- **Число из передачи пересчитывается до того, как на нём что-то делят.** Передача описывает
|
|
@@ -73,6 +73,10 @@ Agent(subagent_type: "Explore", prompt: "<тема просьбы>: что по
|
|
|
73
73
|
<Вопрос>
|
|
74
74
|
```
|
|
75
75
|
|
|
76
|
+
Под вопросом идёт таблица положения эпика — та же, что в передаче. Под, а не над: остановка
|
|
77
|
+
называется первой строкой, и положение эпика — то, из чего владелец решает, а не то, о чём его
|
|
78
|
+
спрашивают. Работа вне эпика таблицы не несёт.
|
|
79
|
+
|
|
76
80
|
Замеры, находки ролей и список решений к этому моменту уже записаны в ход работы, и в
|
|
77
81
|
сообщении владельцу они лишние. Отчёт, в конце которого стоит вопрос, выглядит добросовестно
|
|
78
82
|
ровно настолько, насколько надёжно вопрос в нём тонет: владелец трижды переспрашивал, почему
|
|
@@ -163,5 +167,5 @@ cp docs/tasks/_template/progress.md docs/tasks/<КЛЮЧ>-<номер>-<slug>/pr
|
|
|
163
167
|
- **Slug ветки берётся из терминологии договорённости, а не из слов просьбы.** Договорённость
|
|
164
168
|
пишется раньше ветки и как раз там отказывается от слова владельца: спек завёл своё имя
|
|
165
169
|
предмету и прямо сказал, каким словом его не называть, — а ветка и папка задачи остались с
|
|
166
|
-
отвергнутым. Заголовок задачи и
|
|
170
|
+
отвергнутым. Заголовок задачи и PR поправить можно, имя ветки после открытия PR —
|
|
167
171
|
уже нет.
|
|
@@ -30,7 +30,9 @@ description: Правило под «Закон о проверяемости».
|
|
|
30
30
|
|
|
31
31
|
- **Второй экземпляр уже поднятого приложения не поднимается.** До первого запроса выясняется,
|
|
32
32
|
кто отвечает на порту: поднятый заново экземпляр отвечает своей сборкой, а не той, которую
|
|
33
|
-
проверяют. Кто поднимает стенд — владелец или агент, — сказано в именах дерева.
|
|
33
|
+
проверяют. Кто поднимает стенд — владелец или агент, — сказано в именах дерева. Занятый порт,
|
|
34
|
+
обнаруженный поздно, означает, что стенд уже есть: запущенное поверх него останавливается по
|
|
35
|
+
идентификатору процесса, а не по имени команды — у обоих экземпляров оно одно.
|
|
34
36
|
- **Браузер водится одним драйвером на закреплённом профиле.** Остальные двери — второй
|
|
35
37
|
драйвер, `open`, `osascript`, запуск бинарника — закреплённый профиль не спрашивают вовсе.
|
|
36
38
|
- **Выбор браузера протухает и требует повторного вызова.** Выбор, сделанный в начале
|
|
@@ -66,6 +68,13 @@ description: Правило под «Закон о проверяемости».
|
|
|
66
68
|
отвечает 200 старым кодом, а заведённого в ветке обработчика у него нет вовсе, и 404 читается
|
|
67
69
|
как дефект регистрации. Таких процессов бывает несколько; снятие по шаблону команды не
|
|
68
70
|
попадает ни в один — убивать по PID из `lsof`, каждый.
|
|
71
|
+
- **Шаблон имени команды не годится ни чтобы попасть, ни чтобы не задеть.** Два экземпляра
|
|
72
|
+
одного стенда — уже поднятый и только что запущенный — по тексту команды неотличимы: она у них
|
|
73
|
+
одна и та же. Снятие по шаблону уносит оба, и разобрать это потом нечем: снятым оказывается
|
|
74
|
+
ровно тот стенд, ради которого всё затевалось. Своё и чужое различает только идентификатор
|
|
75
|
+
процесса, снятый разбором порта; им и останавливают, поштучно. Обратный промах тот же по
|
|
76
|
+
природе — оболочка запускает процесс под именем, которого в шаблоне нет, и снятие не попадает
|
|
77
|
+
ни во что.
|
|
69
78
|
- Инкрементальная сборка протухает поштучно: разметка бывает уже новая, а клиентский чанк — от
|
|
70
79
|
компиляции до правки. Признак дев-сборки — имена бандла без хеша (`main.js`). Расхождение
|
|
71
80
|
между `curl` и страницей после гидратации — повод пересобрать, а не искать дефект в коде.
|
|
@@ -115,7 +115,7 @@ description: Правило под «Закон о документации пр
|
|
|
115
115
|
паттерн `doc-style-sweep`.
|
|
116
116
|
- **Словарь действует и на разговор с владельцем, не только на файлы.** Он приходит в контекст
|
|
117
117
|
на запуске сессии, поэтому «не читал» основанием не бывает. Слово из левой колонки «Так не
|
|
118
|
-
пишем» всплывало именно в ответах: в дереве его уже вычистили, а в
|
|
118
|
+
пишем» всплывало именно в ответах: в дереве его уже вычистили, а в PR о сделанном оно
|
|
119
119
|
оставалось, и владелец читал ровно то слово, от которого отказались.
|
|
120
120
|
- **Термин берётся из `docs/GLOSSARY.md`, а не придумывается на месте.** Слова, которого там
|
|
121
121
|
нет, у читателя нет тоже: «журнал приложения» простоял в спеке почты, пока владелец не
|
|
@@ -131,19 +131,27 @@ description: Правило под «Закон о документации пр
|
|
|
131
131
|
- **Снятое имя вычищается одним грепом по всему дереву:** правила, их зеркала в скилах,
|
|
132
132
|
документы и комментарии. Описание того, чего в коде уже нет, читается как действующее
|
|
133
133
|
указание.
|
|
134
|
+
- **У снятого слова второе значение возвращается после сплошной замены, а не обходится до
|
|
135
|
+
неё.** Слово снимают ровно потому, что оно стояло над двумя вещами, и второе значение при
|
|
136
|
+
этом остаётся законным. Отобрать его заранее нечем: какое из двух значений в строке, видно
|
|
137
|
+
только по соседнему тексту, а строк бывают сотни. Порядок обратный — сплошная замена, затем
|
|
138
|
+
сплошной просмотр самой правки, и найденное второе значение возвращается поимённо. Из 353
|
|
139
|
+
замен так вернулись шесть, и две первые были поломкой: сверка печатала новое имя дважды
|
|
140
|
+
подряд, а комментарий обещал «поломку вместо PR о том, что долгов нет». Просматривается
|
|
141
|
+
правка, а не дерево после неё: в дереве обе стороны выглядят одинаково верными.
|
|
134
142
|
- **Поиск по дереву не покрывает того, что уже уехало наружу.** Заголовок задачи и её тело,
|
|
135
|
-
заголовок
|
|
143
|
+
заголовок PR и его тело, заголовки коммитов лежат вне файлов, и проверки текстов их не
|
|
136
144
|
читают вовсе. Вычистив слово в дереве, обходят те же места в очереди работ и в истории:
|
|
137
145
|
|
|
138
146
|
```bash
|
|
139
|
-
<клиент хостинга> api "<путь к
|
|
147
|
+
<клиент хостинга> api "<путь к PR>" --jq '.title, .body' | grep -i '<слово>'
|
|
140
148
|
<клиент хостинга> api "<путь к задаче>" --jq '.title, .body' | grep -i '<слово>'
|
|
141
149
|
git log --format='%s%n%b' <база>..HEAD | grep -i '<слово>'
|
|
142
150
|
```
|
|
143
151
|
|
|
144
|
-
Заголовок
|
|
152
|
+
Заголовок PR правится вызовом хостинга, заголовок коммита — только переписыванием ветки,
|
|
145
153
|
поэтому его проверяют до пуша. Выдуманное слово было вычищено из трёх файлов и объявлено
|
|
146
|
-
снятым, а в заголовке
|
|
154
|
+
снятым, а в заголовке PR и в заголовке коммита осталось — владелец прочитал именно его.
|
|
147
155
|
|
|
148
156
|
- **Число в тексте пересчитывается командой в том же коммите, где пишется.** Оно стареет
|
|
149
157
|
внутри одной ветки: «шестнадцать пар» стало неправдой через два коммита после того, как
|
|
@@ -21,7 +21,7 @@ description: Правило под «Закон о поставке» для д
|
|
|
21
21
|
| задача | рабочий элемент (work item) рода `Task` или `Bug`, заголовок `[<номер>] <Что не так>`, исполнитель — учётная запись машинной работы; PR прикрепляется к нему при создании флагом `--work-items`, а коммит — строкой `AB#<номер>` |
|
|
22
22
|
| очередь работ | Azure Boards проекта. Рабочий элемент попадает на доску тем, что заведён: доска показывает элементы своей области и итерации |
|
|
23
23
|
| состояние задачи в очереди работ | поле `State` рабочего элемента: `New` у заведённого, `Active` у взятого в работу, `Resolved` у ждущего разбора. Набор состояний зависит от процесса проекта и назван в `implementation.md`; закрытая задача уходит из очереди слиянием |
|
|
24
|
-
|
|
|
24
|
+
| PR о задаче | заголовок PR `[<номер>] <Что сделано>` — тот же номер, что у рабочего элемента, и его название, переведённое в сделанное; тип и область коммита сюда не идут |
|
|
25
25
|
| обсуждение правки | разбор PR: ревьювер — владелец репозитория, исполнитель — учётная запись машинной работы, метки — те же, что у рабочего элемента |
|
|
26
26
|
| попадание правки в главную ветку | слияние PR; оно же запускает выкатку — `azure-pipelines.yml` |
|
|
27
27
|
| образ того коммита | `IMAGE_TAG=<sha>` в командах `docker compose` на сервере |
|
|
@@ -48,6 +48,11 @@ description: Правило под «Закон о поставке» для д
|
|
|
48
48
|
открытие, пока вершина главной ветки не стала предком текущей, и называет расхождение числом
|
|
49
49
|
коммитов. PR с разошедшейся ветки показывает ревьюверу свою правку вперемешку с чужой, а всё,
|
|
50
50
|
что автор проверил до публикации, он проверил от основания, которого в главной ветке уже нет.
|
|
51
|
+
- **Заведённый рабочий элемент подтверждается ответом очереди работ, а не выводом команды
|
|
52
|
+
заведения.** Команда отвечает за свои вызовы: она может завести элемент и не довести его до
|
|
53
|
+
доски, и её собственный разбор ошибок этот случай называет. Напечатанный номер значит «вызов
|
|
54
|
+
прошёл», а не «работа видна тому, кто по ней придёт». Спрашивается очередь — по номеру, одним
|
|
55
|
+
вызовом, — и ответ читается присутствием элемента на доске, его состоянием и исполнителем.
|
|
51
56
|
- **Номер ветки и номер в заголовке PR сверяются на месте, а состояние — по доске.** Формат
|
|
52
57
|
читается из текста команды и работает без сети; существование рабочего элемента, его
|
|
53
58
|
состояние, исполнитель и то, что он ещё открыт, — только когда есть чем спросить. Нет сети
|
|
@@ -58,13 +63,13 @@ description: Правило под «Закон о поставке» для д
|
|
|
58
63
|
набор вызовов по памяти. Перевод идёт сразу за шагом, который его вызвал: очередь работ
|
|
59
64
|
читают между шагами, а не после них.
|
|
60
65
|
- **Отставшее состояние находится сверкой очереди, а не глазами.** Сверка судит состояние по
|
|
61
|
-
|
|
66
|
+
PR в обе стороны: открытый PR при элементе не в разборе и разбор без открытого PR — оба
|
|
62
67
|
расхождения. Момента, когда задачу берут в работу, ей не видно: ветки на доске нет.
|
|
63
68
|
- **Задачи, чинящиеся одной правкой, сливаются до слияния ветки.** Вторая закрывается как
|
|
64
69
|
дубликат, а недостающее из неё дописывается в первую. После слияния слить уже нельзя: ветка
|
|
65
70
|
въехала, и откатывается она целиком.
|
|
66
71
|
- **Работа, которую одним заходом не закрыть, помечена в двух местах, и они сверяются.** Метка
|
|
67
|
-
на доске и строка о заходах с передачей в
|
|
72
|
+
на доске и строка о заходах с передачей в замысле эпика говорят одно и то же двум читателям:
|
|
68
73
|
исполнитель открывает карточку раньше, чем линию, а планирует по линии. Одна пометка без
|
|
69
74
|
другой лжёт молча, поэтому сверка очереди судит пару в обе стороны. Помечается только то, что
|
|
70
75
|
законно не делится: пометка объёма правом делить не становится.
|
|
@@ -88,9 +93,9 @@ description: Правило под «Закон о поставке» для д
|
|
|
88
93
|
ветке, а задание выкатки прибито условием к главной: прогон ради проверки доходит до сборок и
|
|
89
94
|
там кончается. Прогон команд задания на своей машине его не покрывает: он проверяет команды,
|
|
90
95
|
а не файл конвейера, — верность самого файла читается только по списку прогонов после пуша.
|
|
91
|
-
-
|
|
96
|
+
- **PR проверяется до слияния тем же конвейером, что и главная ветка.** Проверки и сборки
|
|
92
97
|
образов идут на конвейере проверки PR, выкатка — нет: её держит условие по главной ветке у
|
|
93
|
-
своего задания, а образ
|
|
98
|
+
своего задания, а образ PR в реестр не уезжает.
|
|
94
99
|
- **Расхождение прода с главной веткой видно сверкой очереди работ.** Рабочий элемент уходит из
|
|
95
100
|
очереди слиянием, но слияние — ещё не прод: отказавшая выкатка не трогает ни элемент, ни его
|
|
96
101
|
состояние, и заметить её неоткуда. Сверка спрашивает последний прогон главной ветки и судит
|
|
@@ -145,7 +150,7 @@ description: Правило под «Закон о поставке» для д
|
|
|
145
150
|
|
|
146
151
|
Гард поставки стоит на командах агента, поэтому ветку, заведённую руками в редакторе, он не
|
|
147
152
|
видит: имя такой ветки держится памятью. Требование от этого не слабеет — просто отдельной
|
|
148
|
-
проверки под него не заводится: работа опознаётся заголовком рабочего элемента и
|
|
153
|
+
проверки под него не заводится: работа опознаётся заголовком рабочего элемента и PR, а это
|
|
149
154
|
сверяется у всех. Сверка очереди имя ветки не судит вовсе: у открытого PR его не переименовать.
|
|
150
155
|
|
|
151
156
|
Взятие задачи в работу не стережёт ничто: доска ветки не видит, а гард поставки её видит, но
|
|
@@ -191,7 +196,7 @@ description: Правило под «Закон о поставке» для д
|
|
|
191
196
|
- **Учётная запись для пуша и автор PR выбираются отдельно.** Если пушить пришлось из-под другой
|
|
192
197
|
записи, на следующий вызов это не переносится: PR открывают токеном учётной записи машинной
|
|
193
198
|
работы, и от того, чьей записью он открыт, зависит, кого можно назначить ревьювером. Однажды
|
|
194
|
-
смена записи ради пуша утекла в публикацию —
|
|
199
|
+
смена записи ради пуша утекла в публикацию — PR вышел от владельца.
|
|
195
200
|
- **Невалидный файл конвейера виден прогоном нулевой длительности сразу после пуша.** Прогон
|
|
196
201
|
заводится и кончается на разборе файла, не начав ни одного задания: в списке он стоит
|
|
197
202
|
отказом, а внутри нет ни задания, ни лога — читается только длительность. Поэтому список
|
|
@@ -22,7 +22,7 @@ description: Правило под «Закон о поставке» для д
|
|
|
22
22
|
| задача | issue репозитория, заголовок `[<КЛЮЧ>-<номер>] <Что не так>`, исполнитель — учётная запись машинной работы; PR прикрепляется к нему строкой `Closes #<номер>` в теле |
|
|
23
23
|
| очередь работ | борда GitHub Projects. К репозиторию она не привязана: `projectsV2` у него пуст, и задача попадает на борду только явным добавлением |
|
|
24
24
|
| состояние задачи в очереди работ | колонка борды — поле «Status»: заведённая, взятая в работу, ждущая разбора. Имена колонок — в `implementation.md`; закрытая задача уходит из очереди мержем, а не переводом в последнюю колонку |
|
|
25
|
-
|
|
|
25
|
+
| PR о задаче | заголовок PR `[<КЛЮЧ>-<номер>] <Что сделано>` — тот же номер, что у задачи, и её название, переведённое в сделанное; тип и область коммита сюда не идут |
|
|
26
26
|
| обсуждение правки | разбор PR: ревьювер — владелец репозитория, исполнитель — учётная запись машинной работы, метки — те же, что у задачи |
|
|
27
27
|
| попадание правки в главную ветку | мерж PR; он же запускает выкатку — `.github/workflows/deploy.yml` |
|
|
28
28
|
| образ того коммита | `IMAGE_TAG=<sha>` в командах `docker compose` на сервере |
|
|
@@ -49,7 +49,7 @@ description: Правило под «Закон о поставке» для д
|
|
|
49
49
|
разошедшейся ветки показывает ревьюверу свою правку вперемешку с чужой, а всё, что автор
|
|
50
50
|
проверил до публикации, он проверил от основания, которого в главной ветке уже нет.
|
|
51
51
|
- **Ключ задач задаётся один раз, и все три формы имени выводятся из него.** Заголовок задачи,
|
|
52
|
-
имя ветки и заголовок
|
|
52
|
+
имя ветки и заголовок PR строит один и тот же ключ: команда заведения задачи собирает по
|
|
53
53
|
нему заголовок, гард поставки достаёт по нему номер из имени ветки, сверка очереди — из
|
|
54
54
|
заголовка. Форма ветки в профиле дерева пишется той же парой `<КЛЮЧ>-<номер>`, а не своей
|
|
55
55
|
похожей: разойдясь, они не отказывают, а перестают узнавать номер, и проверка, искавшая
|
|
@@ -58,6 +58,11 @@ description: Правило под «Закон о поставке» для д
|
|
|
58
58
|
же вызове и называет, где ключ задаётся. Умолчания у ключа нет намеренно: собранный из
|
|
59
59
|
пустого значения заголовок `[-317]` не совпадает ни с чем, и сверка очереди помечает
|
|
60
60
|
неправильно названной каждую задачу — настоящее расхождение тонет среди этих строк.
|
|
61
|
+
- **Заведённая задача подтверждается ответом очереди работ, а не выводом команды заведения.**
|
|
62
|
+
Команда отвечает за свои вызовы: она может завести задачу и не довести её до борды, и её
|
|
63
|
+
собственный разбор ошибок этот случай называет. Напечатанный номер значит «вызов прошёл», а не
|
|
64
|
+
«задача видна тому, кто по ней работает». Спрашивается очередь — по номеру, одним вызовом, — и
|
|
65
|
+
ответ читается присутствием задачи на борде, её колонкой и исполнителем.
|
|
61
66
|
- **Номер ветки и номер в заголовке PR сверяются на месте, а состояние задачи — по борде.**
|
|
62
67
|
Формат читается из текста команды и работает без сети; существование задачи, её присутствие
|
|
63
68
|
на борде, исполнитель и то, что она ещё открыта, — только когда есть чем спросить. Нет сети
|
|
@@ -68,13 +73,13 @@ description: Правило под «Закон о поставке» для д
|
|
|
68
73
|
перевода, а не набор вызовов GraphQL по памяти. Перевод идёт сразу за шагом, который его
|
|
69
74
|
вызвал: очередь работ читают между шагами, а не после них.
|
|
70
75
|
- **Отставшая колонка находится сверкой очереди, а не глазами.** Сверка судит колонку по
|
|
71
|
-
|
|
76
|
+
PR в обе стороны: открытый PR при задаче не в разборе и разбор без открытого PR — оба
|
|
72
77
|
расхождения. Момента, когда задачу берут в работу, ей не видно: ветки на борде нет.
|
|
73
78
|
- **Задачи, чинящиеся одной правкой, сливаются до мержа.** Вторая стирается вместе с номером,
|
|
74
79
|
а недостающее из неё дописывается в первую. После мержа слить уже нельзя: ветка въехала, и
|
|
75
80
|
откатывается она целиком.
|
|
76
81
|
- **Работа, которую одним заходом не закрыть, помечена в двух местах, и они сверяются.** Метка
|
|
77
|
-
на борде и строка о заходах с передачей в
|
|
82
|
+
на борде и строка о заходах с передачей в замысле эпика говорят одно и то же двум читателям:
|
|
78
83
|
исполнитель открывает карточку раньше, чем линию, а планирует по линии. Одна пометка без
|
|
79
84
|
другой лжёт молча, поэтому сверка очереди судит пару в обе стороны. Помечается только то, что
|
|
80
85
|
законно не делится: пометка объёма правом делить не становится.
|
|
@@ -99,9 +104,9 @@ description: Правило под «Закон о поставке» для д
|
|
|
99
104
|
которая его заводит или переносит, ручной запуск не покрывает. Прогон команд задания на своей
|
|
100
105
|
машине не покрывает её тоже: он проверяет команды, а не файл конвейера, — верность самого
|
|
101
106
|
файла читается только по списку прогонов после пуша.
|
|
102
|
-
-
|
|
107
|
+
- **PR проверяется до мержа тем же конвейером, что и главная ветка.** Проверки и сборки
|
|
103
108
|
образов идут на событии `pull_request`, выкатка — нет: её держит условие по главной ветке у
|
|
104
|
-
своего задания, а образ
|
|
109
|
+
своего задания, а образ PR в реестр не уезжает.
|
|
105
110
|
- **Расхождение прода с главной веткой видно сверкой очереди работ.** Задача уходит из очереди
|
|
106
111
|
мержем, но мерж — ещё не прод: отказавшая выкатка не трогает ни задачу, ни её колонку, и
|
|
107
112
|
заметить её неоткуда. Сверка спрашивает последний прогон главной ветки и судит только
|
|
@@ -133,6 +138,10 @@ description: Правило под «Закон о поставке» для д
|
|
|
133
138
|
сломана, она описывает вчерашний день. Сравнение веток пишется от `origin/main` целиком —
|
|
134
139
|
смешав в одной команде удалённую ссылку для одной стороны и локальную для другой, промах
|
|
135
140
|
изнутри выглядит правильным.
|
|
141
|
+
- **Мерж PR нажимает человек, а не исполнитель работы.** Кнопка и вызов слияния равны: запрет
|
|
142
|
+
на них один. Исполнитель сливает свой PR только тогда, когда человек сказал это прямо и про
|
|
143
|
+
этот PR; сказанное об одном PR на следующий не переносится, а молчание разрешением не
|
|
144
|
+
бывает. Работа кончается открытым и зелёным PR, и в ответе называется его номер.
|
|
136
145
|
- **Автор PR не может быть его ревьювером.** Запрос разбора на самого себя GitHub принимает и
|
|
137
146
|
молча не создаёт — разбор при этом выглядит запрошенным.
|
|
138
147
|
- **Метки, исполнитель и ревьювер PR ставятся вызовами `gh api`, а не `gh pr edit`.** На
|
|
@@ -141,6 +150,15 @@ description: Правило под «Закон о поставке» для д
|
|
|
141
150
|
- **Борда правится запросом GraphQL по идентификатору проекта.** `gh project` с `--owner`
|
|
142
151
|
отвечает `unknown owner type`, когда владелец борды — не та учётная запись, под которой
|
|
143
152
|
идёт вызов.
|
|
153
|
+
- **Почта машинного коммита копируется из компаньона, а не набирается по памяти.** Служебный
|
|
154
|
+
адрес GitHub — `<число>+<логин>@users.noreply.github.com`, и сопоставляется он по числу: логин
|
|
155
|
+
рядом с ним не сверяет никто. Коммит с чужим числом уезжает подписанным посторонним человеком,
|
|
156
|
+
а изнутри промах не виден — имя учётной записи в истории то самое. Ту же строку держит профиль
|
|
157
|
+
дерева, и гард поставки отбивает пуш при расхождении.
|
|
158
|
+
- **Личность машинной записи подтверждается ответом хостинга, а не узнаванием строки.** Знакомый
|
|
159
|
+
вид строки подтверждением не бывает — промах выглядел знакомо. Спрашивается токеном самой
|
|
160
|
+
записи, ответом о себе: логин и число приходят вместе. Поиск по числу для ограниченной записи
|
|
161
|
+
отвечает «не найдено» и её собственным токеном, поэтому годится только ответ о себе.
|
|
144
162
|
- **Сценарии гардов задают настройки git сами, а не берут их с машины.** Коммит во временном
|
|
145
163
|
репозитории сценария наследует общий конфиг: если включена подпись, git идёт в агент ключей,
|
|
146
164
|
а заблокированный агент роняет весь набор — со стороны это выглядит сломанным гардом. Автор,
|
|
@@ -154,7 +172,7 @@ description: Правило под «Закон о поставке» для д
|
|
|
154
172
|
|
|
155
173
|
Гард поставки стоит на командах агента, поэтому ветку, заведённую руками в редакторе, он не
|
|
156
174
|
видит: имя такой ветки держится памятью. Требование от этого не слабеет — просто отдельной
|
|
157
|
-
проверки под него не заводится: работа опознаётся заголовком задачи и
|
|
175
|
+
проверки под него не заводится: работа опознаётся заголовком задачи и PR, а это сверяется
|
|
158
176
|
у всех. Сверка очереди имя ветки не судит вовсе: у открытого PR его не переименовать.
|
|
159
177
|
|
|
160
178
|
Взятие задачи в работу не стережёт ничто: борда ветки не видит, а гард поставки её видит, но
|
|
@@ -162,11 +180,11 @@ description: Правило под «Закон о поставке» для д
|
|
|
162
180
|
работу вместо промаха. Держится это памятью и подсказкой, которую печатает команда заведения
|
|
163
181
|
задачи. Отставшую колонку находит сверка очереди — но уже после того, как PR открыт.
|
|
164
182
|
|
|
165
|
-
Свежесть самой вершины главной ветки гард
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
183
|
+
Свежесть самой вершины главной ветки гард спрашивает вторым ярусом — тем же приёмом, что и
|
|
184
|
+
состояние задачи: есть чем спросить, спрашивает; нет сети или доступа — пропускает молча.
|
|
185
|
+
Первый ярус при этом остаётся, и работает он без сети: локальная ссылка отвечает на вопрос
|
|
186
|
+
«отстала ли ветка от того, что уже лежит в дереве», удалённая — на вопрос «не протухла ли сама
|
|
187
|
+
ссылка». Без второго яруса молчание гарда значило лишь первое, а читалось как второе.
|
|
170
188
|
|
|
171
189
|
## Паттерны
|
|
172
190
|
|
|
@@ -198,7 +216,7 @@ description: Правило под «Закон о поставке» для д
|
|
|
198
216
|
- **Учётная запись для пуша и автор PR выбираются отдельно.** Если пушить пришлось из-под другой
|
|
199
217
|
записи, на следующий вызов это не переносится: PR открывают токеном учётной записи машинной
|
|
200
218
|
работы, и от того, чьей записью он открыт, зависит, кого можно назначить ревьювером. Однажды
|
|
201
|
-
смена записи ради пуша утекла в публикацию —
|
|
219
|
+
смена записи ради пуша утекла в публикацию — PR вышел от владельца.
|
|
202
220
|
- **Невалидный файл конвейера виден прогоном нулевой длительности сразу после пуша.** GitHub
|
|
203
221
|
заводит такой прогон и на ветке, на которую ни один триггер не подписан: в списке он стоит
|
|
204
222
|
отказом, а внутри у него нет ни задания, ни лога — читается только длительность. Поэтому
|