@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
|
@@ -26,6 +26,10 @@
|
|
|
26
26
|
надстройка, которую она закрыла, не сопоставляются ничем, и надстройка остаётся замещать уже
|
|
27
27
|
исправленный раздел.
|
|
28
28
|
|
|
29
|
+
Скопированная пакетная строка правится в источнике пакета, а не в копии: правка внутри
|
|
30
|
+
надстройки расходится с исходником молча, и видно её только там, где сам текст служит ключом
|
|
31
|
+
связи — в статье, у которой есть привязка. Перед правкой строки в надстройке она ищется в
|
|
32
|
+
источнике; не нашлась — строка своя, и правится на месте.
|
|
29
33
|
- **Готовый код пакета не называет имён одного дерева.** Префикс директив кита, ключи подписей
|
|
30
34
|
и имена сущностей принадлежат тому дереву, где паттерн писали; разложенные в соседнем, они
|
|
31
35
|
учат звать то, чего там нет вовсе. Имя директивы при этом отличается от имени в примере: по
|
|
@@ -42,9 +46,12 @@
|
|
|
42
46
|
отдельным шагом, отбивается как неиспользуемый ещё до того, как появится строка, которая его
|
|
43
47
|
зовёт, и работа встаёт на половине. Правка делается одним вызовом либо в порядке «сначала
|
|
44
48
|
использование, потом импорт».
|
|
45
|
-
- **Прогонять сценарии гардов можно, ничего не
|
|
46
|
-
гардов переменной, и пакетную редакцию гоняют
|
|
47
|
-
|
|
49
|
+
- **Прогонять сценарии гардов можно, ничего не раскладывая, — там, где эти сценарии есть.**
|
|
50
|
+
Обвязка набора принимает каталог гардов переменной, и пакетную редакцию гоняют до установки.
|
|
51
|
+
Живёт она в репозитории самого пакета: в поставку едут ресурсы, строка запуска и библиотека, а
|
|
52
|
+
каталога сценариев в ней нет вовсе. Дереву-потребителю остаются свои сценарии на свои гарды —
|
|
53
|
+
искать у себя пакетные значит потратить заход на диагноз по последствиям, ровно тот, от
|
|
54
|
+
которого совет обещал избавить.
|
|
48
55
|
- **Отбитая правка не всегда про текст гарда.** Гард зовут по пути, и файл без права на
|
|
49
56
|
запуск отвечает отказом доступа — ненулевым кодом, который читается как «правка отбита».
|
|
50
57
|
Набор при этом отбивает подряд всё, включая сборку и тесты, и причины не называет.
|
|
@@ -78,3 +85,64 @@
|
|
|
78
85
|
ровно так же, как с кодом дерева: запись в файл вне репозитория была отбита гардом хода
|
|
79
86
|
работы с требованием замысла, к ней не относящегося. Путь в профиле сначала приводится к
|
|
80
87
|
корню дерева, и всё, что вне корня, признака не получает.
|
|
88
|
+
- **Похожесть текстов ближайшую статью не находит.** Замер показал, что законное соседство двух
|
|
89
|
+
статей одного правила и законный перенос удачной статьи на соседнее место дают одно и то же
|
|
90
|
+
число: цитата поэтому ищется точным совпадением, а не мерой похожести.
|
|
91
|
+
- **Отметка об отправке живёт в рабочем дереве, а дерево у каждой ветки своё.** Поставленная в
|
|
92
|
+
одной ветке, в соседней она не видна, и тот же текст уезжает вторым разом; второй записью он
|
|
93
|
+
при этом не становится — приём отбирает уже приехавшее по признаку предложения, и его ответ
|
|
94
|
+
говорит, сколько записей легло и сколько уже лежало. Строка «принято 0, уже лежало 3» означает,
|
|
95
|
+
что нового не уехало ничего.
|
|
96
|
+
- **Отметка, поставленная только на принятое, объявила бы неотправленным то, что дошло раньше.**
|
|
97
|
+
Файл остался бы без неё навсегда: принятым он больше не станет никогда, а гард предложений
|
|
98
|
+
отбивал бы ход у каждого следующего захода. Отправителю разница между принятым и уже лежавшим
|
|
99
|
+
ничего не меняет — оба исхода значат одно: груз доехал.
|
|
100
|
+
- **Отказ отправки, называющий один лишь ключ конфига, уводит читателя не туда.** Ни адреса, ни
|
|
101
|
+
токена в конфиге нет и не будет: оба приходят от владельца приёма — адрес словом, токен
|
|
102
|
+
одноразовым кодом приглашения. Отказ поэтому называет приглашение, а не ключ: ушедший править
|
|
103
|
+
конфиг ответа там не находит и второй раз спрашивает уже владельца.
|
|
104
|
+
- **Редакция пакета, поднятая без раскладки, запирает дерево целиком.** Красит она не свою
|
|
105
|
+
ветку, а главную: сверка раскладки стоит в гейте пуша, и на ней отбивается чужая работа, пакета
|
|
106
|
+
не касающаяся вовсе. Своей веткой такой автор починить это не может — правка лежит в чужой.
|
|
107
|
+
- **Правка разложенного файла без гарда на месте всплывает в чужой ветке.** Знал о ней один
|
|
108
|
+
`sync --check`, а говорил он на следующей раскладке: отказ приходил тому, кто в этот день
|
|
109
|
+
правил соседний ресурс, и выглядел поломкой его работы.
|
|
110
|
+
|
|
111
|
+
## Подъём версии: чем сверять замещённые разделы
|
|
112
|
+
|
|
113
|
+
Замерено на двух подъёмах подряд: в одном шесть замещённых разделов недосчитались новых
|
|
114
|
+
утверждений, в другом два раздела — одиннадцати статей, и ни одна команда об этом не сказала.
|
|
115
|
+
Прежняя редакция при этом нашлась случайной копией в чужом рабочем дереве: установка стирает её
|
|
116
|
+
без следа, поэтому снимок и стоит первым шагом подъёма.
|
|
117
|
+
|
|
118
|
+
Сверяются статьи, а не заголовки — заголовок как раз и совпал, этим раздел замещён:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
sec() { awk -v s="$2" '$0 ~ "^## "s {f=1;next} /^## /{f=0} f' "$1" \
|
|
122
|
+
| grep '^- \*\*' | sed 's/^- \*\*//;s/\*\*.*//'; }
|
|
123
|
+
comm -13 <(sec "$OLD/<ресурс>" '<заголовок>' | sort) <(sec "$NEW/<ресурс>" '<заголовок>' | sort)
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Строка в выводе — статья, которую надстройка проглотила: пакет её дописал, а дерево не увидело.
|
|
127
|
+
Переносится она в надстройку руками.
|
|
128
|
+
|
|
129
|
+
## Выключенная роль: что бывает с настройкой
|
|
130
|
+
|
|
131
|
+
- **Настройка, которую не прочитать, роль не выключает.** Не нашлось `jq`, нет настройки, в
|
|
132
|
+
настройке сломан разбор — гард судит, как судил. Обратный выбор гасил бы слой правил молча, и
|
|
133
|
+
заметить это было бы нечем.
|
|
134
|
+
- **Ключ, написанный не списком, ловит раскладка, а не гард.** Гарду виден только список имён:
|
|
135
|
+
строка вместо списка читается им как «роль включена», и роль работает, хотя дерево считает её
|
|
136
|
+
выключенной. Отказывает на этом разбор настройки — первой же раскладкой, называя ключ.
|
|
137
|
+
- **Выключение живёт в настройке дерева, а не в настройке агента.** Строка, вырезанная из
|
|
138
|
+
настроек агента руками, теряется на первой же правке того файла, и вернуть роль будет нечем.
|
|
139
|
+
Здесь оно объявлено в одном месте и видно всякому, кто читает настройку дерева.
|
|
140
|
+
|
|
141
|
+
## Свойства дерева: две границы
|
|
142
|
+
|
|
143
|
+
- **`only` сильнее требования.** Ресурс, названный поимённо, ложится и при неотвеченном
|
|
144
|
+
требовании; перечень раскладки называет это вслух, а отказ по его пустому компаньону зовёт
|
|
145
|
+
снять ресурс, а не заполнять черновик.
|
|
146
|
+
- **Свойство, которого пакет не объявлял, роняет раскладку** — что в `has` дерева, что в имени
|
|
147
|
+
ресурса. Объявлены свойства перечнем при пакете, рядом с осями различия.
|
|
148
|
+
|
|
@@ -7,6 +7,11 @@
|
|
|
7
7
|
|
|
8
8
|
## Ловушки
|
|
9
9
|
|
|
10
|
+
- **Отступление от просьбы называется в том же докладе, где показан результат.** Сделанное не
|
|
11
|
+
тем способом, о котором просили, отличается от сделанного просимым способом даже при совпавшем
|
|
12
|
+
ответе, и разницу называет исполнитель — одной строкой «сделал не тем, чем сказано, вот чем и
|
|
13
|
+
вот почему». Умолчание держится ровно до того, как просьбу приходится повторять, а платит за
|
|
14
|
+
него доверие ко всему докладу.
|
|
10
15
|
- **Оставшаяся работа не записывается в документ, а заводится задачей.** `docs/BACKLOG.md`
|
|
11
16
|
держит только то, что задачей не бывает: договорённости и решения, которые решено не
|
|
12
17
|
править. Признак — утверждение остаётся, если править его никто не собирается. «Сделать
|
|
@@ -83,3 +88,13 @@
|
|
|
83
88
|
строки. Отличить это от применённой правки по коду возврата нечем — видно только по самому
|
|
84
89
|
файлу, и обычно позже, по заголовкам собранного текста. Текст правится инструментом правки; а
|
|
85
90
|
если замену всё же зовут, место, которое она обещала изменить, перечитывают сразу после неё.
|
|
91
|
+
- **Число, полученное командой, замером ещё не является.** Требование пересчитывать число
|
|
92
|
+
командой соблюдается буквально — команда была, — а мерила ли она предмет числа, не спрашивает
|
|
93
|
+
никто. Вывод бывает ложным по-разному и молча: `grep -E` с границей слова `\b` на BSD часть
|
|
94
|
+
образца игнорирует и об этом не сообщает («278 вхождений» оказались 79, и двенадцать из них о
|
|
95
|
+
другом), регулярка не видит, где кончается блок, и приписывает найденное соседу, а память
|
|
96
|
+
возвращает число, не помня его происхождения, — от замера оно неотличимо. Число пишется той
|
|
97
|
+
командой, которая мерит его предмет, и тем же ходом, каким пишется текст.
|
|
98
|
+
- **Границу слова спрашивают у той команды, которая её знает.** `grep -w`, `rg` и `python3` с
|
|
99
|
+
`re` её реализуют, BSD `grep -E` — нет; проверка стоит одной команды и делается до того, как
|
|
100
|
+
число уедет в текст.
|
|
@@ -7,6 +7,21 @@
|
|
|
7
7
|
|
|
8
8
|
## Ловушки
|
|
9
9
|
|
|
10
|
+
- **Непосчитанная сливаемость конфликтом не бывает.** Хостинг считает её заново после каждой
|
|
11
|
+
правки главной ветки и до конца счёта отвечает неопределённостью. Прочитанная как конфликт,
|
|
12
|
+
она отбивает работу на каждой свежей вершине — то есть ровно там, где отбивать нечего.
|
|
13
|
+
Поэтому и гард, и сверка судят только прямое «конфликтует», а молчание опроса пропускают.
|
|
14
|
+
- **Силовая отправка ветки, стоящей под другой в стопке, закрывает её заявку как слитую.**
|
|
15
|
+
Хостинг считает заявку слитой, когда вершина её ветки достижима из базы; состояние лживое — в
|
|
16
|
+
главной ветке правки нет, а задача остаётся открытой. Требование, из которого это следует, —
|
|
17
|
+
статья правила о том, что нижняя ветка череды историю не переписывает.
|
|
18
|
+
- **Ветка, догнанная в рабочем дереве и не отправленная, работой не считается.** Человек видит
|
|
19
|
+
прежнее состояние и читает его как «не сделано ничего», а сделанное лежит там, где его не
|
|
20
|
+
видит никто. Про неотправленный разрешённый конфликт статья правила это говорит, но догнанная
|
|
21
|
+
ветка без единого спора под неё не подпадает вовсе.
|
|
22
|
+
- **`UNKNOWN` в поле сливаемости означает «ещё не посчитано», а не «конфликтов нет».** Хостинг
|
|
23
|
+
считает её после каждого чужого слияния, и заявка, прочитанная в эту секунду, выглядит
|
|
24
|
+
здоровой.
|
|
10
25
|
- **Одна работа — одна задача, сколько бы файлов она ни задела.** Числа, за которым правка
|
|
11
26
|
становится второй задачей, здесь нет: делится то, что придётся откатывать порознь. Сплошная
|
|
12
27
|
правка текстов дерева была заведена тремя задачами «по объёму» — пришлось стирать две,
|
|
@@ -97,8 +112,57 @@
|
|
|
97
112
|
Сюда уехали случаи, числа и отвергнутые лекарства, стоявшие прежде при статьях правила. Ни одно
|
|
98
113
|
решение по правке на них не стоит: они нужны тому, кто разбирает промах или спорит с гардом.
|
|
99
114
|
|
|
115
|
+
- **Отказ на слиянии остаётся вторым рубежом.** Человек вливает, как только видит зелёное, и до
|
|
116
|
+
второго рубежа дело просто не доходит.
|
|
117
|
+
|
|
118
|
+
- **Список, в котором всё серое, читается как «работа не сделана».** Черновик и недоделанное
|
|
119
|
+
выглядят одинаково; находит такие заявки сверка — ночью, в чужой сессии, после закрытого
|
|
120
|
+
разговора.
|
|
121
|
+
- **Логин рядом со служебным числом не сверяет никто.** Промах в почте изнутри не виден вовсе:
|
|
122
|
+
коммит выглядит своим, а подписан посторонним.
|
|
123
|
+
|
|
124
|
+
- **Ключ задач, разошедшийся с формой ветки в профиле.** Они не отказывают, а перестают узнавать
|
|
125
|
+
номер: проверка, искавшая работу без задачи, пропускает всё подряд.
|
|
126
|
+
- **Сложение у указателя зовут не ради спора, а ради тишины.** Без объявления человека зовут при
|
|
127
|
+
каждом слиянии — по строке, которая нужна целиком с обеих сторон.
|
|
128
|
+
|
|
129
|
+
- **Гейт — обещание, что пуш не приедет красным.** Набор без сборки и снимков обещает то, чего не
|
|
130
|
+
проверяет.
|
|
131
|
+
- **Борда показывает, что сделано и что осталось.** Заявка отвечает на другой вопрос и
|
|
132
|
+
связывается с карточкой сама — отдельной карточки ей не нужно.
|
|
133
|
+
|
|
134
|
+
- **Сливаемость выводили из локального вливания.** Между ним и взглядом владельца главная уходит
|
|
135
|
+
вперёд, и «у меня слилось» о кнопке не говорит ничего. Дерево, чей помощник очереди о поле
|
|
136
|
+
`mergeable` не говорит вовсе, работает как прежде: поля нет — требования нет.
|
|
137
|
+
- **Личность вызова, открывающего заявку.** Дерево, не назвавшее машинной записи, требования
|
|
138
|
+
подстановки токена не получает: сверять ответ хостинга не с чем.
|
|
139
|
+
|
|
140
|
+
- **Ветки, заведённые от главной подряд, роняют друг друга.** Замер по ста шести накопленным
|
|
141
|
+
веткам одного основания: вливание одной делает расходящимися до двадцати трёх, в среднем семь с
|
|
142
|
+
половиной; не расходятся ни с кем двенадцать. Считался он `git merge-tree` в памяти — рабочего
|
|
143
|
+
дерева замер не трогает и веток не двигает.
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
# проба слияния без единой правки в дереве: коммит-слияние заводится в объектной базе
|
|
147
|
+
tree="$(git merge-tree --write-tree origin/main <ветка> | head -1)"
|
|
148
|
+
probe="$(git commit-tree "$tree" -p origin/main -p <ветка> -m проба)"
|
|
149
|
+
git merge-tree --write-tree "$probe" <другая ветка> >/dev/null; echo $? # 1 — разойдутся
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Дерево аргументом сюда не годится: истории у него нет, общее основание не считается, и любая
|
|
153
|
+
проба отвечает «сойдётся».
|
|
154
|
+
|
|
155
|
+
- **Расходится не правка, а строка, куда дописали обе стороны.** В том же замере исходник
|
|
156
|
+
ресурса сливался чисто, а его разложенная копия расходилась первой строкой — той, где стоит
|
|
157
|
+
контрольная сумма ресурса. Две работы правили разные разделы разных файлов, и всё равно
|
|
158
|
+
требовали разбора. Отсюда и правило ветвиться чередой: снимать пришлось бы не расхождение, а
|
|
159
|
+
сам способ хранить копию рядом с исходником.
|
|
160
|
+
|
|
100
161
|
- **Сборка входит в набор гейта.** Четыре мержа подряд уехали в главную ветку, ломая выкатку:
|
|
101
162
|
ошибка типов в непокрытом коде пережила линт и юниты и всплыла на сборке образа.
|
|
163
|
+
- **Набор, переписанный строками, выглядит полным.** В одном дереве шесть проверок лежали рядом
|
|
164
|
+
с гоняемыми и не гонялись ни гейтом, ни конвейером: восемь строк из четырнадцати читались как
|
|
165
|
+
весь набор, и разница была видна только сличением с умолчанием пакета.
|
|
102
166
|
- **Набор гейта не бывает уже набора конвейера.** Дважды подряд правка, прошедшая гейт целиком,
|
|
103
167
|
была отбита конвейером — и оба раза зелёный гейт был прочитан как «локально всё зелено». Отсюда
|
|
104
168
|
и требование отбивать пуш на шаге без строки в наборе, а не печатать предупреждение рядом.
|
|
@@ -110,6 +174,12 @@
|
|
|
110
174
|
в шести ветках за один заход. Обещать по объявлению «конфликтов больше не будет» нельзя: не
|
|
111
175
|
будет ручной работы, а вливать главную в открытые ветки после каждого слияния придётся
|
|
112
176
|
по-прежнему.
|
|
177
|
+
- **Заведённое видно только заводящему.** Шестнадцать задач так были заведены дважды, а заявка
|
|
178
|
+
названа владельцу номером, которого для него не существовало: ограниченная запись видела своё,
|
|
179
|
+
а хостинг отвечал остальным «не найдено».
|
|
180
|
+
- **Обойдённый отказ унёс признак ограничения.** Предел запросов у ограниченной записи стоял на
|
|
181
|
+
нуле — не исчерпан, а не положен вовсе. Отказ обошли вызовом другого рода, обход сработал, и
|
|
182
|
+
расхождение всплыло через двадцать минут и четыре следа, которые пришлось переписывать.
|
|
113
183
|
- **Личность вызова, открывающего заявку.** Прежде обе стороны — подстановка токена и ответ
|
|
114
184
|
хостинга об авторе — держались статьёй и разбором происшествия, и промах повторился на третий
|
|
115
185
|
день.
|
|
@@ -131,3 +201,21 @@
|
|
|
131
201
|
дали, а запрос разбора на автора хостинг принимает молча и не создаёт.
|
|
132
202
|
- **Ревьюверы спрашиваются вызовом REST.** Под токеном машинной записи выборка клиента падает
|
|
133
203
|
целиком, без токена проходит зелёной — отличить «сошлось» от «спросить было нечем» нечем.
|
|
204
|
+
|
|
205
|
+
- **Полнота набора гейта судится по именам шагов конвейера.** Проверки, которой нет и в
|
|
206
|
+
конвейере, там нет тоже: набор, переписанный строками вместо вызова умолчания пакета, теряет
|
|
207
|
+
ровно те проверки, которые пакет заведёт следующей редакцией. Своя строка вместо умолчания
|
|
208
|
+
законна там, где она покрывает то же строже либо зовёт названный скрипт.
|
|
209
|
+
- **Черновик, чья ветка везёт папку задачи, означает идущую работу, а не брошенную.** Оба
|
|
210
|
+
признака нужны вместе: зелёный прогон на вершине без разобранной папки говорит, что работа
|
|
211
|
+
ещё не отдана. Дерево, не назвавшее машинной записи, этой сверки не получает вовсе.
|
|
212
|
+
- **Метку сливаемости не гасит и объявленное сложение обеих сторон.** Хостинг считает сложение
|
|
213
|
+
своим приёмом и настроек слияния не читает: пока ветка не вобрала главную и это не уехало на
|
|
214
|
+
хостинг, заявка стоит конфликтующей при разрешённом на месте расхождении.
|
|
215
|
+
- **Сверки раскладки нет в конвейере, поэтому шага, который она бы закрывала, там тоже нет.**
|
|
216
|
+
Правка мимо источника в день, когда её делают, не ломает ничего.
|
|
217
|
+
- **Рабочее дерево не опустошается ради прогона инструмента.** Вопрос «этот долг был до моих
|
|
218
|
+
правок или от них» решается второй копией дерева, а не прятаньем работы: спрятанного не видит
|
|
219
|
+
ни статус, ни сверка, а команда, прошедшая между прятаньем и возвратом, пишет в те же файлы —
|
|
220
|
+
и возврат встаёт конфликтом. Так ушли в прятанье восемь незакоммиченных файлов при живом
|
|
221
|
+
запрете на эту команду: запрет читался в начале захода, а команда набиралась через сорок ходов.
|
|
@@ -34,3 +34,25 @@
|
|
|
34
34
|
его привязка перестают находиться друг по другу. После разрешения гоняется
|
|
35
35
|
`npm run check:specs` — конфликт в спеке кода не задевает, и ни сборка, ни линтеры его не
|
|
36
36
|
увидят.
|
|
37
|
+
|
|
38
|
+
- **Строку требования к соседнему ресурсу не проверяет ничто, и расхождение видно только
|
|
39
|
+
счётом.** Правило без неё выглядит целым: разделы на месте, привязки сходятся, сверка
|
|
40
|
+
полноты зелёная. Требовать её у всех нельзя — правило, которому нечего требовать, её не
|
|
41
|
+
пишет, — поэтому судит не проверка, а два числа рядом: сколько правил в каталоге и сколько из
|
|
42
|
+
них требование объявило.
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
ls <каталог правил> | wc -l
|
|
46
|
+
grep -rl '^\*\*Требует:\*\*' <каталог правил> | wc -l
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Расхождение отказом само по себе не бывает. Оно называет, сколько правил прочитать глазами,
|
|
50
|
+
и число это падает по мере того, как их читают. Счёт при этом грубый: строка, показанная
|
|
51
|
+
образцом внутри ограды, считается наравне с настоящей — тот, кто учит её писать, попадает
|
|
52
|
+
в число объявивших.
|
|
53
|
+
- **Привязка пишется по тексту статьи, а не по смыслу имени гарда.** Гард, чьё имя звучит про то
|
|
54
|
+
же самое, статью не закрывает: статья перечисляла шесть действий по отдельному слову владельца
|
|
55
|
+
— коммит, пуш, открытие заявки, запись в вики, заведение задачи, правка закона, — а
|
|
56
|
+
поставленный ей гард не держит ни одного из них и отправки предложения среди перечисленного
|
|
57
|
+
нет вовсе. Читается текст статьи целиком, и в привязке называется то место, которое держит
|
|
58
|
+
названное ею, а не соседнее по смыслу.
|
|
@@ -7,6 +7,20 @@
|
|
|
7
7
|
|
|
8
8
|
## Ловушки
|
|
9
9
|
|
|
10
|
+
- **Разрешение владельца, оставленное в репозитории, теряется на каждой новой ветке.** Оно
|
|
11
|
+
записано номером в файл ветки, а следующая ветка отводится от главной и его не несёт: гард
|
|
12
|
+
отбивает работу, которую владелец разрешил, — и повторяется это ровно столько раз, сколько
|
|
13
|
+
веток заведут до слияния разрешившего коммита. Отказ гарда при этом называет файл и молчит о
|
|
14
|
+
том, что запись принадлежит ветке: из его текста это читается как настройка дерева. Пока
|
|
15
|
+
разрешение живёт в репозитории, номер дописывается заново в каждую новую ветку.
|
|
16
|
+
- **Имя чужого дерева в файлы репозитория не пишется, а путь к образцу — пишется.** Обе вещи
|
|
17
|
+
живут рядом с передачей захода именно поэтому: там законен полный путь, а в репозитории —
|
|
18
|
+
только ссылка без имени.
|
|
19
|
+
- **Строка «Ждём владельца» в ходе работы живёт дольше причины, по которой её написали.** Она
|
|
20
|
+
лежит на диске, приходит в контекст следующим заходом и читается как действующее состояние —
|
|
21
|
+
поэтому снимается тем же ходом, которым владелец ответил. Иначе ожидание подтверждает себя
|
|
22
|
+
само: три указания владельца подряд не пересилили одной строки на диске.
|
|
23
|
+
|
|
10
24
|
- **Папка называется именем ветки, один в один.** Хук запуска ищет её по
|
|
11
25
|
`git branch --show-current`, и папка, названная иначе, не находится ничем: работа идёт с
|
|
12
26
|
пустым контекстом, а владельца просят пересказать то, что уже записано.
|
|
@@ -57,6 +71,51 @@
|
|
|
57
71
|
расспрашивает владельца заново. Имя черновику дают словами просьбы, а ветке — терминологией
|
|
58
72
|
договорённости; те же слова, да не те же.
|
|
59
73
|
|
|
74
|
+
- **Ожидание одной части этапа остановкой этапа не бывает.** Части, которые от ожидаемого не
|
|
75
|
+
зависят, делаются тем же ходом: сказать «стоит приёмка» и не тронуть остальное — это
|
|
76
|
+
остановка всей работы по причине, действующей на её десятую часть. Правило говорит про
|
|
77
|
+
задачу, и «стоит одна часть» прочитывается по нему как «стоит работа» — при пяти частях этапа
|
|
78
|
+
ждала одна.
|
|
79
|
+
|
|
80
|
+
- **Строка с путём поручением не бывает.** Адрес называет файл, а не действие; прочитанный как
|
|
81
|
+
задание, он даёт заходу работу, которой владелец не просил. То же с любой репликой без
|
|
82
|
+
глагола: спросить, что с этим делать, дешевле, чем написать полсотни файлов мимо просьбы.
|
|
83
|
+
|
|
84
|
+
- **Тело задачи, написанное вперёд замысла, называет способ, и способ стареет раньше дефекта.**
|
|
85
|
+
Задача серии заводится за недели до того, как её берут, и к этому дню предложенный ход бывает
|
|
86
|
+
уже неверен: привезённое пакетом умеет то, что задача звала написать, названного места в
|
|
87
|
+
дереве не осталось, а посылки, на которых ход стоял, разведка не подтверждает. Читается такое
|
|
88
|
+
тело как действующее указание, поэтому работа начинается с чтения того файла, к которому
|
|
89
|
+
задача относится, а не с исполнения её тела. Расхождение уходит решением по ходу и меняет
|
|
90
|
+
способ, но не цель.
|
|
91
|
+
|
|
92
|
+
- **Работа, упершаяся в разрешение, доводится до конца без той части, которую разрешение
|
|
93
|
+
открывает.** Чужой шаг бывает двух родов: прогон и разбор идут сами и кончатся без
|
|
94
|
+
исполнителя, а отбитое разрешение не кончится никогда — его ждут, и ход, объявивший об этом,
|
|
95
|
+
останавливает работу целиком. Делается всё, что от разрешения не зависит, а непройденное
|
|
96
|
+
пишется строками тела заявки — там его читает ревьювер; реплика владельцу живёт до следующего
|
|
97
|
+
сообщения и в приёмку не попадает.
|
|
98
|
+
|
|
99
|
+
- **Слово владельца об устройстве — постановка, а не решение.** Названное им обычно уже живёт
|
|
100
|
+
в дереве под этим самым словом: у него есть имя на экране, раздел в спеке и поле в модели, и
|
|
101
|
+
сверка стоит одного поиска. Истолкованное по ближайшему коду, слово выглядит исполненной
|
|
102
|
+
просьбой ровно до приёмки: правка при этом влита, а владельцу вместо поля в приложении
|
|
103
|
+
досталась работа в чужой консоли. Разошлось прочтение с деревом — спрашивается владелец, и
|
|
104
|
+
спрашивается до правки.
|
|
105
|
+
|
|
106
|
+
- **Указание работать по ходу — это указание делать его шаги, включая меняющие историю.**
|
|
107
|
+
Отметка сделанного этапа, отправка ветки и открытие заявки ходом предписаны, и отдельного
|
|
108
|
+
слова на каждый не требуется: спросить надо о том, чего в ходе нет вовсе. Изъятие приходит
|
|
109
|
+
из общего запрета дерева на действие без просьбы, прочитанного как требование буквального
|
|
110
|
+
слова, — и получается указание, исполненное наполовину. Граница у этого одна: прямое слово
|
|
111
|
+
владельца о самом шаге. Сказано «ветку не отправляй» — она не отправляется, сколько бы раз
|
|
112
|
+
ход её ни предписывал.
|
|
113
|
+
|
|
114
|
+
- **Строка ожидания живёт дольше причины, по которой её написали.** Записанная в ход работы,
|
|
115
|
+
она приходит в следующий заход раньше любой реплики и подтверждает себя сама: три указания
|
|
116
|
+
подряд не пересилили одну строку на диске. Снимается она тем же ходом, которым владелец
|
|
117
|
+
ответил, — а не тем, в котором о ней вспомнили.
|
|
118
|
+
|
|
60
119
|
- **У меню с закрытым набором нет строки «вопрос не тот».** Вариантами вопрос выглядит
|
|
61
120
|
разобранным, и владельцу, чтобы отвергнуть саму постановку, приходится выходить из набора
|
|
62
121
|
руками. Спрашивают меню то, где выбор действительно закрыт; там, где под сомнением сама
|
|
@@ -82,9 +141,63 @@
|
|
|
82
141
|
работой, а не отдельной правкой.
|
|
83
142
|
- **Папка, уехавшая в главную ветку.** Три раза подряд папка закрытой задачи так и уехала
|
|
84
143
|
неразобранной, в последний раз их набралось пять.
|
|
144
|
+
- **Этап, вставший из-за одной своей части.** Этап состоял из пяти частей, одна ждала поднятых
|
|
145
|
+
владельцем серверов — встали все пять. Остальные четыре от ожидаемого не зависели ничем.
|
|
146
|
+
|
|
147
|
+
- **Замысел эпика, положенный каждым заходом заново, теряет решения предыдущих.** Имя, адрес и
|
|
148
|
+
способ, названные владельцем по ходу, живут там же, где состав и порядок задач.
|
|
149
|
+
- **Чтение обхода из самой команды работает и без сети.** Строка `Task-folder-skip:` читается и
|
|
150
|
+
из тела заявки, и из текста вызова: второй путь остаётся, когда хостинг недоступен.
|
|
151
|
+
- **Черновик без номера — единственная папка, которой в истории нет.** Заводить её туда нечего,
|
|
152
|
+
пока нет имени.
|
|
153
|
+
- **На борде эпик из десяти задач выглядит одной.** Заведённые по одной, они прячут объём:
|
|
154
|
+
владелец видит карточку, а не десять.
|
|
155
|
+
- **Разбор закрытой работы ведёт роль разбора закрытой задачи.** Дерево, её не разложившее,
|
|
156
|
+
ведёт разбор само.
|
|
157
|
+
- **Перечень состояний нужен владельцу в начале работы.** Без него после шести вопросов не видно
|
|
158
|
+
ни того, что будет дальше, ни сколько всего впереди.
|
|
159
|
+
- **Хвост отданной работы — четыре шага:** открыть заявку, дождаться прогона, снять черновик,
|
|
160
|
+
попросить влить. Состояния на диске у них уже нет.
|
|
161
|
+
- **Разбор из одной строки проходит гард так же, как разбор на сто.** Образец разбора
|
|
162
|
+
перечисляет шесть обязательных вопросов таблицей, и пустая таблица проходит наравне с
|
|
163
|
+
заполненной.
|
|
164
|
+
- **Отказ гарда разговора исполняется задним числом.** Владелец видит незаданный вопрос вместе с
|
|
165
|
+
отбитым ходом: прозаический вопрос инструментом не является, и раньше поймать его нечем. Гард
|
|
166
|
+
отмечает пропуск, но не отменяет его.
|
|
167
|
+
- **Обход требования папки нужен там, где работа вливается частями.** Тогда её до конца не
|
|
168
|
+
разбирают, а причина остаётся в заявке.
|
|
169
|
+
- **Строка состояния точнее всякого обещания.** Её видно в файле, её читает страж, за ней стоит
|
|
170
|
+
перечень с обязательным действием — и потому переведённая вперёд она не выдаёт себя ничем.
|
|
171
|
+
- **Ход работы, живущий в рабочем дереве, не виден никому.** Владелец видит ветку без единого
|
|
172
|
+
следа того, что в ней делается, а следующий заход находит пустоту вместо «Где стоим». Это
|
|
173
|
+
второе следствие незакоммиченной папки, и оно тише первого: отказа не приходит вовсе.
|
|
174
|
+
- **Шапка раскладки, оставленная в копии образца, отбивает первую же правку разбора просьбы.**
|
|
175
|
+
Отказ при этом уводит править образец пакета вместо копии под задачу.
|
|
176
|
+
- **Правка по замечаниям идёт без замысла на диске.** Папка разобрана коммитом ветки раньше
|
|
177
|
+
открытия заявки, и состояния у работы с этой минуты нет: судит её история ветки.
|
|
178
|
+
- **Прогон, поставленный раньше дешёвых шагов, съел окно захода.** Потративший его на прогон
|
|
179
|
+
упирался в порог заполнения на четырёх строках привязки — то есть на работе минут на пять.
|
|
180
|
+
- **Граница состояния выглядит законченным куском лучше всякой вехи.** Владельцу отчёт о взятой
|
|
181
|
+
задаче неотличим от остановки: названы номер, ветка и колонка, и всё названное правда.
|
|
85
182
|
- **Заявка на чужом языке.** В дереве, где заявки пишутся на другом языке, чужой заголовок
|
|
86
183
|
дважды уехал на хостинг, и оба раза до него добрались глазами.
|
|
87
184
|
- **Вопрос, утонувший в отчёте.** Владелец трижды переспрашивал, почему работа стоит, и каждый
|
|
88
185
|
круг стоил захода обоим.
|
|
89
186
|
- **Чужой эпик в списке очереди.** Дважды подряд следующей была взята первая задача чужого
|
|
90
187
|
эпика — по списку она выглядела ровно как своя.
|
|
188
|
+
|
|
189
|
+
- **Некоммиченная папка задачи отказывает там, где чинить уже нечего.** Гард спрашивает её с
|
|
190
|
+
диска, поэтому все правки проходят без единого отказа, а признак отданной работы берётся из
|
|
191
|
+
истории ветки. Отказ приходит на открытии заявки — в минуту, когда папка разобрана своими
|
|
192
|
+
руками: замысел снят, и собирать его приходится заново по памяти. Владелец при этом всю
|
|
193
|
+
работу видит ветку без единого следа того, что в ней делается, а следующий заход находит
|
|
194
|
+
пустоту вместо «Где стоим».
|
|
195
|
+
- **Прогон, поставленный первым шагом закрытия, съедает окно захода.** Он стоит дороже всех
|
|
196
|
+
остальных шагов вместе, и потративший его на прогон упирался в порог заполнения на четырёх
|
|
197
|
+
строках привязки — то есть на работе, которая стоила бы минуты, если бы шла первой.
|
|
198
|
+
- **Разрешение работать вне назначенного эпика принадлежит рабочему дереву, а не ветке.**
|
|
199
|
+
Записанное в файл репозитория, оно уезжает вместе с веткой: из соседней его не видно, и гард
|
|
200
|
+
эпика отбивает ровно ту работу, которую владелец разрешил. За один заход это случилось дважды
|
|
201
|
+
— сперва на отказе конца хода, потом на переводе колонки, и оба раза номер дописывался заново.
|
|
202
|
+
Место такому разрешению там же, где передача захода: оно не откатывается вместе с правкой и не
|
|
203
|
+
принадлежит ни одной задаче.
|
|
@@ -7,6 +7,12 @@
|
|
|
7
7
|
|
|
8
8
|
## Ловушки
|
|
9
9
|
|
|
10
|
+
- **Зелёный тест чистой функции молчит о ряде, которого рабочий путь не порождает.** Функция
|
|
11
|
+
верна на том, что ей подали, а подаёт ей ввод сам тест: ряд, собранный ради удобства
|
|
12
|
+
проверки, доказывает поведение на случае, которого в работе не бывает. Так стояли два зелёных
|
|
13
|
+
теста решения об оповещении, а предохранитель, ради которого решение писали, не сработал ни
|
|
14
|
+
разу. Форма ввода берётся с той границы, откуда решение зовут, — у процедуры, у службы, у
|
|
15
|
+
обработчика, — и сверяется с ней, а не выдумывается рядом с проверкой.
|
|
10
16
|
- **Зелёный `nx test <проект>` не значит, что хоть один файл исполнялся.** Либа без своего
|
|
11
17
|
`vitest.config.mts` не запускает ничего — так тесты домена броней не запускались ни разу.
|
|
12
18
|
Либа с конфигом, но без единого `*.spec.ts`, проходит зелёной из-за `passWithNoTests: true`,
|
|
@@ -31,3 +31,52 @@
|
|
|
31
31
|
- **Почему гард ожидания читает ход, а не хостинг.** Спросить хостинг было бы точнее, но сетевой
|
|
32
32
|
вызов на завершении хода падает вместе со связью и отбивал бы работу вместо промаха, а вывод
|
|
33
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
|
+
Признак непрочитанного один: имя функции, названное в разборе, но не открытое.
|
|
58
|
+
|
|
59
|
+
- **Работа не передаётся владельцу словами «сделай сам», пока не прочитан механизм, который её
|
|
60
|
+
отбивает.** Готовая команда с объяснением «у меня не выйдет» выглядит помощью и ею не
|
|
61
|
+
работает: она переносит на владельца незакрытое чтение. Длинная череда отказов доводом здесь
|
|
62
|
+
не бывает — она говорит о том, сколько раз повторили одно движение, а не о том, что механизм
|
|
63
|
+
неисправен.
|
|
64
|
+
|
|
65
|
+
- **Неудобство исполнителя решения владельца не пересматривает.** Принятое решение об отправке —
|
|
66
|
+
открыть заявку, отдать работу, показать сделанное — не отменяется тем, что путь к нему оказался
|
|
67
|
+
длиннее ожидаемого. Довод «так выйдет дольше» говорит о цене, а платит её не тот, кто решение
|
|
68
|
+
принимал: цена называется владельцу вместе со сделанным шагом, а не вместо него. Отличить этот
|
|
69
|
+
случай от законного вопроса просто — законный вопрос про то, чего исполнитель не знает, а этот
|
|
70
|
+
про то, чего ему не хочется.
|
|
71
|
+
|
|
72
|
+
- **Страж выхода судит изменение дерева, а не оставшееся действие.** Он спрашивает, сделано ли за
|
|
73
|
+
ход хоть что-то, — и ход, в котором закрыта половина этапа, а вторая брошена на отбитой
|
|
74
|
+
команде, ему неотличим от полной работы: коммиты есть, дерево изменилось. Ловится им только ход,
|
|
75
|
+
кончившийся ничем. Осталось ли в состоянии действие, не зависящее от того, чего ход ждёт,
|
|
76
|
+
проверяет вниманием тот, кто ведёт ход.
|
|
77
|
+
- **Отбитое разрешение чужим шагом не бывает, и работу оно не останавливает.** Статья о чужом
|
|
78
|
+
шаге написана про то, что идёт само и кончится без исполнителя: прогон, разбор, слияние.
|
|
79
|
+
Разрешение, отбитое средой, само не кончится — оно ждёт слова владельца, — и работа, упершаяся
|
|
80
|
+
в него, встаёт целиком там, где мимо него шло ещё несколько ходов дела. Делается всё, что от
|
|
81
|
+
разрешения не зависит, а несделанное называется в теле заявки, разделом об оставшемся шаге:
|
|
82
|
+
он ровно про это и написан.
|
|
@@ -67,10 +67,25 @@ flowchart TD
|
|
|
67
67
|
идентификатору процесса, а не по имени команды — у обоих экземпляров оно одно.
|
|
68
68
|
- **Браузер водится одним драйвером на закреплённом профиле.** Остальные двери — второй
|
|
69
69
|
драйвер, `open`, `osascript`, запуск бинарника — закреплённый профиль не спрашивают вовсе.
|
|
70
|
+
- **Браузер, поднятый библиотекой изнутри скрипта, — та же дверь, что и запуск бинарника.** В
|
|
71
|
+
строке команды её не видно вовсе: там стоят имя интерпретатора и путь файла, а вождение лежит
|
|
72
|
+
внутри самого файла. Поэтому судится содержимое запускаемого файла и код, переданный доводом
|
|
73
|
+
вместо файла; правило, судившее одну командную строку, обещало больше, чем проверяло, и
|
|
74
|
+
профиль обошли этой дверью дважды за один заход.
|
|
70
75
|
- **Выбор браузера протухает и требует повторного вызова.** Выбор, сделанный в начале
|
|
71
76
|
сессии, не держится: после паузы следующий вызов открывает вкладку в другом профиле молча.
|
|
72
77
|
- **Профиль не выбирается из списка и не спрашивается у владельца.** Список отдаёт неустойчивые
|
|
73
78
|
имена, которые не опознают ничего, а выбор из него ведёт на профиль без входа.
|
|
79
|
+
- **Ненастроенная стража — повод остановиться, а не разрешение ехать.** Пропуск гарда при
|
|
80
|
+
молчащем помощнике сделан затем, чтобы сломанная обвязка не заводила работу в тупик, и
|
|
81
|
+
разрешением работать мимо профиля не является. Исполнитель, получивший от помощника пустой
|
|
82
|
+
вывод, называет это владельцу и браузер не водит: вкладка откроется в том профиле, который
|
|
83
|
+
расширение сочло активным, а какой это профиль — не знает никто.
|
|
84
|
+
- **Экран, закрытый входом, проверяется стендом с подменённым ответом входа, а не живой учётной
|
|
85
|
+
записью.** Приложение получает вход тем же путём, что у человека, — формой, — а отвечает на неё
|
|
86
|
+
стенд; признак, которым закрыт экран, приходит подменённым профилем. Просьба к человеку сделать
|
|
87
|
+
шаг проверки — набрать пароль, открыть вкладку, нажать кнопку — означает неверно выбранный
|
|
88
|
+
путь, а не нехватку прав у исполнителя.
|
|
74
89
|
- **Замер делается на самом длинном значении, а не на образцовом.** Наезд, вылезание за край и
|
|
75
90
|
обрезка без признака видны только там, где содержимое в своё место не влезает; на коротком
|
|
76
91
|
значении всё три выглядят исправными. Значение для замера берётся предельное — то, какое узел
|
|
@@ -93,6 +108,13 @@ flowchart TD
|
|
|
93
108
|
замеряются те же вычисленные значения, а выдумывается только содержимое строки. Обходом было
|
|
94
109
|
бы измерить чужой экран и назвать это замером нужного.
|
|
95
110
|
|
|
111
|
+
- **Замер, который придётся повторять, снимает сквозная спека, а не драйвер.** Ширина окна,
|
|
112
|
+
положение узла и уход содержимого вбок читаются в ней теми же вычисленными значениями, вьюпорт
|
|
113
|
+
задаётся на весь набор, и число сходится при каждом прогоне — а замер руками живёт один заход
|
|
114
|
+
и уходит вместе с ним. Драйвер остаётся там, где смотрят на незнакомый экран: он отвечает на
|
|
115
|
+
«что тут происходит», а не подтверждает известное число. Вывод «замер снять нечем», сделанный
|
|
116
|
+
на закрытом входе, чаще всего означает, что искали не тем.
|
|
117
|
+
|
|
96
118
|
Вывод о вёрстке подкрепляется числом: «выглядит нормально» результатом проверки не является.
|
|
97
119
|
Этого не стережёт ничто — как измерять, разобрано в паттерне `browser-verification-measure`.
|
|
98
120
|
|
|
@@ -121,6 +143,21 @@ flowchart TD
|
|
|
121
143
|
процесса, снятый разбором порта; им и останавливают, поштучно. Обратный промах тот же по
|
|
122
144
|
природе — оболочка запускает процесс под именем, которого в шаблоне нет, и снятие не попадает
|
|
123
145
|
ни во что.
|
|
146
|
+
- **Снятие процесса бывает отбито, и тогда стенд поднимается рядом, а не вместо.** Отбить его
|
|
147
|
+
может среда исполнения — и по своему же стенду прошлого захода; ни разрешение на команду, ни
|
|
148
|
+
переформулировка тут не помогают. Ход отсюда один: свободный порт для нового стенда, а список
|
|
149
|
+
оставленного называется владельцу в конце захода — снять их может только он. Не названные так,
|
|
150
|
+
стенды копятся заходами и держат соединения к хранилищу.
|
|
151
|
+
- **Замер снимает и сквозная спека, а не только драйвер браузера.** Ширина окна, положение узла
|
|
152
|
+
и уход документа вбок читаются в ней теми же вычисленными значениями, вьюпорт задаётся на набор
|
|
153
|
+
тестов, а результат повторяется при каждом прогоне — в отличие от замера руками, который живёт
|
|
154
|
+
ровно один заход. Драйвер остаётся там, где смотрят на незнакомый экран, а не подтверждают
|
|
155
|
+
известное число.
|
|
156
|
+
- **Утверждение о прод-сборке делается по самой сборке, а не по ветке.** Между веткой и тем, что
|
|
157
|
+
отдано читателю, стоит сборка образа: она подставляет значения окружения, вырезает
|
|
158
|
+
неиспользованное и переименовывает символы. Сказанное «в сборке лежит вот это» проверяется
|
|
159
|
+
поиском по отданному файлу — тем более когда речь идёт как раз о значении, которое сборка и
|
|
160
|
+
подставляет.
|
|
124
161
|
- Инкрементальная сборка протухает поштучно: разметка бывает уже новая, а клиентский чанк — от
|
|
125
162
|
компиляции до правки. Признак дев-сборки — имена бандла без хеша (`main.js`). Расхождение
|
|
126
163
|
между `curl` и страницей после гидратации — повод пересобрать, а не искать дефект в коде.
|
|
@@ -129,6 +166,13 @@ flowchart TD
|
|
|
129
166
|
только пакеты из `node_modules`, кода репозитория там нет вовсе. Вывод «дефекта нет, это
|
|
130
167
|
кэш» закрывает разбор, поэтому принимается только после проверки на чистой сборке — три
|
|
131
168
|
круга ушло на застрявшую панель ленты событий, пока дефект лежал в снятии аутлета.
|
|
169
|
+
- **Кэширующий шаг сборки без объявленных выходов отдаёт прошлое молча.** Попадание в кэш при
|
|
170
|
+
этом происходит, а восстанавливать нечего: сборщик не запускается, и в каталоге сборки
|
|
171
|
+
остаётся то, что лежало от прошлого раза. Стенд поднимает эту сборку, и приложение ведёт себя
|
|
172
|
+
как код, которого в дереве нет. Ловушка выше — про другой кэш: тот объясняет расхождение, этот
|
|
173
|
+
его создаёт, и вывод сборщика при нём зелёный. Прежде чем искать дефект в экране, у шага
|
|
174
|
+
сборки спрашивают объявленные выходы; проверяется это сносом каталога сборки и повторным
|
|
175
|
+
вызовом — после попадания в кэш он обязан восстановиться.
|
|
132
176
|
- Сообщение `Angular debugging APIs are not available` в консоли принадлежит расширению
|
|
133
177
|
Chrome, а не приложению: прод-сборка не публикует `window.ng`. Лечить правкой кода не надо —
|
|
134
178
|
`window.ng` в проде это карта внутренностей в руках любого, кто откроет консоль.
|
|
@@ -146,3 +190,17 @@ flowchart TD
|
|
|
146
190
|
проверки, не говорит про образ ничего: в составе прода она есть, а ручной прогон того же
|
|
147
191
|
образа идёт без неё. Пути перечисляются до проверки, а не после того, как один из них
|
|
148
192
|
сошёлся.
|
|
193
|
+
- **Признак снимается с вопроса владельца, а не с предмета правки.** Отданная сервером страница
|
|
194
|
+
отвечает на «собралось ли», и на «видно ли» она не отвечает никогда: показ живёт после
|
|
195
|
+
гидратации, а картинка — после запроса к чужой службе. Признаки под второй вопрос свои —
|
|
196
|
+
`naturalWidth` у картинки больше нуля, узел показа появился на поднятой странице, — и снимаются
|
|
197
|
+
они драйвером, а не запросом к адресу.
|
|
198
|
+
- **Чужой отказ службы диагнозом настройки не бывает.** `403` называет состояние проекта у
|
|
199
|
+
поставщика и молчит о том, какое значение лежит в настройке дерева; прочитанный как диагноз, он
|
|
200
|
+
уводит в починку того, что цело, — а само значение читается одной командой на своей стороне.
|
|
201
|
+
Владельцу оно тем более не заказывается: у захода оно уже есть.
|
|
202
|
+
- **Прежнее поведение читается кодом той версии:** `git show <коммит до правки>:<файл>`. Тело
|
|
203
|
+
коммита называет, что правка сменила, и молчит о том, что было верно до неё; условие показа, в
|
|
204
|
+
которое дописано ещё одно обязательное значение, гасит показанное раньше и в самой правке
|
|
205
|
+
выглядит уточнением. Правка соседней задачи, выкатившаяся тем же днём, входит в проверку прода
|
|
206
|
+
наравне со своей: ветка отвечает за то, что уехало вместе с ней.
|