@rt-tools/agent-kit 0.5.0 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +73 -0
- package/assets/checks/check-doc-paths.mjs +200 -30
- package/assets/checks/check-specs.mjs +42 -7
- package/assets/checks/rt-kit-checks.config.mjs +12 -0
- package/assets/commands/agent-kit-digest.md +83 -0
- package/assets/commands/next-session.md +122 -0
- package/assets/commands/skill-curator.md +33 -1
- package/assets/defaults/gate-map.sh +23 -1
- package/assets/defaults/project.sh +37 -1
- package/assets/docs/GLOSSARY.md +77 -0
- package/assets/hooks/docs-guard.sh +18 -1
- package/assets/hooks/git-guard-delivery.sh +30 -3
- package/assets/hooks/git-guard-main.sh +8 -0
- package/assets/hooks/git-guard-push-tests.sh +8 -1
- package/assets/hooks/grill-gate.sh +38 -16
- package/assets/hooks/lint-after-edit.sh +10 -3
- package/assets/hooks/observe.sh +90 -0
- package/assets/hooks/postmortem-guard.sh +92 -0
- package/assets/hooks/profile-check.sh +43 -0
- package/assets/hooks/qa-dataid-guard.sh +9 -2
- package/assets/hooks/reuse-first-guard.sh +9 -2
- package/assets/hooks/skill-gate.sh +15 -0
- package/assets/hooks/skill-loaded.sh +7 -0
- package/assets/hooks/task-context-load.sh +16 -2
- package/assets/hooks/task-flow-guard.sh +9 -2
- package/assets/hooks/window-fill-guard.sh +157 -0
- package/assets/laws/code-structure.md +10 -0
- package/assets/laws/delivery.md +8 -1
- package/assets/laws/project-documentation.md +9 -0
- package/assets/laws/verifiability.md +9 -0
- package/assets/laws/work-conduct.md +47 -0
- package/assets/patterns/git-workflow-commit.azure.md +16 -12
- package/assets/patterns/git-workflow-commit.github.md +16 -12
- package/assets/patterns/git-workflow-commit.gitlab.md +16 -12
- package/assets/patterns/spec-driven-domain.md +19 -0
- package/assets/patterns/task-flow-close.md +4 -4
- package/assets/patterns/task-flow-handoff.md +115 -0
- package/assets/patterns/task-flow-resume.md +14 -2
- package/assets/patterns/task-flow-start.md +40 -2
- package/assets/rules/doc-style.md +39 -1
- package/assets/rules/git-workflow.azure.md +39 -0
- package/assets/rules/git-workflow.github.md +38 -0
- package/assets/rules/git-workflow.gitlab.md +38 -0
- package/assets/rules/spec-driven.md +14 -0
- package/assets/rules/task-flow.md +70 -3
- package/assets/skills/agent-kit.md +32 -0
- package/assets/templates/postmortem.md +32 -0
- package/assets/templates/proposal.md +39 -0
- package/bin/agent-kit.d.ts.map +1 -1
- package/bin/agent-kit.js +50 -1
- package/bin/agent-kit.js.map +1 -1
- package/lib/catalog.d.ts +33 -0
- package/lib/catalog.d.ts.map +1 -1
- package/lib/catalog.js +55 -1
- package/lib/catalog.js.map +1 -1
- package/lib/commands.d.ts +41 -0
- package/lib/commands.d.ts.map +1 -1
- package/lib/commands.js +315 -3
- package/lib/commands.js.map +1 -1
- package/lib/config.d.ts +11 -1
- package/lib/config.d.ts.map +1 -1
- package/lib/config.js +6 -0
- package/lib/config.js.map +1 -1
- package/lib/hooks-map.d.ts +15 -3
- package/lib/hooks-map.d.ts.map +1 -1
- package/lib/hooks-map.js +47 -11
- package/lib/hooks-map.js.map +1 -1
- package/lib/observations.d.ts +72 -0
- package/lib/observations.d.ts.map +1 -0
- package/lib/observations.js +126 -0
- package/lib/observations.js.map +1 -0
- package/lib/proposals.d.ts +48 -0
- package/lib/proposals.d.ts.map +1 -0
- package/lib/proposals.js +111 -0
- package/lib/proposals.js.map +1 -0
- package/lib/submit.d.ts +24 -0
- package/lib/submit.d.ts.map +1 -0
- package/lib/submit.js +26 -0
- package/lib/submit.js.map +1 -0
- package/lib/sync.d.ts +9 -1
- package/lib/sync.d.ts.map +1 -1
- package/lib/sync.js +4 -6
- package/lib/sync.js.map +1 -1
- package/package.json +1 -1
- package/rt-tools-agent-kit-0.5.2.tgz +0 -0
- package/rt-tools-agent-kit-0.5.0.tgz +0 -0
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# rt-hook: PostToolUse .*
|
|
3
|
+
# Требует: hooks/profile-check.sh
|
|
4
|
+
# rt-hook: PreToolUse .*
|
|
5
|
+
# Заполнение окна: заход доводится до логической точки заранее, а не обрывается на середине.
|
|
6
|
+
#
|
|
7
|
+
# Зачем именно так. Место, где исполнитель помнит ход работы, ограничено, и заполнив его, он
|
|
8
|
+
# теряет не последнее действие, а всю картину разом. Изнутри захода этот предел не виден ничем:
|
|
9
|
+
# ни одна проверка дерева его не показывает, а сжатие контекста срабатывает, когда доводить
|
|
10
|
+
# работу до точки уже нечем.
|
|
11
|
+
#
|
|
12
|
+
# Гард стоит на двух событиях сразу — разводить его по двум файлам значило бы держать два
|
|
13
|
+
# разбора одной записи и два места, где правится один порог:
|
|
14
|
+
# PostToolUse — на первом пороге отдаёт напоминание: пора выбирать точку остановки;
|
|
15
|
+
# PreToolUse — на втором отбивает всё, кроме записи хода работы, передачи и команд поставки.
|
|
16
|
+
# Место между порогами и есть то, на что закрывается заход: дописать ход работы, написать
|
|
17
|
+
# передачу, закоммитить проверенное.
|
|
18
|
+
#
|
|
19
|
+
# Размер окна берётся из настройки дерева. Из записи захода он не выводится: модель записана
|
|
20
|
+
# там без пометки о расширенном окне, и заход на широкое окно от захода на узкое неотличим.
|
|
21
|
+
#
|
|
22
|
+
# ОТКАЗ В ПОЛЬЗУ РАБОТЫ: нет размера окна, нет записи захода, нет разборщика, битый разбор —
|
|
23
|
+
# работа РАЗРЕШАЕТСЯ (exit 0). Сломанный гард не имеет права заклинить работу.
|
|
24
|
+
|
|
25
|
+
input="$(cat 2>/dev/null)"
|
|
26
|
+
[ -z "$input" ] && exit 0
|
|
27
|
+
|
|
28
|
+
command -v jq >/dev/null 2>&1 || exit 0
|
|
29
|
+
|
|
30
|
+
# Профиль дерева: размер окна, пороги, каталоги задач и передачи. Дерево, не задавшее размера
|
|
31
|
+
# окна, стража не получает — считать долю не от чего.
|
|
32
|
+
rt_hooks_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
33
|
+
for profile in "$rt_hooks_dir/../rt-kit/defaults/project.sh" "$rt_hooks_dir/../defaults/project.sh" "${CLAUDE_PROJECT_DIR:-.}/.claude/rt-kit/defaults/project.sh" "${CLAUDE_PROJECT_DIR:-.}/.claude/rt-kit/project.sh"; do
|
|
34
|
+
# shellcheck disable=SC1090
|
|
35
|
+
[ -f "$profile" ] && . "$profile" 2>/dev/null
|
|
36
|
+
done
|
|
37
|
+
|
|
38
|
+
# Слово о нехватке функции профиля: хук, вышедший молча, неотличим от работающего. Файл может
|
|
39
|
+
# быть не разложен — тогда остаётся прежнее поведение, молчаливое.
|
|
40
|
+
# shellcheck disable=SC1090
|
|
41
|
+
[ -f "$rt_hooks_dir/profile-check.sh" ] && . "$rt_hooks_dir/profile-check.sh"
|
|
42
|
+
command -v rt_needs >/dev/null 2>&1 || rt_needs() { command -v "$1" >/dev/null 2>&1; }
|
|
43
|
+
|
|
44
|
+
window="${RT_WINDOW_TOKENS:-}"
|
|
45
|
+
case "$window" in
|
|
46
|
+
'' | *[!0-9]*) exit 0 ;;
|
|
47
|
+
esac
|
|
48
|
+
[ "$window" -gt 0 ] 2>/dev/null || exit 0
|
|
49
|
+
|
|
50
|
+
warn_pct="${RT_WINDOW_WARN_PCT:-40}"
|
|
51
|
+
stop_pct="${RT_WINDOW_STOP_PCT:-50}"
|
|
52
|
+
tasks_dir="${RT_TASKS_DIR:-docs/tasks}"
|
|
53
|
+
handoff_dir="${RT_HANDOFF_DIR:-.claude/handoff}"
|
|
54
|
+
|
|
55
|
+
event="$(printf '%s' "$input" | jq -r '.hook_event_name // empty' 2>/dev/null)"
|
|
56
|
+
transcript="$(printf '%s' "$input" | jq -r '.transcript_path // empty' 2>/dev/null)"
|
|
57
|
+
[ -n "$transcript" ] || exit 0
|
|
58
|
+
[ -f "$transcript" ] || exit 0
|
|
59
|
+
|
|
60
|
+
# Заполнение — это последняя запись ответа с расходом: вход, разовая запись в кэш, прочитанное
|
|
61
|
+
# из кэша и вывод. Сумма по всем записям тут не годится вовсе — прочитанное из кэша повторяется
|
|
62
|
+
# в каждой из них, и сумма выходит в разы больше окна.
|
|
63
|
+
#
|
|
64
|
+
# Хвост в 200 строк: запись захода растёт весь заход, а нужна из неё одна последняя строка.
|
|
65
|
+
fill="$(tail -n 200 "$transcript" 2>/dev/null | jq -s -r '
|
|
66
|
+
[.[] | select(.type == "assistant") | .message.usage | select(. != null)]
|
|
67
|
+
| last
|
|
68
|
+
| if . == null then empty
|
|
69
|
+
else ((.input_tokens // 0) + (.cache_creation_input_tokens // 0)
|
|
70
|
+
+ (.cache_read_input_tokens // 0) + (.output_tokens // 0))
|
|
71
|
+
end
|
|
72
|
+
' 2>/dev/null)"
|
|
73
|
+
|
|
74
|
+
case "$fill" in
|
|
75
|
+
'' | *[!0-9]*) exit 0 ;;
|
|
76
|
+
esac
|
|
77
|
+
|
|
78
|
+
pct=$((fill * 100 / window))
|
|
79
|
+
fill_k=$((fill / 1000))
|
|
80
|
+
window_k=$((window / 1000))
|
|
81
|
+
|
|
82
|
+
# --- первый порог: напоминание, работа не отбивается -------------------------------------
|
|
83
|
+
|
|
84
|
+
if [ "$event" = "PostToolUse" ]; then
|
|
85
|
+
[ "$pct" -ge "$warn_pct" ] || exit 0
|
|
86
|
+
|
|
87
|
+
# Напоминание повторяется не на каждом вызове, а на каждой следующей ступени в пять
|
|
88
|
+
# процентов: иначе оно занимает то самое место, которое бережёт.
|
|
89
|
+
step=$(((pct / 5) * 5))
|
|
90
|
+
session="$(printf '%s' "$input" | jq -r '.session_id // "unknown"' 2>/dev/null)"
|
|
91
|
+
mark_dir="${TMPDIR:-/tmp}/claude-window-fill"
|
|
92
|
+
mark="$mark_dir/$session.step"
|
|
93
|
+
mkdir -p "$mark_dir" 2>/dev/null
|
|
94
|
+
last="$(cat "$mark" 2>/dev/null)"
|
|
95
|
+
case "$last" in
|
|
96
|
+
'' | *[!0-9]*) last=0 ;;
|
|
97
|
+
esac
|
|
98
|
+
[ "$step" -gt "$last" ] || exit 0
|
|
99
|
+
printf '%s' "$step" > "$mark" 2>/dev/null
|
|
100
|
+
|
|
101
|
+
if [ "$pct" -ge "$stop_pct" ]; then
|
|
102
|
+
text="ЗАПОЛНЕНИЕ ОКНА ${pct}% (${fill_k}k из ${window_k}k) — заход закрывается сейчас. Всё, кроме записи хода работы, передачи и команд поставки, уже отбивается."
|
|
103
|
+
else
|
|
104
|
+
text="ЗАПОЛНЕНИЕ ОКНА ${pct}% (${fill_k}k из ${window_k}k). Пора выбирать точку остановки: с ${stop_pct}% останется только закрыть заход. Доведи текущий шаг до состояния, с которого следующий заход продолжит, перепиши «Где стоим» в ходе работы, напиши передачу и отдай владельцу путь к ней — паттерн task-flow-handoff."
|
|
105
|
+
fi
|
|
106
|
+
|
|
107
|
+
jq -n --arg t "$text" \
|
|
108
|
+
'{hookSpecificOutput:{hookEventName:"PostToolUse",additionalContext:$t}}' 2>/dev/null
|
|
109
|
+
exit 0
|
|
110
|
+
fi
|
|
111
|
+
|
|
112
|
+
# --- второй порог: работа отбивается, закрытие захода пропускается ------------------------
|
|
113
|
+
|
|
114
|
+
[ "$event" = "PreToolUse" ] || exit 0
|
|
115
|
+
[ "$pct" -ge "$stop_pct" ] || exit 0
|
|
116
|
+
|
|
117
|
+
tool="$(printf '%s' "$input" | jq -r '.tool_name // empty' 2>/dev/null)"
|
|
118
|
+
path="$(printf '%s' "$input" | jq -r '.tool_input.file_path // empty' 2>/dev/null)"
|
|
119
|
+
cmd="$(printf '%s' "$input" | jq -r '.tool_input.command // empty' 2>/dev/null)"
|
|
120
|
+
|
|
121
|
+
allowed=0
|
|
122
|
+
case "$tool" in
|
|
123
|
+
# Разговор с владельцем и чтение того, что правится при закрытии.
|
|
124
|
+
AskUserQuestion | TodoWrite | Read | SendUserFile)
|
|
125
|
+
allowed=1
|
|
126
|
+
;;
|
|
127
|
+
Edit | Write | MultiEdit | mcp__webstorm__create_new_file)
|
|
128
|
+
# Ход работы и передача. Остальное — работа, а её заход уже не начинает.
|
|
129
|
+
case "$path" in
|
|
130
|
+
"$tasks_dir"/* | */"$tasks_dir"/* | "$handoff_dir"/* | */"$handoff_dir"/* | */scratchpad/*) allowed=1 ;;
|
|
131
|
+
esac
|
|
132
|
+
;;
|
|
133
|
+
Bash | mcp__webstorm__execute_terminal_command)
|
|
134
|
+
# Поставка и сверки: коммит, пуш, отчёт, колонка задачи, состояние дерева. Список
|
|
135
|
+
# дописывается профилем дерева — клиент хостинга и имена команд у каждого свои.
|
|
136
|
+
if rt_needs rt_handoff_allowed_cmd window-fill-guard && rt_handoff_allowed_cmd "$cmd"; then
|
|
137
|
+
allowed=1
|
|
138
|
+
fi
|
|
139
|
+
;;
|
|
140
|
+
esac
|
|
141
|
+
|
|
142
|
+
[ "$allowed" -eq 1 ] && exit 0
|
|
143
|
+
|
|
144
|
+
reason="BLOCKED by window-fill-guard: заполнение окна ${pct}% (${fill_k}k из ${window_k}k), порог остановки ${stop_pct}%. Заход дальше не работает — он закрывается.
|
|
145
|
+
|
|
146
|
+
Что осталось сделать этим заходом:
|
|
147
|
+
1. Перепиши раздел «Где стоим» в ходе работы и добавь запись захода — что сделано, чем подтверждено, что не вышло.
|
|
148
|
+
2. Закоммить проверенное: незакоммиченное не переживёт перерыв.
|
|
149
|
+
3. Напиши передачу в ${handoff_dir}/ и отдай владельцу путь к ней — что в неё входит, говорит паттерн task-flow-handoff.
|
|
150
|
+
|
|
151
|
+
Пропускаются при этом: правка ${tasks_dir}/**, запись передачи, команды поставки и сверки, чтение файлов и вопрос владельцу."
|
|
152
|
+
|
|
153
|
+
jq -n --arg r "$reason" \
|
|
154
|
+
'{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:$r}}' 2>/dev/null \
|
|
155
|
+
|| printf '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"window-fill-guard: окно заполнено, заход закрывается передачей."}}\n'
|
|
156
|
+
|
|
157
|
+
exit 0
|
|
@@ -20,3 +20,13 @@
|
|
|
20
20
|
причина названа рядом.
|
|
21
21
|
- **Отметка об устаревании — повод убрать, а не повод оставить.** Устаревшее объявление,
|
|
22
22
|
которое молча продолжает работать, переживает того, кто его пометил.
|
|
23
|
+
|
|
24
|
+
## Открытые вопросы
|
|
25
|
+
|
|
26
|
+
- **Q-CS-3 — имя файла без обещания рода не судится ничем.** Проверка спрашивает файл, чьё имя
|
|
27
|
+
род называет; имя из одних слов о содержимом не говорит вовсе, и назвать род обязанным можно
|
|
28
|
+
только решением о продукте.
|
|
29
|
+
- **Q-CS-4 — одноступенчатое приведение остаётся непроверенным.** Запрещено обходить сверку
|
|
30
|
+
через промежуточное «неизвестно», а обычное приведение принято: часть его обязательна, и
|
|
31
|
+
запрет отбивал бы её вместе с остальным. Решение изменит, появится ли требование к причине у
|
|
32
|
+
каждого оставшегося.
|
package/assets/laws/delivery.md
CHANGED
|
@@ -16,7 +16,14 @@
|
|
|
16
16
|
которая в одну ветку не влезает, делится на задачи до того, как ветка заводится. Признак
|
|
17
17
|
деления — раздельный откат, а не объём: числа файлов, строк или коммитов, за которым работа
|
|
18
18
|
становится двумя задачами, нет. Правка одного рода остаётся одной задачей, сколько бы файлов
|
|
19
|
-
она ни задела.
|
|
19
|
+
она ни задела. Объём захода исполнителя признаком деления не является тоже: он говорит, какого
|
|
20
|
+
размера задачу стоит заводить среди тех, что делятся законно, и не даёт делить то, что
|
|
21
|
+
откатывается только вместе.
|
|
22
|
+
- **Правка самой поставки проверяется её прогоном, а не рассуждением.** Проверить её иначе
|
|
23
|
+
нечем: она исполняется только там, где выкатывает, и в среде, которой на месте работы нет — с
|
|
24
|
+
чужими правами, чужим хранилищем ключей и чужой сетью. «Проверю после слияния» решением
|
|
25
|
+
исполнителя не бывает: за этими словами стоит выкатка, которой уже не будет, если правка
|
|
26
|
+
окажется неверной. Отложить проверку может только владелец, и он говорит это словами.
|
|
20
27
|
- **Две задачи, которые чинятся одной правкой, — одна задача.** Вторая стирается вместе со
|
|
21
28
|
своим номером, а то, чего в первой не было, дописывается в неё до этого. Две строки об
|
|
22
29
|
одной работе хуже дыры в нумерации: по ним потом не понять, что сделано, а что нет. Слить
|
|
@@ -19,6 +19,10 @@
|
|
|
19
19
|
символ ничего не исполняет, а проверка на нём остаётся зелёной.
|
|
20
20
|
- **Путь, названный в документе, существует.** Ссылка на переехавший файл читается как
|
|
21
21
|
действующее указание, и следующий читатель заводит снятое заново.
|
|
22
|
+
- **Указатель каталога перечисляет всё, что в каталоге лежит.** Записи, которой в указателе нет,
|
|
23
|
+
для читателя не существует: он ищет по указателю, а не обходом каталога, и заводит разбор
|
|
24
|
+
заново. Это обратная сторона предыдущей статьи — не только путь из текста ведёт в файл, но и
|
|
25
|
+
файл назван в тексте, по которому его ищут.
|
|
22
26
|
- **Документ, разошедшийся с приложением, правится тогда же, когда замечено расхождение.**
|
|
23
27
|
Отложенная правка не случается: расхождение перестаёт быть заметным на следующий день.
|
|
24
28
|
- **Расхождение чинится в той стороне, которая неправа, и это не всегда документ.**
|
|
@@ -43,3 +47,8 @@
|
|
|
43
47
|
видит, проверки текстов на них не смотрят, и отказ выглядит сделанным ровно до того, как
|
|
44
48
|
читатель наткнётся на снятое слово в заголовке. Читатель при этом заключает, что от слова
|
|
45
49
|
не отказывались вовсе.
|
|
50
|
+
- **Текст, который переносится в чужое дерево, не описывает состояние этого дерева как факт.**
|
|
51
|
+
О соседней части он говорит условно и называет её по имени: что в дереве стоит, а чего нет,
|
|
52
|
+
знает само дерево, а не текст, приехавший в него. Утверждение, сказанное безусловно, врёт тем
|
|
53
|
+
увереннее, что печатает его сам инструмент, — и поправить его дерево не может, если правки на
|
|
54
|
+
месте у такого текста не предусмотрено.
|
|
@@ -47,3 +47,12 @@
|
|
|
47
47
|
выключают в настройке инструмента, а не обходят в каждом месте.** Обход приходится повторять
|
|
48
48
|
столько раз, сколько таких мест, и ни в одном из них не написано, зачем он: со стороны это
|
|
49
49
|
выглядит ошибкой автора, а не решением.
|
|
50
|
+
- **Польза правила подтверждается наблюдением за тем, как им пользуются, а не мнением о нём.**
|
|
51
|
+
Правило, которого не открыли ни разу, и правило, на котором держится половина работы, в тексте
|
|
52
|
+
выглядят одинаково — и правится первым обычно то, о чём вспомнили, а не то, что мешает.
|
|
53
|
+
Наблюдение ведётся там же, где идёт работа, и переживает отдельный заход: запись, которая
|
|
54
|
+
умирает вместе с сессией, отвечает только на вопрос «что было минуту назад».
|
|
55
|
+
- **Наблюдение за работой не выносит наружу ничего, кроме того, что общее у всех.** Имя правила,
|
|
56
|
+
род события и версия одинаковы везде, где стоит слой правил; путь, домен и имя дерева
|
|
57
|
+
принадлежат одному дереву и в чужом месте не значат ничего, кроме утечки. Держится это
|
|
58
|
+
проверкой на выносящей стороне, а не памятью того, кто пишет.
|
|
@@ -13,8 +13,24 @@
|
|
|
13
13
|
- **Пробел закрывается вопросом владельцу, а не догадкой.** Догадка неотличима от знания:
|
|
14
14
|
она попадает в работу молча и обнаруживается только при приёмке, когда переделывать дороже
|
|
15
15
|
всего.
|
|
16
|
+
- **Вопрос, у которого есть очевидный ответ, работу не останавливает.** Исполнитель называет
|
|
17
|
+
допущение, идёт дальше и записывает его туда же, где идёт работа. Останавливает только тот
|
|
18
|
+
пробел, при котором любая догадка делает работу опасной или бесполезной. Вопрос, заданный
|
|
19
|
+
вместо работы, выглядит добросовестно, а стоит владельцу захода.
|
|
20
|
+
- **Остановка называется первой строкой.** Сообщение, которым исполнитель останавливается,
|
|
21
|
+
начинается с того, чего он ждёт и что будет, если ответа не будет. Замеры, находки и разбор
|
|
22
|
+
к этому моменту уже записаны в ход работы — в сообщении владельцу они лишние. Чем подробнее
|
|
23
|
+
отчёт, тем надёжнее вопрос в нём тонет, и владелец переспрашивает, почему работа стоит.
|
|
16
24
|
- **Владельцу не задаётся вопрос, ответ на который уже записан.** Записанное читают до
|
|
17
25
|
разговора, а не вместо ответа: вопрос о том, что уже решено, обесценивает и остальные.
|
|
26
|
+
- **Вопрос владельцу задаётся после того, как ответ искали в дереве.** Что лежит в дереве,
|
|
27
|
+
исполнитель узнаёт сам: имя, путь, наличие файла и устройство репозитория он берёт командой,
|
|
28
|
+
а не у владельца. Вопрос, ответ на который дала бы одна команда, стоит владельцу захода и
|
|
29
|
+
обесценивает заданные рядом.
|
|
30
|
+
- **Утверждение о дереве стоит ровно столько, сколько команда, его показавшая.** Отрицание —
|
|
31
|
+
«здесь нет», «этого не заводили», «такого файла не бывает» — произносится только как вывод
|
|
32
|
+
команды. Не проверенное отрицание опаснее вопроса: вопрос владелец поправит, а факт от
|
|
33
|
+
исполнителя примет на веру, потому что тот в дерево смотрит.
|
|
18
34
|
- **Решение, однажды записанное, действует, пока его не отменили, и читается до того, как
|
|
19
35
|
принимается заново.** Отменённое решение следа в работе не оставляет — по результату не
|
|
20
36
|
видно ни того, что его принимали, ни того, что от него отказались. Принятое заново оно
|
|
@@ -33,6 +49,14 @@
|
|
|
33
49
|
- **Состояние незаконченной работы восстанавливается без участия владельца.** Иначе каждый
|
|
34
50
|
перерыв стоит ему пересказа, а очередь работ показывает начатое и не говорит, что внутри
|
|
35
51
|
него сделано.
|
|
52
|
+
- **Заход исполнителя конечен, и его конец не совпадает с концом работы.** Место, где
|
|
53
|
+
исполнитель помнит ход работы, ограничено; заполнив его, он теряет не последнее, а всё
|
|
54
|
+
сразу. Заход, доведённый до логической точки заранее, стоит одной записи; оборванный на
|
|
55
|
+
середине — целого захода на восстановление.
|
|
56
|
+
- **Прерванная работа передаётся следующему заходу готовым текстом, а не пересказом
|
|
57
|
+
владельца.** Владелец знает, что работа не кончена, но не знает, где именно она стоит;
|
|
58
|
+
пересказ он даёт по своей памяти, а не по ходу работы, и следующий заход начинает с чужой
|
|
59
|
+
картины.
|
|
36
60
|
- **Замысел и ход работы — разные записи.** Замысел — то, с чем сверяют результат при
|
|
37
61
|
приёмке; правленный по ходу, он перестаёт отличаться от отчёта, и приёмке сверять нечего.
|
|
38
62
|
- **Сделанное отмечается в одном месте.** Две записи об одном разъезжаются молча, и после
|
|
@@ -41,6 +65,11 @@
|
|
|
41
65
|
читается как случайное и отменяется следующим заходом, а отменённое возвращается третьим.
|
|
42
66
|
- **Граница работы названа до её начала.** Не названная вслух граница не существует: правка
|
|
43
67
|
расползается на соседнее, и снимать её приходится вручную.
|
|
68
|
+
- **Действия, которые исполнитель не делает сам, названы списком.** Всё, что уходит за
|
|
69
|
+
пределы рабочего дерева или не откатывается — запись в общий репозиторий, публикация, отчёт,
|
|
70
|
+
правка общего документа, — делается по слову владельца, и слово это даётся на действие, а не
|
|
71
|
+
на работу целиком. Не названная списком граница выводится из общих слов: «делай, что нужно
|
|
72
|
+
по плану» прочитывается как разрешение на всё, что в плане подразумевалось.
|
|
44
73
|
- **Признак закрытия работы назван до её начала и проверяем.** «Работает» признаком не
|
|
45
74
|
является: под ним каждый заход понимает своё, и работа закрывается тогда, когда надоела.
|
|
46
75
|
- **Начатая и брошенная работа видна.** Брошенное на середине выглядит так же, как
|
|
@@ -57,3 +86,21 @@
|
|
|
57
86
|
- **Незаданный вопрос замечает только тот, кто знает, чего хотел.** Вопрос, которого не
|
|
58
87
|
задали, следа не оставляет: работа выглядит понятой ровно до приёмки, и вывести отсутствие
|
|
59
88
|
вопроса не из чего.
|
|
89
|
+
- **Происшествие названо признаком, а не оценкой заднего числа.** Происшествие — заход, в
|
|
90
|
+
котором исполнитель сделал не то, а слой правил этого не отбил. Дефект в коде происшествием
|
|
91
|
+
не является: его объясняет договорённость о продукте. Признак записан один раз, а не
|
|
92
|
+
выводится каждым заходом заново — иначе его назначает тот, кому он мешает.
|
|
93
|
+
- **Происшествие кончается записью, и запись делается в тот же заход.** Через день механизм
|
|
94
|
+
промаха пересказывается уже приглаженно: остаются выводы, а из выводов правило не выводится.
|
|
95
|
+
Запись называет механизм промаха по шагам, что было доступно до него, чем ловилось и что из
|
|
96
|
+
этого ушло в слой правил.
|
|
97
|
+
- **Запись без правки слоя правил закрытой не считается.** Разбор, из которого не вышло ни
|
|
98
|
+
предложения, ни правки закона, правила или паттерна, — жалоба: он объясняет случившееся и
|
|
99
|
+
ничего не меняет, а значит повторится.
|
|
100
|
+
- **Закрытая работа оставляет то, что узнала о правилах, там, откуда это возьмёт машина.**
|
|
101
|
+
Понимание, добытое одной работой, всего дороже соседней — и живёт оно ровно до конца захода,
|
|
102
|
+
если осталось в разговоре. Записанное свободным пересказом лежит не хуже, но переносить его
|
|
103
|
+
приходится руками, и переносится оно ровно до первой занятой недели.
|
|
104
|
+
- **У предложенной правки правил назван адрес: сам слой правил, имена этого дерева или его
|
|
105
|
+
надстройка.** Без адреса правку кладут туда, где она видна автору, — то есть в своё дерево, —
|
|
106
|
+
и общее оседает в одном месте, оставаясь неизвестным всем остальным.
|
|
@@ -212,26 +212,30 @@ npm run task:move -- 86 in-review
|
|
|
212
212
|
Конвейер видит только отправленное, а отправляется оно пушем. Линтеры, юниты и сценарии хуков
|
|
213
213
|
снимает гейт пуша — ниже то, чего он не знает.
|
|
214
214
|
|
|
215
|
-
1.
|
|
215
|
+
1. **Главная ветка влита в эту ветку** — `git fetch origin && git merge origin/main`.
|
|
216
|
+
Всё, что проверяется ниже, проверяется от этого основания: PR с разошедшейся ветки
|
|
217
|
+
показывает ревьюверу правку вперемешку с чужой. Порядок и разбор конфликта — паттерн
|
|
218
|
+
`git-workflow-merge`.
|
|
219
|
+
2. **В ветке только та правка, за которой её заводили** — `git diff main...HEAD --stat`. Чужой
|
|
216
220
|
домен в списке файлов означает, что правка расползлась, и её надо вернуть в свои границы.
|
|
217
|
-
|
|
221
|
+
3. **Ни мока, ни подменённого ответа, ни отладочной строки** — `git diff main...HEAD` читается
|
|
218
222
|
целиком, а не по именам файлов. На прод они уезжают молча и портят настоящие данные.
|
|
219
|
-
|
|
223
|
+
4. **Документ едет тем же коммитом.** Пару называет `docs-guard`, но спек домена и правку его
|
|
220
224
|
поведения он не знает — это остаётся за автором.
|
|
221
|
-
|
|
225
|
+
5. **Проверки текстов и раскладки зелёные** — те, что дерево завело в `tools/`. Какие именно
|
|
222
226
|
есть здесь — `implementation.md` правила.
|
|
223
|
-
|
|
224
|
-
|
|
227
|
+
6. **Все приложения дерева собираются** — `nx build` по каждому. Гейт пуша сборку не гоняет.
|
|
228
|
+
7. **Видимый текст заведён во всех локалях перевода** — тестом полноты словарей, если дерево
|
|
225
229
|
переводится.
|
|
226
|
-
|
|
230
|
+
8. **Правка вёрстки подтверждена замером**, а не взглядом, и снята при узком экране — паттерн
|
|
227
231
|
`browser-verification-measure`.
|
|
228
|
-
|
|
232
|
+
9. **Правка разметки публичного сайта проверена на прод-сборке по всем локалям перевода** —
|
|
229
233
|
паттерн `seo-verify`.
|
|
230
|
-
|
|
231
|
-
|
|
234
|
+
10. **PR привязан к рабочему элементу**, ревьювер и исполнитель стоят.
|
|
235
|
+
11. **Заголовок PR несёт номер элемента и называет работу сделанной:** `[<номер>] <Что
|
|
232
236
|
сделано>`, тем же номером, что стоит у элемента и в имени ветки.
|
|
233
|
-
|
|
234
|
-
|
|
237
|
+
12. **Очередь работ сходится** — `npm run check:board`.
|
|
238
|
+
13. **Состояние PR прочитано, а не выведено из кодов возврата.**
|
|
235
239
|
|
|
236
240
|
Сразу после публикации элемент переводится в разбор, и сверка очереди прогоняется ещё раз: до
|
|
237
241
|
открытия PR состояние она не судит, а после открытия расхождение видит.
|
|
@@ -264,30 +264,34 @@ npm run task:move -- 86 in-review
|
|
|
264
264
|
Проверок на самом PR нет: выкатка запускается пушем в главную ветку, и до мержа никто не
|
|
265
265
|
гоняет ничего. Линтеры, юниты и сценарии хуков снимает гейт пуша — ниже то, чего он не знает.
|
|
266
266
|
|
|
267
|
-
1.
|
|
267
|
+
1. **Главная ветка влита в эту ветку** — `git fetch origin && git merge origin/main`.
|
|
268
|
+
Всё, что проверяется ниже, проверяется от этого основания: PR с разошедшейся ветки
|
|
269
|
+
показывает ревьюверу правку вперемешку с чужой. Порядок и разбор конфликта — паттерн
|
|
270
|
+
`git-workflow-merge`.
|
|
271
|
+
2. **В ветке только та правка, за которой её заводили** — `git diff main...HEAD --stat`. Чужой
|
|
268
272
|
домен в списке файлов означает, что правка расползлась, и её надо вернуть в свои границы.
|
|
269
|
-
|
|
273
|
+
3. **Ни мока, ни подменённого ответа, ни отладочной строки** — `git diff main...HEAD` читается
|
|
270
274
|
целиком, а не по именам файлов. На прод они уезжают молча и портят настоящие данные.
|
|
271
|
-
|
|
275
|
+
4. **Документ едет тем же коммитом.** Пару называет `docs-guard`, но спек домена и правку его
|
|
272
276
|
поведения он не знает — это остаётся за автором.
|
|
273
|
-
|
|
277
|
+
5. **Проверки текстов и раскладки зелёные** — те, что дерево завело в `tools/`: сверка
|
|
274
278
|
сценариев с тестами, путей в документах, раскладки либ, повторов и классов без правила.
|
|
275
279
|
Какие именно есть здесь — `implementation.md` правила.
|
|
276
|
-
|
|
280
|
+
6. **Все приложения дерева собираются** — `nx build` по каждому. Гейт пуша сборку не гоняет:
|
|
277
281
|
она длиннее всего, что он успевает сделать между командой и пушем.
|
|
278
|
-
|
|
282
|
+
7. **Видимый текст заведён во всех локалях перевода** — тестом полноты словарей, если дерево
|
|
279
283
|
переводится.
|
|
280
|
-
|
|
284
|
+
8. **Правка вёрстки подтверждена замером**, а не взглядом, и снята при узком экране — паттерн
|
|
281
285
|
`browser-verification-measure`.
|
|
282
|
-
|
|
286
|
+
9. **Правка разметки публичного сайта проверена на прод-сборке по всем локалям перевода** — паттерн
|
|
283
287
|
`seo-verify`.
|
|
284
|
-
|
|
285
|
-
|
|
288
|
+
10. **Тело PR начинается строкой `Closes #<номер>`**, а метки, ревьювер и исполнитель стоят.
|
|
289
|
+
11. **Заголовок PR несёт номер задачи и называет её сделанной:** `[<КЛЮЧ>-<номер>] <Что сделано>`,
|
|
286
290
|
тем же номером, что стоит у задачи и в имени ветки. Инфинитив из задачи в него не
|
|
287
291
|
переносится, тип и область коммита — тоже.
|
|
288
|
-
|
|
292
|
+
12. **Очередь работ сходится** — `npm run check:board`. Задача на борде, с исполнителем и
|
|
289
293
|
номером в заголовке; PR один на задачу, и закрывает он её целиком.
|
|
290
|
-
|
|
294
|
+
13. **Состояние PR прочитано, а не выведено из кодов возврата** — автор `<бот>`,
|
|
291
295
|
ревьювер — владелец, метки те же, что у задачи. Владельцу называют прочитанное.
|
|
292
296
|
|
|
293
297
|
Сразу после публикации задача переставляется в разбор — `npm run task:move -- <номер>
|
|
@@ -232,26 +232,30 @@ npm run task:move -- 86 in-review
|
|
|
232
232
|
Проверок на самом MR нет ровно до тех пор, пока конвейер не запущен, а запускается он пушем.
|
|
233
233
|
Линтеры, юниты и сценарии хуков снимает гейт пуша — ниже то, чего он не знает.
|
|
234
234
|
|
|
235
|
-
1.
|
|
235
|
+
1. **Главная ветка влита в эту ветку** — `git fetch origin && git merge origin/main`.
|
|
236
|
+
Всё, что проверяется ниже, проверяется от этого основания: MR с разошедшейся ветки
|
|
237
|
+
показывает ревьюверу правку вперемешку с чужой. Порядок и разбор конфликта — паттерн
|
|
238
|
+
`git-workflow-merge`.
|
|
239
|
+
2. **В ветке только та правка, за которой её заводили** — `git diff main...HEAD --stat`. Чужой
|
|
236
240
|
домен в списке файлов означает, что правка расползлась, и её надо вернуть в свои границы.
|
|
237
|
-
|
|
241
|
+
3. **Ни мока, ни подменённого ответа, ни отладочной строки** — `git diff main...HEAD` читается
|
|
238
242
|
целиком, а не по именам файлов. На прод они уезжают молча и портят настоящие данные.
|
|
239
|
-
|
|
243
|
+
4. **Документ едет тем же коммитом.** Пару называет `docs-guard`, но спек домена и правку его
|
|
240
244
|
поведения он не знает — это остаётся за автором.
|
|
241
|
-
|
|
245
|
+
5. **Проверки текстов и раскладки зелёные** — те, что дерево завело в `tools/`. Какие именно
|
|
242
246
|
есть здесь — `implementation.md` правила.
|
|
243
|
-
|
|
244
|
-
|
|
247
|
+
6. **Все приложения дерева собираются** — `nx build` по каждому. Гейт пуша сборку не гоняет.
|
|
248
|
+
7. **Видимый текст заведён во всех локалях перевода** — тестом полноты словарей, если дерево
|
|
245
249
|
переводится.
|
|
246
|
-
|
|
250
|
+
8. **Правка вёрстки подтверждена замером**, а не взглядом, и снята при узком экране — паттерн
|
|
247
251
|
`browser-verification-measure`.
|
|
248
|
-
|
|
252
|
+
9. **Правка разметки публичного сайта проверена на прод-сборке по всем локалям перевода** —
|
|
249
253
|
паттерн `seo-verify`.
|
|
250
|
-
|
|
251
|
-
|
|
254
|
+
10. **Описание MR начинается строкой `Closes #<номер>`**, а метки, ревьювер и исполнитель стоят.
|
|
255
|
+
11. **Заголовок MR несёт номер задачи и называет её сделанной:** `[<КЛЮЧ>-<номер>] <Что
|
|
252
256
|
сделано>`, тем же номером, что стоит у задачи и в имени ветки.
|
|
253
|
-
|
|
254
|
-
|
|
257
|
+
12. **Очередь работ сходится** — `npm run check:board`.
|
|
258
|
+
13. **Состояние MR прочитано, а не выведено из кодов возврата.**
|
|
255
259
|
|
|
256
260
|
Сразу после публикации задача переставляется в разбор, и сверка очереди прогоняется ещё раз: до
|
|
257
261
|
открытия MR список она не судит, а после открытия расхождение видит.
|
|
@@ -89,6 +89,18 @@ docs/specs/<домен>/
|
|
|
89
89
|
`Не покрыто: <причина>`, сценарий с неполным тестом — `Покрытие: частичное — <чего не
|
|
90
90
|
хватает>`.
|
|
91
91
|
|
|
92
|
+
Номер в идентификаторе живёт так:
|
|
93
|
+
|
|
94
|
+
| Что случилось | Что делается с номером |
|
|
95
|
+
| ----------------------- | ---------------------------------------------------------------------------------------------------- |
|
|
96
|
+
| сценарий добавили | берётся следующий свободный — наибольший выданный в домене плюс один, а не дырка в середине |
|
|
97
|
+
| обещание изменили | номер тот же, заголовок теста правится тем же коммитом |
|
|
98
|
+
| сценарий удалили | номер остаётся пустым и новому сценарию не отдаётся; тест удаляется вместе со сценарием |
|
|
99
|
+
| номера захотелось сжать | не пересчитываются: связь с тестами держит только номер, а прогон остаётся зелёным при обеих правках |
|
|
100
|
+
|
|
101
|
+
Номер записывается так же, как у соседей в этом же файле: сверка ищет его шаблоном, и номер,
|
|
102
|
+
записанный иначе, не совпадёт ни в спеке, ни в заголовке теста.
|
|
103
|
+
|
|
92
104
|
## Порядок работы
|
|
93
105
|
|
|
94
106
|
1. Задача заводится сценариями: что станет верно, когда работа закончится.
|
|
@@ -121,3 +133,10 @@ docs/specs/<домен>/
|
|
|
121
133
|
- Закон, названный в тексте, но забытый в строке `**Законы:**`: по закону тогда не узнать,
|
|
122
134
|
какие домены на нём стоят.
|
|
123
135
|
- Правка `.proto` без спеков задетых доменов: `docs-guard` отбивает такой коммит.
|
|
136
|
+
- **Выросший домен делится на поддомены, а не на новые домены.** Новый домен пришлось бы
|
|
137
|
+
заводить в указателе, сверять с кодом отдельно и объяснять, чем он соседу не поддомен;
|
|
138
|
+
поддомен остаётся в своём домене и наследует его контракт. Соседний домен заводится только
|
|
139
|
+
тогда, когда предмет живёт своей сущностью.
|
|
140
|
+
- **Границу между доменами проводит владелец, а не автор очередной правки.** Автор видит свою
|
|
141
|
+
правку, а не то, чем предмет обрастёт: домен, заведённый по ходу дела, через месяц оказывается
|
|
142
|
+
половиной соседнего, и разводить их приходится вместе с номерами сценариев.
|
|
@@ -15,7 +15,7 @@ description: Паттерн правила task-flow. Брать при закр
|
|
|
15
15
|
- Этапы замысла закрыты, проверки зелёные, отчёт готовится к публикации.
|
|
16
16
|
- `npm run check:specs` перечислил договорённость в разделе «Пора вливать».
|
|
17
17
|
|
|
18
|
-
##
|
|
18
|
+
## 9. Договорённость вливается в спек домена
|
|
19
19
|
|
|
20
20
|
Последним коммитом отчёта, до слияния. Код к этому моменту написан, поэтому привязки
|
|
21
21
|
`файл:символ` известны — правило въезжает в спек домена сразу проверяемым.
|
|
@@ -44,7 +44,7 @@ npm run check:specs # раздел «Пора вливать» называе
|
|
|
44
44
|
npm run check:specs # после вливания: привязки на месте, сценарии не потерялись
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
-
##
|
|
47
|
+
## 10. Тексты домена приводятся к сделанному
|
|
48
48
|
|
|
49
49
|
В спек уезжает только то, что записали до кода. Остальные тексты — правила, паттерны, законы
|
|
50
50
|
приложения — после правки никто не перечитывает, и они продолжают описывать старое дерево.
|
|
@@ -85,7 +85,7 @@ grep -rn -A3 "Чего из закона здесь нет" <каталог пр
|
|
|
85
85
|
Что сделали на этом шаге, пишется в тело отчёта: что перечитали, что изменили, а если ничего
|
|
86
86
|
не изменили — почему. Форма раздела — паттерн `git-workflow-commit`.
|
|
87
87
|
|
|
88
|
-
##
|
|
88
|
+
## 11. Папка задачи разбирается
|
|
89
89
|
|
|
90
90
|
Целиком в архив не переносится: `docs/archive/` — место для записей о состоявшемся, которые
|
|
91
91
|
кто-то читает, а не свалка ходов работы.
|
|
@@ -106,7 +106,7 @@ rm -r docs/tasks/<КЛЮЧ>-<номер>-<slug>
|
|
|
106
106
|
Разбор идёт в том же отчёте, что и работа: папка, оставленная до мержа, попадает в главную
|
|
107
107
|
ветку и читается там как текущая.
|
|
108
108
|
|
|
109
|
-
##
|
|
109
|
+
## 12. Сверка
|
|
110
110
|
|
|
111
111
|
```bash
|
|
112
112
|
npm run check:board # папка закрытой задачи среди текущих, брошенные черновики
|