claudeos-core 2.4.0 → 2.4.1

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.ru.md CHANGED
@@ -7,7 +7,11 @@
7
7
  [![license](https://img.shields.io/npm/l/claudeos-core.svg?color=blue)](LICENSE)
8
8
  [![downloads](https://img.shields.io/npm/dm/claudeos-core.svg?logo=npm&color=blue&label=downloads)](https://www.npmjs.com/package/claudeos-core)
9
9
 
10
- **Автоматическая генерация документации Claude Code из вашего реального исходного кода.** CLI-инструмент, который статически анализирует ваш проект, а затем запускает 4-pass конвейер Claude для создания `.claude/rules/`, standards, skills и guides так что Claude Code следует конвенциям **именно вашего** проекта, а не общим.
10
+ **Заставьте Claude Code следовать конвенциям _именно вашего_ проекта с первой попытки — а не общим дефолтам.**
11
+
12
+ Детерминированный Node.js scanner сначала читает ваш код; затем 4-pass конвейер Claude пишет полный набор — `CLAUDE.md` + автоматически загружаемые `.claude/rules/` + standards + skills + L4 memory. 10 языков вывода, 5 post-generation validator-ов и явный path allowlist, не позволяющий LLM выдумывать файлы или фреймворки, отсутствующие в вашем коде.
13
+
14
+ Работает на [**12 стеках**](#supported-stacks) (включая monorepo) — одна команда `npx`, без конфигурации, resume-safe, идемпотентно.
11
15
 
12
16
  ```bash
13
17
  npx claudeos-core init
@@ -19,18 +23,28 @@ npx claudeos-core init
19
23
 
20
24
  ## Что это такое?
21
25
 
22
- Вы используете Claude Code. Он умный, но **не знает конвенций вашего проекта**:
23
- - Ваша команда использует MyBatis, а Claude генерирует код для JPA.
24
- - Ваша обёртка `ApiResponse.ok()`, а Claude пишет `ResponseEntity.success()`.
25
- - Ваши пакеты — `controller/order/`, а Claude создаёт `order/controller/`.
26
+ Вы используете Claude Code. Он мощный, но каждая сессия начинается с нуля — у него нет памяти о том, как устроен _ваш_ проект. Поэтому он откатывается на «в целом хорошие» дефолты, которые редко совпадают с тем, что реально делает ваша команда:
27
+
28
+ - Ваша команда использует **MyBatis**, а Claude генерирует JPA-репозитории.
29
+ - Ваша обёртка для ответов — `ApiResponse.ok()`, а Claude пишет `ResponseEntity.success()`.
30
+ - Ваши пакеты — layer-first (`controller/order/`), а Claude создаёт domain-first (`order/controller/`).
31
+ - Ваши ошибки идут через централизованный middleware, а Claude разбрасывает `try/catch` по каждому endpoint.
32
+
33
+ Хочется иметь набор `.claude/rules/` для каждого проекта — Claude Code автоматически загружает его в каждой сессии — но писать эти rules вручную для каждого нового repo занимает часы, и они расходятся с кодом по мере его эволюции.
34
+
35
+ **ClaudeOS-Core пишет их за вас, прямо из вашего реального исходного кода.** Детерминированный Node.js scanner сначала читает ваш проект (стек, ORM, layout пакетов, конвенции, пути файлов). Затем 4-pass конвейер Claude превращает извлечённые факты в полный набор документации:
26
36
 
27
- Поэтому вы тратите немалую часть времени на правку каждого сгенерированного файла.
37
+ - **`CLAUDE.md`** индекс проекта, который Claude читает в каждой сессии
38
+ - **`.claude/rules/`** — автоматически загружаемые rules по категориям (`00.core` / `10.backend` / `20.frontend` / `30.security-db` / `40.infra` / `60.memory` / `70.domains` / `80.verification`)
39
+ - **`claudeos-core/standard/`** — справочные документы («почему» за каждым rule)
40
+ - **`claudeos-core/skills/`** — переиспользуемые паттерны (CRUD scaffolding, шаблоны страниц)
41
+ - **`claudeos-core/memory/`** — decision log + failure patterns, растущие вместе с проектом
28
42
 
29
- **ClaudeOS-Core решает эту проблему.** Он сканирует ваш реальный исходный код, выясняет ваши конвенции и записывает полный набор правил в `.claude/rules/`каталог, который Claude Code читает автоматически. В следующий раз, когда вы скажете *"Создай CRUD для заказов"*, Claude последует вашим конвенциям с первой попытки.
43
+ Поскольку scanner передаёт Claude явный path allowlist, LLM **не может выдумать файлы или фреймворки, которых нет в вашем коде**. Пять post-generation validator-ов (`claude-md-validator`, `content-validator`, `pass-json-validator`, `plan-validator`, `sync-checker`) проверяют вывод до отправки language-invariant, поэтому одни и те же правила применяются независимо от того, генерируете ли вы на английском, русском или одном из 8 других языков.
30
44
 
31
45
  ```
32
- До: Вы → Claude Code → "в целом хороший" код → правка вручную
33
- После: Вы → Claude Code → код, соответствующий вашему проекту → используйте как есть
46
+ До: Вы → Claude Code → "в целом хороший" код → ручные правки каждый раз
47
+ После: Вы → Claude Code → код, соответствующий ВАШЕМУ проекту → используйте как есть
34
48
  ```
35
49
 
36
50
  ---
@@ -119,37 +133,45 @@ npx claudeos-core init
119
133
  </details>
120
134
 
121
135
  <details>
122
- <summary><strong>📄 Что попадает в ваш <code>CLAUDE.md</code> (реальный фрагмент)</strong></summary>
136
+ <summary><strong>📄 Что попадает в ваш <code>CLAUDE.md</code> (реальный фрагмент — Section 1 + 2)</strong></summary>
123
137
 
124
138
  ```markdown
125
- ## 4. Core Architecture
126
-
127
- ### Core Patterns
128
-
129
- - **Hexagonal ports & adapters**: domain ports live in `io.spring.core.{aggregate}`
130
- and are implemented by `io.spring.infrastructure.repository.MyBatis{Aggregate}Repository`.
131
- The domain layer has zero MyBatis imports.
132
- - **CQRS-lite read/write split (same DB)**: write side goes through repository ports
133
- + entities; read side is a separate `readservice` package whose `@Mapper`
134
- interfaces return `*Data` DTOs directly (no entity hydration).
135
- - **No aggregator/orchestrator layer**: multi-source orchestration happens inside
136
- application services (e.g., `ArticleQueryService`); there is no `*Aggregator`
137
- class in the codebase.
138
- - **Application-supplied UUIDs**: entity constructors assign their own UUID; PK is
139
- passed via `#{user.id}` on INSERT. The global
140
- `mybatis.configuration.use-generated-keys=true` flag is dead config
141
- (auto-increment is unused).
142
- - **JWT HS512 authentication**: `io.spring.infrastructure.service.DefaultJwtService`
143
- is the sole token subject in/out; `io.spring.api.security.JwtTokenFilter`
144
- extracts the token at the servlet layer.
139
+ # CLAUDE.md spring-boot-realworld-example-app
140
+
141
+ > Reference implementation of the RealWorld backend specification on
142
+ > Java 11 + Spring Boot 2.6, exposing both REST and GraphQL endpoints
143
+ > over a hexagonal MyBatis persistence layer.
144
+
145
+ ## 1. Role Definition
146
+
147
+ As the senior developer for this repository, you are responsible for
148
+ writing, modifying, and reviewing code. Responses must be written in English.
149
+ A Java Spring Boot REST + GraphQL API server organized around a hexagonal
150
+ (ports & adapters) architecture, with a CQRS-lite read/write split inside
151
+ an XML-driven MyBatis persistence layer and JWT-based authentication.
152
+
153
+ ## 2. Project Overview
154
+
155
+ | Item | Value |
156
+ |---|---|
157
+ | Language | Java 11 |
158
+ | Framework | Spring Boot 2.6.3 |
159
+ | Build Tool | Gradle (Groovy DSL) |
160
+ | Persistence | MyBatis 3 via `mybatis-spring-boot-starter:2.2.2` (no JPA) |
161
+ | Database | SQLite (`org.xerial:sqlite-jdbc:3.36.0.3`) — `dev.db` (default), `:memory:` (test) |
162
+ | Migration | Flyway — single baseline `V1__create_tables.sql` |
163
+ | API Style | REST (`io.spring.api.*`) + GraphQL via Netflix DGS `:4.9.21` |
164
+ | Authentication | JWT HS512 (`jjwt-api:0.11.2`) + Spring Security `PasswordEncoder` |
165
+ | Server Port | 8080 (default) |
166
+ | Test Stack | JUnit Jupiter 5, Mockito, AssertJ, rest-assured, spring-mock-mvc |
145
167
  ```
146
168
 
147
- Примечание: каждое утверждение выше основано на реальном исходном коде имена классов, пути пакетов, ключи конфигурации и флаг dead-config извлечены сканером ещё до того, как Claude начал писать файл.
169
+ Каждое значение выше точные координаты зависимостей, имя файла `dev.db`, имя миграции `V1__create_tables.sql`, «no JPA» извлечено сканером из `build.gradle` / `application.properties` / дерева исходников ещё до того, как Claude начал писать файл. Ничего не угадано.
148
170
 
149
171
  </details>
150
172
 
151
173
  <details>
152
- <summary><strong>🛡️ Реальное автоматически загружаемое правило (<code>.claude/rules/10.backend/03.data-access-rules.md</code>)</strong></summary>
174
+ <summary><strong>🛡️ Реальное автоматически загружаемое правило (<code>.claude/rules/10.backend/01.controller-rules.md</code>)</strong></summary>
153
175
 
154
176
  ````markdown
155
177
  ---
@@ -157,42 +179,56 @@ paths:
157
179
  - "**/*"
158
180
  ---
159
181
 
160
- # Data Access Rules
182
+ # Controller Rules
183
+
184
+ ## REST (`io.spring.api.*`)
161
185
 
162
- ## XML-only SQL
163
- - Every SQL statement lives in `src/main/resources/mapper/*.xml`.
164
- NO `@Select` / `@Insert` / `@Update` / `@Delete` annotations on `@Mapper` methods.
165
- - Each `@Mapper` interface has exactly one XML file at
166
- `src/main/resources/mapper/{InterfaceName}.xml`.
167
- - `<mapper namespace="...">` MUST be the fully qualified Java interface name.
168
- The single existing exception is `TransferData.xml` (free-form `transfer.data`).
186
+ - Controllers are the SOLE response wrapper for HTTP — no aggregator/facade above them.
187
+ Return `ResponseEntity<?>` or a body Spring serializes via `JacksonCustomizations`.
188
+ - Each controller method calls exactly ONE application service method. Multi-source
189
+ composition lives in the application service.
190
+ - Controllers MUST NOT import `io.spring.infrastructure.*`. No direct `@Mapper` access.
191
+ - Validate command-param arguments with `@Valid`. Custom JSR-303 constraints live under
192
+ `io.spring.application.{aggregate}.*`.
193
+ - Resolve the current user via `@AuthenticationPrincipal User`.
194
+ - Let exceptions propagate to `io.spring.api.exception.CustomizeExceptionHandler`
195
+ (`@ControllerAdvice`). Do NOT `try/catch` business exceptions inside the controller.
169
196
 
170
- ## Dynamic SQL
171
- - `<if>` predicates MUST guard both null and empty:
172
- `<if test="X != null and X != ''">`. Empty-only is the existing HIGH-severity bug pattern.
173
- - Prefer `LIMIT n OFFSET m` over MySQL-style `LIMIT m, n`.
197
+ ## GraphQL (`io.spring.graphql.*`)
198
+
199
+ - DGS components (`@DgsComponent`) are the sole GraphQL response wrappers.
200
+ Use `@DgsQuery` / `@DgsData` / `@DgsMutation`.
201
+ - Resolve the current user via `io.spring.graphql.SecurityUtil.getCurrentUser()`.
174
202
 
175
203
  ## Examples
176
204
 
177
205
  ✅ Correct:
178
- ```xml
179
- <update id="update">
180
- UPDATE articles
181
- <set>
182
- <if test="article.title != null and article.title != ''">title = #{article.title},</if>
183
- updated_at = #{article.updatedAt}
184
- </set>
185
- WHERE id = #{article.id}
186
- </update>
206
+ ```java
207
+ @PostMapping
208
+ public ResponseEntity<?> createArticle(@AuthenticationPrincipal User user,
209
+ @Valid @RequestBody NewArticleParam param) {
210
+ Article article = articleCommandService.createArticle(param, user);
211
+ ArticleData data = articleQueryService.findById(article.getId(), user)
212
+ .orElseThrow(ResourceNotFoundException::new);
213
+ return ResponseEntity.ok(Map.of("article", data));
214
+ }
187
215
  ```
188
216
 
189
217
  ❌ Incorrect:
190
- ```xml
191
- <mapper namespace="article.mapper"> <!-- NO — namespace MUST be FQCN -->
218
+ ```java
219
+ @PostMapping
220
+ public ResponseEntity<?> create(@RequestBody NewArticleParam p) {
221
+ try {
222
+ articleCommandService.createArticle(p, currentUser);
223
+ } catch (Exception e) { // NO — let CustomizeExceptionHandler handle it
224
+ return ResponseEntity.status(500).body(e.getMessage()); // NO — leaks raw message
225
+ }
226
+ return ResponseEntity.ok().build();
227
+ }
192
228
  ```
193
229
  ````
194
230
 
195
- Glob `paths: ["**/*"]` означает, что Claude Code автоматически загружает это правило при редактировании любого файла в проекте. Примеры ✅/❌ берутся прямо из реальных конвенций этой кодовой базы и существующих паттернов багов.
231
+ Glob `paths: ["**/*"]` означает, что Claude Code автоматически загружает это правило при редактировании любого файла в проекте. Каждое имя класса, путь пакета и exception handler в правиле берутся прямо из просканированного кода включая реальные `CustomizeExceptionHandler` и `JacksonCustomizations` этого проекта.
196
232
 
197
233
  </details>
198
234
 
@@ -200,25 +236,26 @@ Glob `paths: ["**/*"]` означает, что Claude Code автоматиче
200
236
  <summary><strong>🧠 Автоматически сгенерированный сид <code>decision-log.md</code> (реальный фрагмент)</strong></summary>
201
237
 
202
238
  ```markdown
203
- ## 2026-04-26 — CQRS-lite read/write split inside the persistence layer
204
-
205
- - **Context:** Writes go through `core.*Repository` port → `MyBatis*Repository`
206
- adapter → `io.spring.infrastructure.mybatis.mapper.{Aggregate}Mapper`.
207
- Reads bypass the domain port: application service →
208
- `io.spring.infrastructure.mybatis.readservice.{Concept}ReadService` directly,
209
- returning flat `*Data` DTOs from `io.spring.application.data.*`.
210
- - **Options considered:** Single repository surface returning hydrated entities
211
- for both reads and writes.
212
- - **Decision:** Same database, two `@Mapper` packages — `mapper/` (write side,
213
- operates on core entities) and `readservice/` (read side, returns `*Data` DTOs).
214
- Read DTOs avoid entity hydration overhead.
215
- - **Consequences:** Reads are NOT routed through the domain port this is
216
- intentional, not a bug. Application services may inject both a `*Repository`
217
- (writes) and one or more `*ReadService` interfaces (reads) at the same time.
218
- Do NOT add hydrate-then-map glue in the read path.
239
+ ## 2026-04-26 — Hexagonal ports & adapters with MyBatis-only persistence
240
+
241
+ - **Context:** `io.spring.core.*` exposes `*Repository` ports (e.g.,
242
+ `io.spring.core.article.ArticleRepository`) implemented by
243
+ `io.spring.infrastructure.repository.MyBatis*Repository` adapters.
244
+ The domain layer has zero `org.springframework.*` /
245
+ `org.apache.ibatis.*` / `io.spring.infrastructure.*` imports.
246
+ - **Options considered:** JPA/Hibernate, Spring Data, MyBatis-Plus
247
+ `BaseMapper`. None adopted.
248
+ - **Decision:** MyBatis 3 (`mybatis-spring-boot-starter:2.2.2`) with
249
+ hand-written XML statements under `src/main/resources/mapper/*.xml`.
250
+ Hexagonal port/adapter wiring keeps the domain framework-free.
251
+ - **Consequences:** Every SQL lives in XML`@Select`/`@Insert`/`@Update`/`@Delete`
252
+ annotations are forbidden. New aggregates require both a
253
+ `core.{aggregate}.{Aggregate}Repository` port AND a
254
+ `MyBatis{Aggregate}Repository` adapter; introducing a JPA repository would
255
+ split the persistence model.
219
256
  ```
220
257
 
221
- Pass 4 заполняет `decision-log.md` архитектурными решениями, извлечёнными из `pass2-merged.json`, чтобы будущие сессии помнили *почему* кодовая база выглядит так, а не только *как* она выглядит.
258
+ Pass 4 заполняет `decision-log.md` архитектурными решениями, извлечёнными из `pass2-merged.json`, чтобы будущие сессии помнили *почему* кодовая база выглядит так, как выглядит — не только *как* она выглядит. Каждый рассмотренный вариант («JPA/Hibernate», «MyBatis-Plus») и каждое следствие основаны на реальном блоке зависимостей `build.gradle`.
222
259
 
223
260
  </details>
224
261
 
@@ -277,13 +314,17 @@ your-project/
277
314
 
278
315
  ## Кому это подходит?
279
316
 
280
- | Если вы... | Это поможет вам... |
317
+ | Если вы... | Боль, которую это снимает |
281
318
  |---|---|
282
- | **Соло-разработчик**, начинающий новый проект с Claude Code | Полностью пропустить фазу "учим Claude нашим конвенциям" |
283
- | **Тимлид**, поддерживающий общие стандарты | Автоматизировать рутину поддержания `.claude/rules/` в актуальном состоянии |
284
- | **Уже использующий Claude Code**, но устал править генерируемый код | Заставить Claude следовать ВАШИМ паттернам, а не целом хорошим" |
319
+ | **Соло-разработчик**, начинающий новый проект с Claude Code | «Учить Claude нашим конвенциям каждую сессию» — больше нет. `CLAUDE.md` + 8-категорийные `.claude/rules/` сгенерированы за один проход. |
320
+ | **Тимлид**, поддерживающий общие стандарты в нескольких repo | `.claude/rules/` расходятся по мере того, как люди переименовывают пакеты, меняют ORM или response wrapper. ClaudeOS-Core пере-синхронизирует детерминированно — один и тот же вход → byte-identical вывод, без diff-шума. |
321
+ | **Уже использующий Claude Code**, но устал править генерируемый код | Неправильный response wrapper, неправильный layout пакетов, JPA вместо MyBatis, `try/catch` повсюду, когда у вас централизованный middleware. Scanner извлекает ваши реальные конвенции; каждый pass Claude работает с явным path allowlist. |
322
+ | **Onboarding на новый repo** (существующий проект, вход в команду) | Запустите `init` на repo и получите живую architecture map: stack-таблица в CLAUDE.md, rules по слоям с примерами ✅/❌, decision log, заполненный «почему» за крупными выборами (JPA vs MyBatis, REST vs GraphQL и т. д.). Прочитать 5 файлов лучше, чем 5000 файлов исходников. |
323
+ | **Работающий на корейском / японском / китайском / ещё 7 языках** | Большинство генераторов rules для Claude Code — только английский. ClaudeOS-Core пишет полный набор на **10 языках** (`en/ko/ja/zh-CN/es/vi/hi/ru/fr/de`) с **byte-identical структурной валидацией** — одинаковый verdict `claude-md-validator` независимо от языка вывода. |
324
+ | **Работающий на monorepo** (Turborepo, pnpm/yarn workspaces, Lerna) | Backend- и frontend-домены анализируются в одном запуске разными промптами; `apps/*/` и `packages/*/` обходятся автоматически; per-stack rules emit-ятся под `70.domains/{type}/`. |
325
+ | **Контрибьютор OSS или экспериментатор** | Вывод gitignore-friendly — `claudeos-core/` это ваш локальный рабочий каталог, отправлять нужно только `CLAUDE.md` + `.claude/`. Resume-safe при прерывании; идемпотентно при повторных запусках (ваши ручные правки rules сохраняются без `--force`). |
285
326
 
286
- **Не подходит, если:** вы хотите универсальный preset bundle из agents/skills/rules, который работает с первого дня без шага сканирования (см. [docs/ru/comparison.md](docs/ru/comparison.md) — что под какие задачи подходит), либо ваш проект пока не вписывается в один из [поддерживаемых стеков](#supported-stacks).
327
+ **Не подходит, если:** вы хотите универсальный preset bundle из agents/skills/rules, который работает с первого дня без шага сканирования (см. [docs/ru/comparison.md](docs/ru/comparison.md) — что под какие задачи подходит), либо ваш проект пока не вписывается в один из [поддерживаемых стеков](#supported-stacks), либо вам нужен только один `CLAUDE.md` (встроенного `claude /init` достаточно — нет необходимости устанавливать ещё один инструмент).
287
328
 
288
329
  ---
289
330
 
@@ -296,9 +337,28 @@ ClaudeOS-Core инвертирует обычный workflow Claude Code:
296
337
  Здесь: Код читает ваш стек → Код передаёт подтверждённые факты Claude → Claude пишет docs из фактов
297
338
  ```
298
339
 
299
- Ключевая идея: **Node.js scanner сначала читает ваш исходный код** (детерминированно, без AI), а затем 4-pass конвейер Claude пишет документацию, ограниченную тем, что обнаружил сканер. Claude не может выдумать пути или фреймворки, которых на самом деле нет в вашем коде.
340
+ Конвейер выполняется в **три стадии**, с кодом по обе стороны от LLM-вызова:
341
+
342
+ **1. Шаг A — Scanner (детерминированно, без LLM).** Node.js scanner обходит корень проекта, читает `package.json` / `build.gradle` / `pom.xml` / `pyproject.toml`, парсит файлы `.env*` (с redaction чувствительных переменных вроде `PASSWORD/SECRET/TOKEN/JWT_SECRET/...`), классифицирует архитектурный паттерн (5 паттернов Java A/B/C/D/E, Kotlin CQRS / multi-module, Next.js App vs. Pages Router, FSD, components-pattern), обнаруживает домены и строит явный allowlist всех существующих путей к исходникам. Вывод: `project-analysis.json` — единственный source of truth для всего, что следует дальше.
343
+
344
+ **2. Шаг B — 4-Pass Claude конвейер (ограничен фактами шага A).**
345
+ - **Pass 1** читает репрезентативные файлы по группам доменов и извлекает ~50–100 конвенций на домен — response wrapper, logging library, error handling, naming convention, test pattern. Запускается один раз на группу доменов (`max 4 domains, 40 files per group`), так что context никогда не переполняется.
346
+ - **Pass 2** объединяет весь per-domain анализ в общую картину проекта и разрешает разногласия, выбирая доминирующую конвенцию.
347
+ - **Pass 3** пишет `CLAUDE.md` + `.claude/rules/` + `claudeos-core/standard/` + skills + guides — разбит на стадии (`3a` facts → `3b-core/3b-N` rules+standards → `3c-core/3c-N` skills+guides → `3d-aux` database+mcp-guide), так что промпт каждой стадии помещается в context window LLM, даже когда `pass2-merged.json` большой. Sub-divides 3b/3c в batch-и по ≤15 доменов для проектов с ≥16 доменами.
348
+ - **Pass 4** заполняет L4 memory layer (`decision-log.md`, `failure-patterns.md`, `compaction.md`, `auto-rule-update.md`) и добавляет универсальные scaffold rules. Pass 4 **запрещено модифицировать `CLAUDE.md`** — Section 8 Pass 3 авторитетна.
349
+
350
+ **3. Шаг C — Верификация (детерминированно, без LLM).** Пять validator-ов проверяют вывод:
351
+ - `claude-md-validator` — 25 структурных проверок `CLAUDE.md` (8 sections, H3/H4 counts, memory file uniqueness, T1 canonical heading invariant). Language-invariant: тот же verdict независимо от `--lang`.
352
+ - `content-validator` — 10 content-проверок, включая path-claim верификацию (`STALE_PATH` ловит выдуманные ссылки `src/...`) и MANIFEST drift detection.
353
+ - `pass-json-validator` — well-formedness JSON Pass 1/2/3/4 + stack-aware section count.
354
+ - `plan-validator` — консистентность plan ↔ disk (legacy, в основном no-op с v2.1.0).
355
+ - `sync-checker` — консистентность регистраций disk ↔ `sync-map.json` по 7 отслеживаемым каталогам.
356
+
357
+ Три уровня severity (`fail` / `warn` / `advisory`), так что warning-и не блокируют CI на LLM-галлюцинациях, которые пользователь может починить вручную.
358
+
359
+ Инвариант, связывающий всё вместе: **Claude может цитировать только пути, реально существующие в вашем коде**, потому что шаг A передаёт ему конечный allowlist. Если LLM всё-таки попытается что-то выдумать (редко, но случается на определённых seed), шаг C ловит это до отправки docs.
300
360
 
301
- Полное описание архитектуры см. в [docs/ru/architecture.md](docs/ru/architecture.md).
361
+ Подробности по pass-ам, marker-based resume, обходной путь staged-rules для блока чувствительных путей `.claude/` в Claude Code и внутренности обнаружения стека — см. [docs/ru/architecture.md](docs/ru/architecture.md).
302
362
 
303
363
  ---
304
364