@rt-tools/agent-kit 0.5.3 → 0.7.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/README.md +15 -1
- package/assets/checks/check-file-size.mjs +127 -0
- package/assets/checks/check-push-gate.mjs +139 -0
- package/assets/checks/rt-kit-checks.config.mjs +21 -0
- package/assets/defaults/gate-map.sh +90 -34
- package/assets/defaults/project.sh +26 -3
- package/assets/hooks/skill-gate-layers.sh +156 -0
- package/assets/hooks/skill-gate.sh +11 -2
- package/assets/laws/code-structure.md +3 -0
- package/assets/laws/delivery.md +9 -0
- package/assets/laws/observability.md +46 -0
- package/assets/laws/project-documentation.md +4 -0
- package/assets/laws/reuse-first.md +2 -0
- package/assets/laws/verifiability.md +5 -0
- package/assets/patterns/browser-verification-stand.md +22 -2
- package/assets/patterns/doc-style-trace.md +111 -0
- package/assets/patterns/git-workflow-commit.azure.md +18 -0
- package/assets/patterns/git-workflow-commit.github.md +19 -1
- package/assets/patterns/git-workflow-commit.gitlab.md +18 -0
- package/assets/patterns/git-workflow-docker.md +203 -0
- package/assets/patterns/git-workflow-secrets.md +93 -0
- package/assets/patterns/observability-record.md +114 -0
- package/assets/patterns/seo-verify.md +1 -1
- package/assets/patterns/spec-driven-domain.md +2 -2
- package/assets/patterns/spec-driven-rule.md +5 -0
- package/assets/patterns/styling-bem-sheet.md +178 -0
- package/assets/patterns/task-flow-close.md +20 -0
- package/assets/patterns/task-flow-resume.md +5 -0
- package/assets/patterns/translations-content.md +107 -0
- package/assets/patterns/translations-key.md +1 -1
- package/assets/rules/angular-patterns.md +5 -0
- package/assets/rules/browser-verification.md +17 -12
- package/assets/rules/component-structure.md +6 -2
- package/assets/rules/doc-style.md +16 -0
- package/assets/rules/git-workflow.azure.md +60 -1
- package/assets/rules/git-workflow.github.md +67 -1
- package/assets/rules/git-workflow.gitlab.md +61 -1
- package/assets/rules/lists.md +13 -0
- package/assets/rules/observability.md +147 -0
- package/assets/rules/permissions.md +23 -0
- package/assets/rules/reuse-first.md +9 -0
- package/assets/rules/seo.md +57 -9
- package/assets/rules/shared-code.md +6 -0
- package/assets/rules/spec-driven.md +9 -0
- package/assets/rules/styling-bem.md +34 -1
- package/assets/rules/task-flow.md +5 -0
- package/assets/rules/testing.md +46 -8
- package/assets/rules/translations.md +11 -5
- package/assets/rules/typescript-conventions.md +5 -0
- package/lib/assets.d.ts +1 -1
- package/lib/assets.d.ts.map +1 -1
- package/lib/assets.js +2 -4
- package/lib/assets.js.map +1 -1
- package/lib/catalog.d.ts +73 -0
- package/lib/catalog.d.ts.map +1 -1
- package/lib/catalog.js +121 -0
- package/lib/catalog.js.map +1 -1
- package/lib/commands.d.ts.map +1 -1
- package/lib/commands.js +84 -5
- package/lib/commands.js.map +1 -1
- package/lib/integrity.d.ts +25 -12
- package/lib/integrity.d.ts.map +1 -1
- package/lib/integrity.js +40 -18
- package/lib/integrity.js.map +1 -1
- package/lib/proposals.d.ts +9 -1
- package/lib/proposals.d.ts.map +1 -1
- package/lib/proposals.js +11 -2
- package/lib/proposals.js.map +1 -1
- package/lib/retired.d.ts +30 -0
- package/lib/retired.d.ts.map +1 -0
- package/lib/retired.js +19 -0
- package/lib/retired.js.map +1 -0
- package/lib/sync.d.ts +45 -1
- package/lib/sync.d.ts.map +1 -1
- package/lib/sync.js +44 -10
- package/lib/sync.js.map +1 -1
- package/package.json +1 -1
- package/rt-tools-agent-kit-0.7.0.tgz +0 -0
- package/assets/laws/application/money.md +0 -41
- package/assets/laws/application/ownership.md +0 -32
- package/assets/patterns/ownership-scope-resolve.md +0 -69
- package/assets/patterns/pricing-quote.md +0 -71
- package/assets/rules/ownership-scope.md +0 -63
- package/assets/rules/pricing.md +0 -64
- package/rt-tools-agent-kit-0.5.3.tgz +0 -0
|
@@ -148,7 +148,27 @@ npm run check:docs # пути, названные в текстах, суще
|
|
|
148
148
|
выкачено» с тем, что работает месяц, — беззвучная ложь, тем убедительнее, чем старше.
|
|
149
149
|
- **Номера сценариев при вливании не пересчитываются.** Идентификатор — ключ связи с тестами;
|
|
150
150
|
сдвиг рвёт сверку у соседей, которых правка не касалась.
|
|
151
|
+
- **«Что не входит» после вливания читается целиком, а не дописывается.** Договорённость несёт
|
|
152
|
+
свои границы, и при вливании они ложатся рядом с границами домена: половина повторяет уже
|
|
153
|
+
стоявшее другими словами, а строка «этого раздела ещё нет» становится ложью ровно той
|
|
154
|
+
работой, которая её вливает. Сверка спеков в этот раздел не смотрит вовсе. Снимается
|
|
155
|
+
дословный повтор и то, что работа сделала входящим.
|
|
156
|
+
- **Шаги закрытия с владельцем не согласуются — они перечислены здесь.** Разбор работы
|
|
157
|
+
правилами входит в закрытие так же, как вливание договорённости и разбор папки; владелец
|
|
158
|
+
решает не то, запускать ли его, а что делать с находками. Ход, кончившийся таким вопросом,
|
|
159
|
+
отбивает гард разговора: за ход правила не читались, а ответ стоит в них. Спрашивается только
|
|
160
|
+
то, чего в правилах нет.
|
|
161
|
+
- **Блок готового кода в паттерне стареет от чужой правки.** Он не привязан ни к чему: сверка
|
|
162
|
+
спеков читает утверждения правила, а пример под ними не читает вовсе. Два поля, ставших
|
|
163
|
+
обязательными в чужой работе, сделали пример в соседнем паттерне несобираемым — сам он при
|
|
164
|
+
этом не изменился ни на знак и в след задачи не попал, потому что ни одного слова той работы
|
|
165
|
+
в нём нет. Паттерн находится по имени правленого символа, а не по теме работы.
|
|
151
166
|
- **Правило без привязки в спек домена не въезжает.** Кода, который его исполняет, нет —
|
|
152
167
|
значит это намерение, и место ему в открытых вопросах домена, а не в правилах.
|
|
168
|
+
- **Замысел линии работ правят только там, где вписывают «чем кончилась».** Границы линии и
|
|
169
|
+
порядок задач в ней при этом остаются прежними, а работа их уже нарушила: задача, решившая
|
|
170
|
+
читать спеки, оставила над собой границу «спеки — вторая очередь», и следующий исполнитель
|
|
171
|
+
прочитает её как действующую. Границы линии перечитываются целиком тем же заходом, что и
|
|
172
|
+
итог работы.
|
|
153
173
|
- **Архив не обновляется после выкатки.** Уехавшее туда описывает день переезда, и правится
|
|
154
174
|
оно только вместе с признанием, что описывало неверно.
|
|
@@ -102,5 +102,10 @@ git log --oneline origin/main..HEAD
|
|
|
102
102
|
несохранённым и почему» — единственное, по чему это видно, пока отчёта нет.
|
|
103
103
|
- **Подтверждение — вывод команды или замер, а не пересказ.** «Проверил, работает» через
|
|
104
104
|
заход неотличимо от «казалось, что работает».
|
|
105
|
+
- **Число из передачи пересчитывается до того, как на нём что-то делят.** Передача описывает
|
|
106
|
+
день, когда её писали, лежит вне дерева, и не читает её ни одна проверка. Оценка «работы
|
|
107
|
+
вдвое больше предыдущей» при пересчёте на текущем коммите не подтвердилась: по числу
|
|
108
|
+
утверждений объёмы оказались почти равны. Деление работы по чужой оценке делит не то, и
|
|
109
|
+
владельцу называются свои числа.
|
|
105
110
|
- **Доэтапное отделяется от своего.** Красное, найденное по дороге и не этой работой
|
|
106
111
|
сделанное, помечается таковым сразу: иначе следующий заход примет его за свою поломку.
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: translations-content
|
|
3
|
+
kind: pattern
|
|
4
|
+
rule: translations
|
|
5
|
+
description: Паттерн правила translations. Брать при работе с переводами содержимого записи — производный перевод при сохранении, запись локали руками через язык админки, разбор отказа провайдера, сброс кэша отданных страниц. Не брать для подписей интерфейса — это паттерн translations-key.
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Перевод содержимого записи
|
|
9
|
+
|
|
10
|
+
Паттерн правила `translations`. Что при этом должно быть верно — закон
|
|
11
|
+
`docs/constitution/application/locales.md`.
|
|
12
|
+
|
|
13
|
+
## Когда брать
|
|
14
|
+
|
|
15
|
+
- Владелец правит тексты записи, и остальные локали должны догнать.
|
|
16
|
+
- Админка ответила, что сохранила на языке ввода, а перевод на остальные не удался.
|
|
17
|
+
- Локаль надо заполнить руками: провайдер недоступен, а страница на этом языке нужна сегодня.
|
|
18
|
+
- Проверяется, что отданная страница показывает свежий текст.
|
|
19
|
+
|
|
20
|
+
## Перевод идёт сам, и просить его нечем
|
|
21
|
+
|
|
22
|
+
Кнопки «перевести» нет. Владелец печатает на своём языке, а процедура сохранения зовёт перевод
|
|
23
|
+
до транзакции и кладёт в хранилище уже все локали. Локаль ввода приезжает полем запроса и
|
|
24
|
+
берётся из языка админки, а не из браузера гостя.
|
|
25
|
+
|
|
26
|
+
В партию идёт не всё подряд: сборщик отбрасывает строку, чей исходный текст не менялся **и**
|
|
27
|
+
которая переведена на все целевые локали. Отсюда два следствия:
|
|
28
|
+
|
|
29
|
+
- сохранение записи без правки текстов провайдера не зовёт вовсе — перестановка изображения или
|
|
30
|
+
правка числа ничего не стоит;
|
|
31
|
+
- строка, у которой хоть одна локаль пуста, поедет на перевод при первом же сохранении, без
|
|
32
|
+
правки самого текста.
|
|
33
|
+
|
|
34
|
+
## Локаль пишется руками через язык админки
|
|
35
|
+
|
|
36
|
+
Табов локалей в форме нет, и это не упущение: поле одно, а какая локаль за ним стоит, решает
|
|
37
|
+
язык интерфейса. Значит записать перевод руками — это переключить язык в шапке админки и
|
|
38
|
+
заполнить те же поля.
|
|
39
|
+
|
|
40
|
+
Путь этот не аварийный: пока у провайдера пуст счёт, он и есть обычный порядок, и каждый
|
|
41
|
+
видимый текст заводится по разу на локаль. Считать его временным и ждать автоперевода не надо.
|
|
42
|
+
|
|
43
|
+
Порядок такой:
|
|
44
|
+
|
|
45
|
+
1. Меню владельца в шапке → выбрать язык.
|
|
46
|
+
2. Открыть запись. Текстовые поля покажут текст **этой** локали; пустые они там, где локали у
|
|
47
|
+
записи нет.
|
|
48
|
+
3. Заполнить и сохранить.
|
|
49
|
+
|
|
50
|
+
Соседние локали при этом целы: черновик пишет в карту по коду локали, а остальные ключи уезжают
|
|
51
|
+
в запрос как пришли. Отказ провайдера ничего не портит — в хранилище ложится ровно то, что
|
|
52
|
+
прислала форма.
|
|
53
|
+
|
|
54
|
+
Записанное руками потом не перетирается: у поля заполнены все локали, и сборщик партии больше
|
|
55
|
+
не берёт его, пока владелец не изменит исходный текст.
|
|
56
|
+
|
|
57
|
+
Собирать вызов сохранения скриптом для этого не надо, и правило это прямо запрещает: черновик
|
|
58
|
+
перезаписывает запись целиком, а вложенная запись, не попавшая в список, удаляется вместе со
|
|
59
|
+
своими связями.
|
|
60
|
+
|
|
61
|
+
## Отказ провайдера читается не по экрану
|
|
62
|
+
|
|
63
|
+
Владельцу показывается одна фраза без причины. Причина живёт в логах строкой своего контекста:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
docker compose -f <состав прода> --env-file <файл окружения> logs api --since 30m \
|
|
67
|
+
| grep -i translation
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Строка несёт код ответа, но не текст: клиент бросает отказ по коду, не читая тела. Что именно
|
|
71
|
+
ответил провайдер, спрашивается у него напрямую тем же ключом; для разового вызова его берут
|
|
72
|
+
руками — приложение эту переменную не читает, но значение там то же, что владелец завёл в
|
|
73
|
+
админке. Отказ по деньгам означает пустой счёт, а не сломанный ключ: список моделей при этом
|
|
74
|
+
отдаётся, и строка интеграции показывает «работает». Где лежит сам ключ и почему проба
|
|
75
|
+
зелёная — паттерн `git-workflow-secrets`.
|
|
76
|
+
|
|
77
|
+
## Отданная страница показывает прежний текст, пока не сброшен кэш
|
|
78
|
+
|
|
79
|
+
Записанный перевод виден в хранилище сразу, а гостю — нет: страницы лежат в кэше прокси. На
|
|
80
|
+
проде он сбрасывается так же, как на стенде:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
docker exec <контейнер прокси> sh -c 'rm -rf /var/cache/nginx/site/*; nginx -s reload'
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Сверяется отданной разметкой по каждой правленой локали, а не взглядом на админку:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
for l in <локали>; do
|
|
90
|
+
printf '%-8s ' "$l"
|
|
91
|
+
curl -sL "https://<адрес сайта>/$l/" | grep -oE '<meta name="description" content="[^"]{0,80}'
|
|
92
|
+
done
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Частые промахи
|
|
96
|
+
|
|
97
|
+
- **Проверять результат в админке.** Форма показывает то, что в хранилище, и молчит о кэше: три
|
|
98
|
+
локали были записаны и проверены, а сайт ещё полчаса отдавал прежний текст на всех.
|
|
99
|
+
- **Считать, что перевода нет, раз пришло предупреждение.** Прежние локали остаются на месте;
|
|
100
|
+
пустой окажется только та, которой не было раньше.
|
|
101
|
+
- **Писать в хранилище напрямую.** Запись в боевое хранилище запрещена совсем, а колонка со
|
|
102
|
+
свободной структурой выглядит безобидной целью — тексты правятся через админку, и другого
|
|
103
|
+
пути у них нет.
|
|
104
|
+
- **Переводить имя собственное.** Оно остаётся как есть во всех локалях: так велит словарь в
|
|
105
|
+
задании провайдеру, и рукописный перевод обязан вести себя так же.
|
|
106
|
+
- **Копировать одно письмо языка в другое.** Упрощённое и традиционное письмо — разные локали и
|
|
107
|
+
разное письмо; посимвольная копия простояла на проде, и гость читал чужие иероглифы.
|
|
@@ -27,7 +27,7 @@ description: Паттерн правила translations. Брать, когда
|
|
|
27
27
|
| `admin.json` | админ-панель |
|
|
28
28
|
| `mail.json` | письма и документ-основание |
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
Набор локалей перевода назван в `implementation.md` правила. Ключ заводится во
|
|
31
31
|
всех — пустое значение считается пропуском, а не переводом.
|
|
32
32
|
|
|
33
33
|
## Подстановка
|
|
@@ -40,6 +40,11 @@ description: Правило под «Закон о фронтовом прило
|
|
|
40
40
|
объявлена подписка.
|
|
41
41
|
- **Источник действия носит суффикс `Source` в имени.** Иначе поток и значение в коде
|
|
42
42
|
неотличимы, и `next` уходит не туда.
|
|
43
|
+
- **Вызов сервиса внутри `computed` зависимостью не становится.** Производное значение следит
|
|
44
|
+
только за прочитанными сигналами, а обычный метод сигналом не является: значение остаётся
|
|
45
|
+
таким, каким было в момент первого счёта. Текущий язык, текущее владение, текущий признак
|
|
46
|
+
среды читаются сигналом службы — тогда производное пересобирается вместе с их сменой. Ни
|
|
47
|
+
сборка, ни линтер этого не видят.
|
|
43
48
|
- **Списочный стор наследует общую основу.** Записи, страница, порядок, условия отбора, строка
|
|
44
49
|
поиска и конфиг выборки уже там, и наследнику остаются четыре строки.
|
|
45
50
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: browser-verification
|
|
3
3
|
kind: rule
|
|
4
4
|
law: verifiability
|
|
5
|
-
description: Правило под «Закон о проверяемости». Брать при любой проверке через браузер и при запросах curl или wget к дев-серверу.
|
|
5
|
+
description: Правило под «Закон о проверяемости». Брать при любой проверке через браузер и при запросах curl или wget к дев-серверу. Называет, где подняты приложения дерева, чему на дев-сервере верить нельзя и чем измерять вместо взгляда. Готовый код — в паттернах browser-verification-stand и browser-verification-measure.
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Проверка работающего приложения — как это устроено здесь
|
|
@@ -16,7 +16,7 @@ description: Правило под «Закон о проверяемости».
|
|
|
16
16
|
| В законе | Здесь |
|
|
17
17
|
| --------------------------------- | ----------------------------------------------------------------------------------------------- |
|
|
18
18
|
| работающее приложение | то, что поднято в этом дереве; перечень и порты — в `implementation.md` рядом |
|
|
19
|
-
| место, где его видит пользователь | прод-сборка за настоящим
|
|
19
|
+
| место, где его видит пользователь | прод-сборка за настоящим прокси дерева, а не дев-сервер |
|
|
20
20
|
| замер | `getComputedStyle`, `getBoundingClientRect`, контраст, совпадение центров, попадание во вьюпорт |
|
|
21
21
|
| драйвер браузера | `claude-in-chrome` на закреплённом профиле этого дерева |
|
|
22
22
|
|
|
@@ -39,6 +39,11 @@ description: Правило под «Закон о проверяемости».
|
|
|
39
39
|
имена, которые не опознают ничего, а выбор из него ведёт на профиль без входа.
|
|
40
40
|
- **Прод-конфигурация проверяется только за настоящим прокси.** Голый сервер отдачи страниц
|
|
41
41
|
про кэш, перенаправления и заголовки не знает ничего.
|
|
42
|
+
- **Первый заход на публичный экран метится признаком служебного посещения.** Драйвер водит
|
|
43
|
+
обычный браузер, и счётчик посещений не отличает проверку от гостя: `navigator.webdriver` у
|
|
44
|
+
него `false`, строка `User-Agent` — живого браузера. Чем метится заход, сказано в именах
|
|
45
|
+
дерева; признак, который живёт в хранилище браузера, дописывается один раз на профиль, а не
|
|
46
|
+
к каждому адресу.
|
|
42
47
|
|
|
43
48
|
Вывод о вёрстке подкрепляется числом: «выглядит нормально» результатом проверки не является.
|
|
44
49
|
Этого не стережёт ничто — как измерять, разобрано в паттерне `browser-verification-measure`.
|
|
@@ -50,21 +55,21 @@ description: Правило под «Закон о проверяемости».
|
|
|
50
55
|
|
|
51
56
|
## Паттерны
|
|
52
57
|
|
|
53
|
-
- `browser-verification-stand` — честный стенд из прод-сборки, вход в
|
|
58
|
+
- `browser-verification-stand` — честный стенд из прод-сборки, вход в закрытое приложение,
|
|
59
|
+
разбор порта.
|
|
54
60
|
- `browser-verification-measure` — замер вместо взгляда, ловушки инструмента `computer`.
|
|
55
61
|
|
|
56
62
|
## Ловушки
|
|
57
63
|
|
|
58
64
|
- **Сначала выяснить, что отвечает на порту:** `lsof -nP -iTCP:<порт> -sTCP:LISTEN` до первого
|
|
59
|
-
запроса. На
|
|
60
|
-
старым кодом, а
|
|
61
|
-
регистрации. Таких процессов бывает несколько;
|
|
62
|
-
один — убивать по PID из `lsof`, каждый.
|
|
63
|
-
- Инкрементальная сборка протухает поштучно: разметка
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
`app.routes.ts`.
|
|
65
|
+
запроса. На порту приложения регулярно висит собранный артефакт из прошлой сессии — он
|
|
66
|
+
отвечает 200 старым кодом, а заведённого в ветке обработчика у него нет вовсе, и 404 читается
|
|
67
|
+
как дефект регистрации. Таких процессов бывает несколько; снятие по шаблону команды не
|
|
68
|
+
попадает ни в один — убивать по PID из `lsof`, каждый.
|
|
69
|
+
- Инкрементальная сборка протухает поштучно: разметка бывает уже новая, а клиентский чанк — от
|
|
70
|
+
компиляции до правки. Признак дев-сборки — имена бандла без хеша (`main.js`). Расхождение
|
|
71
|
+
между `curl` и страницей после гидратации — повод пересобрать, а не искать дефект в коде.
|
|
72
|
+
Отсюда же нельзя делать вывод «такого маршрута нет»: сверяться с объявлением маршрутов.
|
|
68
73
|
- **Кэш объясняет расхождение, но не подтверждает его.** В `.angular/cache/…/vite/deps` лежат
|
|
69
74
|
только пакеты из `node_modules`, кода репозитория там нет вовсе. Вывод «дефекта нет, это
|
|
70
75
|
кэш» закрывает разбор, поэтому принимается только после проверки на чистой сборке — три
|
|
@@ -16,10 +16,10 @@ description: Правило под «Закон о фронтовом прило
|
|
|
16
16
|
|
|
17
17
|
| В законе | Здесь |
|
|
18
18
|
| ---------------------------------- | ---------------------------------------------------------------------------- |
|
|
19
|
-
| компонент |
|
|
19
|
+
| компонент | `<префикс>-<имя>` — префикс один на все приложения дерева |
|
|
20
20
|
| готовое, а не вычисление в шаблоне | `computed()`; там, где значение приходит из контекста шаблона, — чистый пайп |
|
|
21
21
|
| якорь для проверки | атрибут `qa-dataid` в kebab-case по смыслу элемента |
|
|
22
|
-
| корень разметки | `:host` с классом блока от `host: { class: '
|
|
22
|
+
| корень разметки | `:host` с классом блока от `host: { class: '<префикс>-<имя>' }` |
|
|
23
23
|
|
|
24
24
|
## Где это лежит
|
|
25
25
|
|
|
@@ -33,6 +33,10 @@ description: Правило под «Закон о фронтовом прило
|
|
|
33
33
|
(computeFlag())`, чтения сигналов не трогает.
|
|
34
34
|
- **Каждый интерактивный элемент несёт `qa-dataid`.** Это единственный якорь спек: классы BEM
|
|
35
35
|
меняются вместе с вёрсткой, а поиск по роли и тексту ломается на локалях перевода.
|
|
36
|
+
- **Компоненту разрешён только элементный селектор.** Правило линтера требует у компонента
|
|
37
|
+
элемент с приставкой дерева и именем через дефис, у директивы — атрибут и имя одним словом.
|
|
38
|
+
Приём, который вешается на чужой тег, пишется директивой с самого начала: у компонента с
|
|
39
|
+
селектором-атрибутом линт краснеет уже после того, как написаны все три файла и стили.
|
|
36
40
|
- **Класс блока висит на хосте, а не на обёртке внутри шаблона.** Лишняя обёртка вокруг всех
|
|
37
41
|
детей — это раскладка, и ей место на `:host`.
|
|
38
42
|
|
|
@@ -56,6 +56,20 @@ description: Правило под «Закон о документации пр
|
|
|
56
56
|
имена веток и правила линтеров: выглядят адресом, адресом не являются.
|
|
57
57
|
- **Документ едет в том же коммите, что и правка, которую он описывает.** Обход — строка
|
|
58
58
|
`Docs-skip: <причина>` в теле коммита; пустая причина не принимается.
|
|
59
|
+
- **Документ не длиннее предела длины.** Текст, который не влезает на экран целиком, дописывают
|
|
60
|
+
в конец, не перечитав начала, — так в одном документе и оказываются два ответа на один вопрос.
|
|
61
|
+
Предел тот же, что у кода, и считается так же — все строки; выросший спек делится на
|
|
62
|
+
поддомены, а не переносит границу. Описание прошлого из счёта выведено: архив по устройству
|
|
63
|
+
перечисляет то, чего в дереве уже нет, а папка задачи умирает со слиянием.
|
|
64
|
+
- **Файл, уезжающий в описание прошлого, называет в шапке свой прежний адрес.** Записи архива
|
|
65
|
+
ссылались на него, пока он был живым, и после переезда эти ссылки ведут в пустоту: проверка
|
|
66
|
+
путей архив не читает вовсе, поэтому промах не краснеет никогда. Найти переехавшее нечем —
|
|
67
|
+
имя записи архива с прежним адресом не совпадает, и поиск по нему её не показывает. Одна
|
|
68
|
+
строка в шапке дешевле правки всех ссылающихся записей и прошлого не трогает.
|
|
69
|
+
- **Текст, называющий состояние машины, устаревает без единой правки в дереве.** Ловушка о том,
|
|
70
|
+
что на машине установлено, верна в день, когда её пишут, и становится неправдой сама собой —
|
|
71
|
+
ни одна сверка этого не видит: они читают дерево, а состарилась машина. Утверждение о машине
|
|
72
|
+
пишется способом её спросить: команда и то, с чем сверять ответ, вместо снимка ответа.
|
|
59
73
|
|
|
60
74
|
## Чего из закона здесь нет
|
|
61
75
|
|
|
@@ -74,6 +88,8 @@ description: Правило под «Закон о документации пр
|
|
|
74
88
|
|
|
75
89
|
- `doc-style-write` — как формулировать: примеры «так» и «не так», правила для комментариев.
|
|
76
90
|
- `doc-style-sweep` — разбор документа, накопившего список работ, на действующее и закрытое.
|
|
91
|
+
- `doc-style-trace` — обратный проход: закрытые задачи против текстов, поиск того, чего не
|
|
92
|
+
написали.
|
|
77
93
|
|
|
78
94
|
## Скилы дерева
|
|
79
95
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: git-workflow
|
|
3
3
|
kind: rule
|
|
4
4
|
law: delivery
|
|
5
|
-
description: Правило под «Закон о поставке» для дерева в Azure DevOps. Брать на заведение задачи, ветки, коммит, пуш, создание PR, слияние, а также на правку схемы хранилища, её миграций и вызовы миграций. Называет рабочий элемент как начало работы, его состояние как ход работы, соответствие задачи и ветки один к одному, имя ветки, формат коммита, учётную запись машинной работы, обязательный состав PR, гарды поставки и сверку очереди работ. Готовый код — в паттернах git-workflow-commit, git-workflow-merge, git-workflow-migration и git-workflow-
|
|
5
|
+
description: Правило под «Закон о поставке» для дерева в Azure DevOps. Брать на заведение задачи, ветки, коммит, пуш, создание PR, слияние, а также на правку схемы хранилища, её миграций и вызовы миграций. Называет рабочий элемент как начало работы, его состояние как ход работы, соответствие задачи и ветки один к одному, имя ветки, формат коммита, учётную запись машинной работы, обязательный состав PR, гарды поставки и сверку очереди работ. Готовый код — в паттернах git-workflow-commit, git-workflow-merge, git-workflow-migration, git-workflow-restart, git-workflow-docker и git-workflow-secrets.
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Поставка — как это устроено здесь
|
|
@@ -63,6 +63,11 @@ description: Правило под «Закон о поставке» для д
|
|
|
63
63
|
- **Задачи, чинящиеся одной правкой, сливаются до слияния ветки.** Вторая закрывается как
|
|
64
64
|
дубликат, а недостающее из неё дописывается в первую. После слияния слить уже нельзя: ветка
|
|
65
65
|
въехала, и откатывается она целиком.
|
|
66
|
+
- **Работа, которую одним заходом не закрыть, помечена в двух местах, и они сверяются.** Метка
|
|
67
|
+
на доске и строка о заходах с передачей в линии работ говорят одно и то же двум читателям:
|
|
68
|
+
исполнитель открывает карточку раньше, чем линию, а планирует по линии. Одна пометка без
|
|
69
|
+
другой лжёт молча, поэтому сверка очереди судит пару в обе стороны. Помечается только то, что
|
|
70
|
+
законно не делится: пометка объёма правом делить не становится.
|
|
66
71
|
- **Слияние в главную ветку выкатывает прод.** Фильтры путей конвейера покрывают документы
|
|
67
72
|
отдельно, поэтому переменные окружения, секреты и записи имён ставятся до слияния, а не
|
|
68
73
|
после.
|
|
@@ -72,6 +77,24 @@ description: Правило под «Закон о поставке» для д
|
|
|
72
77
|
умолчаниями, которые он разрешает. Умолчание образа задаётся в самом образе.
|
|
73
78
|
- **Образы выкатываются по sha коммита, а не по метке «последний».** Метка в реестре отстаёт
|
|
74
79
|
от главной ветки, и прод молча возвращается к прежней версии, продолжая отвечать.
|
|
80
|
+
- **Выкатка убирает за собой старые образы, оставляя три последних sha.** Помеченный sha образ
|
|
81
|
+
висячим не бывает никогда, и чистка висячего его не касается: за полгода они съедают диск
|
|
82
|
+
сервера целиком. Три sha — это глубина отката, и меньше брать нельзя: поломка, замеченная
|
|
83
|
+
через две выкатки, откатывается уже некуда.
|
|
84
|
+
- **Описание прода правится вместе с составом прода.** Устройство, путь запроса, гейты и
|
|
85
|
+
бэкапы описаны текстами вне слоёв правил, и ни линтер, ни сборка их не читают: расхождение
|
|
86
|
+
копится молча, а читают эти тексты как действующие. Пару стережёт гард документов.
|
|
87
|
+
- **Правка конвейера прогоняется до слияния ручным запуском.** Конвейер запускается на любой
|
|
88
|
+
ветке, а задание выкатки прибито условием к главной: прогон ради проверки доходит до сборок и
|
|
89
|
+
там кончается. Прогон команд задания на своей машине его не покрывает: он проверяет команды,
|
|
90
|
+
а не файл конвейера, — верность самого файла читается только по списку прогонов после пуша.
|
|
91
|
+
- **Отчёт проверяется до слияния тем же конвейером, что и главная ветка.** Проверки и сборки
|
|
92
|
+
образов идут на конвейере проверки PR, выкатка — нет: её держит условие по главной ветке у
|
|
93
|
+
своего задания, а образ отчёта в реестр не уезжает.
|
|
94
|
+
- **Расхождение прода с главной веткой видно сверкой очереди работ.** Рабочий элемент уходит из
|
|
95
|
+
очереди слиянием, но слияние — ещё не прод: отказавшая выкатка не трогает ни элемент, ни его
|
|
96
|
+
состояние, и заметить её неоткуда. Сверка спрашивает последний прогон главной ветки и судит
|
|
97
|
+
только завершённый: идущий ещё может кончиться выкаткой.
|
|
75
98
|
- **Цепочка миграций прогоняется с пустого хранилища до слияния.** Порядок применения
|
|
76
99
|
лексикографический по имени каталога, а метку времени ставит момент создания: миграция из
|
|
77
100
|
ветки, начатой раньше, встаёт перед той, от которой зависит.
|
|
@@ -81,6 +104,25 @@ description: Правило под «Закон о поставке» для д
|
|
|
81
104
|
заголовок читается списком, а свободный текст — только целиком.
|
|
82
105
|
- **Перед пушем прогоняются все линтеры, а не один.** Линтер кода обычно не читает файлы
|
|
83
106
|
стилей вовсе, и правила оформления без второго прогона не проверяет ничто.
|
|
107
|
+
- **Сборка входит в набор наравне с линтом и юнитами.** Линтер типов не читает, а юниты читают
|
|
108
|
+
только то, что импортировано тестом: ошибка типов в непокрытом коде доживает до сборки
|
|
109
|
+
образа, то есть до слияния. Четыре слияния подряд так и уехали в главную ветку, ломая
|
|
110
|
+
выкатку.
|
|
111
|
+
- **Набор гейта пуша не бывает уже набора конвейера.** Гейт — обещание, что пуш не приедет
|
|
112
|
+
красным; набор, из которого выкинуты сборка и снимки, обещает то, чего не проверяет. Шаг
|
|
113
|
+
конвейера, которому в наборе гейта нет ни строки, ни объявленного исключения с причиной,
|
|
114
|
+
отбивает пуш, а не печатается рядом с ним: напечатанное предупреждение исполнитель читает как
|
|
115
|
+
разрешение. Дважды подряд правка, прошедшая гейт целиком, была отбита конвейером — и оба раза
|
|
116
|
+
зелёный гейт был прочитан как «локально всё зелено».
|
|
117
|
+
- **После вливания главной ветки набор проверок пересматривается по тому, что ветка везёт
|
|
118
|
+
теперь.** Вливание меняет состав правки: проверять по тому, что правил автор, — значит
|
|
119
|
+
проверять половину, а отвечает ветка целиком. Ветка, не тронувшая ни строки показа, прогоняет
|
|
120
|
+
снимки витрин с того момента, как вливание принесло чужую правку оформления.
|
|
121
|
+
- **Утверждение о главной ветке делается по удалённой ссылке, а не по локальной.** Локальная
|
|
122
|
+
протухает в ту минуту, когда её подтянули в последний раз, и молчит об этом: она не пуста и не
|
|
123
|
+
сломана, она описывает вчерашний день. Сравнение веток пишется от `origin/main` целиком —
|
|
124
|
+
смешав в одной команде удалённую ссылку для одной стороны и локальную для другой, промах
|
|
125
|
+
изнутри выглядит правильным.
|
|
84
126
|
- **Рабочий элемент привязывается к PR при создании, а не после.** `az repos pr create`
|
|
85
127
|
принимает `--work-items`; привязка второй командой обходится молча, когда у токена нет права
|
|
86
128
|
править чужой элемент, и PR остаётся ни с чем не связанным.
|
|
@@ -124,6 +166,8 @@ description: Правило под «Закон о поставке» для д
|
|
|
124
166
|
- `git-workflow-merge` — главная ветка влита в ветку задачи, конфликт разобран.
|
|
125
167
|
- `git-workflow-migration` — правка схемы хранилища и её миграций.
|
|
126
168
|
- `git-workflow-restart` — ручной перезапуск прода.
|
|
169
|
+
- `git-workflow-docker` — образы на своей машине: демон, реестр, сборка под платформу сервера.
|
|
170
|
+
- `git-workflow-secrets` — ключи внешних служб: где лежат, как заводятся, что говорит их состояние.
|
|
127
171
|
|
|
128
172
|
## Ловушки
|
|
129
173
|
|
|
@@ -148,6 +192,21 @@ description: Правило под «Закон о поставке» для д
|
|
|
148
192
|
записи, на следующий вызов это не переносится: PR открывают токеном учётной записи машинной
|
|
149
193
|
работы, и от того, чьей записью он открыт, зависит, кого можно назначить ревьювером. Однажды
|
|
150
194
|
смена записи ради пуша утекла в публикацию — отчёт вышел от владельца.
|
|
195
|
+
- **Невалидный файл конвейера виден прогоном нулевой длительности сразу после пуша.** Прогон
|
|
196
|
+
заводится и кончается на разборе файла, не начав ни одного задания: в списке он стоит
|
|
197
|
+
отказом, а внутри нет ни задания, ни лога — читается только длительность. Поэтому список
|
|
198
|
+
прогонов ветки смотрится тем же движением, что и пуш: `az pipelines runs list` по своей
|
|
199
|
+
ветке.
|
|
200
|
+
- **`online` у агента на своей машине означает запущенный процесс, а не работающий конвейер.**
|
|
201
|
+
Две стороны сходятся отдельно: требования заданий и возможности самого агента в его пуле.
|
|
202
|
+
Пока пересечения нет, агент стоит `online` и не берёт ничего, а задания ждут размещённого
|
|
203
|
+
пула — по состоянию это выглядит настроенным. Владельцу называют выполненное задание с его
|
|
204
|
+
номером, а не строку состояния.
|
|
205
|
+
- **Вход в реестр образов из агента, запущенного службой, отказывает молча.** Служба идёт без
|
|
206
|
+
сеанса пользователя, а клиент реестра уходит в системный помощник хранения ключей и получает
|
|
207
|
+
отказ во взаимодействии — задание падает до сборки. Свой каталог настроек с пустым помощником
|
|
208
|
+
не спасает: клиент переписывает пустое значение обратно сам. Готовые команды — паттерн
|
|
209
|
+
`git-workflow-docker`.
|
|
151
210
|
- **Новое рабочее дерево получает только то, что лежит в индексе.** `git worktree add`
|
|
152
211
|
разворачивает коммит, а настройки, ключи, локальные разрешения и зависимости в коммит не
|
|
153
212
|
входят: свежее дерево выглядит готовым и упирается в нехватку не сразу, а на первом гарде,
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: git-workflow
|
|
3
3
|
kind: rule
|
|
4
4
|
law: delivery
|
|
5
|
-
description: Правило под «Закон о поставке» для дерева на GitHub. Брать на заведение задачи, ветки, коммит, пуш, создание PR, мерж, а также на правку схемы хранилища, её миграций и вызовы миграций. Называет задачу на борде как начало работы, колонку задачи как ход работы, соответствие задачи и ветки один к одному, имя ветки, формат коммита, учётную запись машинной работы, обязательный состав PR, гарды поставки и сверку очереди работ. Готовый код — в паттернах git-workflow-commit, git-workflow-merge, git-workflow-migration и git-workflow-
|
|
5
|
+
description: Правило под «Закон о поставке» для дерева на GitHub. Брать на заведение задачи, ветки, коммит, пуш, создание PR, мерж, а также на правку схемы хранилища, её миграций и вызовы миграций. Называет задачу на борде как начало работы, колонку задачи как ход работы, соответствие задачи и ветки один к одному, имя ветки, формат коммита, учётную запись машинной работы, обязательный состав PR, гарды поставки и сверку очереди работ. Готовый код — в паттернах git-workflow-commit, git-workflow-merge, git-workflow-migration, git-workflow-restart, git-workflow-docker и git-workflow-secrets.
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Поставка — как это устроено здесь
|
|
@@ -73,6 +73,11 @@ description: Правило под «Закон о поставке» для д
|
|
|
73
73
|
- **Задачи, чинящиеся одной правкой, сливаются до мержа.** Вторая стирается вместе с номером,
|
|
74
74
|
а недостающее из неё дописывается в первую. После мержа слить уже нельзя: ветка въехала, и
|
|
75
75
|
откатывается она целиком.
|
|
76
|
+
- **Работа, которую одним заходом не закрыть, помечена в двух местах, и они сверяются.** Метка
|
|
77
|
+
на борде и строка о заходах с передачей в линии работ говорят одно и то же двум читателям:
|
|
78
|
+
исполнитель открывает карточку раньше, чем линию, а планирует по линии. Одна пометка без
|
|
79
|
+
другой лжёт молча, поэтому сверка очереди судит пару в обе стороны. Помечается только то, что
|
|
80
|
+
законно не делится: пометка объёма правом делить не становится.
|
|
76
81
|
- **Мерж в главную ветку выкатывает прод.** Исключения по путям покрывают только документы,
|
|
77
82
|
поэтому переменные окружения, секреты и записи имён ставятся до мержа, а не после.
|
|
78
83
|
- **Признак режима объявлен в образе, а не только в составе прода.** Значение, заданное
|
|
@@ -81,6 +86,26 @@ description: Правило под «Закон о поставке» для д
|
|
|
81
86
|
умолчаниями, которые он разрешает. Умолчание образа задаётся в самом образе.
|
|
82
87
|
- **Образы выкатываются по sha коммита, а не по метке «последний».** Метка в реестре отстаёт
|
|
83
88
|
от главной ветки, и прод молча возвращается к прежней версии, продолжая отвечать.
|
|
89
|
+
- **Выкатка убирает за собой старые образы, оставляя три последних sha.** Помеченный sha образ
|
|
90
|
+
висячим не бывает никогда, и чистка висячего его не касается: за полгода они съедают диск
|
|
91
|
+
сервера целиком. Три sha — это глубина отката, и меньше брать нельзя: поломка, замеченная
|
|
92
|
+
через две выкатки, откатывается уже некуда.
|
|
93
|
+
- **Описание прода правится вместе с составом прода.** Устройство, путь запроса, гейты и
|
|
94
|
+
бэкапы описаны текстами вне слоёв правил, и ни линтер, ни сборка их не читают: расхождение
|
|
95
|
+
копится молча, а читают эти тексты как действующие. Пару стережёт гард документов.
|
|
96
|
+
- **Правка конвейера прогоняется до мержа ручным запуском.** `workflow_dispatch` у выкатки
|
|
97
|
+
запускает её на любой ветке, а сама выкатка прибита условием к главной: прогон ради проверки
|
|
98
|
+
доходит до сборок и там кончается. Триггер регистрируется по главной ветке, поэтому правку,
|
|
99
|
+
которая его заводит или переносит, ручной запуск не покрывает. Прогон команд задания на своей
|
|
100
|
+
машине не покрывает её тоже: он проверяет команды, а не файл конвейера, — верность самого
|
|
101
|
+
файла читается только по списку прогонов после пуша.
|
|
102
|
+
- **Отчёт проверяется до мержа тем же конвейером, что и главная ветка.** Проверки и сборки
|
|
103
|
+
образов идут на событии `pull_request`, выкатка — нет: её держит условие по главной ветке у
|
|
104
|
+
своего задания, а образ отчёта в реестр не уезжает.
|
|
105
|
+
- **Расхождение прода с главной веткой видно сверкой очереди работ.** Задача уходит из очереди
|
|
106
|
+
мержем, но мерж — ещё не прод: отказавшая выкатка не трогает ни задачу, ни её колонку, и
|
|
107
|
+
заметить её неоткуда. Сверка спрашивает последний прогон главной ветки и судит только
|
|
108
|
+
завершённый: идущий ещё может кончиться выкаткой.
|
|
84
109
|
- **Цепочка миграций прогоняется с пустого хранилища до мержа.** Порядок применения
|
|
85
110
|
лексикографический по имени каталога, а метку времени ставит момент создания: миграция из
|
|
86
111
|
ветки, начатой раньше, встаёт перед той, от которой зависит.
|
|
@@ -90,6 +115,24 @@ description: Правило под «Закон о поставке» для д
|
|
|
90
115
|
заголовок читается списком, а свободный текст — только целиком.
|
|
91
116
|
- **Перед пушем прогоняются все линтеры, а не один.** Линтер кода обычно не читает файлы
|
|
92
117
|
стилей вовсе, и правила оформления без второго прогона не проверяет ничто.
|
|
118
|
+
- **Сборка входит в набор наравне с линтом и юнитами.** Линтер типов не читает, а юниты читают
|
|
119
|
+
только то, что импортировано тестом: ошибка типов в непокрытом коде доживает до сборки
|
|
120
|
+
образа, то есть до мержа. Четыре мержа подряд так и уехали в главную ветку, ломая выкатку.
|
|
121
|
+
- **Набор гейта пуша не бывает уже набора конвейера.** Гейт — обещание, что пуш не приедет
|
|
122
|
+
красным; набор, из которого выкинуты сборка и снимки, обещает то, чего не проверяет. Шаг
|
|
123
|
+
конвейера, которому в наборе гейта нет ни строки, ни объявленного исключения с причиной,
|
|
124
|
+
отбивает пуш, а не печатается рядом с ним: напечатанное предупреждение исполнитель читает как
|
|
125
|
+
разрешение. Дважды подряд правка, прошедшая гейт целиком, была отбита конвейером — и оба раза
|
|
126
|
+
зелёный гейт был прочитан как «локально всё зелено».
|
|
127
|
+
- **После вливания главной ветки набор проверок пересматривается по тому, что ветка везёт
|
|
128
|
+
теперь.** Вливание меняет состав правки: проверять по тому, что правил автор, — значит
|
|
129
|
+
проверять половину, а отвечает ветка целиком. Ветка, не тронувшая ни строки показа, прогоняет
|
|
130
|
+
снимки витрин с того момента, как вливание принесло чужую правку оформления.
|
|
131
|
+
- **Утверждение о главной ветке делается по удалённой ссылке, а не по локальной.** Локальная
|
|
132
|
+
протухает в ту минуту, когда её подтянули в последний раз, и молчит об этом: она не пуста и не
|
|
133
|
+
сломана, она описывает вчерашний день. Сравнение веток пишется от `origin/main` целиком —
|
|
134
|
+
смешав в одной команде удалённую ссылку для одной стороны и локальную для другой, промах
|
|
135
|
+
изнутри выглядит правильным.
|
|
93
136
|
- **Автор PR не может быть его ревьювером.** Запрос разбора на самого себя GitHub принимает и
|
|
94
137
|
молча не создаёт — разбор при этом выглядит запрошенным.
|
|
95
138
|
- **Метки, исполнитель и ревьювер PR ставятся вызовами `gh api`, а не `gh pr edit`.** На
|
|
@@ -131,6 +174,8 @@ description: Правило под «Закон о поставке» для д
|
|
|
131
174
|
- `git-workflow-merge` — главная ветка влита в ветку задачи, конфликт разобран.
|
|
132
175
|
- `git-workflow-migration` — правка схемы хранилища и её миграций.
|
|
133
176
|
- `git-workflow-restart` — ручной перезапуск прода.
|
|
177
|
+
- `git-workflow-docker` — образы на своей машине: демон, реестр, сборка под платформу сервера.
|
|
178
|
+
- `git-workflow-secrets` — ключи внешних служб: где лежат, как заводятся, что говорит их состояние.
|
|
134
179
|
|
|
135
180
|
## Ловушки
|
|
136
181
|
|
|
@@ -154,6 +199,27 @@ description: Правило под «Закон о поставке» для д
|
|
|
154
199
|
записи, на следующий вызов это не переносится: PR открывают токеном учётной записи машинной
|
|
155
200
|
работы, и от того, чьей записью он открыт, зависит, кого можно назначить ревьювером. Однажды
|
|
156
201
|
смена записи ради пуша утекла в публикацию — отчёт вышел от владельца.
|
|
202
|
+
- **Невалидный файл конвейера виден прогоном нулевой длительности сразу после пуша.** GitHub
|
|
203
|
+
заводит такой прогон и на ветке, на которую ни один триггер не подписан: в списке он стоит
|
|
204
|
+
отказом, а внутри у него нет ни задания, ни лога — читается только длительность. Поэтому
|
|
205
|
+
список прогонов ветки смотрится тем же движением, что и пуш — `gh run list --branch <ветка>`.
|
|
206
|
+
Один такой отказ простоял в списке до мержа, и на него никто не посмотрел: выкатка после
|
|
207
|
+
мержа отказала ровно тем же.
|
|
208
|
+
- **Контекст `runner` в `env` задания отбивает весь файл конвейера.** Там доступны только
|
|
209
|
+
`github`, `needs`, `strategy`, `matrix`, `vars`, `secrets` и `inputs`; `runner` появляется на
|
|
210
|
+
уровне шага, где то же значение приходит переменной окружения. Такой файл не принимается
|
|
211
|
+
вовсе: прогон кончается за ноль секунд, не начав ни одного задания. Разбор YAML этого не
|
|
212
|
+
ловит — синтаксис верный, а доступность контекстов синтаксисом не является.
|
|
213
|
+
- **`online` у раннера на своей машине означает запущенный процесс, а не работающий
|
|
214
|
+
конвейер.** Две стороны сходятся отдельно: `runs-on` у заданий и метки самого раннера. Пока
|
|
215
|
+
пересечения нет, раннер стоит `online` и не берёт ничего, а задания уходят в облако — по
|
|
216
|
+
состоянию это выглядит настроенным. Владельцу называют выполненное задание с его номером, а
|
|
217
|
+
не строку состояния.
|
|
218
|
+
- **Вход в реестр образов из раннера, запущенного службой, отказывает молча.** Служба идёт без
|
|
219
|
+
сеанса пользователя, а клиент реестра уходит в системный помощник хранения ключей и получает
|
|
220
|
+
отказ во взаимодействии — задание падает до сборки. Свой каталог настроек с пустым помощником
|
|
221
|
+
не спасает: клиент переписывает пустое значение обратно сам. Готовые команды — паттерн
|
|
222
|
+
`git-workflow-docker`.
|
|
157
223
|
- **Новое рабочее дерево получает только то, что лежит в индексе.** `git worktree add`
|
|
158
224
|
разворачивает коммит, а настройки, ключи, локальные разрешения и зависимости в коммит не
|
|
159
225
|
входят: свежее дерево выглядит готовым и упирается в нехватку не сразу, а на первом гарде,
|