@rt-tools/agent-kit 0.4.0 → 0.5.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.github.mjs +45 -2
- package/assets/checks/check-board.github.mjs +7 -14
- package/assets/checks/check-specs.mjs +89 -10
- package/assets/defaults/gate-map.sh +8 -2
- package/assets/defaults/project.sh +25 -0
- package/assets/hooks/git-guard-delivery.sh +87 -4
- package/assets/hooks/grill-gate.sh +96 -0
- package/assets/hooks/task-flow-guard.sh +14 -3
- package/assets/laws/project-documentation.md +10 -0
- package/assets/laws/verifiability.md +13 -0
- package/assets/laws/work-conduct.md +11 -0
- package/assets/patterns/git-workflow-commit.github.md +4 -0
- package/assets/patterns/spec-driven-domain.md +16 -0
- package/assets/patterns/task-flow-close.md +71 -7
- package/assets/patterns/task-flow-start.md +14 -2
- package/assets/rules/angular-patterns.md +4 -0
- package/assets/rules/browser-verification.md +4 -3
- package/assets/rules/doc-style.md +14 -0
- package/assets/rules/spec-driven.md +11 -1
- package/assets/rules/task-flow.md +42 -2
- package/assets/skills/agent-kit.md +4 -0
- package/assets/templates/rule.md +1 -1
- package/lib/commands.d.ts.map +1 -1
- package/lib/commands.js +1 -1
- package/lib/commands.js.map +1 -1
- package/lib/hooks-map.d.ts +5 -2
- package/lib/hooks-map.d.ts.map +1 -1
- package/lib/hooks-map.js +11 -6
- package/lib/hooks-map.js.map +1 -1
- package/package.json +1 -1
- package/rt-tools-agent-kit-0.5.0.tgz +0 -0
- package/rt-tools-agent-kit-0.4.0.tgz +0 -0
|
@@ -15,6 +15,10 @@
|
|
|
15
15
|
всего.
|
|
16
16
|
- **Владельцу не задаётся вопрос, ответ на который уже записан.** Записанное читают до
|
|
17
17
|
разговора, а не вместо ответа: вопрос о том, что уже решено, обесценивает и остальные.
|
|
18
|
+
- **Решение, однажды записанное, действует, пока его не отменили, и читается до того, как
|
|
19
|
+
принимается заново.** Отменённое решение следа в работе не оставляет — по результату не
|
|
20
|
+
видно ни того, что его принимали, ни того, что от него отказались. Принятое заново оно
|
|
21
|
+
расходится с прежним молча и стоит той же работы второй раз.
|
|
18
22
|
- **Понимание записано там, где идёт работа.** Оставленное в переписке живёт у одного
|
|
19
23
|
участника и до следующего дня; работу продолжает тот, у кого этой переписки нет.
|
|
20
24
|
- **Сказанное владельцем записывается его словами и задним числом не переписывается.**
|
|
@@ -22,6 +26,10 @@
|
|
|
22
26
|
- **Договорённость о том, как продукт себя ведёт, записана раньше кода, который её
|
|
23
27
|
исполняет.** Записанная после, она пишется по коду и повторяет его ошибки: разойтись ей
|
|
24
28
|
уже не с чем, а значит она ничего не проверяет.
|
|
29
|
+
- **Описание приведено к сделанному прежде, чем работа закрыта.** Договорённость пишется до
|
|
30
|
+
кода и описывает замысел, а к концу работы приложение отличается и от замысла тоже.
|
|
31
|
+
Расхождение, отложенное на потом, не находится: назавтра оно уже незаметно, а описание
|
|
32
|
+
продолжают читать как верное.
|
|
25
33
|
- **Состояние незаконченной работы восстанавливается без участия владельца.** Иначе каждый
|
|
26
34
|
перерыв стоит ему пересказа, а очередь работ показывает начатое и не говорит, что внутри
|
|
27
35
|
него сделано.
|
|
@@ -39,6 +47,9 @@
|
|
|
39
47
|
нетронутое, и второй заход начинает его заново.
|
|
40
48
|
- **Записи о законченной работе не лежат среди записей о текущей.** Закрытое, лежащее рядом
|
|
41
49
|
с действующим, читается как действующее — тем убедительнее, чем оно старше.
|
|
50
|
+
- **Законченная работа убирает за собой до того, как войдёт в общее дерево.** Потом за
|
|
51
|
+
оставленным уже никто не следит: работа перешла к следующей задаче, а правки, которой это
|
|
52
|
+
убрали бы заодно, больше нет.
|
|
42
53
|
- **Достаточность понимания судит тот, кто просил.** Машине видно наличие записи, но не то,
|
|
43
54
|
что в ней закрыты все пробелы: запись из одной строки проходит так же, как разбор на сто.
|
|
44
55
|
Признак достаточности, выведенный из объёма или числа вопросов, сам становится целью —
|
|
@@ -305,6 +305,10 @@ in-review`, — и `npm run check:board` прогоняется ещё раз:
|
|
|
305
305
|
`git commit --amend` при этом уносит в коммит всё, что осталось в индексе, — так в коммит
|
|
306
306
|
уехало удаление файла, принадлежавшее соседней ветке. Состав коммита читается
|
|
307
307
|
`git show --stat` сразу после него, а не на разборе PR.
|
|
308
|
+
- Состав индекса читается `git diff --cached --stat` **до** коммита, а не только `git show --stat`
|
|
309
|
+
после него. Команды дерева кладут файлы в индекс сами: `npm run task:new` добавляет папку
|
|
310
|
+
задачи, и вместе с ней уезжает всё, что лежало рядом, — так в индексе оказался временный
|
|
311
|
+
каталог диагностики.
|
|
308
312
|
- `gh project` с `--owner` отвечает `unknown owner type`: владелец борды — другая учётная
|
|
309
313
|
запись, и правка идёт только через GraphQL.
|
|
310
314
|
- Заведённый тикет на борду сама она не забирает: репозиторий с ней не связан, и добавление
|
|
@@ -23,11 +23,16 @@ docs/specs/<домен>/
|
|
|
23
23
|
spec.md — как домен работает
|
|
24
24
|
implementation.md — таблица «правило → файл:символ»
|
|
25
25
|
scenarios.md — сценарии SC-<ПРЕФИКС>-<НОМЕР>
|
|
26
|
+
<поддомен>/ — свой spec.md, implementation.md и scenarios.md
|
|
26
27
|
proposed/<фича>/ — только то, чего ещё нет
|
|
27
28
|
```
|
|
28
29
|
|
|
29
30
|
Шаблон — `docs/specs/_template/spec.md`, указатель с префиксами — `docs/specs/README.md`.
|
|
30
31
|
|
|
32
|
+
Поддомен спрашивается наравне с доменом: те же обязательные разделы, тот же компаньон рядом,
|
|
33
|
+
та же связь сценариев с тестами. Домен, у которого половина поддоменов описана, а половина
|
|
34
|
+
заведена пустыми каталогами, зелёным не бывает.
|
|
35
|
+
|
|
31
36
|
## Обязательные разделы
|
|
32
37
|
|
|
33
38
|
`## Зачем` · `## Терминология` с подразделом `### Как это называется в интерфейсе` ·
|
|
@@ -94,6 +99,14 @@ docs/specs/<домен>/
|
|
|
94
99
|
|
|
95
100
|
## Частые промахи
|
|
96
101
|
|
|
102
|
+
- Выросший домен делят на новые домены, а не на поддомены: новый домен приходится заводить в
|
|
103
|
+
указателе, сверять с кодом отдельно и объяснять, чем он соседу не поддомен, — а поддомен
|
|
104
|
+
остаётся в своём домене и наследует его контракт. Соседний домен заводится только тогда,
|
|
105
|
+
когда предмет живёт своей сущностью. Границу проводит владелец: деление переписывает номера
|
|
106
|
+
во всех заголовках тестов домена, и вернуть его назад тем же движением нельзя.
|
|
107
|
+
- Счётчик правил или сценариев в указателе доменов: он пересчитывается при каждой правке
|
|
108
|
+
любого спека, и через год большая часть таких чисел молча описывает позавчерашний спек.
|
|
109
|
+
Указатель держит домен, префикс и одну строку «о чём».
|
|
97
110
|
- `tasks.md` в спеке: шаги — артефакт сессии, им место в ветке или в описании PR.
|
|
98
111
|
- Скопированная из контракта таблица полей: источник — `libs/common/proto/proto/<область>/v1/`,
|
|
99
112
|
и компилируется из двух только одна.
|
|
@@ -102,6 +115,9 @@ docs/specs/<домен>/
|
|
|
102
115
|
- Место, где правило исполняется, внутри текста правила: оно меняется при первом рефакторинге,
|
|
103
116
|
и для него заведён `implementation.md`.
|
|
104
117
|
- Пометка «Не покрыто» при существующем тесте — отказ: долг закрыли, а отметку не сняли.
|
|
118
|
+
- Пометка «Не покрыто» читается дословно и с начала строки. Любое слово между ней и двоеточием
|
|
119
|
+
— «Не покрыто, и прогоном не покрывается вовсе: …» — и сценарий считается непомеченным вовсе,
|
|
120
|
+
а причина, ради которой пометку и писали, до отчёта не доезжает.
|
|
105
121
|
- Закон, названный в тексте, но забытый в строке `**Законы:**`: по закону тогда не узнать,
|
|
106
122
|
какие домены на нём стоят.
|
|
107
123
|
- Правка `.proto` без спеков задетых доменов: `docs-guard` отбивает такой коммит.
|
|
@@ -44,7 +44,48 @@ npm run check:specs # раздел «Пора вливать» называе
|
|
|
44
44
|
npm run check:specs # после вливания: привязки на месте, сценарии не потерялись
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
-
## 2.
|
|
47
|
+
## 2. Тексты домена приводятся к сделанному
|
|
48
|
+
|
|
49
|
+
В спек уезжает только то, что записали до кода. Остальные тексты — правила, паттерны, законы
|
|
50
|
+
приложения — после правки никто не перечитывает, и они продолжают описывать старое дерево.
|
|
51
|
+
Следующий читатель принимает их за верные.
|
|
52
|
+
|
|
53
|
+
Что перечитывать, берётся из раздела замысла, где названо, что работа задевает: там стоят
|
|
54
|
+
спеки, законы и правила по её следу. К ним добавляется то, что всплыло по ходу. Всю
|
|
55
|
+
конституцию и все правила читать не надо.
|
|
56
|
+
|
|
57
|
+
| Род текста | Что с ним делается |
|
|
58
|
+
| --------------------------------- | -------------------------------------------------------------------------------------------------------- |
|
|
59
|
+
| спек домена и его поддомены | у новой фичи появляется правило, сценарий и привязка; из «Что не входит» убирается то, что теперь входит |
|
|
60
|
+
| правило и его `implementation.md` | новое утверждение с привязкой `файл:символ`; снятое убирается вместе со строкой привязки |
|
|
61
|
+
| паттерн | код, разошедшийся с деревом, правится; новый приём дописывается разделом |
|
|
62
|
+
| закон приложения и общий закон | **файл не правится**: владельцу приносится текст статьи, работа идёт дальше без неё |
|
|
63
|
+
| обзорный документ продукта | новая фича дописывается строкой; строка о снятом правится |
|
|
64
|
+
|
|
65
|
+
Устаревшее чаще всего лежит в трёх местах, и все три читаются целиком:
|
|
66
|
+
|
|
67
|
+
- **«Чего из закона здесь нет» в правиле.** Сверка спеков этот раздел не читает, поэтому
|
|
68
|
+
неправда живёт в нём сколько угодно: правило три задачи подряд писало, что нужного механизма
|
|
69
|
+
в дереве нет, — а он был;
|
|
70
|
+
- **«Что не входит» в спеке домена.** Туда писали границу задачи, а задача давно закрыта;
|
|
71
|
+
- **«Где это лежит» в правиле.** Файлы переезжают, пути в таблице остаются.
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
# где правило и спеки говорят о том, что задевала работа
|
|
75
|
+
grep -rn -i "<слово работы>" <каталог правил>/*/SKILL.md docs/specs/*/spec.md
|
|
76
|
+
# раздел, который не сверяется ничем, — читается глазами целиком
|
|
77
|
+
grep -rn -A3 "Чего из закона здесь нет" <каталог правил>/<правило>/SKILL.md
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**Закон в ветке не правится.** Статья закона — договорённость с владельцем, и меняет её он.
|
|
81
|
+
Работа с ней разошлась — пишется готовый текст статьи: в ход работы и в тело отчёта. Файл
|
|
82
|
+
закона правится после ответа. С законами приложения так же: деньги, локали и доступ — та же
|
|
83
|
+
договорённость, только про это приложение.
|
|
84
|
+
|
|
85
|
+
Что сделали на этом шаге, пишется в тело отчёта: что перечитали, что изменили, а если ничего
|
|
86
|
+
не изменили — почему. Форма раздела — паттерн `git-workflow-commit`.
|
|
87
|
+
|
|
88
|
+
## 3. Папка задачи разбирается
|
|
48
89
|
|
|
49
90
|
Целиком в архив не переносится: `docs/archive/` — место для записей о состоявшемся, которые
|
|
50
91
|
кто-то читает, а не свалка ходов работы.
|
|
@@ -65,7 +106,7 @@ rm -r docs/tasks/<КЛЮЧ>-<номер>-<slug>
|
|
|
65
106
|
Разбор идёт в том же отчёте, что и работа: папка, оставленная до мержа, попадает в главную
|
|
66
107
|
ветку и читается там как текущая.
|
|
67
108
|
|
|
68
|
-
##
|
|
109
|
+
## 4. Сверка
|
|
69
110
|
|
|
70
111
|
```bash
|
|
71
112
|
npm run check:board # папка закрытой задачи среди текущих, брошенные черновики
|
|
@@ -75,11 +116,34 @@ npm run check:docs # пути, названные в текстах, суще
|
|
|
75
116
|
|
|
76
117
|
## Ловушки
|
|
77
118
|
|
|
78
|
-
- **Папку разбирают до
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
подряд папка закрытой задачи так и уехала в главную
|
|
82
|
-
|
|
119
|
+
- **Папку разбирают до слияния — потом о ней уже никто не вспомнит.** Сверка очереди считает
|
|
120
|
+
задачу закрытой по слиянию: до него папка среди текущих законна, а после за неё никто не
|
|
121
|
+
отвечает — работа перешла к следующей задаче, и находка достанется чужому заходу. Три раза
|
|
122
|
+
подряд папка закрытой задачи так и уехала в главную ветку, в последний раз их набралось
|
|
123
|
+
пять. Теперь это держит гард поставки: слияние отбивается, пока папка лежит в ветке.
|
|
124
|
+
- **Разбирают последним коммитом, а не перед открытием отчёта.** Пока идёт ревью, замысел
|
|
125
|
+
нужен на диске: без него правку по замечаниям не пропустит гард хода работы. Порядок такой:
|
|
126
|
+
правки по ревью, потом разбор папки, потом слияние.
|
|
127
|
+
- **Разбор папки идёт последним, после того как гейт пуша прошёл целиком.** Гард хода работы
|
|
128
|
+
не пускает правку кода приложения без замысла на диске, а после разбора замысла нет: чужое
|
|
129
|
+
замечание линтера, приехавшее мержем из главной ветки, чинить уже нечем, и гейт пуша стоит.
|
|
130
|
+
Порядок один: мерж главной ветки, все линтеры и проверки зелёные, вливание договорённости,
|
|
131
|
+
приведение текстов домена, разбор папки. Понадобилась правка кода после разбора — замысел
|
|
132
|
+
восстанавливается на диске на время правки, и разбор повторяется тем же коммитом.
|
|
133
|
+
- **Тексты правятся до разбора папки.** Список того, что перечитывать, лежит в замысле, а
|
|
134
|
+
разбор папки его удаляет. После разбора остаётся только память о том, что задевали.
|
|
135
|
+
- **Утверждение правила снимается вместе со строкой привязки.** Связь идёт по тексту
|
|
136
|
+
утверждения. Убрали утверждение и оставили строку в `implementation.md` — сверка спеков
|
|
137
|
+
краснеет; убрали строку и оставили утверждение — тоже.
|
|
138
|
+
- **Раздел «Чего из закона здесь нет» читается глазами, греп тут не помогает.** Искать
|
|
139
|
+
приходится не то слово, которое ждёшь: правило ссылалось на статью закона, которой в законе
|
|
140
|
+
нет вовсе, и по слову из своей темы эта строка находилась — а неправда была в другом.
|
|
141
|
+
- **Сказать «сверено», не открыв файл, нельзя.** Правило читается целиком. Устаревшее
|
|
142
|
+
утверждение стоит в списке среди верных и ничем от них не отличается.
|
|
143
|
+
- **Если папку просто удалить, первым пропадёт `grill.md`.** Удалить проще, чем разобрать, а
|
|
144
|
+
слова владельца записаны только там, и восстановить их неоткуда. Поэтому гард требует, чтобы
|
|
145
|
+
ветка добавила запись в архив. Что именно перенесли, он не проверяет — это смотрит владелец
|
|
146
|
+
на ревью.
|
|
83
147
|
- **Вливание после мержа не делается.** В главной ветке тогда лежит раздел «предложено, но не
|
|
84
148
|
выкачено» с тем, что работает месяц, — беззвучная ложь, тем убедительнее, чем старше.
|
|
85
149
|
- **Номера сценариев при вливании не пересчитываются.** Идентификатор — ключ связи с тестами;
|
|
@@ -45,8 +45,9 @@ Agent(subagent_type: "Explore", prompt: "<тема просьбы>: что по
|
|
|
45
45
|
| Чем будет видно, что задача закрыта | «работает» признаком не является |
|
|
46
46
|
| Есть ли образец, с которого снимается подход | разведка найдёт похожее, а не то |
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
Форму вопроса задают настройки владельца: где они требуют меню, спрашивается меню, и тогда к
|
|
49
|
+
каждому вопросу добавляется свободный вариант — у закрытого набора нет строки «вопрос не тот».
|
|
50
|
+
Выбор слова, имени и термина уточняется прозой в любом случае.
|
|
50
51
|
|
|
51
52
|
Ответы пишутся в `docs/tasks/_draft-<slug>/grill.md` — папка ещё черновик, номера нет.
|
|
52
53
|
|
|
@@ -67,6 +68,12 @@ Workflow(name: "plan", args: "docs/tasks/_draft-<slug>")
|
|
|
67
68
|
(`spec-critic`) → замысел и разбивка (`project-manager`). Пробелы, которые роли не смогли
|
|
68
69
|
закрыть, возвращаются владельцу — их относит главный агент.
|
|
69
70
|
|
|
71
|
+
Договорённость, вышедшая из конвейера, сверяется с `grill.md` построчно до того, как по ней
|
|
72
|
+
пойдёт работа. Роль пишет текст, не видя владельца, и способна развернуть его ответ в
|
|
73
|
+
противоположный: очередь этапов оказалась перевёрнута, а два пункта из входящих переехали в
|
|
74
|
+
«не входит». Находка критика, расходящаяся с ответом владельца, относится владельцу — она не
|
|
75
|
+
исполняется молча и не считается закрытой правкой текста.
|
|
76
|
+
|
|
70
77
|
### 4. Задача, ветка, папка
|
|
71
78
|
|
|
72
79
|
```bash
|
|
@@ -115,3 +122,8 @@ cp docs/tasks/_template/progress.md docs/tasks/<КЛЮЧ>-<номер>-<slug>/pr
|
|
|
115
122
|
пережить.
|
|
116
123
|
- **Задача заводится командой, а не четырьмя вызовами подряд.** Борда к репозиторию не
|
|
117
124
|
привязана, и задача попадает на неё только явным добавлением.
|
|
125
|
+
- **Slug ветки берётся из терминологии договорённости, а не из слов просьбы.** Договорённость
|
|
126
|
+
пишется раньше ветки и как раз там отказывается от слова владельца: спек завёл своё имя
|
|
127
|
+
предмету и прямо сказал, каким словом его не называть, — а ветка и папка задачи остались с
|
|
128
|
+
отвергнутым. Заголовок задачи и отчёта поправить можно, имя ветки после открытия отчёта —
|
|
129
|
+
уже нет.
|
|
@@ -59,6 +59,10 @@ description: Правило под «Закон о фронтовом прило
|
|
|
59
59
|
сигнал, — это ручной пересчёт, и он рано или поздно отстаёт от источника.
|
|
60
60
|
- **Геттеров в компонентах нет.** Геттер пересчитывается на каждой перерисовке, и цена его не
|
|
61
61
|
видна ни в одном месте кода.
|
|
62
|
+
- **Статический атрибут без значения задаёт входу пустую строку, а не умолчание.**
|
|
63
|
+
`<ng-template someControl>` даёт `''`, и вход с осмысленным умолчанием молча его теряет;
|
|
64
|
+
сигнальный вход с алиасом здесь ничем не отличается от `@Input()`. Вход, у которого умолчание
|
|
65
|
+
что-то значит, приводит пустую строку к нему сам — `transform` или проверка в `computed`.
|
|
62
66
|
- **Подписка на каждый вызов метода не даёт выбрать, что делать с предыдущим запросом.**
|
|
63
67
|
Быстрые нажатия дают гонку ответов, и побеждает тот, что вернулся последним, а не тот, что
|
|
64
68
|
нажали последним.
|
|
@@ -15,7 +15,7 @@ description: Правило под «Закон о проверяемости».
|
|
|
15
15
|
|
|
16
16
|
| В законе | Здесь |
|
|
17
17
|
| --------------------------------- | ----------------------------------------------------------------------------------------------- |
|
|
18
|
-
| работающее приложение |
|
|
18
|
+
| работающее приложение | то, что поднято в этом дереве; перечень и порты — в `implementation.md` рядом |
|
|
19
19
|
| место, где его видит пользователь | прод-сборка за настоящим `deploy/nginx.conf`, а не дев-сервер |
|
|
20
20
|
| замер | `getComputedStyle`, `getBoundingClientRect`, контраст, совпадение центров, попадание во вьюпорт |
|
|
21
21
|
| драйвер браузера | `claude-in-chrome` на закреплённом профиле этого дерева |
|
|
@@ -28,8 +28,9 @@ description: Правило под «Закон о проверяемости».
|
|
|
28
28
|
|
|
29
29
|
## Как закон применяется здесь
|
|
30
30
|
|
|
31
|
-
-
|
|
32
|
-
|
|
31
|
+
- **Второй экземпляр уже поднятого приложения не поднимается.** До первого запроса выясняется,
|
|
32
|
+
кто отвечает на порту: поднятый заново экземпляр отвечает своей сборкой, а не той, которую
|
|
33
|
+
проверяют. Кто поднимает стенд — владелец или агент, — сказано в именах дерева.
|
|
33
34
|
- **Браузер водится одним драйвером на закреплённом профиле.** Остальные двери — второй
|
|
34
35
|
драйвер, `open`, `osascript`, запуск бинарника — закреплённый профиль не спрашивают вовсе.
|
|
35
36
|
- **Выбор браузера протухает и требует повторного вызова.** Выбор, сделанный в начале
|
|
@@ -84,6 +84,20 @@ description: Правило под «Закон о документации пр
|
|
|
84
84
|
- **Снятое имя вычищается одним грепом по всему дереву:** правила, их зеркала в скилах,
|
|
85
85
|
документы и комментарии. Описание того, чего в коде уже нет, читается как действующее
|
|
86
86
|
указание.
|
|
87
|
+
- **Поиск по дереву не покрывает того, что уже уехало наружу.** Заголовок задачи и её тело,
|
|
88
|
+
заголовок отчёта и его тело, заголовки коммитов лежат вне файлов, и проверки текстов их не
|
|
89
|
+
читают вовсе. Вычистив слово в дереве, обходят те же места в очереди работ и в истории:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
<клиент хостинга> api "<путь к отчёту>" --jq '.title, .body' | grep -i '<слово>'
|
|
93
|
+
<клиент хостинга> api "<путь к задаче>" --jq '.title, .body' | grep -i '<слово>'
|
|
94
|
+
git log --format='%s%n%b' <база>..HEAD | grep -i '<слово>'
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Заголовок отчёта правится вызовом хостинга, заголовок коммита — только переписыванием ветки,
|
|
98
|
+
поэтому его проверяют до пуша. Выдуманное слово было вычищено из трёх файлов и объявлено
|
|
99
|
+
снятым, а в заголовке отчёта и в заголовке коммита осталось — владелец прочитал именно его.
|
|
100
|
+
|
|
87
101
|
- **Число в тексте пересчитывается командой в том же коммите, где пишется.** Оно стареет
|
|
88
102
|
внутри одной ветки: «шестнадцать пар» стало неправдой через два коммита после того, как
|
|
89
103
|
было написано, и нашёл это владелец, а не проверка. Число, которое придётся пересчитывать
|
|
@@ -69,12 +69,22 @@ description: Правило под «Закон о документации пр
|
|
|
69
69
|
обслуживает, но забыл описать, видна только в декораторе.
|
|
70
70
|
- **Код отказа принимается, только если он в домене бросается.** Коды выписывались по
|
|
71
71
|
замыслу, и на одном пути обещанный отказ не бросал никто.
|
|
72
|
-
- **Префикс сценариев в
|
|
72
|
+
- **Префикс сценариев в спеке один, и по всему дереву он занят им одним.** Второй префикс
|
|
73
|
+
внутри спека означает, что предмет описан дважды; занятый чужим — что по номеру не видно,
|
|
74
|
+
чей это сценарий. Договорённость о продукте — исключение: она нумеруется вместе со спеком, в
|
|
75
|
+
который вольётся, и занятым префикс от неё не становится.
|
|
76
|
+
- **Поддомен спрашивается наравне с доменом.** Те же обязательные разделы, тот же компаньон
|
|
77
|
+
рядом, та же связь сценариев с тестами. Домен, у которого половина поддоменов описана, а
|
|
78
|
+
половина заведена пустыми каталогами, зелёным не бывает.
|
|
73
79
|
- **У закона обязателен раздел «Статьи», а кроме них он держит только открытые вопросы.**
|
|
74
80
|
Истории правок и доводов о выбранном когда-то варианте в законе нет: историю держит система
|
|
75
81
|
контроля версий, а довод с отвергнутой альтернативой — свойство работы, и место ему в
|
|
76
82
|
«Ловушках» правила. Закрытый вопрос из закона уходит, а пустой раздел ради заголовка
|
|
77
83
|
проверку всё равно проходил.
|
|
84
|
+
- **Предложенный закон правила не требует.** Договорённость, записанную раньше кода,
|
|
85
|
+
привязывать не к чему, а требование правила заставило бы завести его с якорями в
|
|
86
|
+
несуществующие места. Признак стоит строкой статуса в самом законе, а не в списке исключений
|
|
87
|
+
рядом с проверкой.
|
|
78
88
|
- **Закон, назвавший файл проекта, — отказ.** Путям и привязкам место в правиле: иначе закон
|
|
79
89
|
нельзя ни прочитать без знания дерева, ни применить на другом приложении.
|
|
80
90
|
- **Правило объявляет закон, под который написано.** Правило без закона — набор приёмов, из
|
|
@@ -35,10 +35,19 @@ description: Правило под «Закон о ведении работы»
|
|
|
35
35
|
|
|
36
36
|
- **Правка кода приложения отбивается, пока на диске нет замысла.** Гард требует папку задачи
|
|
37
37
|
по имени ветки, `plan.md` в ней и названную в его шапке договорённость о продукте.
|
|
38
|
+
- **Влитая договорённость ветку не запирает.** После вливания директории «предложено» на диске
|
|
39
|
+
нет, а замысел на неё ссылается до конца работы: гард отличает влитое от незаведённого по
|
|
40
|
+
истории ветки и пропускает первое. Иначе последний коммит отчёта закрывал бы дорогу правкам
|
|
41
|
+
по замечаниям разбора.
|
|
38
42
|
- **Договорённость требуется по путям правки, а не по оценке задачи.** `apps/**` и `libs/**`
|
|
39
43
|
— признак; правила, тексты, обвязка и зависимости под него не подпадают. Обход — строка
|
|
40
44
|
`**Поведение:** не меняется — <причина владельца>` в замысле; пустая причина не
|
|
41
45
|
принимается.
|
|
46
|
+
- **Ход, в котором владельцу задан вопрос, не заканчивается, пока за этот же ход не читались
|
|
47
|
+
законы и правила.** Чтением считается любой из трёх путей: загрузка правила, чтение файла
|
|
48
|
+
законов или правил, поиск по ним. Отбивает гард разговора — на завершении хода, а не на
|
|
49
|
+
инструменте вопроса: спрашивают чаще прозой, чем меню. Найденное ложится в раздел «Что уже
|
|
50
|
+
сказано в правилах» разбора.
|
|
42
51
|
- **Состояние незаконченной работы приходит в контекст на запуске сессии.** Замысел и ход
|
|
43
52
|
работы отдаются целиком, разбор просьбы — путём. Ветка вида `<КЛЮЧ>-*` без папки даёт
|
|
44
53
|
предупреждение с готовой командой, но сессию не рвёт.
|
|
@@ -55,6 +64,19 @@ description: Правило под «Закон о ведении работы»
|
|
|
55
64
|
- **Папка закрытой задачи разбирается, а не переносится целиком.** В `docs/archive/` уезжает
|
|
56
65
|
то, что объясняет состоявшееся решение; остальное удаляется. Неразобранную ловит сверка
|
|
57
66
|
очереди работ.
|
|
67
|
+
- **Слияние отбивается, пока ветка везёт папку своей задачи.** Требование стоит на слиянии, а
|
|
68
|
+
не на открытии отчёта: до слияния папка ещё нужна — правка по замечаниям разбора идёт в ту
|
|
69
|
+
же ветку, а без замысла на диске её отбивает гард хода работы. На открытии отчёта о лежащей
|
|
70
|
+
папке говорится вслух, и только. Судится содержимое ветки, а не рабочее дерево: снесённая,
|
|
71
|
+
но не закоммиченная папка въехала бы вместе с веткой.
|
|
72
|
+
- **Ветка, снёсшая папку, обязана прибавить запись в архив.** Снести дешевле, чем разобрать, и
|
|
73
|
+
первым уходит разбор просьбы — единственная запись слов владельца. Что именно увезено,
|
|
74
|
+
требование не судит: это судит владелец.
|
|
75
|
+
- **Обход — строка `Task-folder-skip: <причина>` в отчёте или в самой команде слияния.**
|
|
76
|
+
Работа, вливаемая частями, папку до конца не разбирает. Чтение из команды работает и без
|
|
77
|
+
сети: единственный сетевой путь отбивал бы оффлайн то самое слияние, причина которого
|
|
78
|
+
написана в отчёте. Пустая причина обходом не считается, а сам обход снимает отказ, но не
|
|
79
|
+
гасит строку сверки очереди — иначе он через месяц становится рабочим путём.
|
|
58
80
|
|
|
59
81
|
## Чего из закона здесь нет
|
|
60
82
|
|
|
@@ -78,8 +100,17 @@ description: Правило под «Закон о ведении работы»
|
|
|
78
100
|
остальные тексты, и правка по ходу отличима от первоначальной записи только по истории.
|
|
79
101
|
Держится это тем же, чем и порядок разбора.
|
|
80
102
|
|
|
81
|
-
|
|
82
|
-
|
|
103
|
+
Приведение текстов к сделанному не проверяет ничто, и проверки на него не будет: что устарело
|
|
104
|
+
в правиле и в спеке, машине не видно — раздел «Чего из закона здесь нет» не читает ни одна
|
|
105
|
+
сверка, а «Что не входит» выглядит верным ровно так же, как в день, когда его писали. Держится
|
|
106
|
+
это шагом закрытия работы и следом задачи в замысле: там названо, что перечитать. Правило и
|
|
107
|
+
спек правятся в ветке, закон — нет: его статья приносится владельцу текстом, а работа идёт
|
|
108
|
+
дальше без неё.
|
|
109
|
+
|
|
110
|
+
Что именно перенесли в архив, не проверяется. Гард видит, что папка уезжает в главную ветку и
|
|
111
|
+
что ветка что-то в архив добавила, но не может судить, то ли это и стоило ли переносить именно
|
|
112
|
+
это. Сверять содержимое машине нечем — смотрит владелец на ревью. Отсюда же и обход: если
|
|
113
|
+
работа вливается частями, папку до конца не разбирают, а причина остаётся в отчёте.
|
|
83
114
|
|
|
84
115
|
## Паттерны
|
|
85
116
|
|
|
@@ -105,6 +136,15 @@ description: Правило под «Закон о ведении работы»
|
|
|
105
136
|
- **Субагент вопросов владельцу не задаёт.** Ни роли, ни конвейер до него не достучатся —
|
|
106
137
|
они возвращают текст главному агенту. Поэтому разбор ведёт главный агент, а роли стоят по
|
|
107
138
|
обе стороны от него.
|
|
139
|
+
- **Если дефект чинится правкой одного общего числа, спроси владельца, тем ли способом ты его
|
|
140
|
+
чинишь.** Замер показывает, что дефект ушёл, — но не то, что причину вылечили. В одной
|
|
141
|
+
задаче так ушли две правки подряд: сначала подняли общее число у соседнего узла, потом
|
|
142
|
+
перенесли узел в другое место разметки. Обе владелец отверг, а нужный способ назвал сам.
|
|
143
|
+
Спрашивают до правки, а не показывают замер после.
|
|
144
|
+
- **Линия работ по теме читается до того, как решается раскладка.** Файл линии держит решения,
|
|
145
|
+
которые пережили десяток задач, и разведка по коду их не находит: снятое решение следа в
|
|
146
|
+
дереве не оставляет. Домен, заведённый генератором и снесённый через полчаса, стоял в линии
|
|
147
|
+
прямым запретом — но линию открыли уже после того, как он был заведён во второй раз.
|
|
108
148
|
- **Слово для нового понятия берётся из `docs/GLOSSARY.md` или заводится там же.** Третий файл
|
|
109
149
|
папки задачи называется `progress.md`, а не `journal.md`, ровно поэтому: журнал в этом
|
|
110
150
|
дереве один, и он другой.
|
|
@@ -57,6 +57,10 @@ npx agent-kit sync --check # ничего не писать, отказать
|
|
|
57
57
|
|
|
58
58
|
## Ловушки
|
|
59
59
|
|
|
60
|
+
- **Линтер по следам правки судит файл целиком, а не внесённую правку.** Импорт, добавленный
|
|
61
|
+
отдельным шагом, отбивается как неиспользуемый ещё до того, как появится строка, которая его
|
|
62
|
+
зовёт, и работа встаёт на половине. Правка делается одним вызовом либо в порядке «сначала
|
|
63
|
+
использование, потом импорт».
|
|
60
64
|
- **Прогонять сценарии гардов можно, ничего не раскладывая.** Обвязка набора принимает каталог
|
|
61
65
|
гардов переменной, и пакетную редакцию гоняют по сценариям дерева до установки. Заход,
|
|
62
66
|
потраченный на диагноз по последствиям, стоил ровно этой строки.
|
package/assets/templates/rule.md
CHANGED
|
@@ -15,7 +15,7 @@ description: Правило под закон «<Название закона>
|
|
|
15
15
|
|
|
16
16
|
<Правка, по которой правило узнаётся. Гейт зовёт его по этому признаку, а не по названию.>
|
|
17
17
|
|
|
18
|
-
##
|
|
18
|
+
## Как закон применяется здесь
|
|
19
19
|
|
|
20
20
|
Каждый пункт начинается жирной статьёй, и у каждой статьи есть строка в `implementation.md`
|
|
21
21
|
рядом. Утверждение, которому места в коде не нашлось, сюда не ставится: оно уходит прозой в
|
package/lib/commands.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../../projects/agent-kit/src/lib/commands.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAO7C,MAAM,WAAW,iBAAiB;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC;AAED,2FAA2F;AAC3F,MAAM,WAAW,YAAY;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;;;OAIG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;CACvC;AAoDD,+DAA+D;AAC/D,eAAO,MAAM,WAAW,EAAE,MAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../../projects/agent-kit/src/lib/commands.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAO7C,MAAM,WAAW,iBAAiB;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC;AAED,2FAA2F;AAC3F,MAAM,WAAW,YAAY;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;;;OAIG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;CACvC;AAoDD,+DAA+D;AAC/D,eAAO,MAAM,WAAW,EAAE,MAAyB,CAAC;AAyFpD;;;;GAIG;AACH,wBAAgB,IAAI,CAChB,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,SAAS,MAAM,EAAO,EAC5B,QAAQ,GAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAM,EAC/C,SAAS,GAAE,MAAW,GACvB,iBAAiB,CAgCnB;AAgBD,wBAAgB,IAAI,CAAC,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,OAAO,GAAG,iBAAiB,CA2EzE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,iBAAiB,CA+CpF;AAED,wBAAgB,MAAM,CAAC,GAAG,EAAE,YAAY,GAAG,iBAAiB,CA2C3D;AAED;;;;;GAKG;AACH,wBAAgB,IAAI,CAAC,GAAG,EAAE,YAAY,GAAG,iBAAiB,CAkDzD"}
|
package/lib/commands.js
CHANGED
|
@@ -97,7 +97,7 @@ const gapLines = (result) => result.gaps.flatMap((gap) => [
|
|
|
97
97
|
const unboundLines = (result) => result.unbound.length
|
|
98
98
|
? [
|
|
99
99
|
`гарды разложены, но в \`${SETTINGS_PATH}\` их не зовёт никто: ${result.unbound.length}`,
|
|
100
|
-
...result.unbound.map((binding) => ` ${binding.path} — ${binding.event} ${binding.matcher}`),
|
|
100
|
+
...result.unbound.map((binding) => ` ${binding.path} — ${binding.event}${binding.matcher ? ` ${binding.matcher}` : ''}`),
|
|
101
101
|
` вставь в \`${SETTINGS_PATH}\` раздел \`hooks\` — готовый кусок ниже:`,
|
|
102
102
|
...JSON.stringify({ hooks: hooksSection(result.unbound) }, null, 4)
|
|
103
103
|
.split('\n')
|