@rt-tools/agent-kit 0.1.0 → 0.3.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 (131) hide show
  1. package/README.md +88 -9
  2. package/assets/hooks/browser-device-id.sh +20 -0
  3. package/assets/hooks/browser-guard-device-id.sh +27 -0
  4. package/assets/hooks/browser-guard-no-listing.sh +17 -0
  5. package/assets/hooks/browser-guard-no-other-drivers.sh +78 -0
  6. package/assets/hooks/browser-guard-require-select.sh +53 -0
  7. package/assets/hooks/commit-msg.sh +26 -0
  8. package/assets/hooks/constitution-index.sh +42 -0
  9. package/assets/hooks/dev-server-guard.sh +113 -0
  10. package/assets/hooks/docs-guard.sh +96 -0
  11. package/assets/hooks/git-guard-delivery.sh +110 -0
  12. package/assets/hooks/git-guard-main.sh +72 -0
  13. package/assets/hooks/git-guard-push-tests.sh +73 -0
  14. package/assets/hooks/lint-after-edit.sh +94 -0
  15. package/assets/hooks/qa-dataid-guard.sh +81 -0
  16. package/assets/hooks/reuse-first-guard.sh +83 -0
  17. package/assets/hooks/skill-gate-rearm.sh +22 -0
  18. package/assets/hooks/skill-gate.sh +68 -0
  19. package/assets/hooks/skill-loaded.sh +20 -0
  20. package/assets/hooks/sql-guard.sh +129 -0
  21. package/assets/laws/access.md +3 -12
  22. package/assets/laws/admin-lists.md +9 -21
  23. package/assets/laws/admin-navigation.md +3 -15
  24. package/assets/laws/code-structure.md +5 -16
  25. package/assets/laws/delivery.md +2 -16
  26. package/assets/laws/entity-editing.md +7 -20
  27. package/assets/laws/entity-models.md +10 -17
  28. package/assets/laws/frontend-application.md +3 -14
  29. package/assets/laws/lib-imports.md +0 -13
  30. package/assets/laws/locales.md +2 -11
  31. package/assets/laws/project-documentation.md +7 -20
  32. package/assets/laws/reuse-first.md +0 -9
  33. package/assets/laws/search-visibility.md +0 -13
  34. package/assets/laws/shared-code.md +0 -13
  35. package/assets/laws/verifiability.md +0 -13
  36. package/assets/patterns/angular-patterns-state.md +94 -0
  37. package/assets/patterns/api-layer-pair.md +78 -0
  38. package/assets/patterns/browser-verification-measure.md +83 -0
  39. package/assets/patterns/browser-verification-stand.md +79 -0
  40. package/assets/patterns/component-structure-new.md +98 -0
  41. package/assets/patterns/doc-style-sweep.md +100 -0
  42. package/assets/patterns/doc-style-write.md +106 -0
  43. package/assets/patterns/git-workflow-commit.md +175 -0
  44. package/assets/patterns/git-workflow-merge.md +82 -0
  45. package/assets/patterns/git-workflow-migration.md +58 -0
  46. package/assets/patterns/git-workflow-restart.md +49 -0
  47. package/assets/patterns/lib-layers-move.md +77 -0
  48. package/assets/patterns/lib-layers-new.md +70 -0
  49. package/assets/patterns/permissions-procedure.md +69 -0
  50. package/assets/patterns/platform-access-di.md +70 -0
  51. package/assets/patterns/reuse-first-extend.md +73 -0
  52. package/assets/patterns/seo-page.md +92 -0
  53. package/assets/patterns/seo-verify.md +64 -0
  54. package/assets/patterns/shared-code-new.md +80 -0
  55. package/assets/patterns/spec-driven-domain.md +100 -0
  56. package/assets/patterns/spec-driven-rule.md +112 -0
  57. package/assets/patterns/styling-bem-component.md +77 -0
  58. package/assets/patterns/styling-bem-layout.md +67 -0
  59. package/assets/patterns/testing-e2e.md +90 -0
  60. package/assets/patterns/testing-unit.md +93 -0
  61. package/assets/patterns/translations-key.md +51 -0
  62. package/assets/patterns/ts-procedure.md +66 -0
  63. package/assets/rules/angular-patterns.md +52 -0
  64. package/assets/rules/api-layer.md +53 -0
  65. package/assets/rules/browser-verification.md +69 -0
  66. package/assets/rules/component-structure.md +48 -0
  67. package/assets/rules/doc-style.md +61 -0
  68. package/assets/rules/git-workflow.md +106 -0
  69. package/assets/rules/lib-layers.md +54 -0
  70. package/assets/rules/permissions.md +52 -0
  71. package/assets/rules/platform-access.md +49 -0
  72. package/assets/rules/reuse-first.md +69 -0
  73. package/assets/rules/seo.md +50 -0
  74. package/assets/rules/shared-code.md +45 -0
  75. package/assets/rules/spec-driven.md +89 -0
  76. package/assets/rules/styling-bem.md +59 -0
  77. package/assets/rules/testing.md +69 -0
  78. package/assets/rules/translations.md +52 -0
  79. package/assets/rules/typescript-conventions.md +46 -0
  80. package/assets/templates/gate-map.sh +37 -0
  81. package/assets/templates/implementation.md +38 -0
  82. package/assets/templates/pattern.md +4 -0
  83. package/assets/templates/project.sh +41 -0
  84. package/assets/templates/rule.md +12 -23
  85. package/bin/agent-kit.d.ts +1 -1
  86. package/bin/agent-kit.d.ts.map +1 -1
  87. package/bin/agent-kit.js +63 -7
  88. package/bin/agent-kit.js.map +1 -1
  89. package/bin/prompt.d.ts +9 -0
  90. package/bin/prompt.d.ts.map +1 -0
  91. package/bin/prompt.js +57 -0
  92. package/bin/prompt.js.map +1 -0
  93. package/index.d.ts +2 -0
  94. package/index.d.ts.map +1 -1
  95. package/index.js +2 -0
  96. package/index.js.map +1 -1
  97. package/lib/assets.d.ts +10 -2
  98. package/lib/assets.d.ts.map +1 -1
  99. package/lib/assets.js +24 -28
  100. package/lib/assets.js.map +1 -1
  101. package/lib/catalog.d.ts +44 -0
  102. package/lib/catalog.d.ts.map +1 -0
  103. package/lib/catalog.js +86 -0
  104. package/lib/catalog.js.map +1 -0
  105. package/lib/commands.d.ts +13 -1
  106. package/lib/commands.d.ts.map +1 -1
  107. package/lib/commands.js +106 -11
  108. package/lib/commands.js.map +1 -1
  109. package/lib/companion.d.ts +53 -0
  110. package/lib/companion.d.ts.map +1 -0
  111. package/lib/companion.js +33 -0
  112. package/lib/companion.js.map +1 -0
  113. package/lib/config.d.ts +29 -1
  114. package/lib/config.d.ts.map +1 -1
  115. package/lib/config.js +43 -6
  116. package/lib/config.js.map +1 -1
  117. package/lib/picker.d.ts +47 -0
  118. package/lib/picker.d.ts.map +1 -0
  119. package/lib/picker.js +112 -0
  120. package/lib/picker.js.map +1 -0
  121. package/lib/stamp.d.ts +2 -5
  122. package/lib/stamp.d.ts.map +1 -1
  123. package/lib/stamp.js +25 -10
  124. package/lib/stamp.js.map +1 -1
  125. package/lib/sync.d.ts +3 -0
  126. package/lib/sync.d.ts.map +1 -1
  127. package/lib/sync.js +20 -1
  128. package/lib/sync.js.map +1 -1
  129. package/package.json +1 -1
  130. package/rt-tools-agent-kit-0.3.0.tgz +0 -0
  131. package/rt-tools-agent-kit-0.1.0.tgz +0 -0
@@ -0,0 +1,48 @@
1
+ ---
2
+ name: component-structure
3
+ kind: rule
4
+ law: frontend-application
5
+ description: Правило под закон «Фронтовое приложение». Брать при правке любого файла компонента и его шаблона — порядок свойств декоратора, группировка импортов, договорённости шаблона, обязательный якорь для спек, класс блока на хосте. Готовый код — в паттерне component-structure-new. Чем это названо здесь — в implementation.md рядом.
6
+ ---
7
+
8
+ # Файл компонента — каким приёмом
9
+
10
+ Правило под закон `{{lawsDir}}/frontend-application.md`. Закон говорит, что должно быть верно;
11
+ здесь — как устроен сам файл компонента и его шаблон. Какой у компонентов префикс, чем зовётся
12
+ якорь спек и где лежат правила линтера — `implementation.md` рядом. Состояние и потоки —
13
+ `angular-patterns`, оформление — `styling-bem`, окружение браузера — `platform-access`, слой
14
+ обращения к серверу — `api-layer`. Все пять под одним законом.
15
+
16
+ ## Когда берётся
17
+
18
+ Заведение или правка файла компонента и его шаблона.
19
+
20
+ ## Что здесь действует
21
+
22
+ - **Шаблон не зовёт методов.** Вызов в привязке считается заново на каждую проверку изменений;
23
+ готовое значение объявляется вычисляемым, а там, где оно зависит от контекста шаблона, —
24
+ чистым преобразователем.
25
+ - **Каждый интерактивный элемент несёт якорь для спек.** Это единственная устойчивая зацепка:
26
+ классы оформления меняются вместе с вёрсткой, а поиск по роли и тексту ломается на первой же
27
+ второй локали.
28
+ - **Класс блока висит на хосте, а не на обёртке внутри шаблона.** Лишняя обёртка вокруг всех
29
+ детей — это раскладка, и ей место на хосте.
30
+ - **Якорь для спек не заменяет доступности и не снимается при правке вёрстки.** Доступность
31
+ отдельно, якорь отдельно; на якорь завязаны спеки, и снятый он роняет их молча.
32
+
33
+ ## Паттерны
34
+
35
+ - `component-structure-new` — готовый файл компонента и договорённости шаблона.
36
+
37
+ ## Ловушки
38
+
39
+ - **Ссылка на фрагмент в разметке не прокручивает страницу.** Когда в разметке объявлен
40
+ базовый адрес, браузер разрешает фрагмент относительно него: вместо прокрутки получается
41
+ полная навигация с перезагрузкой. Прокрутка делается средствами маршрутизатора.
42
+ - **Один и тот же компонент в обеих ветках условия — это условная привязка.** Две ветки с
43
+ разными входами пересоздают компонент и теряют его состояние.
44
+ - **Компонент, который рисуется в перекрытии, из хоста вызывающего не адресуется.** Его
45
+ разметка лежит вне хоста, и селектор от хоста до его кнопок не дотянется: такие кнопки носят
46
+ собственные якоря в своём шаблоне.
47
+ - **Готовое не пишется заново.** Своя разметка с ролью оповещения, таблицы, диалога, вкладок
48
+ или подсказки означает, что мимо готового компонента прошли. Правило целиком — `reuse-first`.
@@ -0,0 +1,61 @@
1
+ ---
2
+ name: doc-style
3
+ kind: rule
4
+ law: project-documentation
5
+ description: Правило под закон «Документация проекта». Брать при правке любого документа, включая спеки, а также комментариев в коде, тел коммитов и описаний PR. Пути, которые существуют, пара «правка и её документ», словарь проекта, запрет упоминать чужие проекты. Готовые формулировки — в паттерне doc-style-write. Чем это названо здесь — в implementation.md рядом.
6
+ ---
7
+
8
+ # Тексты проекта — каким приёмом
9
+
10
+ Правило под закон `{{lawsDir}}/project-documentation.md`. Закон говорит, что должно быть верно
11
+ про тексты; здесь — каким приёмом это держится и что остаётся за автором. Где лежит словарь,
12
+ чем проверяются пути и какие пары требует гейт — `implementation.md` рядом. Устройство спеков и
13
+ слоёв документации — правило `spec-driven` под тем же законом.
14
+
15
+ ## Когда берётся
16
+
17
+ Правка любого документа, комментария в коде, тела коммита, описания PR.
18
+
19
+ ## Что здесь действует
20
+
21
+ - **Путь, названный в документе, существует.** Ссылка на переехавший файл читается как
22
+ действующее указание, и следующий читатель заводит снятое заново.
23
+ - **Описание прошлого из проверки путей выведено целиком.** Архив по устройству называет файлы,
24
+ которых уже нет, и правкой это не лечится.
25
+ - **Документ едет в том же коммите, что и правка, которую он описывает.** Обход — отметка с
26
+ причиной в теле коммита; пустая причина не принимается.
27
+ - **Термин берётся из словаря проекта, а не придумывается на месте.** Слова, которого там нет,
28
+ у читателя нет тоже. Новое слово либо заводится в словаре вместе с правкой, либо заменяется
29
+ тем, что уже есть.
30
+ - **Чужие проекты не упоминаются нигде** — ни имени репозитория, ни «портировано из», ни ссылок
31
+ на его файлы. Описывается то, что код делает здесь, в терминах этого проекта.
32
+
33
+ ## Паттерны
34
+
35
+ - `doc-style-write` — как формулировать: примеры «так» и «не так», правила для комментариев.
36
+ - `doc-style-sweep` — разбор документа, накопившего список работ, на действующее и закрытое.
37
+
38
+ ## Ловушки
39
+
40
+ - **Оставшаяся работа не записывается в документ, а заводится задачей.** «Сделать потом» в
41
+ плане, README или спеке — второй список работ: он расходится с очередью задач молча, а
42
+ разбирать его потом дороже, чем завести задачу сразу. Документ держит только то, что задачей
43
+ не бывает: договорённости и решения, которые решено не править.
44
+ - **Словарь действует и на разговор с владельцем, не только на файлы.** Слово, от которого в
45
+ дереве отказались, всплывает именно в отчёте о сделанном — и владелец читает ровно то слово,
46
+ которое просил не употреблять.
47
+ - **Проход по словарю глазами слово не находит.** «Формулировки приведены к словарю» означает
48
+ ровно те строки, которые в тот момент читали. Снятое слово вычищается поиском по всему дереву,
49
+ а не вычиткой; ищутся сочетания, а не корень — совпадений по корню законных обычно больше,
50
+ чем нарушений.
51
+ - **Снятое имя вычищается одним проходом по всему дереву:** правила, их зеркала, документы и
52
+ комментарии. Описание того, чего в коде уже нет, читается как действующее указание.
53
+ - **Число в тексте пересчитывается командой в том же коммите, где пишется.** Оно стареет внутри
54
+ одной ветки. Число, которое придётся пересчитывать при каждой правке, лучше не писать вовсе;
55
+ число, полученное разбором текста, сверяется на выборке руками — разбор, не знающий второй
56
+ формы записи, ошибается молча.
57
+ - **Сделанность читается по дереву, а не по тексту, который о ней написан.** Это верно в обе
58
+ стороны: вычеркнутый пункт при несделанной работе и несделанным названная задача, закрытая
59
+ наполовину, встречаются одинаково часто. Пункт плана описывает день, когда его написали.
60
+ - **Комментарий в файле — такое же утверждение, как строка в документе.** Выдуманное
61
+ обоснование живёт в коде годами и каждый раз читается как основание ничего не трогать.
@@ -0,0 +1,106 @@
1
+ ---
2
+ name: git-workflow
3
+ kind: rule
4
+ law: delivery
5
+ description: Правило под закон «Поставка». Брать на заведение задачи, ветки, коммит, пуш, создание PR, слияние, а также на правку схемы хранилища и её миграций. Задача как начало работы, колонка задачи как ход работы, соответствие задачи и ветки один к одному, формат коммита, обязательный состав PR, сторожевые хуки. Готовый код — в паттернах git-workflow-commit, git-workflow-merge, git-workflow-migration и git-workflow-restart. Чем это названо здесь — в implementation.md рядом.
6
+ ---
7
+
8
+ # Поставка — каким приёмом
9
+
10
+ Правило под закон `{{lawsDir}}/delivery.md`. Закон говорит, что должно быть верно; здесь — каким
11
+ приёмом это держится. Как названы главная ветка, борда, колонки, формат имени ветки и учётная
12
+ запись машинной работы — `implementation.md` рядом.
13
+
14
+ ## Когда берётся
15
+
16
+ Заведение задачи и ветки, коммит, пуш, открытие PR, слияние, правка схемы хранилища и её
17
+ миграций, ручной перезапуск прода.
18
+
19
+ ## Что здесь действует
20
+
21
+ - **Коммит в главную ветку отбивается гардом.** Гард ищет вызов коммита в любом месте команды и
22
+ смотрит текущую ветку на момент запуска, поэтому составная «создать ветку и сразу коммитить»
23
+ отклоняется целиком: ветки в момент разбора ещё нет.
24
+ - **Ветка без номера задачи PR не открывает.** Локально такая ветка законна, но правка из неё —
25
+ это выкатка, за которой в очереди работ ничего не стоит.
26
+ - **Номер ветки и номер в заголовке PR сверяются на месте, а состояние задачи — по борде.**
27
+ Формат читается из текста команды и работает без сети; существование задачи, её присутствие в
28
+ очереди, исполнитель и то, что она ещё открыта, — только когда есть чем спросить. Нет сети
29
+ или нет токена — второй ярус молча пропускается: проверка, падающая в самолёте, перестаёт
30
+ что-либо значить.
31
+ - **Колонка задачи двигается тем же движением, что и работа.** Ветка заведена — задача
32
+ переставляется во взятые в работу, PR открыт — в разбор. Перевод идёт сразу за шагом, который
33
+ его вызвал: очередь работ читают между шагами, а не после них.
34
+ - **Отставшая колонка находится сверкой очереди, а не глазами.** Сверка судит колонку по отчёту
35
+ в обе стороны: открытый PR при задаче не в разборе и разбор без открытого PR — оба
36
+ расхождения.
37
+ - **Задачи, чинящиеся одной правкой, сливаются до слияния ветки.** Недостающее из поглощённой
38
+ дописывается в первую, а сама она уходит из очереди. После слияния ветки слить уже нельзя:
39
+ она въехала, и откатывается целиком.
40
+ - **Слияние в главную ветку выкатывает прод.** Исключения по путям покрывают только документы,
41
+ поэтому переменные окружения, секреты и записи имён ставятся до слияния, а не после.
42
+ - **Признак режима объявлен в образе, а не только в составе прода.** Значение, заданное
43
+ составом, действует лишь на контейнер, поднятый этим составом; ручной прогон того же образа
44
+ идёт с пустым значением, а пусто здесь означает разработку — со всеми отладочными
45
+ умолчаниями, которые она разрешает.
46
+ - **Образы выкатываются по хешу коммита, а не по метке «последний».** Метка в реестре отстаёт
47
+ от главной ветки, и прод молча возвращается к прежней версии, продолжая отвечать.
48
+ - **Цепочка миграций прогоняется с пустого хранилища до слияния.** Порядок применения
49
+ лексикографический по имени каталога, а метку времени ставит момент создания: миграция из
50
+ ветки, начатой раньше, встаёт перед той, от которой зависит.
51
+ - **Документ едет в том же коммите, что и правка.** Обход — отметка с причиной в теле коммита;
52
+ пустая причина не принимается.
53
+ - **Заголовок коммита сверяется с форматом на месте.** Разобранный по типу и области заголовок
54
+ читается списком, а свободный текст — только целиком.
55
+ - **Перед пушем прогоняются все линтеры, а не один.** Линтер кода обычно не читает файлы стилей
56
+ вовсе, и правила оформления без второго прогона не проверяет ничто.
57
+
58
+ ## Паттерны
59
+
60
+ - `git-workflow-commit` — ветка, коммит, пуш и PR от учётной записи машинной работы.
61
+ - `git-workflow-merge` — влить главную ветку в ветку задачи и разрешить конфликт.
62
+ - `git-workflow-migration` — файл миграции и прогон цепочки на одноразовом хранилище.
63
+ - `git-workflow-restart` — ручной перезапуск прода без отката на прежний образ.
64
+
65
+ ## Ловушки
66
+
67
+ - **Одна работа — одна задача, сколько бы файлов она ни задела.** Числа, за которым правка
68
+ становится второй задачей, нет: делится то, что придётся откатывать порознь. Сплошная правка,
69
+ разделённая «по объёму», кончается стиранием лишних задач, закрытием их PR и переносом
70
+ коммитов с конфликтами.
71
+ - **Задача заводится одной командой, а не набором вызовов подряд.** Очередь работ к репозиторию
72
+ обычно не привязана, и задача попадает в неё только явным добавлением: переписанный руками
73
+ шаг оставляет её вне очереди, и заметить это нечем.
74
+ - **Ветка заводится вторым вызовом, а не тем же.** Гард главной ветки отклоняет составную
75
+ «создать ветку и сразу коммитить» целиком.
76
+ - **Колонка, приведённая в порядок задним числом, ничего не значила ровно тогда, когда очередь
77
+ читали.** Перевод стоит одной команды и делается на месте, а не собирается в уборку под
78
+ конец: очередь для того и ведётся, чтобы отвечать в любой момент.
79
+ - **Сторона конфликта бывает удалением, и «сохранить обе стороны» заводит второе объявление.**
80
+ Главная ветка снимает объявление, потому что символ переехал, — в конфликте это выглядит как
81
+ сторона, которая ничего не дописала. Разбирается чтением версии главной ветки целиком, а не
82
+ по куску: обе копии сами по себе исправны, сборка и линтер зелёные.
83
+ - **Конфликт при вливании главной ветки почти всегда лежит в текстах, а не в коде.** Соседние
84
+ ветки дописывают в конец одних и тех же списков; зелёная сборка после слияния про такой
85
+ конфликт не говорит ничего.
86
+ - **PR без ревьювера, исполнителя и меток открывать нельзя.** Ревьювер не узнаёт, что его ждут,
87
+ а метки — единственное, по чему в очереди из полутора десятков PR видно род правки и её
88
+ область.
89
+ - **Заголовок PR без номера задачи не сопоставить с очередью.** В списке PR тела не видно, а
90
+ строка о закрытии задачи живёт именно там. Название при этом идёт в сделанном: задача просит
91
+ исправить, PR отчитывается, что исправлено.
92
+ - **На самом PR не гоняется ничто.** Выкатка запускается пушем в главную ветку, и выборочный
93
+ прогон по затронутому до PR не доходит: сборки, проверки текстов и браузер идут до
94
+ публикации.
95
+ - **Субагентам работа с историей запрещена полностью, включая чтение состояния.** Отложенные
96
+ изменения, спрятанные субагентом, выглядят как потеря всей работы. Историю ведёт главный
97
+ агент.
98
+ - **Подъём контейнера без явного тега образа подставляет «последний».** Приложение при этом
99
+ отвечает, и подмену видно только по пропавшим строкам нового кода в журнале.
100
+ - **Команда разработчика для миграций на живом хранилище не запускается.** Любое расхождение
101
+ состояния она лечит предложением сбросить хранилище, а в нём лежат данные владельца.
102
+ - **Переименованная миграция остаётся в хранилище под прежним именем.** Накат падает на «объект
103
+ уже существует» и лечится отметкой о применении, а не повторным накатом.
104
+ - **Флаги инструмента миграций не те, что в примерах из сети.** На неизвестный флаг команда
105
+ печатает справку, а не строку ошибки, — промах виден только в ней. Какие флаги есть сейчас,
106
+ смотрят в её собственной справке, а не в этом тексте.
@@ -0,0 +1,54 @@
1
+ ---
2
+ name: lib-layers
3
+ kind: rule
4
+ law: lib-imports
5
+ description: Правило под закон «Импорты между либами». Брать при правке манифестов проектов, алиасов, конфигов границ, любого бареля и проверок раскладки, а также когда решается, где живёт общий символ. Готовый порядок действий — в паттернах lib-layers-new и lib-layers-move. Чем это названо здесь — в implementation.md рядом.
6
+ ---
7
+
8
+ # Импорты между либами — каким приёмом
9
+
10
+ Правило под закон `{{lawsDir}}/lib-imports.md`. Закон говорит, кто кого видит; здесь — каким
11
+ приёмом это держится. Как нарезаны семьи и слои в этом дереве, чем названы теги и где лежат
12
+ конфиги границ — `implementation.md` рядом.
13
+
14
+ ## Когда берётся
15
+
16
+ Правка манифеста проекта, алиасов, конфига границ, любого бареля, проверок раскладки. И раньше
17
+ всего этого — решение, в какой либе живёт общий символ.
18
+
19
+ ## Что здесь действует
20
+
21
+ - **Чужой символ не реэкспортируется ни одной из двух форм.** Запрещены и прямой реэкспорт по
22
+ алиасу, и пара «импорт плюс экспорт того же имени»: вторая выглядит как собственное
23
+ объявление и глазами в разборе проходит.
24
+ - **Строка с алиасом чужой либы в бареле — тот же реэкспорт.** Относительный путь в бареле
25
+ законен: он собирает наружу собственные файлы либы.
26
+ - **Не хватает права — оно дописывается строкой в конфиге домена с комментарием.** Импорт,
27
+ который «просто заработал», означает, что тег ещё не сужен.
28
+ - **У либы, общей всем приложениям, список зависимостей пуст, и каркас фронта туда не
29
+ попадает.** Её импортирует и серверная сторона, и каркас уехал бы в её сборку; общий двум
30
+ фронтовым семьям токен внедрения живёт отдельной либой.
31
+ - **Основание семейства видит только слой утилит.** Его зовут все домены семьи, и любая его
32
+ зависимость становится общей для всех сразу.
33
+ - **Домен заводится под предмет, а не под механику.** Механика, общая нескольким доменам, едет
34
+ в либу, которой она уже видна: у фронта это основание семейства, у серверной стороны — слой
35
+ утилит, перечисленный у каждого домена.
36
+
37
+ ## Паттерны
38
+
39
+ - `lib-layers-new` — завести или удалить либу: генератор, теги, алиас, README.
40
+ - `lib-layers-move` — перенести код между либами: порядок, границы, импорты, README обеих.
41
+
42
+ ## Ловушки
43
+
44
+ - **Либа, которую никто не импортирует, не проверена ничем.** Линтер и тесты проверяют её саму,
45
+ а не договор с потребителем: потерянное поле в модели ошибкой не считается, пока нет
46
+ вызывающего кода. Первый импортёр и есть первая проверка — слой моделей принимается после
47
+ сборки и живого прогона сценария, а не по зелёному линтеру с тестами.
48
+ - **Проверка раскладки принимается на нарушении, а не на зелёном прогоне.** Нарушение вносится
49
+ руками, прогон краснеет, правка снимается. У самих проверок тестов обычно нет, и это
50
+ единственная их приёмка.
51
+ - **Удаление каталога средствами гита оставляет то, что гит не отслеживал.** Кэш сборщика
52
+ внутри удалённой либы остаётся на диске, и проверка продолжает видеть её как домен без слоёв.
53
+ - **Пустой слой механики неотличим от слота под будущую задачу.** Проверка требует полного
54
+ набора слоёв у всех, и оба случая выглядят одинаково.
@@ -0,0 +1,52 @@
1
+ ---
2
+ name: permissions
3
+ kind: rule
4
+ law: access
5
+ description: Правило под закон «Доступ». Брать при заведении или правке обработчика серверной стороны, перехватчика входа, стража маршрута и декларации меню. Четыре вида доступа, объявление ровно одно, пресет плюс точечные правки, закрытие раздела и его адреса одной декларацией. Готовый код — в паттерне permissions-procedure. Чем это названо здесь — в implementation.md рядом.
6
+ ---
7
+
8
+ # Доступ — каким приёмом
9
+
10
+ Правило под закон `{{lawsDir}}/access.md`. Закон говорит, что должно быть верно; здесь — каким
11
+ приёмом это держится. Как названы права, метки объявления и где лежат перехватчик и сложение
12
+ прав — `implementation.md` рядом.
13
+
14
+ ## Когда берётся
15
+
16
+ Заведение или правка обработчика серверной стороны, перехватчика входа, стража маршрута,
17
+ декларации пункта меню.
18
+
19
+ ## Что здесь действует
20
+
21
+ - **Каждый обработчик объявляет свой доступ меткой, и объявление ровно одно.** Обработчик без
22
+ объявления или с двумя не даёт приложению подняться: молчание здесь опаснее отказа.
23
+ - **Видов доступа четыре: по праву, любому вошедшему, публично и публично с чтением входа.**
24
+ Последний отдаёт вошедшему больше, чем гостю, — так владелец видит скрытые записи в общем
25
+ списке.
26
+ - **Права пользователя — это права пресета, поверх которых применены его точечные правки.**
27
+ - **Запрос без входа отбивается как неаутентифицированный, а вход без права — как отказ в
28
+ доступе.** Это разные ответы: первый лечится входом, второй — нет.
29
+ - **Право проверяется перехватчиком до тела обработчика.** Обработчик не решает, пускать ли
30
+ вызывающего.
31
+ - **Публичность объявляется с причиной.** Причина — аргумент метки, записанный для читателя
32
+ кода; ни в ответ, ни в журнал она не уходит.
33
+ - **Пункт меню и адрес раздела закрыты по одной декларации.** Иначе скрытый пункт закрывает
34
+ раздел лишь на вид: адрес открывается по прямой ссылке.
35
+ - **Пока права не получены, интерфейс ничего не прячет.** Пустая шапка после сетевого сбоя
36
+ выглядит как сломанное приложение и не оставляет выхода.
37
+
38
+ ## Паттерны
39
+
40
+ - `permissions-procedure` — объявление доступа у обработчика и закрытие раздела интерфейса.
41
+
42
+ ## Ловушки
43
+
44
+ - **Обработчик, о котором перехватчик ничего не знает, отбивается как отказ в доступе, а не
45
+ пропускается.**
46
+ - **Страж стоит на дочерних маршрутах защищённой группы, а не на самой группе.** Страж группы
47
+ отрабатывает один раз за загрузку страницы и переходов между разделами не видит.
48
+ - **Права приходят ответом профиля уже внутри защищённой группы**, поэтому страж дожидается
49
+ запуска приложения. Отказ запроса ожидание не роняет: с неизвестными правами не закрывается
50
+ ничего.
51
+ - **Метки объявления живут в утилитах домена входа, а не рядом с перехватчиком.** Их ставит
52
+ каждый домен с обработчиками, и ребро к объявлениям дешевле ребра к секрету и хранилищу.
@@ -0,0 +1,49 @@
1
+ ---
2
+ name: platform-access
3
+ kind: rule
4
+ law: frontend-application
5
+ description: Правило под закон «Фронтовое приложение». Брать, когда правка задевает глобальный объект или среду исполнения — окно, глобальную область, признак браузера, хранилище, наблюдатели. Глобальное приходит внедрением, среда проверяется службой, а не наличием глобала. Не действует на серверной стороне. Готовый код — в паттерне platform-access-di. Чем это названо здесь — в implementation.md рядом.
6
+ ---
7
+
8
+ # Окружение браузера — каким приёмом
9
+
10
+ Правило под закон `{{lawsDir}}/frontend-application.md`. Закон говорит, что должно быть верно;
11
+ здесь — каким приёмом прямое обращение к глобальному объекту заменяется. Какими токенами и
12
+ службами это названо и откуда они приходят — `implementation.md` рядом. Состояние —
13
+ `angular-patterns`, файл компонента — `component-structure`, оформление — `styling-bem`, слой
14
+ обращения к серверу — `api-layer`. Все пять под одним законом.
15
+
16
+ Правило про фронт: на серверной стороне своя среда, и ничего из перечисленного к ней не
17
+ относится.
18
+
19
+ ## Когда берётся
20
+
21
+ Правка задевает глобальный объект, признак среды, хранилище браузера или наблюдателя за
22
+ разметкой.
23
+
24
+ ## Что здесь действует
25
+
26
+ - **Глобальный объект приходит внедрением, а не берётся напрямую.** Тип уточняется приведением
27
+ к глобальной области: конструкторы наблюдателей объявлены на ней, а не на интерфейсе окна.
28
+ - **Среда проверяется службой, а не наличием глобала.** Проверка по наличию верна случайно и
29
+ ломается на первой же среде, где глобал подставлен.
30
+ - **Место прямого доступа заводится только с согласия владельца.** Их немного, и каждое
31
+ осознанно: скрипт, работающий до подъёма приложения, обработчик отказа подъёма и код,
32
+ исполняемый внутри страницы в сквозной спеке. Новое в этот список не добавляется молча.
33
+
34
+ ## Паттерны
35
+
36
+ - `platform-access-di` — готовые внедрения, приведение типа, чистые функции, проверка среды.
37
+
38
+ ## Ловушки
39
+
40
+ - **Фабрика токена окна бросает отказ, когда у документа нет представления.** Под отдачей
41
+ страницы сервером представление есть, и внедрение полем класса безопасно, но служба,
42
+ обязанная работать без разметки вовсе, берёт окно внутри метода под проверкой среды.
43
+ - **После правки, добавляющей окно в службу, которая создаётся на подъёме, нужна не только
44
+ сборка, но и поднятый сервер отдачи страниц.** Падение видно только там.
45
+ - **Вокруг хранилища проверка среды не нужна.** Служба хранилища и так уходит в память вне
46
+ браузера, и лишняя проверка вокруг чтения и записи — мёртвый код.
47
+ - **В чистых функциях внедрения нет** — окно принимается параметром, а внедряет его вызывающий.
48
+ - **Подготавливать состояние сквозной спеки записью в хранилище нельзя** — спека проходит те же
49
+ шаги, что и пользователь.
@@ -0,0 +1,69 @@
1
+ ---
2
+ name: reuse-first
3
+ kind: rule
4
+ law: reuse-first
5
+ description: Правило под закон «Единообразие приложения». Брать перед заведением любого нового экрана, компонента, поля, стора, сервиса, переводчика моделей или обработчика — на что опираться, по каким признакам видно, что готовое обошли. Что делать, когда готового не хватило, — в паттерне reuse-first-extend. Чем это названо здесь — в implementation.md рядом.
6
+ ---
7
+
8
+ # Единообразие — каким приёмом
9
+
10
+ Правило под закон `{{lawsDir}}/reuse-first.md`. Закон говорит, что одинаковые вещи ведут себя
11
+ одинаково; здесь — каким приёмом это держится. На какие именно источники вида и основы это
12
+ дерево опирается — `implementation.md` рядом.
13
+
14
+ ## Когда берётся
15
+
16
+ Заведение нового файла: экрана, компонента, поля, стора, сервиса, переводчика моделей,
17
+ обработчика серверной стороны. Правило берётся **до** первой строки, а не после.
18
+
19
+ ## Что здесь действует
20
+
21
+ - **Источник вида выбирается по приложению, а не по привычке.** У дерева может быть больше
22
+ одного источника — свой у каждого приложения; перепутанный приносит на экран форму, которой в
23
+ этом приложении больше нигде нет.
24
+ - **Работа начинается с чтения готового, а не с чистого файла.** Сначала находится опора —
25
+ готовый компонент, базовый класс, образец в соседнем домене, — потом пишется своё поверх неё.
26
+ Соседний домен читается целиком: приём, который кажется новым, обычно уже написан, а
27
+ переименованный при переносе он перестаёт узнаваться.
28
+ - **Свой примитив и своя основа заводятся только с явного одобрения владельца.** Спрашивается
29
+ это до того, как написан первый файл, а не после.
30
+ - **Панель правки записи наследует общую основу, а не собирается своей разметкой.** Тогда она
31
+ открывается, закрывается и спрашивает про несохранённое одинаково во всех разделах.
32
+ - **Об удаче и об отказе сообщает общая шина, а не своя разметка на экране.** Своё сообщение
33
+ расходится с соседним видом, местом и временем показа.
34
+ - **Компонент объявляется отдельными файлами разметки и стилей.** Шаблон и стили внутри
35
+ декоратора, атрибут стиля в разметке и правка размеров привязкой к стилю — это оформление, до
36
+ которого не дотянется ни источник вида, ни линтер стилей.
37
+ - **У компонента экрана файл стилей по умолчанию пустой.** Раскладка объявлена один раз в общем
38
+ слое приложения, а экран её только применяет.
39
+ - **Готовое расширяется, а не клонируется рядом.** Недостающий вариант заводится в источнике
40
+ вида или в базовом классе, и его видят остальные экраны. Клон, написанный рядом, забирает
41
+ правки на себя и расходится с оригиналом с первой же.
42
+
43
+ ## Паттерны
44
+
45
+ - `reuse-first-extend` — что делать, когда готового не хватило: расширить готовое, объявить
46
+ разовое отступление маркером, снять его.
47
+
48
+ ## Признаки, по которым видно, что готовое обошли
49
+
50
+ - в шаблоне фичи стоит нативный элемент ввода, кнопки, выбора, таблицы или диалога;
51
+ - отказ или предупреждение собраны руками — своя область оповещения вместо готового сообщения;
52
+ - в стилях фичи появились перекрытие всего экрана, своя вуаль, слой поверх всего, свои кадры
53
+ вращения или мерцания;
54
+ - в файле стилей экрана объявлена раскладка, а не только его собственные отличия;
55
+ - компонент сам реализует договор поля формы, вместо того чтобы наследовать основу;
56
+ - имя файла кончается на род готового компонента — кнопку, поле, диалог, таблицу — и лежит вне
57
+ источника вида;
58
+ - переводчик моделей переводит поля вручную, минуя общую основу;
59
+ - обработчик серверной стороны объявлен без общей метки.
60
+
61
+ ## Ловушки
62
+
63
+ - **Перенос переизобретением не считается.** Строка, которая уже лежала в дереве, при переезде
64
+ меняет отступ, оставаясь тем же кодом; сверка идёт без отступов, иначе каждый переезд читался
65
+ бы как новый код.
66
+ - **Ответ, данный до чтения образца, образец отменяет.** Согласованная форма переигрывается,
67
+ как только находится готовая: договорённость слабее того, что уже написано и работает.
68
+ - **Подсказка, зовущая за ненаписанным, останавливает работу.** Пока свой вариант не написан,
69
+ правило зовёт за готовым — а не за тем, что «должно появиться».
@@ -0,0 +1,50 @@
1
+ ---
2
+ name: seo
3
+ kind: rule
4
+ law: search-visibility
5
+ description: Правило под закон «Видимость в поиске». Брать при любой правке, доходящей до разметки публичной части — шаблоны страниц, заголовок и описание, структурированные данные, канонический адрес, языковые ссылки, маршруты, карта сайта, правила обхода, конфиг прокси. Готовый код — в паттернах seo-page и seo-verify. Чем это названо здесь — в implementation.md рядом.
6
+ ---
7
+
8
+ # Видимость в поиске — каким приёмом
9
+
10
+ Правило под закон `{{lawsDir}}/search-visibility.md`. Закон говорит, что должно быть верно;
11
+ здесь — каким приёмом это держится. Какие локали набраны, где лежит служба тегов и чем зовётся
12
+ канонический путь — `implementation.md` рядом.
13
+
14
+ ## Когда берётся
15
+
16
+ Любая правка, доходящая до разметки публичной части: шаблон страницы, теги в голове документа,
17
+ структурированные данные, маршруты, карта сайта, правила обхода, конфиг прокси.
18
+
19
+ ## Что здесь действует
20
+
21
+ - **Свои теги помечены собственным атрибутом и при повторном применении переписываются.** Чужое
22
+ в голове документа не трогается: после оживления там остаются теги от отдачи сервером.
23
+ - **Канонический адрес ведёт на локализованный путь**, а не на корень и не на адрес локали по
24
+ умолчанию.
25
+ - **Языковые ссылки строятся по локалям, перевод которых готов**, плюс ссылка на локаль по
26
+ умолчанию. Полный список локалей для этого не годится: переводы содержимого заполняются
27
+ отдельно и готовы не всегда.
28
+ - **Список альтернативных локалей не включает локаль самой страницы** — иначе она объявлена и
29
+ основной, и альтернативной сразу.
30
+ - **Адрес в структурированных данных — канонический адрес самой страницы**, не корень.
31
+ - **Перенаправление с прежнего адреса отдаётся с временем жизни и кэшируется прокси.** Ключ
32
+ кэша строится без строки запроса, поэтому запросы с ней идут мимо кэша.
33
+
34
+ ## Паттерны
35
+
36
+ - `seo-page` — правка разметки страницы: теги, структурированные данные, новый маршрут, новая
37
+ страница в карте сайта.
38
+ - `seo-verify` — проверка отданной разметки на прод-сборке.
39
+
40
+ ## Ловушки
41
+
42
+ - **Тег, добавленный мимо общей службы, не помечен и потому не переписывается.** Он переживёт
43
+ переход между страницами и останется от чужой страницы.
44
+ - **Новый маршрут без ветки под каждую локаль существует только в локали по умолчанию.**
45
+ Остальные адреса отдадут отказ и поисковику, и читателю.
46
+ - **Новая страница не попадает в карту сайта сама** — карта строится из записей, а не из
47
+ маршрутов.
48
+ - **Адрес режется по первому знаку вопроса и только им.** Простой разрез по всем вхождениям
49
+ теряет всё после второго, и перенаправление приходит на страницу без разметки источника —
50
+ источник обращения считается неверно.
@@ -0,0 +1,45 @@
1
+ ---
2
+ name: shared-code
3
+ kind: rule
4
+ law: shared-code
5
+ description: Правило под закон «Общий код приложений». Брать, когда значение должно одинаково пониматься всеми приложениями — предел выборки, набор операторов условия, направление порядка, длина поля, форма запроса и ответа списка. Откуда берётся общее, что считается копией и что ловит проверка повторов. Готовый код — в паттерне shared-code-new. Чем это названо здесь — в implementation.md рядом.
6
+ ---
7
+
8
+ # Общий код — каким приёмом
9
+
10
+ Правило под закон `{{lawsDir}}/shared-code.md`. Закон говорит, что общим быть обязано; здесь —
11
+ каким приёмом это держится. Из какого пакета и какой либы что берётся — `implementation.md`
12
+ рядом.
13
+
14
+ ## Когда берётся
15
+
16
+ Значение, которое должны одинаково понимать разные приложения: число-настройка, набор значений,
17
+ форма запроса и ответа списка, длина поля.
18
+
19
+ ## Что здесь действует
20
+
21
+ - **Число-настройка лежит в общей либе и оттуда берётся всеми сторонами.** Умолчание доводом не
22
+ передаётся: пока довод есть, домен вправе назвать своё число — и называет, расходясь с
23
+ соседним на единицу, которую никто не заметит.
24
+ - **Набор значений из общего пакета заново не объявляется.** Своё перечисление с теми же
25
+ членами считается копией, даже если имена разошлись.
26
+ - **Значение из набора сверяется общей функцией, а промах разбирает вызывающий.** Сервер
27
+ отбивает запрос отказом, экран берёт умолчание: политика на непонятное значение у сторон
28
+ разная, и общей может быть только сверка.
29
+ - **Общим делается лишь то, где политика одна.** Переводчик, у которого стороны читают
30
+ непонятное значение по-разному, общим не становится — он расходится молча.
31
+ - **Перечисления полей порядка и отбора домена копией не считаются.** Они повторяют имена, по
32
+ которым сортирует сервер именно этого домена, и совпадение здесь случайное.
33
+
34
+ ## Паттерны
35
+
36
+ - `shared-code-new` — как завести новое общее число, функцию или тип и не оставить копию.
37
+
38
+ ## Ловушки
39
+
40
+ - **Помощник приведения типов для сверки с набором не годится.** Значение вне набора он пишет в
41
+ журнал и возвращает строкой, то есть глотает ровно тот случай, ради которого сверку и завели.
42
+ - **Накопленные повторы лежат в списке исключений и отказом не считаются.** Гейт падает только
43
+ на новом; список исключений только сокращается.
44
+ - **Проверка не ловит ту же логику, написанную заново под другим именем.** Совпадение она ищет
45
+ по тексту, а не по смыслу.