@rt-tools/agent-kit 0.9.1 → 0.11.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.
Files changed (119) hide show
  1. package/README.md +5 -0
  2. package/assets/agents/conscience.md +58 -0
  3. package/assets/agents/prose-editor.md +44 -0
  4. package/assets/agents/strict-teacher.md +59 -0
  5. package/assets/checks/board.github.mjs +56 -1
  6. package/assets/checks/check-board.github.mjs +24 -0
  7. package/assets/checks/check-doc-paths.mjs +4 -15
  8. package/assets/checks/check-dupes.mjs +5 -6
  9. package/assets/checks/check-file-size.mjs +6 -20
  10. package/assets/checks/check-prose-style.mjs +137 -0
  11. package/assets/checks/check-reuse.mjs +5 -5
  12. package/assets/checks/check-state-next.mjs +194 -0
  13. package/assets/checks/check-states.mjs +142 -0
  14. package/assets/checks/check-styles.mjs +5 -5
  15. package/assets/checks/check-turn-map.mjs +146 -0
  16. package/assets/checks/lib-common.mjs +3 -3
  17. package/assets/checks/rt-kit-checks.config.mjs +85 -1
  18. package/assets/commands/agent-kit-digest.md +6 -5
  19. package/assets/defaults/project.sh +108 -6
  20. package/assets/defaults/turn-map.md +46 -0
  21. package/assets/docs/GLOSSARY.md +17 -15
  22. package/assets/hooks/browser-device-id.sh +2 -0
  23. package/assets/hooks/browser-guard-device-id.sh +11 -1
  24. package/assets/hooks/browser-guard-no-asking.sh +11 -1
  25. package/assets/hooks/browser-guard-no-listing.sh +11 -1
  26. package/assets/hooks/browser-guard-no-other-drivers.sh +9 -1
  27. package/assets/hooks/browser-guard-require-select.sh +13 -2
  28. package/assets/hooks/claim-guard.sh +115 -0
  29. package/assets/hooks/commit-msg.sh +2 -0
  30. package/assets/hooks/conscience-guard.sh +100 -0
  31. package/assets/hooks/constitution-index.sh +2 -0
  32. package/assets/hooks/deny-tail.sh +32 -0
  33. package/assets/hooks/dev-server-guard.sh +10 -2
  34. package/assets/hooks/docs-guard.sh +16 -2
  35. package/assets/hooks/exam-guard.sh +123 -0
  36. package/assets/hooks/git-guard-delivery-signature.sh +77 -0
  37. package/assets/hooks/git-guard-delivery.sh +156 -68
  38. package/assets/hooks/git-guard-main.sh +14 -0
  39. package/assets/hooks/git-guard-push-tests.sh +51 -2
  40. package/assets/hooks/glossary-load.sh +2 -0
  41. package/assets/hooks/grill-gate.sh +14 -0
  42. package/assets/hooks/handoff-entry-guard.sh +73 -0
  43. package/assets/hooks/handoff-write.sh +103 -0
  44. package/assets/hooks/lint-after-edit.sh +2 -0
  45. package/assets/hooks/observe.sh +2 -0
  46. package/assets/hooks/postmortem-guard.sh +14 -0
  47. package/assets/hooks/proposal-guard.sh +14 -0
  48. package/assets/hooks/prose-style-guard.sh +75 -0
  49. package/assets/hooks/qa-dataid-guard.sh +14 -1
  50. package/assets/hooks/rerun-guard.sh +88 -0
  51. package/assets/hooks/reuse-first-guard.sh +14 -1
  52. package/assets/hooks/roles.sh +34 -0
  53. package/assets/hooks/skill-gate-layers.sh +2 -0
  54. package/assets/hooks/skill-gate-rearm.sh +2 -0
  55. package/assets/hooks/skill-gate.sh +14 -0
  56. package/assets/hooks/skill-loaded.sh +2 -0
  57. package/assets/hooks/sql-guard-parse.sh +2 -0
  58. package/assets/hooks/sql-guard-request.sh +2 -0
  59. package/assets/hooks/sql-guard-target.sh +2 -0
  60. package/assets/hooks/sql-guard-write.sh +4 -1
  61. package/assets/hooks/sql-guard.sh +14 -1
  62. package/assets/hooks/task-context-load.sh +2 -0
  63. package/assets/hooks/task-flow-guard.sh +73 -7
  64. package/assets/hooks/turn-entry-load.sh +62 -0
  65. package/assets/hooks/turn-exit-guard.sh +191 -0
  66. package/assets/hooks/utf8.sh +35 -0
  67. package/assets/hooks/waiting-turn-guard.sh +14 -0
  68. package/assets/hooks/window-fill-guard.sh +43 -2
  69. package/assets/laws/work-conduct.md +29 -0
  70. package/assets/patterns/cargo-triage-mark.md +119 -0
  71. package/assets/patterns/task-flow-close.md +29 -8
  72. package/assets/patterns/task-flow-handoff.md +19 -1
  73. package/assets/patterns/task-flow-resume.md +36 -4
  74. package/assets/patterns/task-flow-start.md +56 -6
  75. package/assets/patterns/turn-entry-map.md +81 -0
  76. package/assets/rules/cargo-triage.md +126 -0
  77. package/assets/rules/git-workflow.azure.md +36 -9
  78. package/assets/rules/git-workflow.github.md +74 -9
  79. package/assets/rules/git-workflow.gitlab.md +40 -12
  80. package/assets/rules/task-flow.md +136 -71
  81. package/assets/rules/testing.md +15 -1
  82. package/assets/rules/turn-entry.md +93 -0
  83. package/assets/samples/tasks/_template/plan.md +4 -1
  84. package/assets/samples/tasks/_template/progress.md +1 -0
  85. package/assets/skills/agent-kit.md +33 -0
  86. package/assets/templates/project.sh +16 -0
  87. package/bin/agent-kit.d.ts.map +1 -1
  88. package/bin/agent-kit.js +42 -1
  89. package/bin/agent-kit.js.map +1 -1
  90. package/lib/cargo-state.d.ts +62 -0
  91. package/lib/cargo-state.d.ts.map +1 -0
  92. package/lib/cargo-state.js +118 -0
  93. package/lib/cargo-state.js.map +1 -0
  94. package/lib/cargo.d.ts +42 -0
  95. package/lib/cargo.d.ts.map +1 -1
  96. package/lib/cargo.js +2 -0
  97. package/lib/cargo.js.map +1 -1
  98. package/lib/commands.d.ts.map +1 -1
  99. package/lib/commands.js +64 -4
  100. package/lib/commands.js.map +1 -1
  101. package/lib/config.d.ts +8 -0
  102. package/lib/config.d.ts.map +1 -1
  103. package/lib/config.js +1 -0
  104. package/lib/config.js.map +1 -1
  105. package/lib/observations.d.ts +35 -1
  106. package/lib/observations.d.ts.map +1 -1
  107. package/lib/observations.js +14 -2
  108. package/lib/observations.js.map +1 -1
  109. package/lib/ship.d.ts +3 -0
  110. package/lib/ship.d.ts.map +1 -1
  111. package/lib/ship.js +56 -0
  112. package/lib/ship.js.map +1 -1
  113. package/lib/thresholds.d.ts +49 -0
  114. package/lib/thresholds.d.ts.map +1 -0
  115. package/lib/thresholds.js +151 -0
  116. package/lib/thresholds.js.map +1 -0
  117. package/package.json +1 -1
  118. package/rt-tools-agent-kit-0.11.0.tgz +0 -0
  119. package/rt-tools-agent-kit-0.9.1.tgz +0 -0
@@ -0,0 +1,126 @@
1
+ ---
2
+ name: cargo-triage
3
+ kind: rule
4
+ law: work-conduct
5
+ description: Правило под «Закон о ведении работы». Брать, когда разбирается груз, приехавший в приём, — разборы происшествий и предложения от деревьев. Называет, чем груз читается, что значит взять отчёт в работу и когда у записи появляются отметки о починке и о выпуске. Готовые вызовы — в паттерне cargo-triage-mark.
6
+ ---
7
+
8
+ # Разбор приехавшего груза — как это устроено здесь
9
+
10
+ Правило под закон `docs/constitution/work-conduct.md`. Закон говорит, что работа ведётся так,
11
+ чтобы её состояние переживало заход; здесь — как это держится для чужой работы, приехавшей
12
+ грузом. Своя работа идёт правилом `task-flow` под тем же законом, и одно продолжает другое:
13
+ взятие отчёта в работу заводит задачу, а с задачи начинается тот ход.
14
+
15
+ ## Как это называется здесь
16
+
17
+ | В законе | Здесь |
18
+ | -------------------------------------- | --------------------------------------------------------------------------- |
19
+ | работа, о которой сказал кто-то другой | груз: разбор происшествия и предложение, приехавшие в приём от дерева |
20
+ | состояние работы, пережившее заход | состояние записи груза: новое, в работе, готово, выпущено |
21
+ | отметка о сделанном | вызов команды отметки — она переводит записи и пишет приём починки и версию |
22
+ | место, где состояние читают | админка приёма: столбец состояния, отбор по нему и панель записи |
23
+ | ответ на «чем исправлено» | приём починки: статья правила, гард, проверка, правка кода |
24
+ | ответ на «где искать фикс» | версия выпуска: строка, которой дерево назвало выпуск |
25
+
26
+ ## Где это лежит
27
+
28
+ В этом дереве — таблица в `implementation.md` рядом: адрес приёма, чем зовётся команда отметки
29
+ и как называются состояния в её доводах. Пути живут там, а не здесь: правило переносится между
30
+ репозиториями, а адрес приёма и имя команды у каждого дерева свои.
31
+
32
+ ## Ход
33
+
34
+ Ход одной записи груза от приезда до выпуска: где ставится каждая отметка и что делается
35
+ раньше неё.
36
+
37
+ ```mermaid
38
+ flowchart TD
39
+ A[Запись груза приехала в приём] --> B[Список сужается отбором по «новое» и идёт порядком приезда]
40
+ B --> C{Работа по записи будет}
41
+ C -->|Нет| D[Состояние не двигается: состояния отказа набором не заведено]
42
+ C -->|Да| E[Заводится задача, и тем же ходом запись переводится в «в работе»]
43
+ E --> F[Работа идёт обычным ходом: ветка, папка задачи, замысел]
44
+ F --> G{Правка влита в главную ветку}
45
+ G -->|Нет| F
46
+ G -->|Да| H[Запись переводится в «готово», и с переходом едет приём починки]
47
+ H --> I{Редакция с починкой опубликована}
48
+ I -->|Нет| I
49
+ I -->|Да| J[Публикующий переводит запись в «выпущено» и называет версию]
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
+ человек груз читает, а разбирает его тот, кто по нему работает.
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
+ - `cargo-triage-mark` — готовые вызовы: сухой прогон, отметка пачкой, приём починки и версия
111
+ выпуска, разбор отбитой строки.
112
+
113
+ ## Ловушки
114
+
115
+ - **Отметка, отложенная «на потом», не ставится.** Между решением и следующим ходом проходит
116
+ день, и запись груза к этому дню помнит только приём. Отмечают тем же ходом, которым решили.
117
+ - **Сухой прогон отметкой не считается.** Он показывает, что уехало бы, и следа наружу не
118
+ оставляет: запись остаётся в прежнем состоянии, а исполнитель уходит с ощущением сделанного.
119
+ - **«Готово» по открытой заявке — отметка о том, чего в дереве нет.** Между открытием и
120
+ слиянием проходит день и больше, а заявку ещё и закрывают без слияния.
121
+ - **Приём починки, написанный пересказом разбора, отвечает не на тот вопрос.** Запись груза уже
122
+ несёт то, что было не так; отметка говорит, что с этим сделали, — и читают её как раз затем,
123
+ чтобы понять, стоит ли чинить у себя.
124
+ - **Ответ команды с нулём переведённых читается как отказ, а не как успех.** Строка «переведено
125
+ 0, уже стояло 3» означает, что этот разбор не двинул ничего: либо записи отмечены раньше,
126
+ либо ключи названы не те.
@@ -72,6 +72,22 @@ flowchart TD
72
72
  открытие, пока вершина главной ветки не стала предком текущей, и называет расхождение числом
73
73
  коммитов. PR с разошедшейся ветки показывает ревьюверу свою правку вперемешку с чужой, а всё,
74
74
  что автор проверил до публикации, он проверил от основания, которого в главной ветке уже нет.
75
+ - **Несошедшиеся условия поставки называются одним отказом, а не по одному.** Гард копит их все
76
+ и печатает разом. Отбитый по первому промаху исполнитель правит основание, повторяет вызов,
77
+ упирается в заголовок, правит заголовок, упирается в рабочий элемент — и каждый круг стоит
78
+ ещё одного вызова, хотя всё несошедшееся было известно уже на первом.
79
+ - **Условие, известное в начале работы, спрашивается в начале.** Заведение ветки отбивает
80
+ основание, в котором нет вершины главной ветки, и рабочую копию, подписывающую коммиты не той
81
+ почтой, что объявило дерево. На пуше и на открытии PR те же проверки остаются вторым рубежом,
82
+ но там они стоят дороже: основание чинится вливанием с разбором конфликта, подпись —
83
+ переписыванием всей ветки.
84
+ - **Судится то основание, которое названо командой, а не вершина рабочей копии.** Ветку заводят
85
+ и от вершины главной ветки прямо — этой командой основание как раз и берут свежим, — и гард,
86
+ читающий только текущую вершину, отбивал бы её наравне с веткой от вчерашнего дерева.
87
+ Основание, о котором дерево ничего не знает, не судится вовсе.
88
+ - **Ветка без номера рабочего элемента условий поставки не получает.** Локальная ветка под пробу
89
+ законна, и требовать от неё свежего основания значило бы отбивать работу, которая в главную
90
+ не поедет: PR с такой ветки не откроется.
75
91
  - **Правка кода отдаётся человеку открытым PR, а не запушенной веткой.** Ветка в списке ветвей
76
92
  ему не показывается, в его дела не приходит и обсуждения не имеет: до открытия PR правки для
77
93
  человека нет. Открывается он тем же ходом, которым исполнитель говорит, что работу отдаёт, и
@@ -100,6 +116,12 @@ flowchart TD
100
116
  элемент переводится в `Active`, PR открыт — в `Resolved`; делает это команда перевода, а не
101
117
  набор вызовов по памяти. Перевод идёт сразу за шагом, который его вызвал: очередь работ
102
118
  читают между шагами, а не после них.
119
+ - **Рабочий элемент, оставшийся в начальном состоянии, PR не открывает.** Гард поставки называет
120
+ это состояние и команду перевода: по очереди работ такой элемент читается как невзятый, хотя
121
+ работа по нему сделана и выложена. На заведении ветки состояние не спрашивается — там его ещё
122
+ не двигали, и требование отбивало бы первую же команду работы вместе с той, которая его и
123
+ снимает. Имя начального состояния дерево называет само; не названо — состояние не судится
124
+ вовсе.
103
125
  - **На доске стоят рабочие элементы, а не PR о них.** Доска показывает, что сделано и что
104
126
  осталось; PR отвечает на другой вопрос — как именно сделано, — и открывается из элемента, где
105
127
  связь с ним стоит сама. Здесь эта связь ставится при создании PR, поэтому отдельная карточка
@@ -209,16 +231,21 @@ flowchart TD
209
231
  проверки под него не заводится: работа опознаётся заголовком рабочего элемента и PR, а это
210
232
  сверяется у всех. Сверка очереди имя ветки не судит вовсе: у открытого PR его не переименовать.
211
233
 
212
- Взятие задачи в работу не стережёт ничто: доска ветки не видит, а гард поставки её видит, но
213
- доску не правит сетевой вызов в разборе команды падал бы вместе со связью и отбивал бы
214
- работу вместо промаха. Держится это памятью и подсказкой, которую печатает команда заведения
215
- задачи. Отставшее состояние находит сверка очереди но уже после того, как PR открыт.
234
+ Рабочий элемент в работу гард не переводит: доску он не правит правка доски в разборе команды
235
+ падала бы вместе со связью и отбивала бы работу вместо промаха. Перевод держится памятью и
236
+ подсказкой, которую печатает команда заведения. Элемент, оставшийся в начальном состоянии, гард
237
+ называет на открытии PRто есть после того, как его должны были перевести; прочие расхождения
238
+ состояния находит сверка очереди.
216
239
 
217
- Свежесть самой вершины главной ветки гард не проверяет: он судит по тому, что лежит в дереве, и
218
- вершину недельной давности от сегодняшней не отличает. Сетевой вызов сюда не заводится по той же
219
- причине, что и выше, он падал бы вместе со связью. Поэтому гард ловит ветку, отставшую
220
- заведомо, а `git fetch` перед вливанием стоит первым пунктом чеклиста и держится тем же, чем
221
- держатся остальные его пункты.
240
+ Ревьювера гард здесь не спрашивает: снятие черновика идёт правкой самого PR тем же вызовом, что
241
+ и остальные его поля, — и от прочих правок машине оно неотличимо. Держится это словарём выше, где
242
+ разбор PR ведёт ревьювер, и памятью того, кто черновик снимает.
243
+
244
+ Свежесть самой вершины главной ветки гард спрашивает вторым ярусом — тем же приёмом, что и
245
+ состояние задачи: есть чем спросить, спрашивает; нет сети или доступа — пропускает молча. Первый
246
+ ярус при этом остаётся, и работает он без сети: локальная ссылка отвечает на вопрос «отстало ли
247
+ основание от того, что уже лежит в дереве», удалённая — на вопрос «не протухла ли сама ссылка».
248
+ Без второго яруса молчание гарда значило лишь первое, а читалось как второе.
222
249
 
223
250
  ## Паттерны
224
251
 
@@ -72,6 +72,22 @@ flowchart TD
72
72
  вершина главной ветки не стала предком текущей, и называет расхождение числом коммитов. PR с
73
73
  разошедшейся ветки показывает ревьюверу свою правку вперемешку с чужой, а всё, что автор
74
74
  проверил до публикации, он проверил от основания, которого в главной ветке уже нет.
75
+ - **Несошедшиеся условия поставки называются одним отказом, а не по одному.** Гард копит их все
76
+ и печатает разом. Отбитый по первому промаху исполнитель правит основание, повторяет вызов,
77
+ упирается в заголовок, правит заголовок, упирается в задачу — и каждый круг стоит ещё одного
78
+ вызова, хотя всё несошедшееся было известно уже на первом.
79
+ - **Условие, известное в начале работы, спрашивается в начале.** Заведение ветки отбивает
80
+ основание, в котором нет вершины главной ветки, и рабочую копию, подписывающую коммиты не той
81
+ почтой, что объявило дерево. На пуше и на открытии PR те же проверки остаются вторым рубежом,
82
+ но там они стоят дороже: основание чинится вливанием с разбором конфликта, подпись —
83
+ переписыванием всей ветки.
84
+ - **Судится то основание, которое названо командой, а не вершина рабочей копии.** Ветку заводят
85
+ и от `origin/main` прямо — этой командой основание как раз и берут свежим, — и гард, читающий
86
+ только текущую вершину, отбивал бы её наравне с веткой от вчерашнего дерева. Основание, о
87
+ котором дерево ничего не знает, не судится вовсе.
88
+ - **Ветка без номера задачи условий поставки не получает.** Локальная ветка под пробу законна, и
89
+ требовать от неё свежего основания значило бы отбивать работу, которая в главную не поедет:
90
+ PR с такой ветки не откроется.
75
91
  - **Ключ задач задаётся один раз, и все три формы имени выводятся из него.** Заголовок задачи,
76
92
  имя ветки и заголовок PR строит один и тот же ключ: команда заведения задачи собирает по
77
93
  нему заголовок, гард поставки достаёт по нему номер из имени ветки, сверка очереди — из
@@ -89,13 +105,18 @@ flowchart TD
89
105
  ответ читается присутствием задачи на борде, её колонкой и исполнителем.
90
106
  - **Номер ветки и номер в заголовке PR сверяются на месте, а состояние задачи — по борде.**
91
107
  Формат читается из текста команды и работает без сети; существование задачи, её присутствие
92
- на борде, исполнитель и то, что она ещё открыта, — только когда есть чем спросить. Нет сети
93
- или нет токена — второй ярус молча пропускается: проверка, падающая в самолёте, перестаёт
94
- что-либо значить.
108
+ на борде, её колонка, исполнитель, то, что она ещё открыта, и разбор у PR — только когда есть
109
+ чем спросить. Нет сети или нет токена — второй ярус молча пропускается: проверка, падающая в
110
+ самолёте, перестаёт что-либо значить.
95
111
  - **Колонка задачи двигается тем же движением, что и работа.** Ветка заведена — задача
96
112
  переставляется во взятые в работу, PR открыт — в ждущие разбора; делает это команда
97
113
  перевода, а не набор вызовов GraphQL по памяти. Перевод идёт сразу за шагом, который его
98
114
  вызвал: очередь работ читают между шагами, а не после них.
115
+ - **Задача, оставшаяся в первой колонке, PR не открывает.** Гард поставки называет её колонку и
116
+ команду перевода: по очереди работ такая задача читается как невзятая, хотя работа по ней
117
+ сделана и выложена. На заведении ветки колонка не спрашивается — там её ещё не двигали, и
118
+ требование отбивало бы первую же команду работы вместе с той, которая его и снимает. Имя
119
+ первой колонки дерево называет само; не названо — колонка не судится вовсе.
99
120
  - **На борде стоят задачи, а не PR о них.** Борда показывает, что сделано и что осталось; PR
100
121
  отвечает на другой вопрос — как именно сделано, — и открывается из карточки задачи, где связь
101
122
  с ним заполняется сама полем «Linked pull requests». Карточка PR живёт своей жизнью: колонки
@@ -157,6 +178,13 @@ flowchart TD
157
178
  заблокирована самим хостингом: зелёная страница PR владельцу ничего не разрешает, а список, в
158
179
  котором всё серое, читается как «работа не сделана». Гард снятия черновика сюда не достаёт —
159
180
  он судит один ход и молчит, пока ветка везёт папку своей задачи.
181
+ - **Конфликтующий открытый PR — расхождение сверки очереди работ.** Конфликт приезжает в
182
+ отданный PR чужим слиянием, без единого действия автора: основание, проверенное на открытии,
183
+ устаревает в ту минуту, когда владелец влил соседнюю работу. Гард снятия черновика сюда не
184
+ достаёт — он судит один ход, а PR стоит в очереди днями, и по списку конфликт не виден вовсе:
185
+ метку хостинг показывает только внутри самого PR. Непосчитанная сливаемость расхождением не
186
+ считается: хостинг считает её заново после каждой правки главной ветки, и строка на
187
+ «ещё не посчитано» краснела бы на каждой свежей вершине.
160
188
  - **Расхождение прода с главной веткой видно сверкой очереди работ.** Задача уходит из очереди
161
189
  мержем, но мерж — ещё не прод: отказавшая выкатка не трогает ни задачу, ни её колонку, и
162
190
  заметить её неоткуда. Сверка спрашивает последний прогон главной ветки и судит только
@@ -206,12 +234,44 @@ flowchart TD
206
234
  - **Черновик снимается отдельным вызовом — `gh pr ready <номер>`.** Им исполнитель отвечает за
207
235
  готовность: проверки пройдены, доработок не осталось, работа сходится с задачей. Снятие
208
236
  черновика и просьба влить — один ход, а не два разных дня.
237
+ - **Черновик не снимается с ветки, которая не сливается.** Зелёный прогон говорит «не
238
+ сломано», сливаемость — «кнопку можно нажать», и владельцу нужно второе: снятый черновик он
239
+ читает как приглашение влить и идёт нажимать. Спрашивается это у хостинга тем же вызовом, что
240
+ автор и ревьювер, — `mergeable` приходит в том же ответе; выводить сливаемость из того, что
241
+ вливание прошло локально, нельзя: между локальным вливанием и взглядом владельца главная
242
+ ветка успевает уйти вперёд. За один заход так было снято три черновика подряд, и все три
243
+ заявки владелец увидел конфликтующими. Держится это гардом поставки, а не памятью: статья
244
+ стояла здесь и до того, и промах повторился в тот же день. Дерево, чей помощник очереди работ
245
+ о сливаемости не говорит вовсе, работает как прежде — поля нет, требования нет.
246
+ - **Указателю, в который ветки только дописывают строки, объявляется сложение обеих сторон.**
247
+ Конфликт там не спор: обе допись нужны целиком, а зовёт он человека при каждом слиянии в
248
+ главную ветку — за один заход одна и та же строка разрешалась шесть раз в шести ветках.
249
+ Объявление снимает ручное разрешение: слияние проходит само. **Метку сливаемости на странице
250
+ заявки оно при этом не снимает** — хостинг считает её своим приёмом и настройки слияния не
251
+ читает. Гаснет метка только после того, как ветка вобрала главную и это уехало на хостинг.
252
+ Обещать по этому объявлению «конфликтов больше не будет» нельзя: не будет ручной работы, а
253
+ вливать главную в открытые ветки после каждого слияния придётся по-прежнему.
254
+ - **Разрешённый конфликт, оставшийся незапушенным, хуже неразрешённого.** Владелец видит
255
+ прежнее состояние и читает его как «не сделано ничего», а сделанное лежит в рабочем дереве
256
+ исполнителя, где его не видит никто. Ветка, в которой разрешён конфликт, пушится тем же
257
+ ходом — либо конфликт не разрешается вовсе.
258
+ - **Одно и то же вливание главной ветки, сделанное третий раз за заход, останавливает
259
+ работу.** Ветки, дописывающие строку в один и тот же список, роняют друг друга в конфликт при
260
+ каждом слиянии, и вливание главной по кругу — это починка проявления. На третьем круге
261
+ называется причина и спрашивается владелец, а не делается четвёртый круг.
262
+ - **Черновик не снимается, пока у PR нет разбора.** Гард поставки смотрит запрошенного ревьювера
263
+ и оставленный отзыв: снятый черновик читается как «можно вливать», а вливать некому. Раньше
264
+ этого хода спросить негде — до открытия PR ревьювера нет вовсе. Судится и вызов без номера:
265
+ без него клиент берёт PR текущей ветки, и требование снималось бы одним пробелом. Возврат PR
266
+ в черновик — `gh pr ready --undo` — требования не получает: он делает то же, чего гард и
267
+ добивается.
209
268
  - **Мерж PR нажимает человек, а не исполнитель работы.** Кнопка и вызов слияния равны: запрет
210
269
  на них один. Исполнитель сливает свой PR только тогда, когда человек сказал это прямо и про
211
270
  этот PR; сказанное об одном PR на следующий не переносится, а молчание разрешением не
212
271
  бывает. Работа кончается PR, с которого снят черновик, и в ответе называется его номер.
213
272
  - **Автор PR не может быть его ревьювером.** Запрос разбора на самого себя GitHub принимает и
214
- молча не создаёт — разбор при этом выглядит запрошенным.
273
+ молча не создаёт — разбор при этом выглядит запрошенным. Поэтому в разборе считаются только
274
+ запрос и отзыв не от автора: гард снятия черновика читает состояние PR именно так.
215
275
  - **Метки, исполнитель и ревьювер PR ставятся вызовами `gh api`, а не `gh pr edit`.** На
216
276
  репозитории со старой бордой `gh pr edit` отвечает отказом про Projects (classic) и до
217
277
  правки не доходит вовсе.
@@ -243,10 +303,11 @@ flowchart TD
243
303
  проверки под него не заводится: работа опознаётся заголовком задачи и PR, а это сверяется
244
304
  у всех. Сверка очереди имя ветки не судит вовсе: у открытого PR его не переименовать.
245
305
 
246
- Взятие задачи в работу не стережёт ничто: борда ветки не видит, а гард поставки её видит, но
247
- борду не правит сетевой вызов в разборе команды падал бы вместе со связью и отбивал бы
248
- работу вместо промаха. Держится это памятью и подсказкой, которую печатает команда заведения
249
- задачи. Отставшую колонку находит сверка очереди но уже после того, как PR открыт.
306
+ Задачу в работу гард не переводит: борду он не правит правка борды в разборе команды падала бы
307
+ вместе со связью и отбивала бы работу вместо промаха. Перевод держится памятью и подсказкой,
308
+ которую печатает команда заведения задачи. Задачу, оставшуюся в первой колонке, гард называет на
309
+ открытии PRто есть после того, как её должны были переставить; прочие расхождения колонки
310
+ находит сверка очереди.
250
311
 
251
312
  Свежесть самой вершины главной ветки гард спрашивает вторым ярусом — тем же приёмом, что и
252
313
  состояние задачи: есть чем спросить, спрашивает; нет сети или доступа — пропускает молча.
@@ -284,7 +345,11 @@ flowchart TD
284
345
  - **Учётная запись для пуша и автор PR выбираются отдельно.** Если пушить пришлось из-под другой
285
346
  записи, на следующий вызов это не переносится: PR открывают токеном учётной записи машинной
286
347
  работы, и от того, чьей записью он открыт, зависит, кого можно назначить ревьювером. Однажды
287
- смена записи ради пуша утекла в публикацию — PR вышел от владельца.
348
+ смена записи ради пуша утекла в публикацию — PR вышел от владельца. Разница между читающим и
349
+ пишущим вызовом в самом тексте команды не видна: личность приходит окружением, поэтому у
350
+ вызова на запись токен называется явно, а открытая заявка проверяется ответом хостинга о её
351
+ авторе — напечатанная ссылка говорит, что заявка создана, и молчит о том, кем. Чинится это
352
+ только переоткрытием: автора у заявки не сменить.
288
353
  - **Невалидный файл конвейера виден прогоном нулевой длительности сразу после пуша.** GitHub
289
354
  заводит такой прогон и на ветке, на которую ни один триггер не подписан: в списке он стоит
290
355
  отказом, а внутри у него нет ни задания, ни лога — читается только длительность. Поэтому
@@ -71,6 +71,22 @@ flowchart TD
71
71
  вершина главной ветки не стала предком текущей, и называет расхождение числом коммитов. MR с
72
72
  разошедшейся ветки показывает ревьюверу свою правку вперемешку с чужой, а всё, что автор
73
73
  проверил до публикации, он проверил от основания, которого в главной ветке уже нет.
74
+ - **Несошедшиеся условия поставки называются одним отказом, а не по одному.** Гард копит их все
75
+ и печатает разом. Отбитый по первому промаху исполнитель правит основание, повторяет вызов,
76
+ упирается в заголовок, правит заголовок, упирается в задачу — и каждый круг стоит ещё одного
77
+ вызова, хотя всё несошедшееся было известно уже на первом.
78
+ - **Условие, известное в начале работы, спрашивается в начале.** Заведение ветки отбивает
79
+ основание, в котором нет вершины главной ветки, и рабочую копию, подписывающую коммиты не той
80
+ почтой, что объявило дерево. На пуше и на открытии MR те же проверки остаются вторым рубежом,
81
+ но там они стоят дороже: основание чинится вливанием с разбором конфликта, подпись —
82
+ переписыванием всей ветки.
83
+ - **Судится то основание, которое названо командой, а не вершина рабочей копии.** Ветку заводят
84
+ и от вершины главной ветки прямо — этой командой основание как раз и берут свежим, — и гард,
85
+ читающий только текущую вершину, отбивал бы её наравне с веткой от вчерашнего дерева.
86
+ Основание, о котором дерево ничего не знает, не судится вовсе.
87
+ - **Ветка без номера задачи условий поставки не получает.** Локальная ветка под пробу законна, и
88
+ требовать от неё свежего основания значило бы отбивать работу, которая в главную не поедет:
89
+ MR с такой ветки не откроется.
74
90
  - **Правка кода отдаётся человеку открытым MR, а не запушенной веткой.** Ветка в списке ветвей
75
91
  ему не показывается, в дела не приходит и обсуждения не имеет: до открытия MR правки для
76
92
  человека нет. Открывается он тем же ходом, которым исполнитель говорит, что работу отдаёт, и
@@ -83,6 +99,12 @@ flowchart TD
83
99
  - **Черновик снимается отдельным вызовом — `glab mr update <номер> --ready`.** Им исполнитель
84
100
  отвечает за готовность: проверки пройдены, доработок не осталось, работа сходится с задачей.
85
101
  Снятие черновика и просьба влить — один ход, а не два разных дня.
102
+ - **Черновик не снимается, пока у MR нет разбора.** Гард поставки смотрит запрошенного ревьювера
103
+ и оставленный отзыв: снятый черновик читается как «можно вливать», а вливать некому. Раньше
104
+ этого хода спросить негде — до открытия MR ревьювера нет вовсе. В разборе считаются только
105
+ запрос и отзыв не от автора: разбор на самого себя разбором не бывает. Судится и вызов без
106
+ номера — без него клиент берёт MR текущей ветки, и требование снималось бы одним пробелом;
107
+ возврат MR в черновик требования не получает.
86
108
  - **Заведённая задача подтверждается ответом очереди работ, а не выводом команды заведения.**
87
109
  Команда отвечает за свои вызовы: она может завести задачу и не довести её до доски, и её
88
110
  собственный разбор ошибок этот случай называет. Напечатанный номер значит «вызов прошёл», а не
@@ -90,13 +112,18 @@ flowchart TD
90
112
  ответ читается присутствием задачи на доске, её списком и исполнителем.
91
113
  - **Номер ветки и номер в заголовке MR сверяются на месте, а состояние задачи — по доске.**
92
114
  Формат читается из текста команды и работает без сети; существование задачи, её метка
93
- списка, исполнитель и то, что она ещё открыта, — только когда есть чем спросить. Нет сети
94
- или нет токена — второй ярус молча пропускается: проверка, падающая в самолёте, перестаёт
95
- что-либо значить.
115
+ списка, исполнитель, то, что она ещё открыта, и разбор у MR — только когда есть чем спросить.
116
+ Нет сети или нет токена — второй ярус молча пропускается: проверка, падающая в самолёте,
117
+ перестаёт что-либо значить.
96
118
  - **Список задачи двигается тем же движением, что и работа.** Ветка заведена — задача
97
119
  переставляется во взятые в работу, MR открыт — в ждущие разбора; делает это команда
98
120
  перевода, а не набор вызовов по памяти. Перевод идёт сразу за шагом, который его вызвал:
99
121
  очередь работ читают между шагами, а не после них.
122
+ - **Задача, оставшаяся в первом списке, MR не открывает.** Гард поставки называет её список и
123
+ команду перевода: по очереди работ такая задача читается как невзятая, хотя работа по ней
124
+ сделана и выложена. На заведении ветки список не спрашивается — там его ещё не двигали, и
125
+ требование отбивало бы первую же команду работы вместе с той, которая его и снимает. Имя
126
+ первого списка дерево называет само; не названо — список не судится вовсе.
100
127
  - **На доске стоят задачи, а не MR о них.** Доска показывает, что сделано и что осталось; MR
101
128
  отвечает на другой вопрос — как именно сделано, — и открывается из задачи, где связь с ним
102
129
  стоит сама. Карточка MR живёт своей жизнью: метки списка у неё нет, из очереди она не уходит и
@@ -207,16 +234,17 @@ flowchart TD
207
234
  проверки под него не заводится: работа опознаётся заголовком задачи и PR, а это сверяется
208
235
  у всех. Сверка очереди имя ветки не судит вовсе: у открытого MR его не переименовать.
209
236
 
210
- Взятие задачи в работу не стережёт ничто: доска ветки не видит, а гард поставки её видит, но
211
- доску не правит сетевой вызов в разборе команды падал бы вместе со связью и отбивал бы
212
- работу вместо промаха. Держится это памятью и подсказкой, которую печатает команда заведения
213
- задачи. Отставший список находит сверка очереди но уже после того, как MR открыт.
237
+ Задачу в работу гард не переводит: доску он не правит правка доски в разборе команды падала бы
238
+ вместе со связью и отбивала бы работу вместо промаха. Перевод держится памятью и подсказкой,
239
+ которую печатает команда заведения задачи. Задачу, оставшуюся в первом списке, гард называет на
240
+ открытии MRто есть после того, как её должны были переставить; прочие расхождения списка
241
+ находит сверка очереди.
214
242
 
215
- Свежесть самой вершины главной ветки гард не проверяет: он судит по тому, что лежит в дереве, и
216
- вершину недельной давности от сегодняшней не отличает. Сетевой вызов сюда не заводится по той же
217
- причине, что и выше, он падал бы вместе со связью. Поэтому гард ловит ветку, отставшую
218
- заведомо, а `git fetch` перед вливанием стоит первым пунктом чеклиста и держится тем же, чем
219
- держатся остальные его пункты.
243
+ Свежесть самой вершины главной ветки гард спрашивает вторым ярусом тем же приёмом, что и
244
+ состояние задачи: есть чем спросить, спрашивает; нет сети или доступа пропускает молча. Первый
245
+ ярус при этом остаётся, и работает он без сети: локальная ссылка отвечает на вопрос «отстало ли
246
+ основание от того, что уже лежит в дереве», удалённая на вопрос «не протухла ли сама ссылка».
247
+ Без второго яруса молчание гарда значило лишь первое, а читалось как второе.
220
248
 
221
249
  ## Паттерны
222
250