claudeos-core 2.3.2 → 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 +790 -74
- package/CODE_OF_CONDUCT.md +15 -0
- package/README.de.md +374 -876
- package/README.es.md +374 -875
- package/README.fr.md +374 -875
- package/README.hi.md +374 -875
- package/README.ja.md +374 -875
- package/README.ko.md +374 -874
- package/README.md +374 -876
- package/README.ru.md +374 -877
- package/README.vi.md +374 -875
- package/README.zh-CN.md +374 -874
- package/SECURITY.md +51 -0
- package/bin/commands/init.js +192 -37
- package/content-validator/index.js +97 -4
- package/health-checker/index.js +44 -10
- package/package.json +92 -90
- package/pass-json-validator/index.js +58 -7
- package/pass-prompts/templates/angular/pass3.md +15 -14
- package/pass-prompts/templates/common/claude-md-scaffold.md +81 -0
- package/pass-prompts/templates/common/pass3-footer.md +104 -0
- package/pass-prompts/templates/java-spring/pass3.md +19 -18
- package/pass-prompts/templates/kotlin-spring/pass3.md +23 -22
- package/pass-prompts/templates/node-express/pass3.md +18 -17
- package/pass-prompts/templates/node-fastify/pass3.md +11 -10
- package/pass-prompts/templates/node-nestjs/pass3.md +11 -10
- package/pass-prompts/templates/node-nextjs/pass3.md +18 -17
- package/pass-prompts/templates/node-vite/pass3.md +11 -10
- package/pass-prompts/templates/python-django/pass3.md +18 -17
- package/pass-prompts/templates/python-fastapi/pass3.md +18 -17
- package/pass-prompts/templates/python-flask/pass3.md +9 -8
- package/pass-prompts/templates/vue-nuxt/pass3.md +9 -8
- package/plan-installer/domain-grouper.js +45 -5
- package/plan-installer/index.js +11 -1
- package/plan-installer/scanners/scan-java.js +98 -2
- package/plan-installer/stack-detector.js +44 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,722 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## Releases
|
|
4
|
+
|
|
5
|
+
Quick navigation to recent releases:
|
|
6
|
+
|
|
7
|
+
- [`2.4.1`](#241--2026-04-26) — Documentation overhaul, 10-language localization, fixture sanitization (post-release docs)
|
|
8
|
+
- [`2.4.0`](#240--2026-04-25) — Session Continuity Protocol (v2.4 series feature 1 of 3)
|
|
9
|
+
- [`2.3.3`](#233--2026-04-24) — Template emoji consistency + optional `totalLines` splitter axis
|
|
10
|
+
- [`2.3.2`](#232--2026-04-23) — `cmdInit` decomposition + UX polish + validator co-evolution
|
|
11
|
+
- [`2.3.1`](#231--2026-04-23) — Patch: Windows CI breakage in `npm test`
|
|
12
|
+
- [`2.3.0`](#230--2026-04-23) — Language-invariant structural validation; path-hallucination defense; single-SPA detection
|
|
13
|
+
- [`2.2.0`](#220--2026-04-21) — Deterministic 8-section CLAUDE.md scaffold
|
|
14
|
+
- [`2.1.2`](#212--2026-04-21) — Patch: master plan removal cleanup regression
|
|
15
|
+
- [`2.1.1`](#211--2026-04-20) — Docs-only maintenance
|
|
16
|
+
- [`2.1.0`](#210--2026-04-20) — Pass 3 split mode (3a/3b/3c/3d-aux); `Prompt is too long` mitigation
|
|
17
|
+
- [`2.0.x`](#202--2026-04-20) — Pass 4 architecture refactor; gap-fill no-op invariant
|
|
18
|
+
- [`1.7.x`](#171--2026-04-11) — Initial monorepo detection; multi-stack expansion
|
|
19
|
+
- [`1.6.x`](#162--2026-04-09) — 6 → 10+ stack templates (NestJS, Vue-Nuxt, Fastify, Angular)
|
|
20
|
+
- [`1.5.x`](#151--2026-04-06) — Initial public preview
|
|
21
|
+
|
|
22
|
+
For older entries scroll past v1.5.0 or use the GitHub blame view.
|
|
23
|
+
|
|
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
|
+
|
|
76
|
+
## [2.4.0] — 2026-04-25
|
|
77
|
+
|
|
78
|
+
First feature in the v2.4 series: **Session Continuity Protocol** —
|
|
79
|
+
a recommended prose block inside Section 8's Memory Workflow that
|
|
80
|
+
addresses Claude Code's auto-compact behavior. Auto-compact may
|
|
81
|
+
truncate session context mid-work, dropping previously-loaded
|
|
82
|
+
`failure-patterns.md` references, recently-recorded decisions in
|
|
83
|
+
`decision-log.md`, and the `paths`-glob-conditional rule files
|
|
84
|
+
that had been activated for the working files. Session Continuity
|
|
85
|
+
gives the LLM an explicit re-entry routine for these three context
|
|
86
|
+
elements when a session resumes after compact or restart.
|
|
87
|
+
|
|
88
|
+
This release ships only the protocol itself. Two further v2.4
|
|
89
|
+
features (Self-Check Framework, Common Pattern Taxonomy) are
|
|
90
|
+
planned but not yet implemented; they will land in subsequent
|
|
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).
|
|
97
|
+
|
|
98
|
+
### Scaffold — Session Resume block in `claude-md-scaffold.md`
|
|
99
|
+
|
|
100
|
+
- **Problem addressed.** Claude Code sessions that exceed the
|
|
101
|
+
context window trigger auto-compact: portions of older turns
|
|
102
|
+
are summarized or dropped to make room. Restarted sessions
|
|
103
|
+
begin with no in-context state. Both situations leave the LLM
|
|
104
|
+
unaware of three pieces of state that were previously loaded:
|
|
105
|
+
(1) the error patterns it had scanned at session start from
|
|
106
|
+
`failure-patterns.md`, (2) the design decisions it had
|
|
107
|
+
consulted (or appended) in `decision-log.md`, and (3) the
|
|
108
|
+
`paths`-conditional rule files under `.claude/rules/**` that
|
|
109
|
+
had been activated for the files being edited. CLAUDE.md is
|
|
110
|
+
always re-loaded on session start, but the rest of the L4
|
|
111
|
+
layer is not.
|
|
112
|
+
|
|
113
|
+
- **Change.** Add a new prose block to the scaffold's Section 8
|
|
114
|
+
template, immediately following the 6-step `Memory Workflow`
|
|
115
|
+
numbered list. The block opens with the bold label
|
|
116
|
+
`**Session Resume (after auto-compact or restart)**:` and
|
|
117
|
+
carries a 3-bullet list instructing the LLM to: re-scan
|
|
118
|
+
`failure-patterns.md`, re-read the 3 most recent entries of
|
|
119
|
+
`decision-log.md`, and re-match rule files by `paths` glob
|
|
120
|
+
for the current working files. The block lives inside the
|
|
121
|
+
scaffold's existing `# CLAUDE.md template structure` fenced
|
|
122
|
+
example, so generated CLAUDE.md files (Korean, Japanese,
|
|
123
|
+
Chinese, etc.) inherit the block in the target language.
|
|
124
|
+
|
|
125
|
+
- **Why prose, not a third H4.** Section 8's structural
|
|
126
|
+
validator enforces EXACTLY 2 `####` headings (`L4 Memory
|
|
127
|
+
Files` + `Memory Workflow`). Adding `#### Session Resume`
|
|
128
|
+
would break every existing CLAUDE.md and require validator
|
|
129
|
+
surgery. Prose form sits inside the Memory Workflow section,
|
|
130
|
+
visually distinguished by the bold label, with no impact on
|
|
131
|
+
the H4 count. The scaffold's per-section spec explicitly
|
|
132
|
+
states "MUST NOT be a `####` subsection" so future
|
|
133
|
+
contributors do not regress this.
|
|
134
|
+
|
|
135
|
+
- **RECOMMENDED, not required.** Pre-v2.4 CLAUDE.md files were
|
|
136
|
+
generated without Session Resume. The validator does not
|
|
137
|
+
enforce the block's presence — only that, if present, it
|
|
138
|
+
takes the prose form rather than an H4. This preserves
|
|
139
|
+
backward compatibility for every existing project. New
|
|
140
|
+
generations via `npx claudeos-core init` (v2.4+) include
|
|
141
|
+
the block by default.
|
|
142
|
+
|
|
143
|
+
- **Tests.** Three new cases in `claude-md-validator.test.js`
|
|
144
|
+
under a new `Session Resume block (v2.4.0)` describe:
|
|
145
|
+
(1) a valid English fixture with the block in prose form
|
|
146
|
+
passes all 25 structural checks identically to the
|
|
147
|
+
Session-Resume-less `valid-en.md`;
|
|
148
|
+
(2) a fixture with the block placed as a third H4 under
|
|
149
|
+
Section 8 fails with the canonical `[S-H4-8]` error
|
|
150
|
+
("found 3, expected 2"), proving the validator catches the
|
|
151
|
+
most likely manual-editing mistake;
|
|
152
|
+
(3) the existing `valid-en.md` (no Session Resume block at
|
|
153
|
+
all) continues to pass, asserting backward compatibility
|
|
154
|
+
against accidental future tightening.
|
|
155
|
+
|
|
156
|
+
- **Two new fixtures.**
|
|
157
|
+
`tests/fixtures/claude-md/valid-en-with-session-resume.md`
|
|
158
|
+
is a copy of `valid-en.md` with the block appended in prose
|
|
159
|
+
form. `tests/fixtures/claude-md/bad-session-resume-as-h4.md`
|
|
160
|
+
is a minimal valid CLAUDE.md with the block placed as
|
|
161
|
+
`#### Session Resume`. The 10 existing language fixtures
|
|
162
|
+
(`valid-en.md`, `valid-ko.md` (`observed-ko-fixed.md`),
|
|
163
|
+
`valid-ja.md`, `valid-zh-CN.md`, `valid-es.md`,
|
|
164
|
+
`valid-vi.md`, `valid-hi.md`, `valid-ru.md`, `valid-fr.md`,
|
|
165
|
+
`valid-de.md`) are unchanged.
|
|
166
|
+
|
|
167
|
+
### Prompt-pipeline integration
|
|
168
|
+
|
|
169
|
+
- **Embed safety.** The scaffold ships to Pass 3 prompts via
|
|
170
|
+
`prompt-generator.js::demoteScaffoldMetaHeaders`, which
|
|
171
|
+
rewrites `## ` to `### ` for scaffold meta-sections while
|
|
172
|
+
preserving headings inside fenced code blocks (the template
|
|
173
|
+
example). Session Resume sits inside the markdown fence at
|
|
174
|
+
scaffold lines 7322–13929, so demote leaves it byte-identical.
|
|
175
|
+
Verified: the demoted scaffold contains exactly 2 `####`
|
|
176
|
+
headings (the template's `L4 Memory Files` and `Memory
|
|
177
|
+
Workflow`) and a Session Resume block of 850 bytes with
|
|
178
|
+
3 bullets — same as the source.
|
|
179
|
+
|
|
180
|
+
- **i18n unaffected.** The scaffold's Section 8 per-section
|
|
181
|
+
spec (lines 603–680) instructs the LLM to render Section 8
|
|
182
|
+
headings with both the English canonical token and the
|
|
183
|
+
target-language gloss (e.g. `## 8. Common Rules & Memory
|
|
184
|
+
(L4) (<localized gloss>)`). Session Resume's bold
|
|
185
|
+
label is treated as ordinary prose and translates freely
|
|
186
|
+
alongside its bullets — verified against Korean and
|
|
187
|
+
Japanese CLAUDE.md fixtures, both of which pass all 25
|
|
188
|
+
structural checks with the block translated.
|
|
189
|
+
|
|
190
|
+
### Validator behavior matrix
|
|
191
|
+
|
|
192
|
+
| CLAUDE.md state | Session Resume present? | Form | Result |
|
|
193
|
+
|---|---|---|---|
|
|
194
|
+
| Pre-v2.4 generated | No | — | ✅ Pass (unchanged) |
|
|
195
|
+
| v2.4 generated | Yes | Prose | ✅ Pass |
|
|
196
|
+
| Hand-edited mistake | Yes | `#### Session Resume` (3rd H4) | ❌ `[S-H4-8]` error |
|
|
197
|
+
| Hand-edited mistake | Yes | Prose, but in Section 5 instead of 8 | ✅ Pass (validator does not enforce content position) |
|
|
198
|
+
|
|
199
|
+
The last row is a known limitation: structural validation
|
|
200
|
+
checks heading counts, table positions, and canonical heading
|
|
201
|
+
tokens, but does not enforce that arbitrary prose blocks
|
|
202
|
+
appear in their semantically correct section. This is by
|
|
203
|
+
design — the structural validator is the inner ring of
|
|
204
|
+
defense, and over-policing prose position would constrain
|
|
205
|
+
legitimate translation and project-specific elaboration. If
|
|
206
|
+
future operational evidence shows users repeatedly placing
|
|
207
|
+
Session Resume in the wrong section, a `content-validator`
|
|
208
|
+
advisory (warning, not error) can be added without changing
|
|
209
|
+
the structural rule.
|
|
210
|
+
|
|
211
|
+
### Combined guarantees
|
|
212
|
+
|
|
213
|
+
- **No existing CLAUDE.md is invalidated.** Backward
|
|
214
|
+
compatibility was the explicit primary constraint; verified
|
|
215
|
+
against all 10 language fixtures, the Korean observed
|
|
216
|
+
fixture, and BOM-prefixed variants.
|
|
217
|
+
- **No validator logic changed.** `structural-checks.js` is
|
|
218
|
+
byte-identical to v2.3.3. The Session Resume rule is
|
|
219
|
+
enforced indirectly: prose form is invisible to existing
|
|
220
|
+
checks; H4 form is caught by the pre-existing
|
|
221
|
+
`checkH4Counts` (S-H4-8) rule.
|
|
222
|
+
- **No scanner, splitter, or Pass 1–4 pipeline changes.**
|
|
223
|
+
Pure scaffold + fixtures + tests addition.
|
|
224
|
+
- **Test suite 702 / 702 pass** (up from 699 in v2.3.3),
|
|
225
|
+
with the +3 coming exclusively from the new Session Resume
|
|
226
|
+
describe block. No existing test was modified or skipped.
|
|
227
|
+
|
|
228
|
+
### Documentation & repository assets
|
|
229
|
+
|
|
230
|
+
A repository-level addition ships alongside the protocol.
|
|
231
|
+
It does not touch code or tests; it improves discoverability
|
|
232
|
+
for prospective users browsing the repository on GitHub.
|
|
233
|
+
|
|
234
|
+
- **CHANGELOG navigation block.** A "Releases" section was
|
|
235
|
+
added at the top of `CHANGELOG.md`, listing the 13 most
|
|
236
|
+
recent releases (v2.4.0 through v1.5.x) with a one-line
|
|
237
|
+
summary and a GitHub-compatible anchor link to each
|
|
238
|
+
entry. Older entries remain reachable by scroll or by
|
|
239
|
+
GitHub blame. Anchor format follows GFM rules
|
|
240
|
+
(`[2.4.0] — 2026-04-25` becomes `#240--2026-04-25`); all
|
|
241
|
+
13 anchors are verified to resolve on GitHub.
|
|
242
|
+
|
|
243
|
+
### Verified backward compatibility
|
|
244
|
+
|
|
245
|
+
For the repository addition:
|
|
246
|
+
- **`CHANGELOG.md` ships in npm as before.** The TOC
|
|
247
|
+
addition is plain markdown; the file remains in the
|
|
248
|
+
package, so the navigation block is also visible on
|
|
249
|
+
npmjs.com's package page.
|
|
250
|
+
- **No test impact.** Test suite remains 702 / 702.
|
|
251
|
+
- **No bin script behavior change.** `npx claudeos-core
|
|
252
|
+
init` and all subcommands are byte-identical to the
|
|
253
|
+
protocol-only state earlier in this entry.
|
|
254
|
+
|
|
255
|
+
### Pipeline robustness — bug fixes (post-protocol additions)
|
|
256
|
+
|
|
257
|
+
Fifteen bug fixes addressing failure modes surfaced during follow-up
|
|
258
|
+
testing on additional stack/layout combinations. All have unit test
|
|
259
|
+
coverage; no behavior change for projects whose previous output was
|
|
260
|
+
already correct. Test suite grows from 702 to 736 (+34 new cases:
|
|
261
|
+
3 Session Resume + 5 totalLines axis + 5 SKILL.md/path resolution +
|
|
262
|
+
3 root-package frequency + 5 Logback fallback + 2 nested port
|
|
263
|
+
+ 2 cross-module deep-sweep + 3 monorepo path resolution +
|
|
264
|
+
2 ellipsis placeholder / doc-writing-rules.md exclusion +
|
|
265
|
+
2 deeply-nested-port window expansion + 2 deep-sweep extended layers +
|
|
266
|
+
3 MANIFEST global coverage / domains-folder pattern +
|
|
267
|
+
2 health-checker soft-fail tier +
|
|
268
|
+
1 70.domains canonical convention regression guard +
|
|
269
|
+
3 always-typed `70.domains/{type}/` per-domain layout
|
|
270
|
+
(loadDomainTypeMap helper / pass3-footer ALWAYS-typed convention /
|
|
271
|
+
ensureDirectories pre-creates both backend+frontend sub-folders) +
|
|
272
|
+
1 02.domains.md orchestrator convention regression guard +
|
|
273
|
+
1 single-batch per-domain enforcement (buildBatchScopeNote always fires);
|
|
274
|
+
minus overlap = +34 net).
|
|
275
|
+
|
|
276
|
+
- **`content-validator/index.js` — orchestrator/sub-skill MANIFEST
|
|
277
|
+
exception generalized.** The pre-existing v2.3.0 exception was
|
|
278
|
+
scoped to sub-skills under the legacy `{NN}.{name}.md` convention,
|
|
279
|
+
so generators that emit a category-level orchestrator at
|
|
280
|
+
`{category}/SKILL.md` (with sub-skills at
|
|
281
|
+
`{category}/{stem}/SKILL.md` or `{category}/{stem}/{name}.md`,
|
|
282
|
+
no `NN.` prefix) produced one `MANIFEST_DRIFT` advisory per
|
|
283
|
+
registered sub-skill. The fix relaxes the
|
|
284
|
+
sub-skill regex (`(?:\d+\.)?[^/]+\.md$`) to make the numeric
|
|
285
|
+
prefix optional, and adds a category-level rule: when CLAUDE.md
|
|
286
|
+
references `{category}/SKILL.md`, every sub-skill registered
|
|
287
|
+
under that category is treated as covered transitively. Integrity
|
|
288
|
+
checks (`STALE_SKILL_ENTRY` for missing files, `MANIFEST_DRIFT`
|
|
289
|
+
for unrelated parents) continue to fire at full strength — this
|
|
290
|
+
is purely a false-positive elimination.
|
|
291
|
+
|
|
292
|
+
- **`plan-installer/scanners/scan-java.js` — root package
|
|
293
|
+
frequency-based selection.** Pre-fix the rootPackage was set from
|
|
294
|
+
the FIRST matched layer-bearing file's package, which is
|
|
295
|
+
glob-enumeration-order-dependent: a multi-module project where
|
|
296
|
+
the bulk of code lives under one root but a small number of stub
|
|
297
|
+
files sit under a different subtree could non-deterministically
|
|
298
|
+
pick the minority root. The fix counts every (1-, 2-, 3-, 4-)
|
|
299
|
+
segment prefix preceding a layer marker, then picks the LONGEST
|
|
300
|
+
prefix whose count is at least 80% of the maximum. This selects
|
|
301
|
+
the most specific root that still covers the majority of files —
|
|
302
|
+
for a single-package project all prefix lengths tie at 100% and
|
|
303
|
+
the longest wins (intuitive). For a multi-module project the
|
|
304
|
+
threshold filters out minority subtrees while still picking a
|
|
305
|
+
specific common ancestor.
|
|
306
|
+
|
|
307
|
+
- **`plan-installer/scanners/scan-java.js` — Pattern B deep-sweep
|
|
308
|
+
fallback for zero-file domains.** Standard per-domain globs assume
|
|
309
|
+
`{domain}/{layer}/X.java`. Multi-module projects with a
|
|
310
|
+
`front/{domain}/` HTTP layer + `core/{domain}/{layer}/`
|
|
311
|
+
service/dao layer split work via the leading `**`, but
|
|
312
|
+
cross-domain coupling (`core/{otherDomain}/{layer}/{domain}/X.java`
|
|
313
|
+
— services for `{domain}` living under another module's layer
|
|
314
|
+
directory) was missed because the layer dir comes BEFORE the
|
|
315
|
+
domain dir, and `**/{domain}/{layer}/*.java` doesn't match. The
|
|
316
|
+
fix: when standard globs return ZERO files for a Pattern B/D
|
|
317
|
+
domain that's already registered (so it provably exists), fall
|
|
318
|
+
back to `**/${dn}/**/*.java` and classify each file by walking up
|
|
319
|
+
to the nearest layer dir. This catches both
|
|
320
|
+
`${dn}/{layer}/X.java` AND `{layer}/${dn}/X.java` placements.
|
|
321
|
+
Restricted to Pattern B/D zero-file case so projects with healthy
|
|
322
|
+
direct-layout counts behave identically to pre-fix.
|
|
323
|
+
|
|
324
|
+
- **`plan-installer/stack-detector.js` — Gradle/Maven
|
|
325
|
+
`packageManager` populated.** Pre-fix `stack.packageManager` was
|
|
326
|
+
set only for Node.js (npm/yarn/pnpm) and Python (pip/poetry/
|
|
327
|
+
pipenv/pdm). JVM projects using Gradle or Maven left it `null`,
|
|
328
|
+
which surfaced as `PackageMgr: none` in init output and `null`
|
|
329
|
+
in `project-analysis.json`. The fix sets `packageManager =
|
|
330
|
+
"gradle"` when a `build.gradle{.kts}` is detected and
|
|
331
|
+
`"maven"` for `pom.xml`. Node/Python detection runs first and
|
|
332
|
+
sets a value; the JVM fallback only fires when nothing else
|
|
333
|
+
claimed it (so a JVM monorepo with a Node-tooling overlay
|
|
334
|
+
retains the Node package manager).
|
|
335
|
+
|
|
336
|
+
- **`plan-installer/stack-detector.js` — Spring Boot default
|
|
337
|
+
Logback fallback.** Spring Boot ships Logback transitively via
|
|
338
|
+
`spring-boot-starter`; most projects don't declare
|
|
339
|
+
`ch.qos.logback:logback-classic` explicitly, so the
|
|
340
|
+
dependency-only `LOGGING_RULES` regex misses Logback for the
|
|
341
|
+
common case (only finding adapters like log4jdbc when
|
|
342
|
+
declared). The fix adds Logback to `stack.loggingFrameworks`
|
|
343
|
+
when `framework === "spring-boot"` AND the project hasn't
|
|
344
|
+
explicitly opted into log4j2 (which would suppress Logback via
|
|
345
|
+
`spring-boot-starter-log4j2`). Provenance is recorded in
|
|
346
|
+
`stack.detected` as `"logback (spring-boot default)"` so
|
|
347
|
+
consumers can distinguish fallback-derived from explicit
|
|
348
|
+
declaration.
|
|
349
|
+
|
|
350
|
+
- **`plan-installer/stack-detector.js` — nested `port:` matching
|
|
351
|
+
inside `server:` block.** Pre-fix port pattern (1) required
|
|
352
|
+
`port:` to be IMMEDIATELY adjacent to the `server:` line
|
|
353
|
+
(`/server:\s*\n\s*port:\s*(\d+)/`). Real Spring Boot configs
|
|
354
|
+
commonly nest `port:` under `server:` with intermediate keys
|
|
355
|
+
(`ssl:`, `http:`, `error:`, etc.) preceding it. The fix adds
|
|
356
|
+
patterns (5) and (6) — `^server:[\s\S]{0,2000}?\n[ \t]+port:\s*(\d+)$/m`
|
|
357
|
+
with placeholder variant — that lazy-match within a 2000-char
|
|
358
|
+
window after `server:` while requiring leading whitespace on
|
|
359
|
+
the `port:` line (so an outdented sibling `port:` at column 0
|
|
360
|
+
is correctly rejected as outside the server: block).
|
|
361
|
+
|
|
362
|
+
- **`content-validator/index.js` — STALE_PATH monorepo prefix
|
|
363
|
+
resolution.** Pre-fix the path-claim check verified each cited
|
|
364
|
+
`src/...\.(ts|tsx|js|jsx)` path by `path.join(ROOT, claimed)`
|
|
365
|
+
followed by `fs.existsSync()`. Turborepo / pnpm-workspace
|
|
366
|
+
projects keep source files under `apps/<app>/src/...` or
|
|
367
|
+
`packages/<pkg>/src/...`; a rule citing the workspace-relative
|
|
368
|
+
shorthand `src/app/layout.tsx` (the natural single-app form)
|
|
369
|
+
was a false-positive `STALE_PATH` even when the actual file
|
|
370
|
+
existed at `apps/<app>/src/app/layout.tsx`. The fix introduces
|
|
371
|
+
a `resolvePathClaim()` helper with three-step resolution:
|
|
372
|
+
(1) direct `<ROOT>/<claimed>`, (2) `<ROOT>/apps/*/<claimed>`,
|
|
373
|
+
(3) `<ROOT>/packages/*/<claimed>`. The fallback only fires for
|
|
374
|
+
`src/`-prefixed paths and only when the direct match fails;
|
|
375
|
+
genuinely missing files still flag STALE_PATH (verified by a
|
|
376
|
+
defense-against-masking test case).
|
|
377
|
+
|
|
378
|
+
- **`content-validator/index.js` — ellipsis placeholder + meta-doc
|
|
379
|
+
exclusion.** Two coordinated false-positive eliminations
|
|
380
|
+
surfaced after the monorepo fix shipped. (1) `hasPlaceholder()`
|
|
381
|
+
now recognizes the `/.../` ellipsis path segment as a
|
|
382
|
+
placeholder marker, alongside the existing `{...}` curly-brace,
|
|
383
|
+
`Xxx` / `XXX`, and `*` glob forms. LLMs commonly write
|
|
384
|
+
illustrative paths like `src/app/api/.../route.ts` to mean
|
|
385
|
+
"any API route under `app/api/`"; pre-fix the literal `...`
|
|
386
|
+
fragment failed `fs.existsSync()` and got reported as
|
|
387
|
+
`STALE_PATH`. The new pattern `/\/\.\.\.\//` matches a
|
|
388
|
+
three-dot segment between path separators — `...` is not a
|
|
389
|
+
valid directory name on any major filesystem (only `.` and `..`
|
|
390
|
+
are legal dot-only names), so this signal is unambiguous. (2)
|
|
391
|
+
`PATH_CLAIM_EXCLUDE_FILES` now includes
|
|
392
|
+
`00.core/51.doc-writing-rules.md` alongside the existing
|
|
393
|
+
`00.core/52.ai-work-rules.md`. Both are meta-documents
|
|
394
|
+
teaching path discipline to the reader: 51 explicitly states
|
|
395
|
+
"verify file paths before writing them in documents" and
|
|
396
|
+
cites example paths (`src/middleware.ts`,
|
|
397
|
+
`src/app/api/<route>/route.ts`) as illustrations of the rule.
|
|
398
|
+
The content-blind validator would otherwise flag every cited
|
|
399
|
+
example as `STALE_PATH` on every project that doesn't happen
|
|
400
|
+
to contain all the cited illustrative files. The exclusion is
|
|
401
|
+
defense-in-depth alongside the placeholder relaxation: prompt
|
|
402
|
+
guidance encourages placeholders, validator tolerates the
|
|
403
|
+
remaining literal-path examples in this one-file class.
|
|
404
|
+
|
|
405
|
+
- **`plan-installer/stack-detector.js` — `server:` block port window
|
|
406
|
+
expansion (2000 → 20000 chars).** Patterns (5)/(6) added in the
|
|
407
|
+
prior nested-port fix used a 2000-char lazy window between
|
|
408
|
+
`server:` and `port:`. Larger enterprise-style YAMLs commonly nest
|
|
409
|
+
`server:` with `ssl:`/`http:`/`tomcat:`/`compression:`/`error:`
|
|
410
|
+
children spanning 3000+ chars before the `port:` line; the 2000
|
|
411
|
+
limit silently failed to match and the detector defaulted to the
|
|
412
|
+
Spring Boot 8080 fallback. The fix expands the window to 20000
|
|
413
|
+
chars (sufficient for ~600 lines of preceding content) while
|
|
414
|
+
keeping the lazy quantifier — first-match-wins semantics
|
|
415
|
+
guarantee the closest `port:` is captured, so the wider window
|
|
416
|
+
costs nothing in correctness.
|
|
417
|
+
|
|
418
|
+
- **`plan-installer/index.js` — multi-DB array surfaced in console.**
|
|
419
|
+
Pre-fix the `[Phase 1] Detecting stack...` block printed only
|
|
420
|
+
`stack.database` (singular); the `stack.databases` array
|
|
421
|
+
(multi-dialect) populated by `detectDb()` since v2.3.2 was
|
|
422
|
+
invisible to the user and to downstream Pass 1 LLMs that grep
|
|
423
|
+
the console transcript. On dual-datasource projects (e.g. Oracle
|
|
424
|
+
primary + MySQL master/slave) Pass 1 had to re-derive the second
|
|
425
|
+
DB from source code. The fix adds a `Databases:` line listing
|
|
426
|
+
the full array when `databases.length > 1`; single-DB output
|
|
427
|
+
is byte-for-byte identical.
|
|
428
|
+
|
|
429
|
+
- **`plan-installer/scanners/scan-java.js` — extended layer
|
|
430
|
+
recognition in deep-sweep + catch-all service classification.**
|
|
431
|
+
The v2.4.0 deep-sweep (separate prior fix) only recognized the
|
|
432
|
+
canonical layer set
|
|
433
|
+
(`controller`/`service`/`aggregator`/`facade`/`usecase`/
|
|
434
|
+
`orchestrator`/`mapper`/`repository`/`dao`/`dto`/`vo`). Larger
|
|
435
|
+
codebases place implementation code under non-canonical
|
|
436
|
+
layers like `factory/`, `strategy/`, `impl/`, `helper/`,
|
|
437
|
+
`handler/`, `manager/`, `client/`, etc. Pre-fix these files were
|
|
438
|
+
silently dropped (no `break`), causing legitimate domains to
|
|
439
|
+
report 0 totalFiles and surfacing as "Group N: ~0 files" in
|
|
440
|
+
Phase 4 output. The fix expands the recognized layer list to 22
|
|
441
|
+
entries and adds a catch-all: any `.java` file under the domain
|
|
442
|
+
tree that fails layer classification is counted as a `service`
|
|
443
|
+
(the most generic backend role). This catches both
|
|
444
|
+
`core/{dn}/{nonstandard-layer}/X.java` and bare-domain
|
|
445
|
+
`core/{dn}/X.java` (no layer subdir) layouts.
|
|
446
|
+
|
|
447
|
+
- **`content-validator/index.js` — global MANIFEST coverage rule for
|
|
448
|
+
sub-skill paths.** The v2.4.0 orchestrator/sub-skill exception
|
|
449
|
+
expected a sibling orchestrator at `{category}/{stem}.md` paired
|
|
450
|
+
with sub-skills at `{category}/{stem}/{file}.md`. Pass 3c
|
|
451
|
+
occasionally invents new folder structures (e.g.
|
|
452
|
+
`{category}/domains/{domain}.md` for per-domain notes) that lack
|
|
453
|
+
a matching sibling orchestrator, and every such registration
|
|
454
|
+
surfaced as `MANIFEST_DRIFT`. The fix adds a category-independent
|
|
455
|
+
coverage rule: when CLAUDE.md mentions any `MANIFEST.md` (the
|
|
456
|
+
global skill registry), all SUB-SKILL paths (paths matching the
|
|
457
|
+
deep-folder regex) are considered covered transitively because
|
|
458
|
+
the reader navigates from MANIFEST to find them. TOP-LEVEL
|
|
459
|
+
registrations (`{category}/{file}.md` with no folder layer) are
|
|
460
|
+
unaffected — they still require direct mention. This is purely a
|
|
461
|
+
false-positive elimination on layouts the design intended to
|
|
462
|
+
support; the integrity check `STALE_SKILL_ENTRY` (registered
|
|
463
|
+
file missing on disk) continues to fire at full strength.
|
|
464
|
+
|
|
465
|
+
- **`pass-prompts/templates/common/pass3-footer.md` — explicit
|
|
466
|
+
✅/❌ enforcement block for standard files.** Pass 3b LLMs
|
|
467
|
+
occasionally generated standard files with only ✅ "correct"
|
|
468
|
+
examples and no ❌ "incorrect" example, surfacing as
|
|
469
|
+
`[NO_BAD_EXAMPLE]` advisories from `content-validator`. The
|
|
470
|
+
per-stack template instruction ("Each file MUST include
|
|
471
|
+
Correct/Incorrect examples") was sometimes deprioritized
|
|
472
|
+
during long generation runs. The fix adds a CRITICAL-tier block
|
|
473
|
+
to `pass3-footer.md` (which is appended to every Pass 3 prompt
|
|
474
|
+
regardless of stack) explicitly mandating both ✅ and ❌ blocks
|
|
475
|
+
in every standard file, with a self-check rule
|
|
476
|
+
("Does this file have at least one ❌ block?") to be applied
|
|
477
|
+
before finalizing each file. The pass3-footer is a project-wide
|
|
478
|
+
reminder that runs after the stack-specific body, giving the
|
|
479
|
+
rule late-stage emphasis.
|
|
480
|
+
|
|
481
|
+
- **`bin/commands/init.js` — Pass 3b/3c batch scope clarification.**
|
|
482
|
+
The `buildBatchScopeNote()` helper produced a per-batch
|
|
483
|
+
instruction telling Pass 3 LLMs to "generate per-domain files
|
|
484
|
+
for the domains in this batch". On multi-batch runs (>15
|
|
485
|
+
domains), one observed failure mode was Pass 3b rationalizing
|
|
486
|
+
Rule B (idempotent skip) to bypass the entire batch when common
|
|
487
|
+
files at OTHER paths existed (created by 3b-core). The fix
|
|
488
|
+
strengthens the scope note: explicit per-domain output paths
|
|
489
|
+
(`60.domains/{domain}.md` and `.claude/rules/60.domains/
|
|
490
|
+
{domain}-rules.md`), explicit "Expected output: N new files"
|
|
491
|
+
count to make zero-output detectable, and a guard clause
|
|
492
|
+
forbidding Rule B as justification for whole-batch SKIP when
|
|
493
|
+
per-domain target files don't yet exist. Single-batch runs
|
|
494
|
+
(≤15 domains) are unaffected — this scope note only fires in
|
|
495
|
+
multi-batch mode.
|
|
496
|
+
|
|
497
|
+
- **`health-checker/index.js` — soft-fail (`advisory`) tier for
|
|
498
|
+
`content-validator`.** Pre-fix `content-validator` exited
|
|
499
|
+
non-zero whenever it found any quality advisory (STALE_PATH,
|
|
500
|
+
MANIFEST_DRIFT, NO_BAD_EXAMPLE, etc.), which the health-checker
|
|
501
|
+
rendered as `❌ content-validator fail` in its summary. Init
|
|
502
|
+
output simultaneously printed "ℹ️ Content advisories detected
|
|
503
|
+
— these are quality notes, NOT generation failures", producing
|
|
504
|
+
a confusing dual signal. The fix introduces a third severity
|
|
505
|
+
tier alongside the existing `pass`/`fail`/`warn`: `advisory`
|
|
506
|
+
(icon `ℹ️`), assigned to tools flagged with `softFail: true`.
|
|
507
|
+
`content-validator` carries this flag; on non-zero exit it
|
|
508
|
+
renders as `ℹ️ content-validator advisory` and does NOT propagate
|
|
509
|
+
to the health-checker's overall exit code. The summary line was
|
|
510
|
+
rewritten to distinguish real failures
|
|
511
|
+
(`⚠️ N failed` — gate-blocking) from soft notes
|
|
512
|
+
(`✅ All systems operational (1 advisory, 1 warning)` — gate
|
|
513
|
+
green). Real structural failures (plan-validator, sync-checker,
|
|
514
|
+
manifest-generator) continue to gate the health command's exit
|
|
515
|
+
code, preserving CI-pipeline gating.
|
|
516
|
+
|
|
517
|
+
### Combined guarantees (post-bug-fix state)
|
|
518
|
+
|
|
519
|
+
- **Test suite 736 / 736** (up from 702 in the protocol-only
|
|
520
|
+
state earlier in this entry; +29 new cases as enumerated
|
|
521
|
+
above; no existing test was modified or skipped, with one
|
|
522
|
+
exception: the integrated MANIFEST_DRIFT scenario test had its
|
|
523
|
+
expected drift count adjusted from 3 to 0 to reflect the new
|
|
524
|
+
global-MANIFEST coverage rule, with the rationale documented
|
|
525
|
+
inline in the test body).
|
|
526
|
+
- **No CLI surface changes.** `init`, `lint`, `health`, `memory`
|
|
527
|
+
subcommands and their flags are unchanged. `package.json`
|
|
528
|
+
remains at v2.4.0; no new dependencies.
|
|
529
|
+
- **No backward-compatibility breaks.** Every fix above is
|
|
530
|
+
defensive (false-positive elimination, fallback for missing
|
|
531
|
+
cases) — projects whose pre-fix output was already correct
|
|
532
|
+
continue to produce byte-identical output.
|
|
533
|
+
- **Token-leak audit.** All identifiers used in the bug-fix code
|
|
534
|
+
and tests are generic CRUD examples (widget / notification /
|
|
535
|
+
inventory / order / product / payment etc.); no project
|
|
536
|
+
codenames or company-specific identifiers introduced.
|
|
537
|
+
|
|
538
|
+
### Namespace category unification (root-cause structural fix)
|
|
539
|
+
|
|
540
|
+
Following observation that Pass 3 LLM occasionally cross-contaminated
|
|
541
|
+
namespace category names (creating `.claude/rules/10.backend-api/`
|
|
542
|
+
sibling to `.claude/rules/10.backend/`, etc.), the underlying naming
|
|
543
|
+
asymmetry between rules and standard namespaces is eliminated: all
|
|
544
|
+
shared categories now use IDENTICAL folder names across both
|
|
545
|
+
namespaces, and the prefix collision between `rules/50.sync` and
|
|
546
|
+
`standard/50.verification` is resolved by relocating the standard
|
|
547
|
+
side to `80.verification`.
|
|
548
|
+
|
|
549
|
+
**Before** (asymmetric):
|
|
550
|
+
- standard: `10.backend-api`, `20.frontend-ui`, `50.verification`
|
|
551
|
+
- rules: `10.backend`, `20.frontend`, `50.sync`
|
|
552
|
+
|
|
553
|
+
**After** (unified):
|
|
554
|
+
- standard: `10.backend`, `20.frontend`, **`80.verification`**, `90.optional`
|
|
555
|
+
- rules: `10.backend`, `20.frontend`, `50.sync`, `60.memory`, `70.domains/{type}/`
|
|
556
|
+
|
|
557
|
+
Now `10.*` / `20.*` mean the same conceptual category in both
|
|
558
|
+
namespaces (LLM cannot confuse them). `50.sync` (rules) and
|
|
559
|
+
`80.verification` (standard) no longer share a numeric prefix.
|
|
560
|
+
|
|
561
|
+
**Affected files**: `bin/commands/init.js` ensureDirectories,
|
|
562
|
+
buildBatchScopeNote, buildStageCorePrompt, determineActiveDomains;
|
|
563
|
+
all 12 `pass-prompts/templates/*/pass3.md`; tests
|
|
564
|
+
(`init-command.test.js` EXPECTED_DIRS, `pass3-context-builder.test.js`
|
|
565
|
+
activeDomains key, two `tests/fixtures/claude-md/observed-ko-*.md`
|
|
566
|
+
fixtures); 10-language READMEs (directory tree examples).
|
|
567
|
+
|
|
568
|
+
**Migration**: Existing projects generated with the pre-unification
|
|
569
|
+
convention (`standard/10.backend-api/`, `standard/50.verification/`)
|
|
570
|
+
must re-run `npx claudeos-core init --force` to regenerate under
|
|
571
|
+
the new layout. Validators are namespace-agnostic (use globs) and
|
|
572
|
+
require no changes — old generated content remains readable but
|
|
573
|
+
will not be re-emitted at the legacy paths.
|
|
574
|
+
|
|
575
|
+
**Test coverage**: 736 / 736 pass (+1 from a new
|
|
576
|
+
`buildBatchScopeNote always fires` regression guard added in the
|
|
577
|
+
same release). No existing tests modified except the EXPECTED_DIRS
|
|
578
|
+
list and one `activeDomains` literal — both updated to the new
|
|
579
|
+
canonical category names.
|
|
580
|
+
|
|
581
|
+
## [2.3.3] — 2026-04-24
|
|
582
|
+
|
|
583
|
+
Template hygiene + splitter infrastructure. Two co-shipped changes,
|
|
584
|
+
both derived from two consecutive regression scenarios (one
|
|
585
|
+
React/Vite frontend, 14 domains; one legacy Java/Spring backend,
|
|
586
|
+
7 domains) that surfaced (a) a template inconsistency causing
|
|
587
|
+
spurious `NO_GOOD_EXAMPLE` / `NO_BAD_EXAMPLE` advisories on Vite/
|
|
588
|
+
Angular/Fastify/Flask projects while Java/Spring and seven other
|
|
589
|
+
stacks were clean, and (b) a Pass 1 time-outlier where a 29-file
|
|
590
|
+
domain group ran ~70% longer than a 39-file group because the group
|
|
591
|
+
contained a single 2544-line source file (TUI Grid wrapper) whose
|
|
592
|
+
analysis cost was driven by line count, not file count. Zero
|
|
593
|
+
functional regression: all existing scanners continue to produce
|
|
594
|
+
the legacy `{name, totalFiles}` domain shape and split exactly as
|
|
595
|
+
before. Test suite 699 / 699 pass (up from 694, +5 new tests for
|
|
596
|
+
the optional `totalLines` axis).
|
|
597
|
+
|
|
598
|
+
### Prompt — `pass3.md` code-example emoji consistency
|
|
599
|
+
|
|
600
|
+
- **Problem addressed.** `content-validator` checks standard files
|
|
601
|
+
for the presence of ✅ / ❌ emoji (or per-language equivalents
|
|
602
|
+
for "correct" / "incorrect" across the 10 supported output languages) as a
|
|
603
|
+
structural signal that correct and incorrect code examples are
|
|
604
|
+
both present. Eight of the twelve stack-specific `pass3.md`
|
|
605
|
+
templates (`java-spring`, `kotlin-spring`, `node-express`,
|
|
606
|
+
`node-nestjs`, `node-nextjs`, `python-django`, `python-fastapi`,
|
|
607
|
+
`vue-nuxt`) instruct the LLM with the literal phrase
|
|
608
|
+
`- Correct examples (✅ code blocks)` and
|
|
609
|
+
`- Incorrect examples (❌ code blocks)`, causing the emoji to
|
|
610
|
+
propagate into generated standards verbatim. The remaining four
|
|
611
|
+
(`angular`, `node-fastify`, `node-vite`, `python-flask`) omitted
|
|
612
|
+
the emoji in the instruction phrase, producing standards that
|
|
613
|
+
described correct/incorrect cases in prose without the emoji
|
|
614
|
+
marker the validator expects. Result: clean Java/Spring regression scenario
|
|
615
|
+
(0 advisories, 0 notes) vs. Vite regression scenario (0 advisories, 13 notes)
|
|
616
|
+
— identical pipeline, identical generator, different template
|
|
617
|
+
phrasing.
|
|
618
|
+
|
|
619
|
+
- **Change.** Align the four outlier templates with the eight-stack
|
|
620
|
+
majority. The Angular template retains its TypeScript-specific
|
|
621
|
+
wording (`Correct examples (✅ code blocks in TypeScript)` /
|
|
622
|
+
`Incorrect examples (❌ code blocks showing common Angular
|
|
623
|
+
mistakes)`); the other three adopt the same two-line pattern as
|
|
624
|
+
the majority. No other template content changed.
|
|
625
|
+
|
|
626
|
+
- **Rationale for template change rather than validator exemption.**
|
|
627
|
+
An alternative fix would have been to mark overview-style standard
|
|
628
|
+
files (`00.core/01.project-overview.md`,
|
|
629
|
+
`00.core/02.architecture.md`, etc.) as exempt from the emoji
|
|
630
|
+
check on the grounds that they are descriptive rather than
|
|
631
|
+
example-heavy. That option was rejected because it would hide a
|
|
632
|
+
real template inconsistency rather than fix it, and because the
|
|
633
|
+
Java/Spring stack's zero-notes output proves that overview files
|
|
634
|
+
*can* include ✅/❌ markers without becoming artificial — the
|
|
635
|
+
generator simply needs to be told to include them.
|
|
636
|
+
|
|
637
|
+
- **Scope.** Template prose only. `content-validator` regexes and
|
|
638
|
+
keyword tables are unchanged. Generated standards on
|
|
639
|
+
Angular/Fastify/Vite/Flask projects will now pass the emoji check
|
|
640
|
+
on first generation rather than surfacing advisories that Pass 3c
|
|
641
|
+
/ Pass 3d / Pass 4 eventually reduce. Existing Java/Spring and
|
|
642
|
+
the seven other stacks are unaffected (their templates already
|
|
643
|
+
carried the emoji).
|
|
644
|
+
|
|
645
|
+
### Splitter — optional `totalLines` axis in `splitDomainGroups`
|
|
646
|
+
|
|
647
|
+
- **Problem addressed.** Pass 1 batches domains into groups using
|
|
648
|
+
`MAX_FILES_PER_GROUP = 40` and `MAX_DOMAINS_PER_GROUP = 4`. This
|
|
649
|
+
is sound when per-file size is roughly uniform but produces time
|
|
650
|
+
outliers when a group contains a small number of very large
|
|
651
|
+
files. An observed scenario: a 29-file 4-domain batch took 7 m 0 s,
|
|
652
|
+
while a 39-file single-domain batch and a 34-file 3-domain batch
|
|
653
|
+
on the same project ran in 4 m 9 s and 4 m 22 s respectively.
|
|
654
|
+
Root cause: one of the 4 domains in the slow batch included a
|
|
655
|
+
single 2544-line third-party grid library wrapper file whose
|
|
656
|
+
analysis cost is driven by line count, not file count. Pass 1
|
|
657
|
+
ETA estimation and batch balance both suffer when a single
|
|
658
|
+
large file hides inside an otherwise small-looking group.
|
|
659
|
+
|
|
660
|
+
- **Change.** Introduce `MAX_LINES_PER_GROUP = 8000` as an optional
|
|
661
|
+
third splitting axis alongside the existing file-count and
|
|
662
|
+
domain-count budgets. The new axis is strictly additive: the
|
|
663
|
+
splitter consults `d.totalLines` on each incoming domain and
|
|
664
|
+
flushes the current group early if adding the next domain's
|
|
665
|
+
lines would exceed the budget. When `totalLines` is absent,
|
|
666
|
+
negative, non-number, or `NaN`, the line-budget check is skipped
|
|
667
|
+
entirely and the splitter behaves byte-for-byte as in v2.3.2.
|
|
668
|
+
|
|
669
|
+
- **Backward compatibility.** All five existing scanners
|
|
670
|
+
(`scan-java.js`, `scan-kotlin.js`, `scan-node.js`, `scan-python.js`,
|
|
671
|
+
`scan-frontend.js`) continue to emit `{name, totalFiles, ...}`
|
|
672
|
+
without `totalLines`, so their output passes through the splitter
|
|
673
|
+
with identical grouping to v2.3.2. Scanners that wish to opt into
|
|
674
|
+
line-aware splitting can populate `totalLines` per domain in a
|
|
675
|
+
future release; no scanner change ships in 2.3.3.
|
|
676
|
+
|
|
677
|
+
- **Threshold calibration.** 8000 is a conservative starting point
|
|
678
|
+
equivalent to ~40 files × ~200 lines each — roughly the
|
|
679
|
+
file-count budget expressed in lines. It can be revised once
|
|
680
|
+
scanners begin populating `totalLines` and real distribution data
|
|
681
|
+
accumulates across stacks. The constant is declared at module
|
|
682
|
+
scope (lifted out of the function body, alongside the existing
|
|
683
|
+
`MAX_FILES_PER_GROUP` and `MAX_DOMAINS_PER_GROUP` constants) so
|
|
684
|
+
future tuning is a one-line change with accompanying rationale in
|
|
685
|
+
the adjacent block comment.
|
|
686
|
+
|
|
687
|
+
- **Defensive validation.** `totalLines` is read with a strict
|
|
688
|
+
`typeof d.totalLines === "number" && d.totalLines >= 0` guard.
|
|
689
|
+
Malformed values (strings, `NaN`, negatives) cause the domain to
|
|
690
|
+
be treated as line-count-unknown rather than crashing the
|
|
691
|
+
splitter or producing nonsensical groupings. This protects
|
|
692
|
+
against scanner bugs during the migration period when some
|
|
693
|
+
scanners may emit `totalLines` and others not.
|
|
694
|
+
|
|
695
|
+
- **Tests.** Five new cases in `tests/domain-grouper.test.js`:
|
|
696
|
+
(1) legacy shape produces identical output (backward
|
|
697
|
+
compatibility); (2) line budget flushes when two 5000-line
|
|
698
|
+
domains would combine; (3) line budget does not flush when two
|
|
699
|
+
3000-line domains stay under the 8000 threshold; (4) mixed shape
|
|
700
|
+
(one domain with `totalLines`, one without) works correctly; and
|
|
701
|
+
(5) malformed `totalLines` values (negative, string, `NaN`) fall
|
|
702
|
+
back to legacy behavior. All 33 pre-existing tests in the same
|
|
703
|
+
suite continue to pass unchanged.
|
|
704
|
+
|
|
705
|
+
### Combined guarantees
|
|
706
|
+
|
|
707
|
+
- **Output parity for existing projects.** Projects that previously
|
|
708
|
+
ran clean on v2.3.2 continue to run clean on v2.3.3. Projects on
|
|
709
|
+
Angular/Fastify/Vite/Flask that previously accumulated "No
|
|
710
|
+
✅/❌ example found" advisories will produce fewer or zero such
|
|
711
|
+
advisories on first generation.
|
|
712
|
+
- **No scanner changes, no Pass changes, no pipeline changes.**
|
|
713
|
+
The splitter and template modifications are isolated; all Pass
|
|
714
|
+
1-4 stages, resume semantics, progress accounting, and marker
|
|
715
|
+
validation are byte-identical to v2.3.2.
|
|
716
|
+
- **Test suite 699 / 699 pass** (up from 694), with the +5 coming
|
|
717
|
+
exclusively from the new optional-axis cases. No existing test
|
|
718
|
+
was modified or skipped.
|
|
719
|
+
|
|
3
720
|
## [2.3.2] — 2026-04-23
|
|
4
721
|
|
|
5
722
|
Internal refactor + UX polish + prompt/validator co-evolution for
|
|
@@ -590,7 +1307,7 @@ codes for CI consumers. Test suite 694 / 694 pass (up from 662).
|
|
|
590
1307
|
- **Fix — Pass 3 logging rule glob extended.** The Pass 3 prompt
|
|
591
1308
|
for Java and Kotlin Spring stacks specified auto-load paths as
|
|
592
1309
|
`["**/*.java", "**/logback*.xml", "**/log4j*.xml"]`. This
|
|
593
|
-
missed three file types commonly present in
|
|
1310
|
+
missed three file types commonly present in Spring
|
|
594
1311
|
projects: Logback's Groovy DSL configuration (`logback*.groovy`),
|
|
595
1312
|
Log4j / Log4j2 properties files (`log4j*.properties`), and
|
|
596
1313
|
log4jdbc adapter configuration (`log4jdbc*.properties`).
|
|
@@ -743,21 +1460,21 @@ No source, template, or test changes. Test count unchanged at 662.
|
|
|
743
1460
|
## [2.3.0] — 2026-04-23
|
|
744
1461
|
|
|
745
1462
|
Adds language-invariant structural validation for generated `CLAUDE.md`.
|
|
746
|
-
|
|
1463
|
+
Regression testing v2.2.0 on a Korean-output Vite + React project (`a Vite frontend test project`)
|
|
747
1464
|
surfaced the §9 L4-memory re-declaration anti-pattern *despite* the scaffold,
|
|
748
1465
|
expanded blocklist, and post-generation self-check all being present in the
|
|
749
1466
|
embedded Pass 3 prompt. Root cause: forbidden-section enforcement depended
|
|
750
1467
|
on the LLM matching English canonical labels (`"Memory Layer (L4)"`) against
|
|
751
|
-
its own translated output (
|
|
1468
|
+
its own translated output (the localized form of `"Memory (L4)"` in Korean, Japanese, etc.) — a
|
|
752
1469
|
natural-language equivalence judgment the LLM does not perform reliably
|
|
753
1470
|
across 10 supported languages.
|
|
754
1471
|
|
|
755
|
-
|
|
756
|
-
same
|
|
1472
|
+
Regression testing v2.3.0's initial build on a second test project (`a Vite frontend test project`,
|
|
1473
|
+
same language, same stack family) then surfaced a second
|
|
757
1474
|
multi-repo invariant failure: the §9 problem was fixed, but the *wording*
|
|
758
1475
|
of section headings drifted freely. One project's §7 read
|
|
759
|
-
`"DO NOT Read (
|
|
760
|
-
`"
|
|
1476
|
+
`"DO NOT Read (<localized gloss A>)"` while the sibling's read
|
|
1477
|
+
`"<localized gloss B> (Files Not to Be Read Directly)"`. Both were "equivalent in
|
|
761
1478
|
meaning" per the scaffold, but `grep "## 7. DO NOT Read"` matched the
|
|
762
1479
|
first and missed the second — multi-repo discoverability broken.
|
|
763
1480
|
|
|
@@ -766,14 +1483,14 @@ LLM self-check to deterministic code-level validation that does not depend
|
|
|
766
1483
|
on natural-language matching, and adds a cross-repo title-determinism
|
|
767
1484
|
invariant (English canonical primary + optional translation parenthetical).
|
|
768
1485
|
|
|
769
|
-
Continued
|
|
1486
|
+
Continued regression testing on `a Vite frontend test project` then surfaced two more failure
|
|
770
1487
|
classes unrelated to CLAUDE.md structure:
|
|
771
1488
|
|
|
772
1489
|
1. **Path hallucination in rules/standard**. Pass 3 generated rule files
|
|
773
|
-
referencing `src/feature/routers
|
|
1490
|
+
referencing `src/feature/routers/<feature>RoutePath.ts` when the actual
|
|
774
1491
|
file was `src/feature/routers/routePath.ts`. Root cause: the LLM saw
|
|
775
1492
|
the parent directory `src/feature/` and a TypeScript constant
|
|
776
|
-
`
|
|
1493
|
+
`<FEATURE>_ROUTE_PATH` and "renormalized" the filename to match. Pre-v2.3.0
|
|
777
1494
|
validation did not check whether path claims resolved to real files.
|
|
778
1495
|
|
|
779
1496
|
2. **MANIFEST ↔ CLAUDE.md §6 Skills drift**. Four skills registered in
|
|
@@ -786,7 +1503,7 @@ paths, file-system existence, MANIFEST vs CLAUDE.md cross-reference) —
|
|
|
786
1503
|
no natural-language matching, so it works identically for all 10 output
|
|
787
1504
|
languages.
|
|
788
1505
|
|
|
789
|
-
Running the initial v2.3.0 build against `frontend
|
|
1506
|
+
Running the initial v2.3.0 build against `a Vite frontend test project` surfaced a
|
|
790
1507
|
third, upstream issue in the frontend domain scanner. The project has
|
|
791
1508
|
a single-SPA layout (`src/admin/{api,context,dto,routers,pages/*}/`,
|
|
792
1509
|
plus a separate `src/guide/` for documentation). The subapp scanner,
|
|
@@ -795,13 +1512,13 @@ interpreted `admin` as a platform keyword and emitted the architectural
|
|
|
795
1512
|
layers beneath it as pseudo-domains: `admin-api`, `admin-context`,
|
|
796
1513
|
`admin-dto`, `admin-routers`. That fragmented one SPA into 5+ spurious
|
|
797
1514
|
domains and, critically, primed Pass 3 to fabricate filenames with the
|
|
798
|
-
`admin` prefix — the root cause of the
|
|
1515
|
+
`admin` prefix — the root cause of the `<feature>RoutePath.ts` hallucination
|
|
799
1516
|
pattern. v2.3.0 adds a single-SPA detection rule: when only ONE distinct
|
|
800
1517
|
platform keyword matches across the project tree, subapp emission is
|
|
801
1518
|
suppressed by default, and feature domains are left to the downstream
|
|
802
1519
|
page/FSD/components scanners to discover correctly.
|
|
803
1520
|
|
|
804
|
-
Running the v2.3.0 build against `backend
|
|
1521
|
+
Running the v2.3.0 build against `a Spring backend test project` then surfaced a
|
|
805
1522
|
long-standing resume bug in the init pipeline. When a prior `init` run
|
|
806
1523
|
is interrupted mid-Pass-3 — most commonly a stream idle timeout during
|
|
807
1524
|
the 3d-aux (database + mcp-guide) stage — `pass3-complete.json` is
|
|
@@ -818,9 +1535,9 @@ orchestrator to inspect marker contents: when the marker is partial,
|
|
|
818
1535
|
logic resumes from the next unstarted stage; only fully-completed
|
|
819
1536
|
markers are skipped.
|
|
820
1537
|
|
|
821
|
-
Finally, the full v2.3.0 pipeline run against `frontend
|
|
1538
|
+
Finally, the full v2.3.0 pipeline run against `a Vite frontend test project` (14
|
|
822
1539
|
domains, Korean output) surfaced a structural regression the validator
|
|
823
|
-
itself caught and flagged: `## 9.
|
|
1540
|
+
itself caught and flagged: a `## 9. ` heading translating to "Memory Operations (L4)" appeared in
|
|
824
1541
|
`CLAUDE.md` as a re-declaration of the memory file table already
|
|
825
1542
|
present in Section 8. This was the exact anti-pattern v2.3.0 was
|
|
826
1543
|
designed to prevent, now reappearing despite the scaffold's explicit
|
|
@@ -842,10 +1559,10 @@ but never touches `CLAUDE.md`. The `appendClaudeMdL4Memory()` export
|
|
|
842
1559
|
is preserved as a no-op for any external caller depending on its
|
|
843
1560
|
signature.
|
|
844
1561
|
|
|
845
|
-
Post-retirement
|
|
1562
|
+
Post-retirement regression testing on `a Vite frontend test project` surfaced a final class
|
|
846
1563
|
of issue: four `STALE_PATH` errors in Pass 4-generated rule and
|
|
847
1564
|
standard files (`src/feature/main.tsx` assumed from Vite convention;
|
|
848
|
-
`src/feature/routers
|
|
1565
|
+
`src/feature/routers/<feature>RoutePath.ts` invented by prepending the
|
|
849
1566
|
parent directory name to the filename; `src/components/utils/classNameMaker.ts`
|
|
850
1567
|
fabricated as a plausible-sounding utility). The root cause was
|
|
851
1568
|
parallel to the §9 issue: Pass 3's path grounding rules live in
|
|
@@ -859,7 +1576,7 @@ The guidance also teaches the positive pattern: when in doubt,
|
|
|
859
1576
|
scope a rule to a directory (`src/admin/api/`) rather than
|
|
860
1577
|
inventing a specific filename.
|
|
861
1578
|
|
|
862
|
-
Re-running `init` on `backend
|
|
1579
|
+
Re-running `init` on `a Spring backend test project` with the Fix A build proved
|
|
863
1580
|
path-grounding works in practice — STALE_PATH dropped from the
|
|
864
1581
|
expected 4 to 0 across all Pass 4-generated rule and standard
|
|
865
1582
|
files — but left 8 MANIFEST_DRIFT errors in place. Analysis
|
|
@@ -895,16 +1612,16 @@ implements both halves of this split:
|
|
|
895
1612
|
|
|
896
1613
|
Together, Fix A (Pass 4 path grounding) and Fix B
|
|
897
1614
|
(orchestrator/sub-skill exception + §6 guidance) close the last
|
|
898
|
-
two classes of
|
|
1615
|
+
two classes of regression-observed content-validator errors. The
|
|
899
1616
|
remaining validator surface continues to enforce the strict
|
|
900
1617
|
invariants — fabricated paths, missing skill files, unrelated-
|
|
901
1618
|
parent drift, §9 re-declaration, T1 heading drift, etc. — without
|
|
902
1619
|
relaxation.
|
|
903
1620
|
|
|
904
|
-
Re-running `init` on `frontend
|
|
1621
|
+
Re-running `init` on `a Vite frontend test project` with the Fix A + Fix B
|
|
905
1622
|
build produced `0 MANIFEST_DRIFT` (Fix B suppressed all 8
|
|
906
1623
|
sub-skill drift rows) but left 1 residual `STALE_PATH` in
|
|
907
|
-
`claudeos-core/standard/
|
|
1624
|
+
`claudeos-core/standard/80.verification/02.testing-strategy.md`
|
|
908
1625
|
referencing `src/__mocks__/handlers.ts`. Analysis showed a
|
|
909
1626
|
library-convention hallucination class that the original three
|
|
910
1627
|
anti-patterns did not cover: testing documents reach for MSW /
|
|
@@ -920,30 +1637,29 @@ trigger document types, and the positive pattern: when
|
|
|
920
1637
|
describe testing/styling/state guidance in abstract terms
|
|
921
1638
|
(directory scope or role-based) without naming a specific path.
|
|
922
1639
|
|
|
923
|
-
Final validation pass on both
|
|
1640
|
+
Final validation pass on both regression fixture projects with the complete
|
|
924
1641
|
v2.3.0 build:
|
|
925
1642
|
|
|
926
|
-
- `frontend
|
|
1643
|
+
- `a Vite frontend test project` (Korean output, 14 frontend domains,
|
|
927
1644
|
dual-entry Vite + React 19, single-SPA admin layout,
|
|
928
1645
|
scaffold-page-feature orchestrator with 8 sub-skills):
|
|
929
1646
|
**12 errors → 0 errors** (100% improvement), full health
|
|
930
1647
|
check green, 25/25 CLAUDE.md lint checks passed.
|
|
931
|
-
- `backend
|
|
1648
|
+
- `a Spring backend test project` (Korean output, 8 backend domains,
|
|
932
1649
|
Java 17 + Spring Boot + MyBatis, scaffold-crud-feature
|
|
933
1650
|
orchestrator with 8 sub-skills, multi-dialect DB migration
|
|
934
1651
|
in progress): **8 errors → 0 errors** (100% improvement),
|
|
935
1652
|
full health check green, complete first-try run in 45m 29s
|
|
936
|
-
including the resume-from-partial-marker code path
|
|
937
|
-
for the first time
|
|
1653
|
+
including the resume-from-partial-marker code path exercised
|
|
1654
|
+
for the first time against a captured partial Pass 3 fixture.
|
|
938
1655
|
|
|
939
1656
|
Both projects exercise distinct v2.3.0 code paths (Fix A + Fix B,
|
|
940
1657
|
single-SPA rule, Pass 3 resume, library-convention anti-pattern,
|
|
941
1658
|
orchestrator/sub-skill exception), and both settled at 0 errors
|
|
942
1659
|
without any manual file edits to the generated output. This is
|
|
943
1660
|
the first release where the full end-to-end pipeline produces a
|
|
944
|
-
clean `content-validator [10/10]` report
|
|
945
|
-
|
|
946
|
-
publish-ready.
|
|
1661
|
+
clean `content-validator [10/10]` report against the regression
|
|
1662
|
+
fixture set — the core criterion for v2.3.0 being publish-ready.
|
|
947
1663
|
|
|
948
1664
|
### Added
|
|
949
1665
|
|
|
@@ -996,11 +1712,10 @@ publish-ready.
|
|
|
996
1712
|
The validator enforces this via `checkCanonicalHeadings` (IDs `T1-1`
|
|
997
1713
|
through `T1-8`), and the scaffold documents it as a mandatory format
|
|
998
1714
|
rule reinforced by Pass 3 POST-GEN CHECK step 4b. This closes a
|
|
999
|
-
multi-repo discoverability gap discovered during `frontend
|
|
1000
|
-
|
|
1001
|
-
말아야 할 파일)"` and `"읽지 말 것 (Files Not to Be Read Directly)"`
|
|
1715
|
+
multi-repo discoverability gap discovered during `a Vite frontend test project`
|
|
1716
|
+
regression testing: two test projects generated §7 as `"DO NOT Read (<localized gloss A>)"` and `"<localized gloss B> (Files Not to Be Read Directly)"`
|
|
1002
1717
|
respectively — both "equivalent in meaning" but breaking
|
|
1003
|
-
`grep "## 7. DO NOT Read"` across
|
|
1718
|
+
`grep "## 7. DO NOT Read"` across multiple repos.
|
|
1004
1719
|
|
|
1005
1720
|
- **`content-validator [10/10]` — path-claim + MANIFEST drift.**
|
|
1006
1721
|
A new check appended to the existing 9-stage validator in
|
|
@@ -1039,11 +1754,11 @@ publish-ready.
|
|
|
1039
1754
|
- **`pass-prompts/templates/common/pass3-footer.md` — Path fact
|
|
1040
1755
|
grounding (MANDATORY).** Two new CRITICAL blocks added:
|
|
1041
1756
|
- The parent-directory prefix anti-pattern (the exact
|
|
1042
|
-
|
|
1757
|
+
`<feature>RoutePath.ts` case from the Vite frontend test project's regression run) is
|
|
1043
1758
|
documented with ✅/❌ examples and explanation of *why* the LLM
|
|
1044
1759
|
mis-infers (TypeScript identifier name vs filename are
|
|
1045
|
-
independent — the constant `
|
|
1046
|
-
filename
|
|
1760
|
+
independent — the constant `<FEATURE>_ROUTE_PATH` does not imply
|
|
1761
|
+
filename `<feature>RoutePath.ts`).
|
|
1047
1762
|
- The MANIFEST ↔ CLAUDE.md §6 symmetry rule is stated explicitly,
|
|
1048
1763
|
with post-generation enforcement noted (`content-validator [10/10]
|
|
1049
1764
|
→ MANIFEST_DRIFT`).
|
|
@@ -1053,7 +1768,7 @@ publish-ready.
|
|
|
1053
1768
|
(same subapp implemented for two platforms, e.g., `src/pc/admin/`
|
|
1054
1769
|
+ `src/mobile/admin/` → `pc-admin`, `mobile-admin`). When applied
|
|
1055
1770
|
to a single-SPA project (only one platform keyword matches, as in
|
|
1056
|
-
`frontend
|
|
1771
|
+
`a Vite frontend test project`'s `src/admin/...`), the scanner misinterpreted the
|
|
1057
1772
|
SPA's architectural layers (`api`, `context`, `dto`, `routers`) as
|
|
1058
1773
|
subapps and emitted them as pseudo-domains — both cluttering the
|
|
1059
1774
|
domain plan and priming Pass 3 toward filename hallucinations with
|
|
@@ -1085,8 +1800,8 @@ publish-ready.
|
|
|
1085
1800
|
is invoked and its existing `groupsCompleted` tracking resumes
|
|
1086
1801
|
from the next unstarted stage. Only markers with `completedAt`
|
|
1087
1802
|
set are skipped.
|
|
1088
|
-
- This repairs the
|
|
1089
|
-
mid-stream on `backend
|
|
1803
|
+
- This repairs the regression case where Pass 3d-aux timed out
|
|
1804
|
+
mid-stream on `a Spring backend test project`: on the next `init`, stages 3a-3c
|
|
1090
1805
|
were correctly preserved but 3d-aux was silently skipped,
|
|
1091
1806
|
leaving `claudeos-core/database/` and `claudeos-core/mcp-guide/`
|
|
1092
1807
|
empty and the marker stuck in partial shape.
|
|
@@ -1124,7 +1839,7 @@ publish-ready.
|
|
|
1124
1839
|
exported for test compatibility but is now unreferenced by
|
|
1125
1840
|
production code.
|
|
1126
1841
|
This fix closes the final regression surfaced by end-to-end
|
|
1127
|
-
|
|
1842
|
+
regression testing on `a Vite frontend test project`: the validator was correctly
|
|
1128
1843
|
reporting an `S1` (9 sections) and four `M-*`/`F2-*` errors
|
|
1129
1844
|
against a `CLAUDE.md` whose second memory table had been
|
|
1130
1845
|
appended by Pass 4, not written by Pass 3. The fix keeps the
|
|
@@ -1155,9 +1870,9 @@ publish-ready.
|
|
|
1155
1870
|
section states the rule first — every `src/...` path written in a
|
|
1156
1871
|
rule or standard file must appear verbatim in `pass3a-facts.md` or
|
|
1157
1872
|
`pass2-merged.json` — then documents the three flagship
|
|
1158
|
-
hallucination anti-patterns observed in `frontend
|
|
1159
|
-
|
|
1160
|
-
parent-directory prefix (`src/feature/routers
|
|
1873
|
+
hallucination anti-patterns observed in `a Vite frontend test project`
|
|
1874
|
+
regression testing: Vite-convention assumption (`src/feature/main.tsx`),
|
|
1875
|
+
parent-directory prefix (`src/feature/routers/<feature>RoutePath.ts`),
|
|
1161
1876
|
and plausible-but-unverified utility (`src/components/utils/classNameMaker.ts`).
|
|
1162
1877
|
Each anti-pattern is accompanied by the concrete mechanism that
|
|
1163
1878
|
caused it ("invented based on Vite's stock convention";
|
|
@@ -1199,10 +1914,10 @@ publish-ready.
|
|
|
1199
1914
|
— hallucinated filenames and silent staleness — and cites the
|
|
1200
1915
|
`content-validator` exception so the prompt-side and detector-
|
|
1201
1916
|
side are consistent.
|
|
1202
|
-
This fix closes the final class of
|
|
1203
|
-
`backend
|
|
1917
|
+
This fix closes the final class of field-test-observed errors on
|
|
1918
|
+
`a Spring backend test project` (8 MANIFEST_DRIFT rows, all for
|
|
1204
1919
|
`scaffold-crud-feature/0N.*.md` sub-skills) and the equivalent
|
|
1205
|
-
shape on `frontend
|
|
1920
|
+
shape on `a Vite frontend test project` (8 rows under
|
|
1206
1921
|
`scaffold-page-feature/0N.*.md`). The structural
|
|
1207
1922
|
`CLAUDE.md §6 = entry, MANIFEST = registry` split also
|
|
1208
1923
|
eliminates the recurring regeneration churn where adding or
|
|
@@ -1211,7 +1926,7 @@ publish-ready.
|
|
|
1211
1926
|
|
|
1212
1927
|
- **`tests/content-validator.test.js` — 5 new orchestrator/sub-skill
|
|
1213
1928
|
exception tests.** Coverage: (1) orchestrator mentioned +
|
|
1214
|
-
sub-skills registered → 0 drift (backend
|
|
1929
|
+
sub-skills registered → 0 drift (a Spring backend test project replica);
|
|
1215
1930
|
(2) orchestrator mentioned + one sub-skill file deleted → still
|
|
1216
1931
|
emits 1 `STALE_SKILL_ENTRY` (integrity not suppressed);
|
|
1217
1932
|
(3) orchestrator NOT mentioned → all 5 registered skills drift
|
|
@@ -1250,7 +1965,7 @@ publish-ready.
|
|
|
1250
1965
|
fenced examples, placeholders, and existing paths do not trigger).
|
|
1251
1966
|
- MANIFEST drift scenarios (stale entry, drift, referenced skill,
|
|
1252
1967
|
self-reference exclusion, absent MANIFEST).
|
|
1253
|
-
- Full frontend
|
|
1968
|
+
- Full a Vite frontend test project simulation: 2 STALE_PATH + 2 STALE_SKILL_ENTRY
|
|
1254
1969
|
+ 3 MANIFEST_DRIFT, asserted with exact counts to prevent silent
|
|
1255
1970
|
regression as the validator evolves.
|
|
1256
1971
|
|
|
@@ -1271,13 +1986,13 @@ publish-ready.
|
|
|
1271
1986
|
following the T1 canonical-heading format `## N. <English canonical>
|
|
1272
1987
|
(<translation>)`): `valid-en.md`, `valid-ja.md`, `valid-zh-CN.md`,
|
|
1273
1988
|
`valid-es.md`, `valid-vi.md`, `valid-hi.md`, `valid-ru.md`,
|
|
1274
|
-
`valid-fr.md`, `valid-de.md`, plus `
|
|
1275
|
-
(Korean,
|
|
1989
|
+
`valid-fr.md`, `valid-de.md`, plus `observed-ko-fixed.md`
|
|
1990
|
+
(Korean, captured regression fixture with §9 removed and headings
|
|
1276
1991
|
retrofitted to T1 format). Each passes the same 25 structural
|
|
1277
1992
|
checks — empirical proof of language invariance across CJK,
|
|
1278
1993
|
Cyrillic, Devanagari, Latin, and Vietnamese scripts.
|
|
1279
1994
|
- Bad fixtures (same valid structure + §9 memory re-declaration
|
|
1280
|
-
appended): `
|
|
1995
|
+
appended): `observed-ko-bad.md`, `bad-ja.md`,
|
|
1281
1996
|
`bad-zh-CN.md`, `bad-ru.md`, `bad-hi.md`, `bad-es.md`. All six
|
|
1282
1997
|
produce a **byte-for-byte identical 9-error signature**
|
|
1283
1998
|
(1 S1 + 4 M-* + 4 F2-*), confirming the validator detects the
|
|
@@ -1353,8 +2068,8 @@ how often that net is needed.
|
|
|
1353
2068
|
label blocklist. The new framing states the RULE first (no `##` may
|
|
1354
2069
|
have a title whose semantic category is "rules", "memory", "L4",
|
|
1355
2070
|
"guardrails", or any rephrasing), then gives concrete **translated
|
|
1356
|
-
examples in Korean, Japanese, and Chinese** (
|
|
1357
|
-
|
|
2071
|
+
examples in Korean, Japanese, and Chinese** (the localized form of
|
|
2072
|
+
`Memory (L4)` in each script, plus analogues for Common Rules). The
|
|
1358
2073
|
goal is to make the LLM's translation decision explicit: it must
|
|
1359
2074
|
apply the forbidden rule to its translated heading, not just the
|
|
1360
2075
|
English original. A DECISION RULE block at the end gives a 3-step
|
|
@@ -1397,11 +2112,12 @@ MANIFEST-drift exception.)
|
|
|
1397
2112
|
|
|
1398
2113
|
The §9 re-declaration anti-pattern was the flagship problem v2.2.0 aimed
|
|
1399
2114
|
to solve, and the scaffold + prompt-level blocklist reduced incidence
|
|
1400
|
-
substantially.
|
|
1401
|
-
`CLAUDE.md` with `## 9.
|
|
1402
|
-
`## 8.
|
|
1403
|
-
section whose title
|
|
1404
|
-
equivalent to the blocklisted English
|
|
2115
|
+
substantially. Regression testing on a Korean-output fixture produced a
|
|
2116
|
+
`CLAUDE.md` with a `## 9. ` heading translating to "Memory (L4)" anyway — the LLM
|
|
2117
|
+
successfully matched the localized form of `## 8. Common Rules & Memory (L4)`
|
|
2118
|
+
as its Section 8, then created a §9 section whose translated title was not
|
|
2119
|
+
semantically recognized as equivalent to the blocklisted English
|
|
2120
|
+
`"Memory Layer (L4)"`.
|
|
1405
2121
|
|
|
1406
2122
|
Extending the fix by maintaining per-language blocklists would create
|
|
1407
2123
|
unbounded maintenance surface: 10 supported languages × 6-8 forbidden
|
|
@@ -1579,7 +2295,7 @@ projects or runs.
|
|
|
1579
2295
|
Adds a mandatory post-generation check (count `^## ` headings; must
|
|
1580
2296
|
equal 8; merge surplus into the correct section or move to `rules/*`
|
|
1581
2297
|
/ `standard/*`). The expanded blocklist closes a rename loophole
|
|
1582
|
-
discovered during
|
|
2298
|
+
discovered during regression testing on a Vite + React frontend project
|
|
1583
2299
|
where the LLM appended a §9 whose title combined "Documentation
|
|
1584
2300
|
Writing + AI Common Rules + Memory Layer (L4)" to collect
|
|
1585
2301
|
rule-related content.
|
|
@@ -1590,7 +2306,7 @@ projects or runs.
|
|
|
1590
2306
|
home in rules/standard/skills/guide.
|
|
1591
2307
|
|
|
1592
2308
|
- **`pass-prompts/templates/common/claude-md-scaffold.md`** (in addition to
|
|
1593
|
-
the new-file Add above) was tightened after initial
|
|
2309
|
+
the new-file Add above) was tightened after initial regression testing:
|
|
1594
2310
|
- Hard constraints section now leads with **"EXACTLY 8 SECTIONS. No more,
|
|
1595
2311
|
no less."** plus a recovery procedure for surplus sections.
|
|
1596
2312
|
- Section 6 Rules sub-section explicitly notes that the
|
|
@@ -1641,13 +2357,13 @@ projects or runs.
|
|
|
1641
2357
|
|
|
1642
2358
|
### Why this matters
|
|
1643
2359
|
|
|
1644
|
-
When claudeos-core was
|
|
1645
|
-
|
|
2360
|
+
When claudeos-core was exercised against three test projects (one Spring Boot backend,
|
|
2361
|
+
two Vite + React frontends) in the regression suite, the
|
|
1646
2362
|
generated files were content-correct — standards, rules, and skills
|
|
1647
2363
|
accurately captured each project's patterns — but the `CLAUDE.md` files
|
|
1648
2364
|
had different section counts (8, 8, 9), different section names, and
|
|
1649
2365
|
different section orders. Claude Code reads CLAUDE.md first on every
|
|
1650
|
-
session; inconsistent structure across repos
|
|
2366
|
+
session; inconsistent structure across repos would make it harder for
|
|
1651
2367
|
developers (and Claude Code) to know where to look for a given piece of
|
|
1652
2368
|
information. v2.2.0 fixes the structure while leaving content
|
|
1653
2369
|
project-specific.
|
|
@@ -1659,7 +2375,7 @@ content already in `.claude/rules/*` (auto-loaded) or `claudeos-core/
|
|
|
1659
2375
|
standard/*` (detailed patterns). Removing it eliminates a redundant
|
|
1660
2376
|
maintenance surface and reinforces the "one rule, one home" principle.
|
|
1661
2377
|
|
|
1662
|
-
|
|
2378
|
+
Regression testing also uncovered a latent paths bug. The `40.infra/*` rules
|
|
1663
2379
|
shared a single category-level `paths` frontmatter that only matched
|
|
1664
2380
|
config/infra file extensions (`.env`, `*.config.*`, `*.json`, `*.yml`,
|
|
1665
2381
|
`Dockerfile*`). This meant the logging-monitoring rule — whose guardrails
|
|
@@ -1670,7 +2386,7 @@ trigger was mis-scoped. v2.2.0 now specifies per-file `paths` in the Pass
|
|
|
1670
2386
|
3 prompts and adds a `Rule paths Must Match Rule Content` CRITICAL block
|
|
1671
2387
|
to the footer so future rules cannot inherit the wrong scope by default.
|
|
1672
2388
|
|
|
1673
|
-
A third
|
|
2389
|
+
A third regression testing finding exposed a different layer of the same
|
|
1674
2390
|
philosophy violation. The stack detector parsed Spring Boot's
|
|
1675
2391
|
`application.yml` for `server.port`, but for Node/Vite projects it
|
|
1676
2392
|
simply used a hardcoded framework default (Vite → 5173) whenever no
|
|
@@ -1686,7 +2402,7 @@ canonical source of runtime configuration — framework defaults are
|
|
|
1686
2402
|
last-resort only. This also captures host and API-target values that
|
|
1687
2403
|
previously never appeared in generated CLAUDE.md at all.
|
|
1688
2404
|
|
|
1689
|
-
A fourth
|
|
2405
|
+
A fourth regression testing iteration on a Spring Boot backend project
|
|
1690
2406
|
(regenerated with the interim v2.2.0 scaffold that only allowed a single
|
|
1691
2407
|
Section 8 titled "Memory (L4)") found the LLM producing a §9 titled
|
|
1692
2408
|
"Common Rules & Memory (L4)" — even with the expanded blocklist from
|
|
@@ -1732,7 +2448,7 @@ and were addressed in the same release cycle. **First**, the scaffold's
|
|
|
1732
2448
|
"Section 6 Rules: Always include 60.memory/*" directive, added during
|
|
1733
2449
|
Section 8 redesign, was not echoed in the 12 stack Pass 3 prompts'
|
|
1734
2450
|
rule-category listings — so the LLM received conflicting signals
|
|
1735
|
-
(scaffold says include, stack prompt doesn't mention it).
|
|
2451
|
+
(scaffold says include, stack prompt doesn't mention it). Regression testing
|
|
1736
2452
|
on the backend project confirmed the category was being omitted from
|
|
1737
2453
|
the generated CLAUDE.md §6 Rules table. v2.2.0 fixes both sides: each stack
|
|
1738
2454
|
Pass 3 prompt now explicitly lists `60.memory/*` as a forward-reference
|
|
@@ -1751,7 +2467,7 @@ preservation semantics (memory/ content kept, generated files replaced)
|
|
|
1751
2467
|
explicit. **Third**, the new `.env.example` → CLAUDE.md pipeline created
|
|
1752
2468
|
a theoretical pathway for accidentally committed secrets in `.env.example`
|
|
1753
2469
|
to be amplified into the project's public-facing documentation. Although
|
|
1754
|
-
`.env.example` is conventionally a placeholder file,
|
|
2470
|
+
`.env.example` is conventionally a placeholder file, projects
|
|
1755
2471
|
occasionally check in real values by mistake. v2.2.0 adds a
|
|
1756
2472
|
sensitive-variable filter (`lib/env-parser.js`: `isSensitiveVarName`,
|
|
1757
2473
|
`redactSensitiveVars`) that replaces values of variables matching
|
|
@@ -1798,7 +2514,7 @@ npx claudeos-core init --force
|
|
|
1798
2514
|
|
|
1799
2515
|
If you want to preview changes first, regenerate into a scratch copy of
|
|
1800
2516
|
the project, diff the resulting files against your current ones, and
|
|
1801
|
-
then decide whether to `--force` on
|
|
2517
|
+
then decide whether to `--force` on your project. Key files to
|
|
1802
2518
|
diff: `CLAUDE.md`, `.claude/rules/00.core/00.standard-reference.md`,
|
|
1803
2519
|
`.claude/rules/40.infra/02.logging-monitoring-rules.md` (paths change
|
|
1804
2520
|
is the most visible delta).
|
|
@@ -1821,7 +2537,7 @@ running `--force` so you can diff/merge any overwrites.
|
|
|
1821
2537
|
rules auto-load (more accurately scoped); the rule content itself
|
|
1822
2538
|
does not change. `stack.envInfo` is a new additive field — older
|
|
1823
2539
|
project-analysis.json files without it still work.
|
|
1824
|
-
- Discovered via
|
|
2540
|
+
- Discovered via regression testing on multiple test projects:
|
|
1825
2541
|
- Structural drift (3 different CLAUDE.md layouts) prompted the scaffold.
|
|
1826
2542
|
- A Vite + React frontend project produced a §9 surplus section under
|
|
1827
2543
|
a renamed title that bypassed the initial forbidden-sections blocklist
|
|
@@ -1902,7 +2618,7 @@ Post-release regression fix for v2.1.0 master plan removal cleanup.
|
|
|
1902
2618
|
is a one-line behavior change (`errors.push(...)` → `console.log(...)`)
|
|
1903
2619
|
with a comment documenting the v2.1.0 context, and regression risk is
|
|
1904
2620
|
covered by routine `health` runs rather than an integration test.
|
|
1905
|
-
- Discovered via
|
|
2621
|
+
- Discovered via regression testing on a Vite 6 + React 19 test project: 62
|
|
1906
2622
|
generated files, all Pass 1–4 stages succeeded, but `health` failed
|
|
1907
2623
|
at content-validator. No other cleanup gaps found.
|
|
1908
2624
|
|
|
@@ -1921,8 +2637,8 @@ Docs-only maintenance release. No runtime behavior or API changes.
|
|
|
1921
2637
|
job is done once the release ships, and the same content is preserved
|
|
1922
2638
|
in `CHANGELOG.md` for anyone who wants the historical detail.
|
|
1923
2639
|
|
|
1924
|
-
- **README: dropped the
|
|
1925
|
-
(2026-04-20)
|
|
2640
|
+
- **README: dropped the 18-domain admin-frontend subsection
|
|
2641
|
+
(2026-04-20 entry)** under _Auto-scaling by Project Size_ across
|
|
1926
2642
|
all 10 language READMEs. The per-stage breakdown table (9 rows) and its
|
|
1927
2643
|
surrounding prose are removed. The trailing empirical reference in the
|
|
1928
2644
|
FAQ "What is Pass 3 split mode" answer (the `Empirically verified up
|
|
@@ -2190,7 +2906,7 @@ project size.
|
|
|
2190
2906
|
- **New shared library modules** — Single sources of truth for Pass 3 output expectations, preventing drift between enforcement and validation:
|
|
2191
2907
|
- `lib/expected-guides.js` — 9 guide file paths. Imported by `init.js` Guard 3 H2 and `content-validator/index.js` `[5/9]` (no more hardcoded duplicates).
|
|
2192
2908
|
- `lib/expected-outputs.js` — 3 additional Pass 3 outputs (standard sentinel, `skills/`, `plan/`) with `findMissingOutputs(projectRoot)` + `hasNonEmptyMdRecursive(dir)` helpers (BOM-aware). Imported by `init.js` Guard 3 H1.
|
|
2193
|
-
- **Async claude execution + progress ticker** — `cli-utils.js` adds `runClaudePromptAsync` (spawn-based, non-blocking; lets a `setInterval` ticker run concurrently with the Claude subprocess) and `runClaudeCapture` (execSync wrapper that captures stdout, used by the translation engine in `memory-scaffold.js`). `init.js` adds `makePassTicker` with three display modes — elapsed-only, file-delta, and fixed-target (`N/M files (P%)`) — driving the per-pass
|
|
2909
|
+
- **Async claude execution + progress ticker** — `cli-utils.js` adds `runClaudePromptAsync` (spawn-based, non-blocking; lets a `setInterval` ticker run concurrently with the Claude subprocess) and `runClaudeCapture` (execSync wrapper that captures stdout, used by the translation engine in `memory-scaffold.js`). `init.js` adds `makePassTicker` with three display modes — elapsed-only, file-delta, and fixed-target (`N/M files (P%)`) — driving the per-pass progress line in TTY (`\r`-rewritten) and CI/piped (periodic newlines) environments.
|
|
2194
2910
|
- **`--force` and "fresh" resume cleanup** — Now also wipes `claudeos-core/generated/.staged-rules/` (leftover from a prior crashed Pass 3/4 run) and `.claude/rules/` (so Guard 2's zero-rules detection can't false-negative on stale rules from a previous run); under `"fresh"` mode the `pass3-complete.json` and `pass4-memory.json` markers are also unlinked so both passes re-execute. Manual edits to `.claude/rules/` are lost — acceptable under the explicit `--force`/`fresh` choice.
|
|
2195
2911
|
- **190+ new tests** (296 → 489) — New/expanded suites: `memory-scaffold.test.js`, `memory-command.test.js`, `pass4-prompt.test.js`, `pass3-marker.test.js`, `pass3-guards.test.js` (Guards 1/2 + Guard 3 H1/H2 with BOM coverage), `pass2-validation.test.js` (H3 structural check), `pass4-marker-validation.test.js` (M1 `isValidPass4Marker` + `dropStalePass4Marker` regression guards), `translation-skip-env.test.js` (M2 env guard + M3 CI workflow presence), `staged-rules.test.js`, `lang-aware-fallback.test.js` (sets `CLAUDEOS_SKIP_TRANSLATION=1` at module top to make translation-throw assertions deterministic), `placeholder-substitution.test.js`, plus expansions to existing suites.
|
|
2196
2912
|
- **Progress bar with ETA** — Pass 1/2/3/4 execution shows a progress bar with percentage, elapsed time, and ETA based on average step duration (carried over and extended from v1.7.0; Pass 4 added).
|