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/CHANGELOG.md CHANGED
@@ -4,6 +4,7 @@
4
4
 
5
5
  Quick navigation to recent releases:
6
6
 
7
+ - [`2.4.1`](#241--2026-04-26) — Documentation overhaul, 10-language localization, fixture sanitization (post-release docs)
7
8
  - [`2.4.0`](#240--2026-04-25) — Session Continuity Protocol (v2.4 series feature 1 of 3)
8
9
  - [`2.3.3`](#233--2026-04-24) — Template emoji consistency + optional `totalLines` splitter axis
9
10
  - [`2.3.2`](#232--2026-04-23) — `cmdInit` decomposition + UX polish + validator co-evolution
@@ -22,6 +23,56 @@ For older entries scroll past v1.5.0 or use the GitHub blame view.
22
23
 
23
24
  ---
24
25
 
26
+ ## [2.4.1] — 2026-04-26
27
+
28
+ Post-release documentation, full 10-language localization, and test-fixture sanitization. **No source code, no template, and no scanner behavior change** — Pass 1/2/3/4 outputs and validator verdicts are byte-identical to v2.4.0. Test suite remains 736 / 736 pass.
29
+
30
+ ### Documentation overhaul
31
+
32
+ - **Main `README.md` rewrite** — 455 → 514 lines (+59) without losing brevity. Strengthened sections:
33
+ - **Tagline** (1 line → 3 paragraphs): WHAT (value proposition) + HOW (deterministic scanner + 4-pass + 5 validators + path allowlist) + WHERE (12 stacks, monorepos, one `npx` command, resume-safe, idempotent).
34
+ - **"What is this?"** — 3-bullet problem statement → 4-bullet (added centralized-middleware vs scattered `try/catch`), explicit WHY (Claude Code stateless, every session starts fresh), 5-bullet output list (`CLAUDE.md` / `.claude/rules/` / `standard/` / `skills/` / `memory/`), differentiator (`path allowlist` + 5 named validators + language-invariant).
35
+ - **Demo block** (4 collapsible `<details>`) — every excerpt swapped for stronger content from the actual `spring-boot-realworld-example-app` run: `CLAUDE.md` excerpt = Section 1 + 2 (Role Definition + 11-row Project Overview table) instead of Section 4; rule excerpt = `01.controller-rules.md` (REST + GraphQL + ✅/❌ Java examples) instead of `03.data-access-rules.md`; decision-log seed = "Hexagonal ports & adapters with MyBatis-only persistence" (the FIRST decision, with JPA/Hibernate/Spring Data/MyBatis-Plus considered-and-rejected list) instead of CQRS-lite.
36
+ - **"Who is this for?"** — 3-row table → 7-row table covering Solo dev / Team lead / Existing Claude Code user / Onboarding to a new repo / Working in 10 languages / Monorepo user / OSS contributor; "Not a fit if" expanded from 1 to 3 cases.
37
+ - **"How does it work?"** — 1-paragraph summary → **3-stage breakdown**: Step A (scanner — concrete file types read, sensitive-variable redaction list, architecture-pattern classification), Step B (4-pass with each pass's input/output/split rules, including Pass 4 CLAUDE.md immutability), Step C (5 validators each named with their distinct check classes + 3-tier severity).
38
+ - **`CLAUDE.md` slim** — 367 → 162 lines (−65 % size, −58 % bytes). Replaced the 4 000-character single-paragraph v2.3.0 changelog wall with a one-line v2.4.1 summary that points to `CHANGELOG.md`. The 33-row exhaustive Tests table compressed into 7 thematic categories with "read the test file directly for details" pointer (DRY: avoid duplicating per-file fixture details that live in the test source). Architecture data-flow diagram, file-by-file reference, and Code Conventions retained at full fidelity. Added Documentation section listing localized READMEs + `docs/{lang}/` mirrors.
39
+ - **`docs/comparison.md` and 3 other docs corrections** — `docs/architecture.md` `sync-checker` description ("Cross-references between standards and rules" → "Disk files match the `sync-map.json` registrations"); `docs/stacks.md` Vite/Angular port-extraction fabrication removed (scanner does NOT read `vite.config.server.port` nor `angular.json` for port — both are framework-default fallbacks); `docs/verification.md` "sibling project" wording neutralized to "a CLAUDE.md generated with `--lang ja`".
40
+ - **`README.md` fabricated URL removed** — the `https://github.com/affaan-m/everything-claude-code` link in the "Not a fit" section was a guessed URL not present in the v2.3.2 HEAD; removed in favor of an internal pointer to `docs/comparison.md`.
41
+
42
+ ### 10-language localization
43
+
44
+ - **9 localized READMEs (`README.{ko,ja,zh-CN,es,vi,hi,ru,fr,de}.md`)** — full rewrite to match the new 514-line English structure. All 10 READMEs now share identical structural metrics: **514 lines, 14 H2 sections (fence-aware), 28 code fences, 4 `<details>` blocks, 28 inline-code spans matching ±2**. Code blocks (terminal output, CLAUDE.md excerpt, rule excerpt, decision-log seed, mermaid labels) are byte-identical to English across all 10 languages. Only surrounding prose is translated.
45
+ - **9 new `docs/{lang}/` folders** — every non-English README now has a parallel `docs/{lang}/` directory mirroring the 12 English `docs/*.md` files (architecture, stacks, verification, commands, diagrams, memory-layer, safety, manual-installation, advanced-config, comparison, troubleshooting, README index). Total new files: 9 × 12 = **108 docs/ translations** (~25 000 lines of localized prose). Internal cross-links resolve within each language folder; "English original" pointer at the top of each translated doc links back to `../{filename}.md`.
46
+ - **Language-switcher consistency normalized** — all 10 README headers now use the same convention: 9 `· · ·`-separated language links, current-language entry omitted (matching the original English convention). Earlier mixed conventions (some agents had self-link, some had bold-unlinked, some omitted) have been unified.
47
+ - **`docs/vi/troubleshooting.md` broken-link fix** — `[SECURITY.md](../SECURITY.md)` → `[SECURITY.md](../../SECURITY.md)`. The Vietnamese translator agent had copied the English `../SECURITY.md` literal, which resolves correctly from `docs/` but breaks from `docs/vi/`. Other 8 languages' agents got this right via `../../`.
48
+
49
+ ### Test fixture sanitization (real-project fingerprint purge)
50
+
51
+ - **Removed `tests/fixtures/claude-md/observed-ko-bad.md` and `observed-ko-fixed.md`** (17 KB + 15 KB). These two fixtures were anonymized exports from a real internal Vite + React project: file names had been changed to placeholders (`Acme*` instead of the original component prefix), but **structural fingerprints survived the rename and remained identifiable** — multi-entry `VITE_DESKTOP_PORT 3030` / `VITE_MOBILE_PORT 3033` / `VITE_STORYBOOK_PORT 4040` env-var pattern; internal RBAC convention (`buttonAuthorities` prop + `SYS_CODE_CONSTANTS.USE_BTN_AUTH`); `Orval + axios + generated-api-client/` tooling combination; precise package-version triple (TypeScript 5.8.3 + React 19.1.0 + Vite 6.3.5 + sass 1.89 + orval ^8.5.3); desktop/mobile multi-entry split architecture; `createBrowserRouter` + `RouterProvider` desktop-vs-mobile layout pair; the host placeholder `local-dev.example.internal`. None of the per-token name redactions removed the underlying structural pattern, which is sufficient to identify the source repository.
52
+ - **Added synthetic generic replacements** — `tests/fixtures/claude-md/valid-ko.md` (128 lines, ~4 KB) and `bad-ko.md` (148 lines, ~5 KB), modeled identically on the established `valid-ja.md` / `bad-ja.md` shape: generic `sample-project` with Express 4.19 + PostgreSQL 15 + Prisma 5 + TypeScript 5.4 + Vitest, port 3000, no real-world traceable identifiers. Korean test coverage is preserved (valid + §9 anti-pattern detection both still test in Korean), and the 9-error signature for `bad-ko.md` matches `bad-ja.md` / `bad-zh-CN.md` / `bad-es.md` / `bad-hi.md` / `bad-ru.md` exactly (1 S1 + 4 M-* + 4 F2-*).
53
+ - **`tests/claude-md-validator.test.js` updated** to reference the new fixture names (`valid-ko.md` and `bad-ko.md`) and removed the Korean special-case branch (`code === "ko" ? "observed-ko-fixed.md" : ...`); all 10 supported languages now follow the same `valid-{code}.md` pattern.
54
+ - **New hard rule** committed to project memory: `feedback_no-real-project-fingerprints-in-fixtures.md` — fixture sanitization requires structural-pattern removal (ports, RBAC conventions, tooling combinations, package versions, directory splits), not just name token replacement. Protects against regression.
55
+
56
+ ### CHANGELOG strict-English scrub
57
+
58
+ - **52 substitutions of banned terminology categories** — the per-project memory hard rule defines categories (validation-process labels, project-status descriptors) that may not appear in any document; matching phrases were replaced with neutral test-suite vocabulary (`regression testing`, `regression scenario`, `Spring projects`, `Larger enterprise-style YAMLs`, `your project`, etc.). 16 anonymized project-name placeholders (12 frontend + 4 backend variants) were collapsed to two generic `Vite frontend test project` and `Spring backend test project` labels. Restores full compliance with the project memory hard rule.
59
+ - **12 non-English narrative replacements** — Korean, Japanese, and Chinese fragments inside backticked LLM-output examples were replaced with English placeholder descriptions (e.g., `<localized gloss>`, `the localized form of "Memory (L4)" in each script`, `<localized gloss A> / <localized gloss B>` for the two header-translation drift examples). `CHANGELOG.md` is now strict English narrative end to end — the only remaining non-ASCII characters are universal technical typography (em-dashes, mathematical arrows, inequalities, emoji status markers), none of which constitutes "language content".
60
+ - **Two grammatical cleanups** — minor leftover phrasing from the previous terminology pass was tightened (one tense / possessive correction at line 1704; one redundant compound noun simplified at line 1750).
61
+ - **v2.4.0 entry intro test-count corrected** — `Test suite 702 / 702 pass` → `Test suite 736 / 736 pass (final)`. The 702 number was the initial Session-Continuity-Protocol-only state at the top of the v2.4.0 entry; subsequent sub-sections within the same entry already documented the bump to 736 after 15 pipeline robustness fixes. The intro now reflects the final shipped state to avoid reader confusion.
62
+
63
+ ### Repository hygiene
64
+
65
+ - **`claudeos-core/` test artifact removed from repo root** — leftover output from running the tool against itself during functional tests (3 files in `claudeos-core/generated/` + empty `claudeos-core/memory/`). The directory is `.gitignore`d so it was never committed, but removing the on-disk copy keeps the working tree clean.
66
+ - **No code, template, scanner, or validator changes** — `bin/`, `lib/`, `plan-installer/`, `pass-prompts/templates/`, `claude-md-validator/`, `content-validator/`, `pass-json-validator/`, `health-checker/`, `manifest-generator/`, `sync-checker/`, `plan-validator/` are all byte-identical to v2.4.0. `npm test` still passes 736 / 736.
67
+
68
+ ### Verified backward compatibility
69
+
70
+ - **No breaking changes**. CLI surface (`init`, `lint`, `health`, `memory {compact,score,propose-rules}`, `validate`, `restore`, `refresh`) and all flags (`--lang`, `--force`, `--help`, `--version`) are unchanged. Generated CLAUDE.md / `.claude/rules/` / `claudeos-core/standard,skills,guide,database,mcp-guide,memory/` shapes unchanged.
71
+ - **`npm pack` size dropped 41 %** — 618.8 kB → 365.4 kB tarball as a side effect of the Korean / 8-language README slim-down (was 95–130 kB stale content per locale; now 21–32 kB lean and synced).
72
+ - **Test count unchanged**: 736 / 736 pass on Linux / macOS / Windows × Node 18 / 20.
73
+
74
+ ---
75
+
25
76
  ## [2.4.0] — 2026-04-25
26
77
 
27
78
  First feature in the v2.4 series: **Session Continuity Protocol** —
@@ -37,9 +88,12 @@ elements when a session resumes after compact or restart.
37
88
  This release ships only the protocol itself. Two further v2.4
38
89
  features (Self-Check Framework, Common Pattern Taxonomy) are
39
90
  planned but not yet implemented; they will land in subsequent
40
- 2.4.x releases. Test suite 702 / 702 pass (up from 699, +3 new
41
- tests covering positive prose-form, negative H4-form rejection,
42
- and explicit backward-compatibility for pre-v2.4 CLAUDE.md files).
91
+ 2.4.x releases. Test suite final: **736 / 736 pass** (initial
92
+ Session-Continuity-Protocol-only state shipped at 702/702, +3 new
93
+ tests covering positive prose-form, negative H4-form rejection, and
94
+ explicit backward-compatibility for pre-v2.4 CLAUDE.md files;
95
+ the subsequent 15 pipeline robustness fixes documented below
96
+ brought the total to 736).
43
97
 
44
98
  ### Scaffold — Session Resume block in `claude-md-scaffold.md`
45
99
 
package/README.de.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
- **Generieren Sie Claude-Code-Dokumentation automatisch aus Ihrem tatsächlichen Quellcode.** Ein CLI-Tool, das Ihr Projekt statisch analysiert und anschließend eine 4-Pass-Claude-Pipeline ausführt, um `.claude/rules/`, Standards, Skills und Guides zu generieren — damit Claude Code den Konventionen _Ihres_ Projekts folgt, nicht generischen.
10
+ **Sorgen Sie dafür, dass Claude Code beim ersten Versuch den Konventionen IHRES Projekts folgt nicht generischen Defaults.**
11
+
12
+ Ein deterministischer Node.js-Scanner liest zuerst Ihren Code; eine 4-Pass-Claude-Pipeline schreibt anschließend den vollständigen Satz — `CLAUDE.md` + automatisch geladenes `.claude/rules/` + Standards + Skills + L4-Memory. 10 Ausgabesprachen, 5 Post-Generation-Validatoren und eine explizite Pfad-Allowlist, die das LLM daran hindert, Dateien oder Frameworks zu erfinden, die nicht in Ihrem Code stehen.
13
+
14
+ Funktioniert auf [**12 Stacks**](#supported-stacks) (inklusive Monorepos) — ein einziger `npx`-Befehl, ohne Konfiguration, resume-sicher, idempotent.
11
15
 
12
16
  ```bash
13
17
  npx claudeos-core init
@@ -19,18 +23,28 @@ npx claudeos-core init
19
23
 
20
24
  ## Worum geht es?
21
25
 
22
- Sie nutzen Claude Code. Das Tool ist clever, kennt aber **die Konventionen Ihres Projekts** nicht:
23
- - Ihr Team verwendet MyBatis, aber Claude generiert JPA-Code.
24
- - Ihr Wrapper heißt `ApiResponse.ok()`, aber Claude schreibt `ResponseEntity.success()`.
25
- - Ihre Pakete sind `controller/order/`, aber Claude erstellt `order/controller/`.
26
+ Sie nutzen Claude Code. Es ist mächtig, aber jede Sitzung beginnt von vorn — es hat keine Erinnerung daran, wie _Ihr_ Projekt aufgebaut ist. Also fällt es auf „allgemein gute" Defaults zurück, die selten zu dem passen, was Ihr Team tatsächlich tut:
27
+
28
+ - Ihr Team verwendet **MyBatis**, aber Claude generiert JPA-Repositories.
29
+ - Ihr Response-Wrapper ist `ApiResponse.ok()`, aber Claude schreibt `ResponseEntity.success()`.
30
+ - Ihre Pakete sind layer-first (`controller/order/`), aber Claude erstellt domain-first (`order/controller/`).
31
+ - Ihre Fehler laufen durch zentrale Middleware, aber Claude verstreut `try/catch` in jedem Endpoint.
32
+
33
+ Sie hätten gerne pro Projekt einen `.claude/rules/`-Satz — Claude Code lädt ihn automatisch in jeder Sitzung — aber diese Regeln für jedes neue Repo per Hand zu schreiben dauert Stunden, und sie driften, sobald sich der Code weiterentwickelt.
34
+
35
+ **ClaudeOS-Core schreibt sie für Sie, aus Ihrem tatsächlichen Quellcode.** Ein deterministischer Node.js-Scanner liest zuerst Ihr Projekt (Stack, ORM, Paket-Layout, Konventionen, Dateipfade). Anschließend verwandelt eine 4-Pass-Claude-Pipeline die extrahierten Fakten in einen vollständigen Dokumentationssatz:
26
36
 
27
- So verbringen Sie viel Zeit damit, jede generierte Datei nachzubessern.
37
+ - **`CLAUDE.md`** der Projekt-Index, den Claude in jeder Sitzung liest
38
+ - **`.claude/rules/`** — automatisch geladene Regeln pro Kategorie (`00.core` / `10.backend` / `20.frontend` / `30.security-db` / `40.infra` / `60.memory` / `70.domains` / `80.verification`)
39
+ - **`claudeos-core/standard/`** — Referenz-Dokumente (das „Warum" hinter jeder Regel)
40
+ - **`claudeos-core/skills/`** — wiederverwendbare Muster (CRUD-Scaffolding, Seitentemplates)
41
+ - **`claudeos-core/memory/`** — Decision-Log + Failure-Patterns, die mit dem Projekt mitwachsen
28
42
 
29
- **ClaudeOS-Core löst das.** Es scannt Ihren tatsächlichen Quellcode, ermittelt Ihre Konventionen und schreibt einen vollständigen Satz an Regeln in `.claude/rules/` das Verzeichnis, das Claude Code automatisch liest. Wenn Sie das nächste Mal _„Erstelle ein CRUD für Bestellungen"_ sagen, befolgt Claude Ihre Konventionen schon beim ersten Versuch.
43
+ Weil der Scanner Claude eine explizite Pfad-Allowlist übergibt, **kann das LLM keine Dateien oder Frameworks erfinden, die nicht in Ihrem Code stehen**. Fünf Post-Generation-Validatoren (`claude-md-validator`, `content-validator`, `pass-json-validator`, `plan-validator`, `sync-checker`) verifizieren die Ausgabe, bevor sie ausgeliefert wird sprachunabhängig, sodass dieselben Regeln gelten, ob Sie auf Englisch, Deutsch oder in einer von 8 weiteren Sprachen generieren.
30
44
 
31
45
  ```
32
46
  Vorher: Sie → Claude Code → "allgemein guter" Code → manuelle Korrekturen
33
- Nachher: Sie → Claude Code → Code, der zu Ihrem Projekt passt → einsetzbar
47
+ Nachher: Sie → Claude Code → Code, der zu IHREM Projekt passt → einsetzbar
34
48
  ```
35
49
 
36
50
  ---
@@ -119,37 +133,45 @@ Ausgeführt auf [`spring-boot-realworld-example-app`](https://github.com/gothink
119
133
  </details>
120
134
 
121
135
  <details>
122
- <summary><strong>📄 Was in Ihrer <code>CLAUDE.md</code> landet (echter Auszug)</strong></summary>
136
+ <summary><strong>📄 Was in Ihrer <code>CLAUDE.md</code> landet (echter Auszug — 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
- Hinweis: Jede der obigen Aussagen basiert auf dem tatsächlichen QuellcodeKlassennamen, Paketpfade, Konfigurationsschlüssel und auch das Dead-Config-Flag werden vom Scanner extrahiert, bevor Claude die Datei schreibt.
169
+ Jeder Wert oben — die genauen Dependency-Koordinaten, der Dateiname `dev.db`, der Migrationsname `V1__create_tables.sql`, „no JPA"wird vom Scanner aus `build.gradle` / `application.properties` / dem Quellbaum extrahiert, bevor Claude die Datei schreibt. Nichts wird geraten.
148
170
 
149
171
  </details>
150
172
 
151
173
  <details>
152
- <summary><strong>🛡️ Eine real automatisch geladene Regel (<code>.claude/rules/10.backend/03.data-access-rules.md</code>)</strong></summary>
174
+ <summary><strong>🛡️ Eine real automatisch geladene Regel (<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
- Der Glob `paths: ["**/*"]` bedeutet, dass Claude Code diese Regel automatisch lädt, sobald Sie eine beliebige Datei im Projekt bearbeiten. Die ✅/❌-Beispiele stammen direkt aus den tatsächlichen Konventionen und bestehenden Bug-Mustern dieser Codebasis.
231
+ Der Glob `paths: ["**/*"]` bedeutet, dass Claude Code diese Regel automatisch lädt, sobald Sie eine beliebige Datei im Projekt bearbeiten. Jeder Klassenname, Paketpfad und Exception-Handler in der Regel stammt direkt aus dem gescannten Quellcode — einschließlich des tatsächlichen `CustomizeExceptionHandler` und `JacksonCustomizations` des Projekts.
196
232
 
197
233
  </details>
198
234
 
@@ -200,25 +236,26 @@ Der Glob `paths: ["**/*"]` bedeutet, dass Claude Code diese Regel automatisch l
200
236
  <summary><strong>🧠 Ein automatisch generierter <code>decision-log.md</code>-Seed (echter Auszug)</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 befüllt `decision-log.md` mit den aus `pass2-merged.json` extrahierten Architekturentscheidungen, damit zukünftige Sessions sich daran erinnern, _warum_ die Codebasis so aussieht, wie sie aussieht — nicht nur _wie_ sie aussieht.
258
+ Pass 4 befüllt `decision-log.md` mit den aus `pass2-merged.json` extrahierten Architekturentscheidungen, damit zukünftige Sitzungen sich daran erinnern, _warum_ die Codebasis so aussieht, wie sie aussieht — nicht nur _wie_ sie aussieht. Jede Option („JPA/Hibernate", „MyBatis-Plus") und jede Konsequenz ist im tatsächlichen Dependency-Block der `build.gradle` verankert.
222
259
 
223
260
  </details>
224
261
 
@@ -277,13 +314,17 @@ Kategorien, die zwischen `rules/` und `standard/` denselben Zahlen-Präfix teile
277
314
 
278
315
  ## Für wen ist das?
279
316
 
280
- | Sie sind... | Das hilft Ihnen dabei... |
317
+ | Sie sind... | Der Schmerzpunkt, den das Tool beseitigt |
281
318
  |---|---|
282
- | **Solo-Entwickler**, der ein neues Projekt mit Claude Code beginnt | Die Phase „Claude meine Konventionen beibringen" komplett überspringen |
283
- | **Team-Lead**, der gemeinsame Standards pflegt | Die mühsame Arbeit, `.claude/rules/` aktuell zu halten, automatisieren |
284
- | **Bereits ein Claude-Code-Nutzer**, der das Korrigieren generierten Codes leid ist | Claude IHRE Muster befolgen lassen, nicht „allgemein gute" |
319
+ | **Solo-Entwickler**, der ein neues Projekt mit Claude Code beginnt | „Claude in jeder Sitzung meine Konventionen beibringen" vorbei. `CLAUDE.md` + 8-Kategorien-`.claude/rules/` in einem einzigen Lauf generiert. |
320
+ | **Team-Lead**, der gemeinsame Standards über mehrere Repos hinweg pflegt | `.claude/rules/` driften, wenn Leute Pakete umbenennen, ORMs wechseln oder Response-Wrapper ändern. ClaudeOS-Core synchronisiert deterministisch — gleicher Input, byte-identische Ausgabe, kein Diff-Rauschen. |
321
+ | **Bereits Claude-Code-Nutzer**, aber das Korrigieren generierten Codes leid | Falscher Response-Wrapper, falsches Paket-Layout, JPA wo Sie MyBatis nutzen, verstreutes `try/catch` während Ihr Projekt zentrale Middleware verwendet. Der Scanner extrahiert Ihre echten Konventionen; jeder Claude-Pass läuft gegen eine explizite Pfad-Allowlist. |
322
+ | **Onboarding in ein neues Repo** (bestehendes Projekt, Team-Beitritt) | `init` auf dem Repo ausführen und eine lebendige Architekturkarte erhalten: Stack-Tabelle in CLAUDE.md, schichtenweise Regeln mit ✅/❌-Beispielen, Decision-Log mit dem „Warum" hinter wesentlichen Entscheidungen (JPA vs. MyBatis, REST vs. GraphQL etc.). 5 Dateien lesen schlägt 5.000 Quelldateien lesen. |
323
+ | **Arbeiten auf Koreanisch / Japanisch / Chinesisch / 7 weiteren Sprachen** | Die meisten Claude-Code-Regelgeneratoren sind Englisch-only. ClaudeOS-Core schreibt den vollständigen Satz in **10 Sprachen** (`en/ko/ja/zh-CN/es/vi/hi/ru/fr/de`) mit **byte-identischer struktureller Validierung** — gleiches `claude-md-validator`-Verdikt unabhängig von der Ausgabesprache. |
324
+ | **Auf einem Monorepo arbeiten** (Turborepo, pnpm/yarn-Workspaces, Lerna) | Backend- und Frontend-Domänen werden in einem Lauf mit separaten Prompts analysiert; `apps/*/` und `packages/*/` werden automatisch durchlaufen; stackspezifische Regeln werden unter `70.domains/{type}/` emittiert. |
325
+ | **OSS-Beitrag oder Experimente** | Die Ausgabe ist gitignore-freundlich — `claudeos-core/` ist Ihr lokales Arbeitsverzeichnis, nur `CLAUDE.md` + `.claude/` müssen ausgeliefert werden. Resume-sicher bei Unterbrechungen; idempotent bei erneutem Aufruf (Ihre manuellen Regeländerungen überleben ohne `--force`). |
285
326
 
286
- **Nicht passend, wenn:** Sie ein One-Size-Fits-All-Preset-Bundle aus Agents/Skills/Rules wollen, das ohne Scan-Schritt am ersten Tag funktioniert (siehe [docs/de/comparison.md](docs/de/comparison.md), wo was hinpasst), oder Ihr Projekt noch nicht zu einem der [unterstützten Stacks](#supported-stacks) passt.
327
+ **Nicht passend, wenn:** Sie ein One-Size-Fits-All-Preset-Bundle aus Agents/Skills/Rules wollen, das ohne Scan-Schritt am ersten Tag funktioniert (siehe [docs/de/comparison.md](docs/de/comparison.md), wo was hinpasst), Ihr Projekt noch nicht zu einem der [unterstützten Stacks](#supported-stacks) passt, oder Sie nur eine einzelne `CLAUDE.md` benötigen (das eingebaute `claude /init` reicht — keine Notwendigkeit, ein weiteres Tool zu installieren).
287
328
 
288
329
  ---
289
330
 
@@ -296,9 +337,28 @@ ClaudeOS-Core kehrt den üblichen Claude-Code-Workflow um:
296
337
  Hier: Code liest Ihren Stack → Code übergibt bestätigte Fakten an Claude → Claude schreibt Docs aus Fakten
297
338
  ```
298
339
 
299
- Die Kernidee: **Ein Node.js-Scanner liest zuerst Ihren Quellcode** (deterministisch, ohne KI), danach schreibt eine 4-Pass-Claude-Pipeline die Dokumentation, eingeschränkt durch das, was der Scanner gefunden hat. Claude kann keine Pfade oder Frameworks erfinden, die in Ihrem Code nicht tatsächlich existieren.
340
+ Die Pipeline läuft in **drei Stufen**, mit Code auf beiden Seiten des LLM-Aufrufs:
341
+
342
+ **1. Schritt A — Scanner (deterministisch, kein LLM).** Ein Node.js-Scanner durchläuft Ihr Projekt-Root, liest `package.json` / `build.gradle` / `pom.xml` / `pyproject.toml`, parst `.env*`-Dateien (mit Sensitive-Variable-Redaction für `PASSWORD/SECRET/TOKEN/JWT_SECRET/...`), klassifiziert Ihr Architekturmuster (Javas 5 Muster A/B/C/D/E, Kotlin CQRS / Multi-Module, Next.js App- vs. Pages-Router, FSD, Components-Pattern), entdeckt Domänen und baut eine explizite Allowlist jedes existierenden Quelldateipfads. Ausgabe: `project-analysis.json` — die einzige Quelle der Wahrheit für alles, was folgt.
343
+
344
+ **2. Schritt B — 4-Pass-Claude-Pipeline (eingeschränkt durch die Fakten aus Schritt A).**
345
+ - **Pass 1** liest repräsentative Dateien pro Domänengruppe und extrahiert ~50–100 Konventionen pro Domäne — Response-Wrapper, Logging-Bibliotheken, Error-Handling, Naming-Konventionen, Test-Pattern. Läuft einmal pro Domänengruppe (`max 4 domains, 40 files per group`), sodass der Kontext nie überläuft.
346
+ - **Pass 2** führt alle domänenspezifischen Analysen zu einem projektweiten Bild zusammen und löst Widersprüche durch Wahl der dominanten Konvention auf.
347
+ - **Pass 3** schreibt `CLAUDE.md` + `.claude/rules/` + `claudeos-core/standard/` + Skills + Guides — aufgeteilt in Stages (`3a` Facts → `3b-core/3b-N` Rules+Standards → `3c-core/3c-N` Skills+Guides → `3d-aux` Database+MCP-Guide), sodass jeder Stage-Prompt ins LLM-Context-Window passt, selbst wenn `pass2-merged.json` groß ist. Bei ≥16-Domänen-Projekten werden 3b/3c in Batches von ≤15 Domänen unterteilt.
348
+ - **Pass 4** seedet die L4-Memory-Schicht (`decision-log.md`, `failure-patterns.md`, `compaction.md`, `auto-rule-update.md`) und ergänzt universelle Scaffold-Regeln. Pass 4 ist es **untersagt, `CLAUDE.md` zu modifizieren** — Section 8 von Pass 3 ist autoritativ.
349
+
350
+ **3. Schritt C — Verifikation (deterministisch, kein LLM).** Fünf Validatoren prüfen die Ausgabe:
351
+ - `claude-md-validator` — 25 strukturelle Prüfungen auf `CLAUDE.md` (8 Sections, H3/H4-Counts, Memory-File-Eindeutigkeit, T1-Canonical-Heading-Invariante). Sprachunabhängig: gleiches Verdikt unabhängig von `--lang`.
352
+ - `content-validator` — 10 Content-Prüfungen, einschließlich Path-Claim-Verifikation (`STALE_PATH` fängt fabrizierte `src/...`-Referenzen ab) und MANIFEST-Drift-Erkennung.
353
+ - `pass-json-validator` — Pass-1/2/3/4-JSON-Wohlgeformtheit + stack-bewusste Section-Counts.
354
+ - `plan-validator` — Plan-↔-Disk-Konsistenz (Legacy, seit v2.1.0 weitgehend No-Op).
355
+ - `sync-checker` — Disk-↔-`sync-map.json`-Registrierungskonsistenz über 7 nachverfolgte Verzeichnisse hinweg.
356
+
357
+ Drei Schweregrad-Stufen (`fail` / `warn` / `advisory`), damit Warnungen CI niemals wegen LLM-Halluzinationen blockieren, die der Nutzer manuell beheben kann.
358
+
359
+ Die Invariante, die alles zusammenhält: **Claude darf nur Pfade zitieren, die tatsächlich in Ihrem Code existieren**, weil Schritt A eine endliche Allowlist übergibt. Versucht das LLM trotzdem etwas zu erfinden (selten, aber bei bestimmten Seeds möglich), fängt Schritt C es ab, bevor die Docs ausgeliefert werden.
300
360
 
301
- Die vollständige Architektur finden Sie in [docs/de/architecture.md](docs/de/architecture.md).
361
+ Pass-Details, Marker-basiertes Resume, der Staged-Rules-Workaround für den Sensitive-Path-Block von Claude Codes `.claude/` und Stack-Erkennungs-Internals finden Sie in [docs/de/architecture.md](docs/de/architecture.md).
302
362
 
303
363
  ---
304
364