claudeos-core 2.4.4 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/CHANGELOG.md +81 -0
  2. package/README.de.md +9 -9
  3. package/README.es.md +9 -9
  4. package/README.fr.md +9 -9
  5. package/README.hi.md +9 -9
  6. package/README.ja.md +9 -9
  7. package/README.ko.md +9 -9
  8. package/README.md +9 -9
  9. package/README.ru.md +9 -9
  10. package/README.vi.md +9 -9
  11. package/README.zh-CN.md +9 -9
  12. package/bin/commands/init.js +121 -24
  13. package/bin/commands/lint.js +2 -0
  14. package/bin/commands/memory.js +10 -3
  15. package/content-validator/index.js +82 -13
  16. package/lib/env-parser.js +50 -12
  17. package/lib/memory-scaffold.js +35 -16
  18. package/manifest-generator/index.js +15 -4
  19. package/package.json +1 -1
  20. package/pass-prompts/templates/angular/pass3.md +2 -1
  21. package/pass-prompts/templates/common/claude-md-scaffold.md +1 -1
  22. package/pass-prompts/templates/common/pass3a-facts.md +11 -9
  23. package/pass-prompts/templates/common/pass4.md +3 -3
  24. package/pass-prompts/templates/java-spring/pass3.md +3 -3
  25. package/pass-prompts/templates/kotlin-spring/pass3.md +2 -2
  26. package/pass-prompts/templates/node-express/pass3.md +1 -1
  27. package/pass-prompts/templates/node-fastify/pass3.md +1 -0
  28. package/pass-prompts/templates/node-nestjs/pass3.md +1 -0
  29. package/pass-prompts/templates/node-nextjs/pass3.md +1 -1
  30. package/pass-prompts/templates/node-vite/pass3.md +1 -0
  31. package/pass-prompts/templates/python-django/pass3.md +1 -1
  32. package/pass-prompts/templates/python-fastapi/pass3.md +1 -1
  33. package/pass-prompts/templates/python-flask/pass3.md +1 -0
  34. package/pass-prompts/templates/vue-nuxt/pass3.md +1 -0
  35. package/plan-installer/domain-grouper.js +4 -1
  36. package/plan-installer/index.js +26 -7
  37. package/plan-installer/pass3-context-builder.js +10 -0
  38. package/plan-installer/prompt-generator.js +18 -2
  39. package/plan-installer/scanners/scan-frontend.js +67 -6
  40. package/plan-installer/scanners/scan-java.js +145 -14
  41. package/plan-installer/scanners/scan-kotlin.js +68 -3
  42. package/plan-installer/scanners/scan-node.js +115 -0
  43. package/plan-installer/scanners/scan-python.js +56 -0
  44. package/plan-installer/source-paths.js +61 -0
  45. package/plan-installer/stack-detector.js +262 -24
  46. package/plan-installer/structure-scanner.js +15 -4
package/CHANGELOG.md CHANGED
@@ -4,6 +4,7 @@
4
4
 
5
5
  Quick navigation to recent releases:
6
6
 
7
+ - [`2.5.0`](#250--2026-09-07) — Correctness release: append-only `decision-log.md`, read-only `health`, user-owned rules survive `--force`, flat-layout Java detection, Java multi-module + Next.js route groups, orchestrator-written path allowlist, `.env` credential masking
7
8
  - [`2.4.4`](#244--2026-05-04) — Translation polish for `docs/{lang}/` × 8 non-Korean languages + broken `#quick-start` anchor fix
8
9
  - [`2.4.3`](#243--2026-04-27) — Skills catalog reconciliation (MANIFEST ↔ §6 sync) + `STALE_PATH` naming-convention placeholder exemption
9
10
  - [`2.4.2`](#242--2026-04-26) — README structural tightening + 9-language re-sync (same-day after v2.4.1 docs overhaul)
@@ -26,6 +27,86 @@ For older entries scroll past v1.5.0 or use the GitHub blame view.
26
27
 
27
28
  ---
28
29
 
30
+ ## [2.5.0] — 2026-09-07
31
+
32
+ Correctness release driven by a full-source audit of v2.4.4. No new dependencies, no new files. `project-analysis.json` gains optional, additive fields only (`stack.frontendRoot`, `stack.frontendBundler`, `stack.frontendPort`, `stack.frontendEnvInfo`, domain `pattern: "layer-first"`); pass-marker schemas are unchanged. Minor version bump because five behaviors that users could observe changed on purpose (see **Behavior changes** and **Migration**). Test suite: 736 → **825 / 825** pass (89 added, 2 legacy assertions replaced).
33
+
34
+ ### Fixed — data loss / safety
35
+
36
+ - **`memory compact` no longer touches `decision-log.md`.** Stage 1 ("summarize aged entries") dropped the Context / Options / Decision / Consequences body of every entry older than 30 days — i.e. the "why" the file exists to preserve — while the generated `60.memory/01.decision-log.md` rule and CLAUDE.md §8 promised "permanent, append-only". Pass 4 seeds 3–5 entries dated today, so every project hit this on its first compaction after a month. Compaction now applies to `failure-patterns.md` only; `decision-log.md` is logged as "append-only, never compacted". Scaffold text (`compaction.md`, `60.memory/03.compaction.md`, `pass4.md`) and `docs/commands.md` updated to match.
37
+ - **`npx claudeos-core health` is read-only again.** Since v2.4.3, `health` → `manifest-generator` → `skills-sync` silently patched `CLAUDE.md` §6 and `MANIFEST.md`. A gate documented for CI / pre-commit must not dirty the working tree. Skills reconciliation now runs only when `manifest-generator` is invoked with the `--sync-skills` flag; `init` passes it after Pass 3/4, `health` does not. There is deliberately no environment-variable switch — `health` spawns `manifest-generator` with the inherited environment, so an exported variable would have re-enabled writes from a shell that set it for `init`.
38
+ - **`--force` / "fresh" preserve user-owned files under `.claude/rules/`.** Previously the whole directory was `rmSync`'d, including rule files the user had written before ever running claudeos-core. Only the claudeos-core-managed `NN.` category *directories* (`00.core/` … `90.optional/`) are wiped now (`wipeManagedRuleCategories()`, exported and unit-tested); a `NN.`-prefixed *file* at the rules root (`.claude/rules/01.team-style.md`) is user-authored — the tool never writes one there — and survives. Guard 2 (zero-rules detection) counts only those categories so a preserved user file cannot mask a silent Pass 3 failure.
39
+ - **`.env` credential masking is complete.** The `DATABASE_URL` redaction exemption is gone — its stated justification ("stack-detector reads it") was stale (stack-detector scans raw `.env` text and never reads `envInfo.vars`), while `postgres://user:password@host/db` was written verbatim into `project-analysis.json`, which Pass 3/4 prompts instruct the model to read. Every URL-shaped value (`DATABASE_URL`, `REDIS_URL`, `MONGO_URI`, `jdbc:postgresql://…`, …) now has its userinfo masked to `***:***` with scheme / host / path intact; `envInfo.host` and `envInfo.apiTarget` are masked the same way. Userinfo is everything between `://` and the last `@` of the authority, so a password containing `@` (`p@ss`) is masked whole; it may not contain `/`, `?` or `#`, so an `@` in a path or query (`https://cdn.example.com/npm/@scope/pkg`, `/users/@me`, `?redirect=user@host`) is never rewritten and the real host is never replaced. Scheme-less credentials are recognized only in the Go/MySQL DSN shape (`user:pw@tcp(db:3306)/db`, `@unix(…)`) — a generic `a:b@c` rule would corrupt `mailto:ops@example.com` or `0:30@daily`. A raw `/` inside a password is not a valid URL and is deliberately left alone. Credentials carried as connection *parameters* are masked as well — `?password=` / `;password=` / `pwd` / `secret` / `token` / `access_key` / `api_key` values become `***` with the parameter name kept (`jdbc:postgresql://db/app?user=app&password=***`, `sqlserver://host;user=sa;password=***`), and a Go DSN password containing `@` (`user:p@ss@tcp(h:3306)/db`) is masked whole.
40
+ - **CI time bomb.** `tests/memory-command.test.js` carried five hard-coded `2026-04-xx` dates; from 2026-05-17 one assertion aged past the 30-day compaction window and CI went red. All five use a relative `daysAgo(n)` helper now.
41
+ - **Stale translations in the static-fallback cache.** `claudeos-core/generated/fallback-cache-<lang>.json` was keyed by content *name* (`MEMORY_FILES.compaction.md`), so once a project had a cache, every later change to a static-fallback text (this release changes three: `compaction.md`, `60.memory/03.compaction.md`, `52.ai-work-rules.md`) kept serving the translation of the old English text. Keys now include a hash of the English source (`<name>@<sha1[0:12]>`); a text change is a cache miss automatically and pre-v2.5.0 entries are never read again (they stay in the file, unused).
42
+
43
+ ### Fixed — detection accuracy
44
+
45
+ - **Flat Spring Initializr layout (`com/example/demo/controller/*.java`) is Pattern C, not "Pattern B with one domain named `demo`".** The Pattern B glob `**/*/controller/*.java` always matched the root package's last segment, making Pattern C unreachable for every real Java project. A path counts as flat only when its layer dir is a direct child of the base package **and** no layer-class stem under it starts with that package segment — so single-domain domain-first projects (`payment/controller/PaymentController.java`) stay Pattern B. The Pattern C test now asserts exact domain names instead of `>= 1`. The stem test looks at *every* layer class under the base package (controller, service, mapper, repository, dao, dto), so a single-domain project such as `account/{controller/LoginController, service/AccountService, dto/LoginDto}` stays Pattern B `account` because `AccountService` is named after the package; a `*Application.java` sitting directly in the base package is a positive flat signal on its own (Initializr places it there). Inside a Gradle/Maven module the module's own sub-package (`api/src/main/java/com/example/api/controller/`) is treated like the Initializr base package, so `com.example.api` / `com.example.core` modules yield `user` / `order` rather than a pseudo-domain named after the module. The directory holding the Spring Boot main class (`*Application.java`) is always a base package regardless of the 4-segment `rootPackage` cap, so a 5-segment Initializr base package (`kr/co/<org>/<proj>/<app>`) is classified flat as well. *Known limit:* a single-domain project in which *no* layer class shares the package name (`auth/{controller/LoginController, service/TokenService}`) is read as flat and yields `login` / `token`. Controllers the flat test skips in a tree that another pattern claims are re-attached by class name (Pattern C entries alongside the Pattern B/D/E ones).
46
+ - **Java multi-module Gradle.** Root `build.gradle` with `id 'org.springframework.boot' … apply false` (plugin id, no `spring-boot` coordinate) is now recognized; when the root declares nothing, sub-module `build.gradle{,.kts}` files (≤30) are swept for the Java plugin / Spring Boot coordinates, framework version and Java version. `scan-java` discovers every `[<module>/]src/main/{java,resources}` root once and anchors all patterns there, so `api/src/main/java/...` + `core/src/main/java/...` are scanned by the primary A–E patterns instead of the coarse fallback. Single-module scan time is unchanged (slightly faster); multi-module pays a per-module multiple for full-fidelity results. Source-root discovery ignores `src/test/**` (test-fixture projects such as `src/test/resources/projects/demo/src/main/java/…`) and `buildSrc/`, so neither becomes a module.
47
+ - **Legacy Java version literals.** `sourceCompatibility = '1.8'` produced `languageVersion: "1"`; `<java.version>1.8</java.version>` produced `null`. Both now yield `"8"` (`normalizeJavaVersion`), across Gradle literal / ext-variable / Maven property paths.
48
+ - **Next.js App Router route groups.** `app/(marketing)/about/`, `app/(shop)/(nested)/checkout/` were skipped outright (`name.startsWith("(")`), so route-group-organized apps came back with zero route domains. Groups are expanded (up to 3 levels) and their children evaluated like top-level route folders; Fallback A steps over group segments the same way. The same leaf under different groups (`(shop)/settings` and `(admin)/settings`) are distinct features: colliding leaves are qualified with their group path (`shop-settings`, `admin-settings`) so domain names stay unique; non-colliding leaves keep the bare name. If names still collide after group qualification (leaves that differ only before `pages`: `src/mobile/pages/home` vs `src/desktop/pages/home`), every non-structural path segment is used (`mobile-home`, `desktop-home`). A colliding leaf with no `app`/`pages` anchor (`src/views/home` beside `src/pages/home`) is qualified with its immediate parent (`views-home`, `pages-home`), never with the whole path.
49
+ - **Kotlin version catalog** with a `kotlin = "x.y.z"` version entry or a Kotlin *plugin* coordinate (`org.jetbrains.kotlin.jvm` / `.plugin.*` / `.multiplatform` / `.android` / `.kapt`, `kotlin-gradle-plugin`) now overrides the Java default set by the root plugin id. Library coordinates such as `org.jetbrains.kotlin:kotlin-stdlib` are deliberately *not* a signal — Java projects pin them to settle transitive version conflicts. Independently of the catalog, a "kotlin" keyword anywhere in a build file (`buildSrc/build.gradle.kts` with `kotlin-dsl`, a `kotlin = …` version pin) never flips a project whose source tree contains `.java` files and no `.kt` files — the Kotlin scanner would find zero domains and `init` would abort; `buildSrc/` is also excluded from the sub-module build-file sweep. `build-logic/` and `gradle/plugins/` (Gradle's documented `buildSrc` replacements for Kotlin-DSL convention plugins) are excluded from the source-language evidence as well.
50
+ - **Python framework / ORM keywords are matched case-insensitively.** `pip freeze` and PyPI canonical names are capitalized (`Django==5.0`, `Flask==3.0`, `SQLAlchemy==2.0`); the case-sensitive `includes()` never recognized Django or Flask from `requirements.txt`, and a standard `django-admin startproject` layout then aborted `init` with `domain-groups.json has invalid totalGroups: 0`. Present since v1.x.
51
+ - **Kotlin package-by-feature layout without layer folders** (`com/acme/user/UserController.kt`, `UserService.kt` — the idiomatic Kotlin/Spring layout) produced zero domains and aborted `init`. The single-module fallback now derives the domain from the feature package that holds layer-suffixed classes, or from the class-name stem when the directory is a flat root/app package. Pre-existing since the Kotlin scanner was added. The fallback also runs for files the layer-folder scan did not cover, so a mixed tree (`user/controller/UserController.kt` + `order/OrderController.kt`) keeps both domains; in that mixed case only feature packages named after their classes are accepted (a stray `SomeHandler.kt` in the root package is not promoted). A `dto/` / `vo/` / `entity/` folder sitting directly under the root package no longer manufactures a domain named after the root package (`com/acme/dto/UserDto.kt` → `acme`) that would both survive and force the strict mode; the artifact is dropped when real domains exist.
52
+ - **Layer-first Express / Fastify / Koa** (`src/controllers/`, `src/routes/`, `src/services/`) no longer reports the layer folders themselves as domains. When every candidate folder under `src/` is a layer name, domains are derived from file stems (`user.controller.js`, `users.routes.ts`, `orderService.js` → `user`, `order`; `pattern: "layer-first"`). A plural stem is folded into its singular twin only when *both* exist (`users.routes.ts` + `user.controller.js` → `user`; `-ies`→`-y`, `-es`, `-s`); a lone plural is kept verbatim, never guessed. Feature-first layouts (`src/<domain>/`) and NestJS modules are unchanged. The layer-first path is taken as soon as two layer folders exist; other non-infrastructure siblings (`src/jobs/`, `src/billing/`) become whole-folder feature domains instead of disabling the path (which previously resurrected `controllers` / `routes` as domains). `db/`, `migrations/`, `scripts/`, `public/`, `tests/` and similar are treated as infrastructure. The layer-first path additionally requires a routing layer folder (`controllers/`, `routes/`, `handlers/`, `api/`) at the top: module-first NestJS trees that keep shared `entities/` + `dtos/` next to `src/users/`, `src/orders/` stay module-first (no `users` → `user` rename, no one-file stem domains), and layer-named folders are never emitted as domains by the directory fallback either. Layer/role suffixes are stripped repeatedly and only after a separator or as a PascalCase word (`email.service.impl.ts` → `email`, `prototype.ts` stays `prototype`), and a file's role comes from its layer folder rather than from substrings of its path.
53
+ - **Layer-first FastAPI / Flask** (`app/routers/users.py`, `app/models/user.py`, `app/schemas/`) — same treatment and the same plural folding on the Python side when `app/` holds only layer folders. Feature packages that sit next to the layer folders (`src/routers/users.py` + `src/tasks/billing.py`) become domains as well instead of being dropped, and the layer/feature folders are collected from the same parent so a `src/` frontend tree is never mistaken for Python features. Virtualenvs and `node_modules` under `src/` or `app/` (`env/`, `venv/`, `.venv/`, `virtualenv/`, `site-packages/`) are ignored so they are never scanned as feature packages.
54
+ - **Frontend in a sub-directory.** A backend repo with the SPA in `frontend/`, `client/`, `web/`, `ui/`, `webapp/` or `front/` (own `package.json`, no root `package.json`) now detects the frontend from there (`stack.frontendRoot`) and the frontend scanner is rooted at that directory. Detection uses the same dependency precedence as the root (`next` → `@angular/core` → `nuxt` → `react` → `vue`) plus a config-file fallback (`next.config.*`, `vite.config.*`, `nuxt.config.*`, `angular.json`). Previously such repos were scanned as backend-only. `.claudeos-scan.json` is still read from the *project* root (where it is documented to live), not from the sub-directory, so `frontendScan` overrides keep working for sub-directory SPAs. A repo whose *only* application is the sub-directory SPA is no longer reported as "no language detected": `language` (TypeScript when `typescript` / `tsconfig.json` is present), `languageVersion` and `packageManager` (pnpm / yarn / bun / npm lockfile) are filled from the sub-directory, with backend values taking precedence when a backend exists. The sub-directory's own `.env*` is read as `stack.frontendEnvInfo` (same redaction and masking) and both it and `stack.frontendPort` are projected into `pass3-context.json`. The SPA's language / package manager are filled only after every backend block has run, so a Django / FastAPI / Flask backend with `frontend/package.json` stays `language: python` and keeps its package manager; the structure scanner also dispatches Python frameworks to the Python scanner regardless of `language`, so a Django repo whose root `package.json` exists only for Tailwind/PostCSS tooling is never handed to the Node scanner. A root `package.json` that exists only for tooling (Tailwind/PostCSS/ESLint) no longer makes a Django / FastAPI / Flask repo report `language: typescript` in `project-analysis.json` and CLAUDE.md §2: when a Python manifest is present and no Node backend framework is, `language` is reclaimed as `python` (a NestJS/Express/Fastify framework keeps Node).
55
+ - **Backend port and frontend dev-server port are resolved separately.** The single default chain (`stack.frontend === "angular" ? 4200 …`) handed a Spring/Django backend the Angular/Next dev-server port whenever a SPA lived beside it. `stack.port` is now the backend's port when a backend exists (`.env*` → framework default) and `stack.frontendPort` is the SPA's dev-server port whenever a frontend exists (sub-directory `.env*` → root `.env*` `PORT` for a root SPA → Vite 5173 / Angular 4200 / 3000). For a frontend-only project the two agree. When a single root `.env*` carries both (`SERVER_PORT=8080` + `VITE_PORT=3000`), the frontend-prefixed key (`VITE_*` / `NEXT_*` / `NUXT_*` / `NG_*`) feeds `frontendPort` and only the backend key feeds `stack.port` — previously `VITE_PORT` won the shared `extractPort()` precedence and was documented as the backend's port. `stack.envInfo.port` (what Pass 3 reads for the Server Port row) is set to the backend value under the same rule, with the frontend value exposed as `envInfo.frontendPort`; `plan-installer` uses the same backend definition as the detector (a JVM/Python project is a backend even without a recognized framework), so a plain Maven project beside a Vite SPA keeps 8080.
56
+ - **React + Vite next to a backend picks the Vite template.** Template selection used `stack.framework === "vite"`, which is impossible when Spring/Django owns `framework`, so a Spring + `frontend/` (React + Vite) repo was handed the Next.js frontend template. The bundler is now recorded separately (`stack.frontendBundler = "vite"` — root `package.json`, monorepo workspace packages whose deps are merged into the root view, or the sub-directory; from the `vite` dependency or the `vite.config.*` fallback) and `selectTemplates()` honors it. This also changes monorepos such as `apps/api` (NestJS) + `apps/web` (React + Vite), which previously received the Next.js frontend template.
57
+ - **`stack.frontendRoot` reaches every prompt.** `prompt-generator` prepends a `Frontend source root: {{PROJECT_ROOT}}/<dir>/` note to the shared header when the SPA lives in a sub-directory, so Pass 1/2/3 read the stack templates' `app/…` / `src/…` examples relative to that directory instead of the repo root; `pass3-context.json` carries `frontendRoot` / `frontendBundler` in its slim `stack` block.
58
+ - **Zero-domain abort is explained.** `init` still stops when the scanner finds no domains (there is nothing for Pass 1-3 to analyze and writing an empty CLAUDE.md would be worse), but the message now states the detected stack, lists the layouts the scanner recognizes, points at `project-analysis.json`, and confirms nothing was written — instead of `domain-groups.json has invalid totalGroups: 0`. Under `--force` / "fresh" the message no longer claims nothing was touched: it states that the managed `.claude/rules/NN.*` categories and `generated/` pass files had already been removed and points at version control.
59
+
60
+ ### Fixed — validator coverage
61
+
62
+ - **`STALE_PATH` covers JVM / Python / SFC / MyBatis paths.** `content-validator [10/10]` matched only `src/….{ts,tsx,js,jsx}`, so Java, Kotlin and Python projects had zero path-claim coverage despite "no invented paths" being the headline guarantee. Extensions added: `mjs cjs vue svelte java kt kts py xml sql` (config extensions deliberately excluded — `application-{profile}.yml` is illustrative far more often than a claim). `resolvePathClaim` resolves `src/…` claims against any module directory up to three levels deep that contains `src/` (memoized), not only `apps/*` / `packages/*`, so multi-module citations like `api/src/main/java/…` and the nested Kotlin CQRS layout the scanner itself supports (`servers/query/<x>/src/main/kotlin/…`) are not false positives. A module-qualified citation (`core/src/main/java/…`, `apps/web/src/…`) is captured whole and checked at that exact location only, so citing the wrong module is flagged instead of being rescued by the bare-`src/` module search; virtualenvs (`venv/`, `.venv/`, `env/`, `site-packages/`), `vendor/`, `docs/`, `tools/`, `scripts/`, `test(s)/` and `fixtures/` are never treated as module roots, so a hallucinated `src/…` path that happens to exist under `<venv>/src` is still reported. A module prefix is captured only when it starts a path token, so a package import such as `@acme/ui/src/Button.tsx` is not read as module `acme/ui` (its `src/Button.tsx` tail still resolves through the workspace search), `libsrc/x.ts` never yields a `src/x.ts` claim, and `node_modules/<pkg>/src/…` mentions are skipped as dependency references. `docs/`, `tools/`, `scripts/`, `test(s)/` and `fixtures/` are skipped as module roots only at the project root — inside a workspace container (`apps/docs`, `packages/tools`) they are legitimate packages, so the default Turborepo layout resolves as before; a dev-server URL (`localhost:5173/src/main.tsx`) never yields a `5173` module claim.
63
+
64
+ ### Changed — Pass 3 allowlist is written by the orchestrator
65
+
66
+ - `## Allowed Source Paths` in `pass3a-facts.md` is now injected by `init.js` directly from `project-analysis.json` after Pass 3a (`injectAllowedPathsSection()` in `plan-installer/source-paths.js`): replaces any LLM-written section wholesale (fence-aware, heading-suffix-tolerant, duplicate sections collapsed to one, an unterminated fence at EOF is closed first), appends if absent, emits the documented fallback line when the allowlist is empty, normalizes CRLF → LF, and runs on resumed runs where 3a is skipped. Until now the list reached 3b/3c/3d only if the model hand-copied up to 500 paths out of `pass3-context.json`, and `renderAllowedPathsSection()` was never called at runtime. `pass3a-facts.md` template tells the model not to write the section. If Pass 3a is marked complete but the facts file is missing/empty, `init` now stops with a clear error instead of fabricating a facts file.
67
+
68
+ ### Changed — templates & generated content
69
+
70
+ - `52.ai-work-rules.md` (static fallback): removed the `plan/` master-document rule (master plans were removed in v2.1.0); `00.standard-reference.md` guidance rewritten to agree with `pass3-footer.md` and the doc-writing guide; `build.gradle.kts` added to the manifest lists.
71
+ - Six stack templates no longer tell the model that `50.sync` rules should recommend `npx claudeos-core refresh` (a no-op since v2.1.0).
72
+ - Six stack templates (`angular`, `node-fastify`, `node-nestjs`, `node-vite`, `python-flask`, `vue-nuxt`) gained the `00.core/04.doc-writing-guide.md` forward reference in `00.standard-reference.md`.
73
+ - `angular/pass3.md`: orchestrator renamed `01.scaffold-page-feature.md` so its stem matches the `scaffold-page-feature/` sub-folder that `content-validator` and `ensureDirectories()` expect.
74
+ - `java-spring` / `kotlin-spring`: `40.infra/01.environment-config-rules.md` `paths` now include `**/*.gradle`, `**/*.gradle.kts`, `**/gradle/libs.versions.toml`, `**/pom.xml`; the linked `40.infra/01.environment-config.md` standard description in `java-spring` mentions build scripts and the version catalog accordingly.
75
+ - `claude-md-scaffold.md` §8 usage rule 5: periodic compaction is scoped to `failure-patterns.md` (`decision-log.md` is never compacted).
76
+ - `pass4.md`: "13 hallucination prevention patterns" → 17 (matches the static table); `claudeMdAppended` marker field is `false` (Pass 4 has not touched CLAUDE.md since v2.3.0) in both the template and `init.js`.
77
+ - `init.js` static-fallback log no longer claims "Plans scaffolded + CLAUDE.md appended".
78
+
79
+ ### Docs
80
+
81
+ - README: "byte-identical output" / "Nothing is guessed" / "Same project = same output" reworded to what is actually guaranteed (fixed 8-section structure, scanner facts + Pass 1 reads, validated identically across languages); excerpt headings noted as demoted for rendering; `build.gradle.kts` listed; test badge 825.
82
+ - `docs/safety.md` and `docs/commands.md`: `--force` sections describe the managed-category wipe and the preserved user-owned files under `.claude/rules/`; `docs/commands.md` also scopes `memory compact` to `failure-patterns.md`.
83
+ - `docs/stacks.md`: `.env` section no longer claims a `DATABASE_URL` whitelist; describes credential masking. `docs/verification.md`: `STALE_PATH` row lists the widened extension set and module-directory resolution. `docs/memory-layer.md`: compaction section scoped to `failure-patterns.md`.
84
+ - `lint --help` lists the T1 canonical-heading and S2 content checks.
85
+
86
+ ### Behavior changes (intentional)
87
+
88
+ 1. `memory compact` skips `decision-log.md` (also loses the 400-line cap for that file).
89
+ 2. `health` no longer reconciles MANIFEST ↔ §6; drift is reported as `MANIFEST_DRIFT` advisories. Run `node <tools>/manifest-generator/index.js --sync-skills` to reconcile on demand.
90
+ 3. Flat-layout Java projects now yield one domain per `*Controller` class instead of a single package-named domain; a flat controller next to domain-first packages (`demo/controller/HomeController.java` beside `demo/user/controller/…`) no longer produces a bogus package-named domain — it becomes its own class-name domain (`home`, Pattern C) so it is never silently left out of every domain.
91
+ 4. Kotlin `build.gradle.kts` projects declaring `id("org.springframework.boot")` are now `framework: spring-boot`, which activates `10.backend` output (previously `framework: null`).
92
+ 5. React + Vite frontends that share a repo with a backend (root `package.json`, monorepo workspace, or `frontend/`-style sub-directory) are now generated from the `node-vite` template instead of `node-nextjs`. Re-run `npx claudeos-core init --force` once to regenerate the frontend standards/rules under the Vite template.
93
+
94
+ ### Migration
95
+
96
+ - Existing projects: nothing to do for the memory / health / `.env` fixes — they take effect on the next command.
97
+ - Flat-layout Java projects and route-group Next.js projects: re-run `npx claudeos-core init --force` to regenerate per-domain files under the corrected domain set; a plain resume keeps the old files (Rule B) and adds the new ones alongside.
98
+ - Java / Python projects may see new `STALE_PATH` advisories for `.java` / `.py` / `.xml` paths the model invented; they are advisory-tier and do not fail `init` or `health`.
99
+ - All 10 `README.{lang}.md` files and all 9 localized `docs/{lang}/{commands,safety,stacks,verification,memory-layer}.md` sets carry the v2.5.0 wording (`memory compact` scope, managed-category `--force` wipe, credential masking, widened `STALE_PATH` coverage).
100
+
101
+ ### Tests
102
+
103
+ - 89 new: flat-layout / Initializr detection, multi-module source roots, Java 8 (`1.8`) Gradle + Maven, multi-module Gradle detection ×2, route groups, allowlist injection ×8 (append / replace / empty fallback / fenced heading / heading suffix / CRLF / unclosed fence / duplicate sections), multi-module `STALE_PATH` resolution ×2, `wipeManagedRuleCategories` ×2, case-insensitive Python framework detection ×2, Kotlin package-by-feature fallback ×2, `kotlin-stdlib`-only catalog stays Java, layer-first Express / FastAPI ×2, frontend sub-directory ×6 (dependency, `vite.config` fallback, Nuxt, root React + Vite bundler, scanner rooting, `pass3-context` projection), Vite template selection with a backend present, `Frontend source root` prompt note, `memory compact` leaves `decision-log.md` byte-identical, content-hashed translation cache ×4 (incl. a mocked real translation proving the cache is written), credential masking with `@` / `/` passwords and scheme-less DSNs, Java-only source tree vs kotlin keywords ×3, single-domain Pattern B preservation, `*Application.java` flat signal, per-module packages, `src/test` / `buildSrc` exclusion, Kotlin mixed layout, Python mixed layer/feature layout, sub-directory SPA overrides from the project root, route-group leaf collision, 3-level module `STALE_PATH` resolution, `manifest-generator` skills-sync gating ×3 (plain run read-only / `--sync-skills` / an exported `CLAUDEOS_SKILLS_SYNC` does nothing), `@` in URL path / query / `mailto` never rewritten, flat controller re-attached beside Pattern B, Kotlin flat-root `dto/` artifact ×2, Express mixed layer + feature folders, Python virtualenv under `src/`, leaf collision before `pages`, root-level `NN.` file survives `--force`, SPA-only sub-directory repo ×2 (language / package manager / env facts, backend precedence), module-qualified `STALE_PATH` claims ×3, `frontendPort` / `frontendEnvInfo` projection, backend vs frontend port resolution ×3, Django + `frontend/` stays Python ×2, module-first NestJS with shared `entities/` + `dtos/`, root `.env` `VITE_PORT` beside `SERVER_PORT`, package-import / `libsrc` / `node_modules` non-claims ×2, `--force` zero-domain message, `build-logic/` Kotlin convention plugins, tooling-only root `package.json` in a Django repo, NestJS + stray `requirements.txt`, `SERVER_PORT` + `VITE_PORT` in one `.env` (envInfo.port), framework-less Maven + Vite SPA ports, `*.service.impl.ts` / `prototype.ts` stems, 5-segment base package via `*Application.java`, `views/` vs `pages/` leaf collision, Turborepo `apps/docs` + `packages/tools` resolution, dev-server URL non-claim, connection-parameter credential masking.
104
+ - Replaced: `redactSensitiveVars preserves DATABASE_URL` → masking assertions; inline `--force` wipe reproduction → managed-category assertion. Pass 4 marker fixtures now use `claudeMdAppended: false` to match the template.
105
+
106
+ - **Files changed** — `bin/commands/{init,memory,lint}.js`, `lib/{env-parser,memory-scaffold}.js`, `plan-installer/{stack-detector,structure-scanner,domain-grouper,prompt-generator,pass3-context-builder,source-paths,index}.js`, `plan-installer/scanners/{scan-java,scan-kotlin,scan-node,scan-python,scan-frontend}.js`, `content-validator/index.js`, `manifest-generator/index.js`, 15 templates under `pass-prompts/templates/` (3 common + 12 stack), `README.md` + 9 localized `README.{lang}.md`, `docs/{safety,commands,stacks,verification,memory-layer,manual-installation}.md` (+ the same 5 docs in 9 localized `docs/{lang}/` sets, + 9 localized `manual-installation.md` version strings), 15 test files, `package.json` / `package-lock.json` (`2.4.4` → `2.5.0`).
107
+
108
+ ---
109
+
29
110
  ## [2.4.4] — 2026-05-04
30
111
 
31
112
  Documentation-only release. Translation polish across 8 non-Korean language `docs/{lang}/` directories. Test suite remains 736 / 736 pass.
package/README.de.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/claudeos-core.svg?logo=npm&label=npm)](https://www.npmjs.com/package/claudeos-core)
4
4
  [![CI](https://img.shields.io/github/actions/workflow/status/claudeos-core/claudeos-core/test.yml?branch=master&logo=github&label=CI)](https://github.com/claudeos-core/claudeos-core/actions/workflows/test.yml)
5
- [![tests](https://img.shields.io/badge/tests-736%20passing-brightgreen?logo=node.js&logoColor=white)](https://github.com/claudeos-core/claudeos-core/actions/workflows/test.yml)
5
+ [![tests](https://img.shields.io/badge/tests-825%20passing-brightgreen?logo=node.js&logoColor=white)](https://github.com/claudeos-core/claudeos-core/actions/workflows/test.yml)
6
6
  [![node](https://img.shields.io/node/v/claudeos-core.svg?logo=node.js&logoColor=white&label=node)](https://nodejs.org/)
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)
@@ -25,7 +25,7 @@ Claude Code greift bei jeder neuen Session auf die Standardwerte des jeweiligen
25
25
 
26
26
  **ClaudeOS-Core erzeugt diese Regeln deterministisch neu, direkt aus dem Quellcode.** Zuerst liest ein Node.js-Scanner alles aus: Stack, ORM, Paket-Layout und Dateipfade. Anschließend schreibt eine 4-Pass-Pipeline mit Claude den kompletten Dokumentensatz: `CLAUDE.md`, die automatisch geladenen `.claude/rules/`, dazu Standards und Skills. Eine explizite Pfad-Allowlist hält das LLM dabei in der Spur, aus ihr kann es nicht ausbrechen. Fünf Validatoren prüfen das Ergebnis, bevor es ausgeliefert wird.
27
27
 
28
- Das Resultat: Bei gleichem Input bekommst du byte-identische Ausgabe, in jeder der 10 Sprachen, ohne erfundene Pfade. (Details findest du weiter unten unter [Was es anders macht](#was-es-anders-macht).)
28
+ Das Resultat: Bei gleichem Input bekommst du dieselbe `CLAUDE.md` mit 8 festen Sections, geprüft durch dieselben 25 strukturellen Checks in jeder der 10 Sprachen, und jeder zitierte Quellpfad wird gegen die Festplatte verifiziert. (Details findest du weiter unten unter [Was es anders macht](#was-es-anders-macht).)
29
29
 
30
30
  Für langlebige Projekte legt das Tool außerdem einen separaten [Memory Layer](#memory-layer-optional-für-langlebige-projekte) an.
31
31
 
@@ -115,7 +115,7 @@ Hier ein Lauf auf [`spring-boot-realworld-example-app`](https://github.com/gothi
115
115
  </details>
116
116
 
117
117
  <details>
118
- <summary><strong>Was tatsächlich in deiner <code>CLAUDE.md</code> landet (echter Auszug, Section 1 + 2)</strong></summary>
118
+ <summary><strong>Was tatsächlich in deiner <code>CLAUDE.md</code> landet (echter Auszug, Section 1 + 2; Überschriften für die README-Darstellung auf <code>####</code> herabgestuft, die echte Datei verwendet <code>## N.</code>)</strong></summary>
119
119
 
120
120
  ```markdown
121
121
  # CLAUDE.md — spring-boot-realworld-example-app
@@ -148,7 +148,7 @@ an XML-driven MyBatis persistence layer and JWT-based authentication.
148
148
  | Test Stack | JUnit Jupiter 5, Mockito, AssertJ, rest-assured, spring-mock-mvc |
149
149
  ```
150
150
 
151
- Sämtliche Werte in dieser Tabelle stammen aus dem Code selbst: die exakten Dependency-Koordinaten, der Dateiname `dev.db`, der Migrationsname `V1__create_tables.sql` und auch das "no JPA". Der Scanner liest sie aus `build.gradle`, `application.properties` und dem Source-Tree, bevor Claude die Datei überhaupt anfasst. Geraten wird hier nichts.
151
+ Die Stack-Zeilen (Java 11, Spring Boot 2.6.3, Gradle, MyBatis, SQLite, Port 8080) stammen aus dem deterministischen Scanner. Die feineren Details, also die exakten Dependency-Koordinaten, der Dateiname `dev.db`, der Migrationsname `V1__create_tables.sql` und das "no JPA", liest Pass 1 aus `build.gradle`, `application.properties` und dem Source-Tree, wobei die Scanner-Fakten als Leitplanken dienen; anschließend prüfen die Validatoren sie gegen. Aus Framework-Defaults stammt hier nichts.
152
152
 
153
153
  </details>
154
154
 
@@ -309,7 +309,7 @@ Kategorien mit demselben Nummern-Präfix in `rules/` und `standard/` decken dens
309
309
  | Rolle | Schmerzpunkt, der wegfällt |
310
310
  |---|---|
311
311
  | **Solo-Entwickler**, der ein neues Projekt mit Claude Code startet | "Claude in jeder Session die eigenen Konventionen erklären" entfällt komplett. `CLAUDE.md` und die `.claude/rules/` mit acht Kategorien entstehen in einem einzigen Durchlauf. |
312
- | **Team-Lead**, der gemeinsame Standards über mehrere Repos pflegt | `.claude/rules/` driften, sobald jemand Pakete umbenennt, das ORM tauscht oder den Response-Wrapper anpasst. ClaudeOS-Core synchronisiert deterministisch nach. Gleicher Input liefert byte-identisches Output, also kein Diff-Rauschen. |
312
+ | **Team-Lead**, der gemeinsame Standards über mehrere Repos pflegt | `.claude/rules/` driften, sobald jemand Pakete umbenennt, das ORM tauscht oder den Response-Wrapper anpasst. ClaudeOS-Core generiert gegen ein festes Scaffold mit 8 Sections neu: gleiche Struktur in jedem Repo, gleiches Validator-Urteil, sodass Diffs Konventionsänderungen zeigen statt Layout-Rauschen. |
313
313
  | **Du nutzt Claude Code bereits**, hast aber genug davon, generierten Code immer wieder zu reparieren | Falscher Response-Wrapper, falsches Paket-Layout, JPA, obwohl ihr MyBatis fahrt, verstreute `try/catch`-Blöcke trotz zentraler Middleware. Der Scanner liest die echten Konventionen aus, und jeder Claude-Pass läuft gegen eine explizite Pfad-Allowlist. |
314
314
  | **Onboarding in ein neues Repo** (Bestandsprojekt, neues Team) | Einmal `init` im Repo ausführen, und du hast eine lebendige Architekturkarte: Stack-Tabelle in der CLAUDE.md, Rules pro Layer mit ✅/❌-Beispielen, dazu ein Decision-Log mit dem "Warum" hinter den großen Entscheidungen wie JPA gegen MyBatis oder REST gegen GraphQL. Fünf Dateien lesen schlägt 5.000 Quelldateien wälzen. |
315
315
  | **Du arbeitest auf Koreanisch, Japanisch, Chinesisch oder in 7 weiteren Sprachen** | Die meisten Rule-Generatoren für Claude Code beherrschen nur Englisch. ClaudeOS-Core schreibt das vollständige Set in **10 Sprachen** (`en/ko/ja/zh-CN/es/vi/hi/ru/fr/de`). Die strukturelle Validierung bleibt dabei byte-identisch: Der `claude-md-validator` urteilt unabhängig von der Ausgabesprache gleich. |
@@ -331,7 +331,7 @@ Hier: Code reads your stack → Code passes confirmed facts to Claude → C
331
331
 
332
332
  Die Pipeline läuft in **drei Phasen**; vor und nach dem LLM-Aufruf übernimmt jeweils Code:
333
333
 
334
- **1. Step A — Scanner (deterministisch, ohne LLM).** Ein Node.js-Scanner durchläuft den Projekt-Root, liest `package.json`, `build.gradle`, `pom.xml` und `pyproject.toml`, parst `.env*`-Dateien und maskiert dabei sensible Variablen wie `PASSWORD/SECRET/TOKEN/JWT_SECRET/...`. Anschließend klassifiziert er das Architekturmuster (5 Java-Patterns A/B/C/D/E, Kotlin CQRS oder Multi-Module, Next.js App- gegenüber Pages-Router, FSD, Components-Pattern), erkennt Domänen und baut eine explizite Allowlist aller tatsächlich existierenden Quellpfade. Das Ergebnis landet in `project-analysis.json`, der Single Source of Truth für alles, was danach kommt.
334
+ **1. Step A — Scanner (deterministisch, ohne LLM).** Ein Node.js-Scanner durchläuft den Projekt-Root, liest `package.json`, `build.gradle`, `build.gradle.kts`, `pom.xml` und `pyproject.toml`, parst `.env*`-Dateien und maskiert dabei sensible Variablen wie `PASSWORD/SECRET/TOKEN/JWT_SECRET/...`. Anschließend klassifiziert er das Architekturmuster (5 Java-Patterns A/B/C/D/E, Kotlin CQRS oder Multi-Module, Next.js App- gegenüber Pages-Router, FSD, Components-Pattern), erkennt Domänen und baut eine explizite Allowlist aller tatsächlich existierenden Quellpfade. Das Ergebnis landet in `project-analysis.json`, der Single Source of Truth für alles, was danach kommt.
335
335
 
336
336
  **2. Step B — 4-Pass-Pipeline mit Claude (gebunden an die Fakten aus Step A).**
337
337
  - **Pass 1** liest pro Domain-Gruppe repräsentative Dateien und extrahiert dort jeweils etwa 50 bis 100 Konventionen: Response-Wrapper, Logging-Bibliotheken, Error-Handling, Naming-Konventionen, Test-Patterns. Der Pass läuft einmal pro Domain-Gruppe (`max 4 domains, 40 files per group`), dadurch läuft der Kontext nie über.
@@ -393,7 +393,7 @@ Die meisten Documentation-Tools für Claude Code generieren aus einer Beschreibu
393
393
 
394
394
  Daraus folgen drei konkrete Effekte:
395
395
 
396
- 1. **Deterministische Stack-Erkennung.** Gleiches Projekt plus gleicher Code ergibt gleiche Ausgabe. Es gibt kein "diesmal hat Claude anders gewürfelt".
396
+ 1. **Deterministische Stack-Erkennung und Struktur.** Gleiches Projekt plus gleicher Code ergibt dasselbe Scan-Ergebnis und dasselbe `CLAUDE.md`-Layout mit 8 Sections. Die Formulierungen innerhalb der Sections schreibt weiterhin das LLM; festgelegt sind die Fakten, die es bekommt, und die Form, die es ausfüllen muss.
397
397
  2. **Keine erfundenen Pfade.** Der Pass-3-Prompt führt jeden erlaubten Quellpfad explizit auf, deshalb kann Claude nichts zitieren, was im Code nicht existiert.
398
398
  3. **Multi-Stack-fähig.** Backend- und Frontend-Domänen verwenden im selben Lauf jeweils eigene Analyse-Prompts.
399
399
 
@@ -429,7 +429,7 @@ Was jeder einzelne Validator im Detail prüft, beschreibt [docs/de/verification.
429
429
 
430
430
  Vier Dateien, alle von Pass 4 geschrieben:
431
431
 
432
- - `decision-log.md`: Append-only-Log nach dem Muster "warum X statt Y", geseedet aus `pass2-merged.json`.
432
+ - `decision-log.md`: Append-only-Log nach dem Muster "warum X statt Y", geseedet aus `pass2-merged.json` (wird nie komprimiert).
433
433
  - `failure-patterns.md`: wiederkehrende Fehler mit Frequenz- und Importance-Scores.
434
434
  - `compaction.md`: wie der Memory-Bereich im Lauf der Zeit automatisch komprimiert wird.
435
435
  - `auto-rule-update.md`: Patterns, die später eigene Rules werden sollten.
@@ -437,7 +437,7 @@ Vier Dateien, alle von Pass 4 geschrieben:
437
437
  Zwei Befehle pflegen diesen Layer auf Dauer:
438
438
 
439
439
  ```bash
440
- # Failure-Patterns-Log komprimieren (regelmäßig ausführen)
440
+ # Failure-Patterns-Log komprimieren (regelmäßig ausführen; decision-log.md bleibt unangetastet)
441
441
  npx claudeos-core memory compact
442
442
 
443
443
  # Häufige Failure-Patterns zu Rule-Vorschlägen befördern
package/README.es.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/claudeos-core.svg?logo=npm&label=npm)](https://www.npmjs.com/package/claudeos-core)
4
4
  [![CI](https://img.shields.io/github/actions/workflow/status/claudeos-core/claudeos-core/test.yml?branch=master&logo=github&label=CI)](https://github.com/claudeos-core/claudeos-core/actions/workflows/test.yml)
5
- [![tests](https://img.shields.io/badge/tests-736%20passing-brightgreen?logo=node.js&logoColor=white)](https://github.com/claudeos-core/claudeos-core/actions/workflows/test.yml)
5
+ [![tests](https://img.shields.io/badge/tests-825%20passing-brightgreen?logo=node.js&logoColor=white)](https://github.com/claudeos-core/claudeos-core/actions/workflows/test.yml)
6
6
  [![node](https://img.shields.io/node/v/claudeos-core.svg?logo=node.js&logoColor=white&label=node)](https://nodejs.org/)
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)
@@ -25,7 +25,7 @@ Cada vez que abres una sesión nueva, Claude Code vuelve a los valores genérico
25
25
 
26
26
  **ClaudeOS-Core las regenera de forma reproducible a partir del código real.** Primero entra un scanner en Node.js que reconoce el stack, el ORM, la organización de paquetes y las rutas de archivos. A continuación, la pipeline de 4 pasos sobre Claude escribe el conjunto completo: `CLAUDE.md`, las reglas auto-cargadas en `.claude/rules/`, los estándares y las skills. Todo queda acotado por una lista explícita de rutas permitidas que el modelo no puede saltarse. Y para cerrar, cinco validators revisan el resultado antes de darlo por bueno.
27
27
 
28
- De este modo, la misma entrada produce siempre la misma salida, byte a byte, en cualquiera de los 10 idiomas disponibles, y sin que aparezca jamás una ruta inexistente. Más abajo se entra en detalle en [Qué lo hace diferente](#qué-lo-hace-diferente).
28
+ De este modo, la misma entrada produce siempre la misma estructura de `CLAUDE.md` en 8 secciones, validada por las mismas 25 comprobaciones estructurales en cualquiera de los 10 idiomas disponibles, y cada ruta de código citada se verifica contra el disco. Más abajo se entra en detalle en [Qué lo hace diferente](#qué-lo-hace-diferente).
29
29
 
30
30
  Para proyectos de larga duración, además se prepara una [Memory Layer](#memory-layer-opcional-para-proyectos-de-larga-duración) aparte.
31
31
 
@@ -115,7 +115,7 @@ Lo ejecutamos sobre [`spring-boot-realworld-example-app`](https://github.com/got
115
115
  </details>
116
116
 
117
117
  <details>
118
- <summary><strong>Lo que acaba en tu <code>CLAUDE.md</code> (extracto real, secciones 1 y 2)</strong></summary>
118
+ <summary><strong>Lo que acaba en tu <code>CLAUDE.md</code> (extracto real, secciones 1 y 2; los encabezados se rebajan a <code>####</code> para que se rendericen en el README, el archivo real usa <code>## N.</code>)</strong></summary>
119
119
 
120
120
  ```markdown
121
121
  # CLAUDE.md — spring-boot-realworld-example-app
@@ -148,7 +148,7 @@ an XML-driven MyBatis persistence layer and JWT-based authentication.
148
148
  | Test Stack | JUnit Jupiter 5, Mockito, AssertJ, rest-assured, spring-mock-mvc |
149
149
  ```
150
150
 
151
- Cada valor de la tabla anterior, desde las coordenadas exactas de cada dependencia hasta el nombre del archivo `dev.db`, el de la migración `V1__create_tables.sql` o ese «no JPA», sale del scanner. Lo extrae directamente de `build.gradle`, `application.properties` y el árbol de fuentes antes de que Claude empiece a escribir. Nada se adivina.
151
+ Las filas del stack (Java 11, Spring Boot 2.6.3, Gradle, MyBatis, SQLite, puerto 8080) salen del scanner determinista. Los detalles más finos, desde las coordenadas exactas de cada dependencia hasta el nombre del archivo `dev.db`, el de la migración `V1__create_tables.sql` o ese «no JPA», los lee Pass 1 en `build.gradle`, `application.properties` y el árbol de fuentes, tomando los hechos del scanner como restricción, y después los validators los contrastan. Nada sale de los valores por defecto del framework.
152
152
 
153
153
  </details>
154
154
 
@@ -309,7 +309,7 @@ Las categorías que comparten prefijo numérico entre `rules/` y `standard/` rep
309
309
  | Si eres... | El dolor que quita |
310
310
  |---|---|
311
311
  | **Dev en solitario** que arranca un proyecto con Claude Code | Se acabó lo de explicarle a Claude las convenciones del proyecto en cada sesión. Generas `CLAUDE.md` y las 8 categorías de `.claude/rules/` de una sola pasada. |
312
- | **Tech lead** manteniendo estándares compartidos entre repos | Cuando alguien renombra paquetes, cambia de ORM o retoca el wrapper de respuesta, `.claude/rules/` deja de cuadrar. ClaudeOS-Core lo resincroniza siempre igual: misma entrada, misma salida byte a byte y sin ruido en el diff. |
312
+ | **Tech lead** manteniendo estándares compartidos entre repos | Cuando alguien renombra paquetes, cambia de ORM o retoca el wrapper de respuesta, `.claude/rules/` deja de cuadrar. ClaudeOS-Core lo regenera contra un scaffold fijo de 8 secciones: misma estructura en todos los repos y mismo veredicto del validator, así que el diff muestra cambios de convención y no ruido de maquetación. |
313
313
  | **Ya usas Claude Code** y estás cansado de corregir lo que genera | Wrapper equivocado, paquetes mal organizados, JPA cuando se usa MyBatis, `try/catch` esparcidos cuando ya hay middleware central. El scanner extrae las convenciones reales y cada paso de Claude se ejecuta contra una lista explícita de rutas permitidas. |
314
314
  | **Te incorporas a un repo nuevo** (proyecto existente, llegada al equipo) | Lanzas `init` sobre el repo y obtienes un mapa vivo de la arquitectura: tabla de stack en CLAUDE.md, reglas por capa con ejemplos ✅/❌ y un decision log sembrado con el «por qué» de las decisiones grandes (JPA frente a MyBatis, REST frente a GraphQL, etc.). Leer 5 archivos sale más a cuenta que leer 5.000 fuentes. |
315
315
  | **Trabajas en coreano, japonés, chino o 7 idiomas más** | La mayoría de generadores de reglas para Claude Code solo hablan inglés. ClaudeOS-Core escribe el conjunto completo en **10 idiomas** (`en/ko/ja/zh-CN/es/vi/hi/ru/fr/de`) con **validación estructural byte-identical**: el veredicto de `claude-md-validator` no varía según el idioma de salida. |
@@ -331,7 +331,7 @@ Esto: El código lee tu stack → El código pasa hechos confirmados a Cl
331
331
 
332
332
  La pipeline avanza en **tres etapas**, con código tanto antes como después de la llamada al LLM:
333
333
 
334
- **1. Etapa A — Scanner (reproducible, sin LLM).** Un scanner en Node.js recorre la raíz del proyecto, lee `package.json`, `build.gradle`, `pom.xml` o `pyproject.toml`, parsea los archivos `.env*` (con redacción automática de variables sensibles como `PASSWORD/SECRET/TOKEN/JWT_SECRET/...`), clasifica el patrón de arquitectura (los 5 patrones A/B/C/D/E de Java, CQRS o multi-módulo en Kotlin, App Router o Pages Router en Next.js, FSD, components-pattern), descubre los dominios y compone una lista explícita con todas las rutas de archivos fuente que existen. El resultado se vuelca en `project-analysis.json`, la única fuente de verdad para lo que viene después.
334
+ **1. Etapa A — Scanner (reproducible, sin LLM).** Un scanner en Node.js recorre la raíz del proyecto, lee `package.json`, `build.gradle`, `build.gradle.kts`, `pom.xml` o `pyproject.toml`, parsea los archivos `.env*` (con redacción automática de variables sensibles como `PASSWORD/SECRET/TOKEN/JWT_SECRET/...`), clasifica el patrón de arquitectura (los 5 patrones A/B/C/D/E de Java, CQRS o multi-módulo en Kotlin, App Router o Pages Router en Next.js, FSD, components-pattern), descubre los dominios y compone una lista explícita con todas las rutas de archivos fuente que existen. El resultado se vuelca en `project-analysis.json`, la única fuente de verdad para lo que viene después.
335
335
 
336
336
  **2. Etapa B — Pipeline de 4 pasos sobre Claude (limitada por los hechos de la etapa A).**
337
337
  - **Pass 1** lee archivos representativos por grupo de dominios y extrae unas 50–100 convenciones por dominio: wrappers de respuesta, librería de logging, manejo de errores, convenciones de nombrado, patrones de tests. Se ejecuta una vez por grupo (`max 4 domains, 40 files per group`) para que el contexto nunca se desborde.
@@ -393,7 +393,7 @@ La mayoría de herramientas de documentación para Claude Code parten de una des
393
393
 
394
394
  Esto se traduce en tres consecuencias concretas:
395
395
 
396
- 1. **Detección reproducible del stack.** Mismo proyecto y mismo código equivalen a la misma salida. Nada de «esta vez Claude lo ha hecho distinto».
396
+ 1. **Detección reproducible del stack y de la estructura.** Mismo proyecto y mismo código equivalen al mismo resultado de escaneo y a la misma disposición de `CLAUDE.md` en 8 secciones. La redacción dentro de cada sección sigue siendo del LLM; lo que está fijado son los hechos que recibe y la forma que debe rellenar.
397
397
  2. **Sin rutas inventadas.** El prompt de Pass 3 lleva listadas todas las rutas fuente permitidas; Claude no puede citar nada que no exista.
398
398
  3. **Consciente del multi-stack.** En la misma ejecución, los dominios de backend y de frontend usan prompts de análisis distintos.
399
399
 
@@ -429,7 +429,7 @@ Más allá de la pipeline de scaffolding, ClaudeOS-Core también prepara la carp
429
429
 
430
430
  Son cuatro archivos y los escribe Pass 4:
431
431
 
432
- - `decision-log.md`: bitácora append-only de «por qué elegimos X en lugar de Y», sembrada desde `pass2-merged.json`.
432
+ - `decision-log.md`: bitácora append-only de «por qué elegimos X en lugar de Y», sembrada desde `pass2-merged.json` (nunca se compacta).
433
433
  - `failure-patterns.md`: errores recurrentes con puntuaciones de frecuencia e importancia.
434
434
  - `compaction.md`: cómo se compacta la memoria automáticamente con el tiempo.
435
435
  - `auto-rule-update.md`: patrones que merecen convertirse en reglas nuevas.
@@ -437,7 +437,7 @@ Son cuatro archivos y los escribe Pass 4:
437
437
  Dos comandos mantienen viva esta capa:
438
438
 
439
439
  ```bash
440
- # Compactar el log de failure-patterns (ejecuta de vez en cuando)
440
+ # Compactar el log de failure-patterns (ejecuta de vez en cuando; decision-log.md no se toca)
441
441
  npx claudeos-core memory compact
442
442
 
443
443
  # Promover los failure patterns frecuentes a propuestas de regla
package/README.fr.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/claudeos-core.svg?logo=npm&label=npm)](https://www.npmjs.com/package/claudeos-core)
4
4
  [![CI](https://img.shields.io/github/actions/workflow/status/claudeos-core/claudeos-core/test.yml?branch=master&logo=github&label=CI)](https://github.com/claudeos-core/claudeos-core/actions/workflows/test.yml)
5
- [![tests](https://img.shields.io/badge/tests-736%20passing-brightgreen?logo=node.js&logoColor=white)](https://github.com/claudeos-core/claudeos-core/actions/workflows/test.yml)
5
+ [![tests](https://img.shields.io/badge/tests-825%20passing-brightgreen?logo=node.js&logoColor=white)](https://github.com/claudeos-core/claudeos-core/actions/workflows/test.yml)
6
6
  [![node](https://img.shields.io/node/v/claudeos-core.svg?logo=node.js&logoColor=white&label=node)](https://nodejs.org/)
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)
@@ -25,7 +25,7 @@ Compatible avec [**12 stacks**](#supported-stacks), monorepos compris. Une seule
25
25
 
26
26
  **ClaudeOS-Core régénère ces règles de façon reproductible, à partir du code source réel.** Un scanner Node.js commence par lire le projet : stack, ORM, organisation des paquets, chemins de fichiers. Un pipeline Claude en 4 passes prend ensuite le relais et produit l'ensemble complet : `CLAUDE.md`, les fichiers `.claude/rules/` chargés automatiquement, les standards et les skills. Tout reste cantonné à une liste blanche de chemins explicite, hors de laquelle le LLM ne peut pas sortir. Cinq validateurs contrôlent le résultat avant le rendu final.
27
27
 
28
- Conséquence : pour une même entrée, la sortie est rigoureusement identique au bit près, dans n'importe laquelle des 10 langues, et aucun chemin n'est fabriqué. (Le détail se trouve plus bas, dans [Ce qui le rend différent](#ce-qui-le-rend-différent).)
28
+ Conséquence : pour une même entrée, on obtient toujours la même structure de `CLAUDE.md` en 8 sections, validée par les mêmes 25 contrôles structurels dans n'importe laquelle des 10 langues, et chaque chemin source cité est vérifié sur le disque. (Le détail se trouve plus bas, dans [Ce qui le rend différent](#ce-qui-le-rend-différent).)
29
29
 
30
30
  Pour les projets qui durent dans le temps, un [Memory Layer](#memory-layer-optionnel-pour-les-projets-longue-durée) distinct est également initialisé.
31
31
 
@@ -115,7 +115,7 @@ Exécution sur [`spring-boot-realworld-example-app`](https://github.com/gothinks
115
115
  </details>
116
116
 
117
117
  <details>
118
- <summary><strong>Ce qui finit dans votre <code>CLAUDE.md</code> (extrait réel, sections 1 et 2)</strong></summary>
118
+ <summary><strong>Ce qui finit dans votre <code>CLAUDE.md</code> (extrait réel, sections 1 et 2 ; les titres sont abaissés en <code>####</code> pour l'affichage dans le README, le fichier réel utilise <code>## N.</code>)</strong></summary>
119
119
 
120
120
  ```markdown
121
121
  # CLAUDE.md — spring-boot-realworld-example-app
@@ -148,7 +148,7 @@ an XML-driven MyBatis persistence layer and JWT-based authentication.
148
148
  | Test Stack | JUnit Jupiter 5, Mockito, AssertJ, rest-assured, spring-mock-mvc |
149
149
  ```
150
150
 
151
- Toutes les valeurs ci-dessus, des coordonnées exactes des dépendances au nom de fichier `dev.db`, en passant par la migration `V1__create_tables.sql` et la mention « no JPA », sont extraites par le scanner depuis `build.gradle`, `application.properties` et l'arborescence source, avant même que Claude n'écrive la moindre ligne. Rien n'est deviné.
151
+ Les lignes du stack (Java 11, Spring Boot 2.6.3, Gradle, MyBatis, SQLite, port 8080) proviennent du scanner déterministe. Les détails plus fins, des coordonnées exactes des dépendances au nom de fichier `dev.db`, en passant par la migration `V1__create_tables.sql` et la mention « no JPA », sont lus par la passe 1 dans `build.gradle`, `application.properties` et l'arborescence source, avec les faits du scanner comme contraintes, puis recoupés par les validateurs. Rien ne vient des valeurs par défaut du framework.
152
152
 
153
153
  </details>
154
154
 
@@ -309,7 +309,7 @@ Lorsque `rules/` et `standard/` partagent le même préfixe numérique, ils couv
309
309
  | Profil | Le problème qui disparaît |
310
310
  |---|---|
311
311
  | **Développeur solo** qui démarre un nouveau projet avec Claude Code | « Réexpliquer les conventions à Claude à chaque session » : terminé. `CLAUDE.md` et les `.claude/rules/` répartis en 8 catégories sont générés en une seule passe. |
312
- | **Tech lead** qui maintient des standards communs entre plusieurs dépôts | Les `.claude/rules/` qui dérivent à mesure que les paquets sont renommés, que l'ORM change ou que le wrapper de réponse évolue. ClaudeOS-Core resynchronise tout de façon reproductible : même entrée, même sortie au bit près, donc zéro bruit dans les diffs. |
312
+ | **Tech lead** qui maintient des standards communs entre plusieurs dépôts | Les `.claude/rules/` qui dérivent à mesure que les paquets sont renommés, que l'ORM change ou que le wrapper de réponse évolue. ClaudeOS-Core régénère le tout à partir d'un scaffold fixe en 8 sections : même structure dans chaque dépôt, même verdict du validateur, donc les diffs montrent des changements de convention et non du bruit de mise en page. |
313
313
  | **Utilisateur de Claude Code** lassé de corriger le code généré | Mauvais wrapper de réponse, paquets mal organisés, JPA alors que le projet utilise MyBatis, `try/catch` éparpillés alors qu'un middleware centralisé existe. Le scanner extrait les vraies conventions du projet, et chaque passe Claude opère sur une liste blanche de chemins explicite. |
314
314
  | **Onboarding sur un nouveau dépôt** (projet existant, intégration en équipe) | Un simple `init` suffit pour obtenir une carte d'architecture vivante : tableau de stack dans CLAUDE.md, rules par couche avec exemples ✅/❌, decision log initialisé avec le « pourquoi » des choix structurants (JPA ou MyBatis, REST ou GraphQL, etc.). Lire 5 fichiers vaut mieux qu'éplucher 5 000 fichiers source. |
315
315
  | **Travail en coréen, japonais, chinois ou 7 autres langues** | La plupart des générateurs de rules pour Claude Code se cantonnent à l'anglais. ClaudeOS-Core produit l'ensemble complet dans **10 langues** (`en/ko/ja/zh-CN/es/vi/hi/ru/fr/de`), avec une **validation structurelle identique au bit près**. Le verdict de `claude-md-validator` reste le même quelle que soit la langue de sortie. |
@@ -331,7 +331,7 @@ Ici : Le code lit votre stack → Le code passe les faits confirmés à Cla
331
331
 
332
332
  Le pipeline se déroule en **trois étapes**, avec du code de part et d'autre de l'appel LLM.
333
333
 
334
- **1. Étape A — Scanner (reproductible, sans LLM).** Un scanner Node.js parcourt la racine du projet, lit `package.json`, `build.gradle`, `pom.xml` ou `pyproject.toml`, et analyse les fichiers `.env*`. Les variables sensibles (`PASSWORD/SECRET/TOKEN/JWT_SECRET/...`) sont automatiquement masquées. Le scanner classe ensuite le pattern d'architecture (5 patterns Java A/B/C/D/E, Kotlin CQRS ou multi-module, Next.js App ou Pages Router, FSD, components-pattern), identifie les domaines et construit une liste blanche explicite qui recense chaque chemin de fichier source réellement présent. Le tout finit dans `project-analysis.json`, source unique de vérité pour la suite.
334
+ **1. Étape A — Scanner (reproductible, sans LLM).** Un scanner Node.js parcourt la racine du projet, lit `package.json`, `build.gradle`, `build.gradle.kts`, `pom.xml` ou `pyproject.toml`, et analyse les fichiers `.env*`. Les variables sensibles (`PASSWORD/SECRET/TOKEN/JWT_SECRET/...`) sont automatiquement masquées. Le scanner classe ensuite le pattern d'architecture (5 patterns Java A/B/C/D/E, Kotlin CQRS ou multi-module, Next.js App ou Pages Router, FSD, components-pattern), identifie les domaines et construit une liste blanche explicite qui recense chaque chemin de fichier source réellement présent. Le tout finit dans `project-analysis.json`, source unique de vérité pour la suite.
335
335
 
336
336
  **2. Étape B — Pipeline Claude en 4 passes (contraint par les faits de l'étape A).**
337
337
  - **Pass 1** lit des fichiers représentatifs par groupe de domaines et en extrait 50 à 100 conventions par domaine : wrappers de réponse, bibliothèques de logging, gestion des erreurs, conventions de naming, patterns de tests. La passe tourne une fois par groupe de domaines (`max 4 domains, 40 files per group`), si bien que le contexte ne déborde jamais.
@@ -393,7 +393,7 @@ La plupart des outils de documentation pour Claude Code génèrent à partir d'u
393
393
 
394
394
  Trois conséquences concrètes en découlent.
395
395
 
396
- 1. **Détection de stack reproductible.** À projet et code identiques, sortie identique. Plus de « cette fois Claude est parti sur autre chose ».
396
+ 1. **Détection de stack et structure reproductibles.** À projet et code identiques, même résultat de scan et même agencement de `CLAUDE.md` en 8 sections. La formulation à l'intérieur des sections reste écrite par le LLM ; ce qui est figé, ce sont les faits qu'il reçoit et la forme qu'il doit remplir.
397
397
  2. **Aucun chemin fabriqué.** Le prompt de la passe 3 énumère noir sur blanc chaque chemin source autorisé : Claude ne peut donc pas citer un chemin qui n'existe pas.
398
398
  3. **Pensé multi-stack.** Backend et frontend s'appuient sur des prompts d'analyse distincts, dans une même exécution.
399
399
 
@@ -429,7 +429,7 @@ Au-delà du pipeline de scaffolding décrit plus haut, ClaudeOS-Core initialise
429
429
 
430
430
  Quatre fichiers, tous écrits par la passe 4 :
431
431
 
432
- - `decision-log.md` : journal append-only du « pourquoi avoir choisi X plutôt que Y », initialisé depuis `pass2-merged.json`.
432
+ - `decision-log.md` : journal append-only du « pourquoi avoir choisi X plutôt que Y », initialisé depuis `pass2-merged.json` (jamais compacté).
433
433
  - `failure-patterns.md` : erreurs récurrentes, accompagnées de scores frequency / importance.
434
434
  - `compaction.md` : description de la compaction automatique de la mémoire au fil du temps.
435
435
  - `auto-rule-update.md` : patterns qui devraient être promus au rang de nouvelles rules.
@@ -437,7 +437,7 @@ Quatre fichiers, tous écrits par la passe 4 :
437
437
  Deux commandes assurent la maintenance de cette couche dans la durée :
438
438
 
439
439
  ```bash
440
- # Compacter le log failure-patterns (à lancer périodiquement)
440
+ # Compacter le log failure-patterns (à lancer périodiquement ; decision-log.md n'est pas touché)
441
441
  npx claudeos-core memory compact
442
442
 
443
443
  # Promouvoir les failure patterns fréquents en rules proposées
package/README.hi.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/claudeos-core.svg?logo=npm&label=npm)](https://www.npmjs.com/package/claudeos-core)
4
4
  [![CI](https://img.shields.io/github/actions/workflow/status/claudeos-core/claudeos-core/test.yml?branch=master&logo=github&label=CI)](https://github.com/claudeos-core/claudeos-core/actions/workflows/test.yml)
5
- [![tests](https://img.shields.io/badge/tests-736%20passing-brightgreen?logo=node.js&logoColor=white)](https://github.com/claudeos-core/claudeos-core/actions/workflows/test.yml)
5
+ [![tests](https://img.shields.io/badge/tests-825%20passing-brightgreen?logo=node.js&logoColor=white)](https://github.com/claudeos-core/claudeos-core/actions/workflows/test.yml)
6
6
  [![node](https://img.shields.io/node/v/claudeos-core.svg?logo=node.js&logoColor=white&label=node)](https://nodejs.org/)
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)
@@ -25,7 +25,7 @@ Claude Code हर नए session पर framework के generic defaults प
25
25
 
26
26
  **ClaudeOS-Core यही काम deterministically करता है, सीधे आपके actual source code से।** पहले एक Node.js scanner project को पढ़ता है, यानी stack, ORM, package layout और file paths सब निकाल लेता है। उसके बाद 4-pass Claude pipeline पूरा set generate करती है। `CLAUDE.md`, auto-load होने वाले `.claude/rules/`, standards, skills — ये सब एक explicit path allowlist के अंदर ही बनते हैं, और LLM इस दायरे से बाहर नहीं जा सकता। आखिर में 5 validators output को ship होने से पहले verify कर लेते हैं।
27
27
 
28
- नतीजा यह है कि same input के लिए हमेशा byte-identical output मिलता है, चाहे 10 भाषाओं में से कोई भी चुनी जाए, और कभी invented path नहीं आएगा। (विस्तार से नीचे [क्या इसे अलग बनाता है](#क्या-इसे-अलग-बनाता-है) में।)
28
+ नतीजा यह है कि same input के लिए हमेशा वही 8-section वाला `CLAUDE.md` structure मिलता है, जो चाहे 10 भाषाओं में से कोई भी चुनी जाए, उन्हीं 25 structural checks से validate होता है, और cite किया गया हर source path disk पर verify होता है। (विस्तार से नीचे [क्या इसे अलग बनाता है](#क्या-इसे-अलग-बनाता-है) में।)
29
29
 
30
30
  लंबे चलने वाले projects के लिए एक अलग [Memory Layer](#memory-layer-वैकल्पिक-दीर्घकालिक-प्रोजेक्ट्स-के-लिए) भी seed होता है।
31
31
 
@@ -115,7 +115,7 @@ Claude Code हर नए session पर framework के generic defaults प
115
115
  </details>
116
116
 
117
117
  <details>
118
- <summary><strong>असली <code>CLAUDE.md</code> में आखिर क्या लिखा जाता है (वास्तविक excerpt — Section 1 + 2)</strong></summary>
118
+ <summary><strong>असली <code>CLAUDE.md</code> में आखिर क्या लिखा जाता है (वास्तविक excerpt — Section 1 + 2; README rendering के लिए headings को <code>####</code> पर demote किया गया है, असली file में <code>## N.</code> होता है)</strong></summary>
119
119
 
120
120
  ```markdown
121
121
  # CLAUDE.md — spring-boot-realworld-example-app
@@ -148,7 +148,7 @@ an XML-driven MyBatis persistence layer and JWT-based authentication.
148
148
  | Test Stack | JUnit Jupiter 5, Mockito, AssertJ, rest-assured, spring-mock-mvc |
149
149
  ```
150
150
 
151
- ऊपर table में जो भी value है — exact dependency coordinates, `dev.db` filename, `V1__create_tables.sql` migration नाम, "no JPA" तक वो सब Claude के file लिखने से पहले scanner ने `build.gradle`, `application.properties` और source tree से सीधे निकाला है। एक भी value guess नहीं की गई।
151
+ Stack वाली rows (Java 11, Spring Boot 2.6.3, Gradle, MyBatis, SQLite, port 8080) deterministic scanner से आती हैं। बारीक details — exact dependency coordinates, `dev.db` filename, `V1__create_tables.sql` migration नाम, "no JPA" — Pass 1 scanner के facts को constraint मानकर `build.gradle`, `application.properties` और source tree से पढ़ता है, और फिर validators उन्हें cross-check करते हैं। एक भी value framework defaults से नहीं ली गई।
152
152
 
153
153
  </details>
154
154
 
@@ -309,7 +309,7 @@ your-project/
309
309
  | आप कौन हैं... | यह जो pain हटाता है |
310
310
  |---|---|
311
311
  | **Solo dev जो Claude Code से नया project शुरू कर रहा है** | "हर session में Claude को conventions फिर से सिखाओ" — यह झंझट खत्म। `CLAUDE.md` और 8-category `.claude/rules/` एक ही pass में बन जाते हैं। |
312
- | **Team lead जो कई repos में shared standards maintain करता है** | जब लोग packages rename करते हैं, ORMs बदलते हैं, या response wrappers switch करते हैं, तब `.claude/rules/` drift करने लगते हैं। ClaudeOS-Core इन्हें deterministically फिर से sync कर देता है। Same input = byte-identical output, कोई diff noise नहीं। |
312
+ | **Team lead जो कई repos में shared standards maintain करता है** | जब लोग packages rename करते हैं, ORMs बदलते हैं, या response wrappers switch करते हैं, तब `.claude/rules/` drift करने लगते हैं। ClaudeOS-Core इन्हें एक fixed 8-section scaffold के हिसाब से फिर से generate करता है। हर repo में same structure, same validator verdict, इसलिए diff में layout noise नहीं बल्कि convention के बदलाव दिखते हैं। |
313
313
  | **पहले से Claude Code use कर रहे हैं लेकिन generated code ठीक करते-करते थक चुके हैं** | गलत response wrapper, गलत package layout, MyBatis project में JPA code, centralized middleware के बावजूद बिखरा हुआ `try/catch` — यह सब scanner आपके असली conventions निकालकर रोकता है, और हर Claude pass एक explicit path allowlist पर ही चलता है। |
314
314
  | **नए repo पर onboarding कर रहे हैं** (existing project, team join कर रहे हैं) | Repo पर `init` चलाइए, एक living architecture map मिल जाता है — CLAUDE.md में stack table, ✅/❌ examples के साथ per-layer rules, और बड़े decisions के पीछे "why" से seed किया हुआ decision log (JPA vs MyBatis, REST vs GraphQL, वगैरह)। 5 files पढ़ना 5,000 source files पढ़ने से कहीं तेज़ है। |
315
315
  | **हिन्दी / कोरियाई / जापानी / चीनी समेत 7 अन्य भाषाओं में काम कर रहे हैं** | अधिकांश Claude Code rule generators सिर्फ English में लिखते हैं। ClaudeOS-Core पूरा set **10 भाषाओं** (`en/ko/ja/zh-CN/es/vi/hi/ru/fr/de`) में लिखता है, और structural validation **byte-identical** रहता है — output language कोई भी हो, `claude-md-validator` का verdict same रहता है। |
@@ -331,7 +331,7 @@ ClaudeOS-Core typical Claude Code workflow को उल्टा करके
331
331
 
332
332
  Pipeline **तीन stages** में चलती है, और LLM call के दोनों तरफ code रहता है।
333
333
 
334
- **1. Step A — Scanner (deterministic, कोई LLM नहीं)।** एक Node.js scanner project root को walk करता है, `package.json` / `build.gradle` / `pom.xml` / `pyproject.toml` पढ़ता है, `.env*` files parse करता है (`PASSWORD/SECRET/TOKEN/JWT_SECRET/...` जैसी sensitive variables को redact करते हुए), architecture pattern classify करता है (Java के 5 patterns A/B/C/D/E, Kotlin CQRS / multi-module, Next.js App vs Pages Router, FSD, components-pattern), domains discover करता है, और मौजूदा हर source file path का explicit allowlist बनाता है। इसका output है `project-analysis.json`, जो आगे की हर चीज़ के लिए single source of truth बन जाता है।
334
+ **1. Step A — Scanner (deterministic, कोई LLM नहीं)।** एक Node.js scanner project root को walk करता है, `package.json` / `build.gradle` / `build.gradle.kts` / `pom.xml` / `pyproject.toml` पढ़ता है, `.env*` files parse करता है (`PASSWORD/SECRET/TOKEN/JWT_SECRET/...` जैसी sensitive variables को redact करते हुए), architecture pattern classify करता है (Java के 5 patterns A/B/C/D/E, Kotlin CQRS / multi-module, Next.js App vs Pages Router, FSD, components-pattern), domains discover करता है, और मौजूदा हर source file path का explicit allowlist बनाता है। इसका output है `project-analysis.json`, जो आगे की हर चीज़ के लिए single source of truth बन जाता है।
335
335
 
336
336
  **2. Step B — 4-Pass Claude pipeline (Step A के facts के दायरे में)।**
337
337
  - **Pass 1** हर domain group के representative files पढ़ता है और प्रति domain करीब 50–100 conventions निकालता है — response wrappers, logging libraries, error handling, naming conventions, test patterns वगैरह। यह domain group पर एक बार चलता है (`max 4 domains, 40 files per group`), इसलिए context कभी overflow नहीं होता।
@@ -393,7 +393,7 @@ npx claudeos-core health
393
393
 
394
394
  इसके तीन ठोस नतीजे हैं।
395
395
 
396
- 1. **Deterministic stack detection.** Same project + same code = same output"इस बार Claude थोड़ा अलग roll हो गया" वाली बात नहीं होती।
396
+ 1. **Deterministic stack detection और structure.** Same project + same code = same scan result और वही 8-section `CLAUDE.md` layoutSections के अंदर की wording अब भी LLM लिखता है; fixed सिर्फ वे facts हैं जो उसे दिए जाते हैं और वह shape जो उसे भरनी है।
397
397
  2. **No invented paths.** Pass 3 prompt में हर allowed source path explicitly listed होता है, इसलिए Claude ऐसे paths cite ही नहीं कर सकता जो मौजूद नहीं हैं।
398
398
  3. **Multi-stack aware.** एक ही run में backend और frontend domains अलग-अलग analysis prompts use करते हैं।
399
399
 
@@ -429,7 +429,7 @@ npx claudeos-core health
429
429
 
430
430
  चार files हैं, और सब Pass 4 लिखता है।
431
431
 
432
- - `decision-log.md` — append-only "हमने X की जगह Y क्यों चुना", `pass2-merged.json` से seed होता है
432
+ - `decision-log.md` — append-only "हमने X की जगह Y क्यों चुना", `pass2-merged.json` से seed होता है (कभी compact नहीं होता)
433
433
  - `failure-patterns.md` — frequency / importance scores के साथ बार-बार आने वाली errors
434
434
  - `compaction.md` — समय के साथ memory कैसे auto-compact होती है
435
435
  - `auto-rule-update.md` — वो patterns जिन्हें नए rules बनना चाहिए
@@ -437,7 +437,7 @@ npx claudeos-core health
437
437
  इस layer को समय के साथ maintain करने के लिए दो commands हैं।
438
438
 
439
439
  ```bash
440
- # Failure-patterns log compact करें (समय-समय पर चलाएँ)
440
+ # Failure-patterns log compact करें (समय-समय पर चलाएँ; decision-log.md को छुआ नहीं जाता)
441
441
  npx claudeos-core memory compact
442
442
 
443
443
  # बार-बार आने वाले failure patterns को proposed rules में promote करें