claudeos-core 1.7.1 → 2.0.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.
- package/CHANGELOG.md +121 -0
- package/CONTRIBUTING.md +92 -59
- package/README.de.md +465 -240
- package/README.es.md +446 -223
- package/README.fr.md +461 -238
- package/README.hi.md +485 -261
- package/README.ja.md +440 -235
- package/README.ko.md +244 -56
- package/README.md +215 -47
- package/README.ru.md +462 -238
- package/README.vi.md +454 -230
- package/README.zh-CN.md +476 -252
- package/bin/cli.js +144 -140
- package/bin/commands/init.js +549 -45
- package/bin/commands/memory.js +426 -0
- package/bin/lib/cli-utils.js +206 -143
- package/bootstrap.sh +81 -390
- package/content-validator/index.js +436 -340
- package/lib/expected-guides.js +23 -0
- package/lib/expected-outputs.js +91 -0
- package/lib/language-config.js +35 -0
- package/lib/memory-scaffold.js +1014 -0
- package/lib/plan-parser.js +153 -149
- package/lib/staged-rules.js +118 -0
- package/manifest-generator/index.js +176 -171
- package/package.json +1 -1
- package/pass-json-validator/index.js +337 -299
- package/pass-prompts/templates/common/pass3-footer.md +16 -0
- package/pass-prompts/templates/common/pass4.md +317 -0
- package/pass-prompts/templates/common/staging-override.md +26 -0
- package/plan-installer/prompt-generator.js +120 -96
- package/plan-installer/scanners/scan-frontend.js +216 -9
- package/sync-checker/index.js +133 -132
package/README.md
CHANGED
|
@@ -122,8 +122,34 @@ Supported module types: `command`, `query`, `bff`, `integration`, `standalone`,
|
|
|
122
122
|
- **FSD (Feature-Sliced Design)**: `features/*/`, `widgets/*/`, `entities/*/`
|
|
123
123
|
- **RSC/Client split**: Detects `client.tsx` pattern, tracks Server/Client component separation
|
|
124
124
|
- **Non-standard nested paths**: Detects pages, components, and FSD layers under `src/*/` paths (e.g., `src/admin/pages/dashboard/`, `src/admin/components/form/`, `src/admin/features/billing/`)
|
|
125
|
+
- **Platform/tier-split detection (v2.0.0)**: Recognizes `src/{platform}/{subapp}/` layouts — `{platform}` can be a device/target keyword (`desktop`, `pc`, `web`, `mobile`, `mc`, `mo`, `sp`, `tablet`, `tab`, `pwa`, `tv`, `ctv`, `ott`, `watch`, `wear`) or an access-tier keyword (`admin`, `cms`, `backoffice`, `back-office`, `portal`). Emits one domain per `(platform, subapp)` pair named `{platform}-{subapp}` with per-domain counts for routes/components/layouts/hooks. Runs across Angular, Next.js, React, and Vue simultaneously (multi-extension glob `{tsx,jsx,ts,js,vue}`). Requires ≥2 source files per subapp to avoid noisy 1-file domains.
|
|
126
|
+
- **Monorepo platform split (v2.0.0)**: The platform scan also matches `{apps,packages}/*/src/{platform}/{subapp}/` (Turborepo/pnpm workspace with `src/`) and `{apps,packages}/{platform}/{subapp}/` (workspaces without `src/` wrapper).
|
|
127
|
+
- **Fallback E — routes-file (v2.0.0)**: When primary scanners + Fallbacks A–D all return 0, globs `**/routes/*.{tsx,jsx,ts,js,vue}` and groups by the parent-of-`routes` directory name. Catches React Router file-routing projects (CRA/Vite + `react-router`) that don't match Next.js `page.tsx` or FSD layouts. Generic parent names (`src`, `app`, `pages`) are filtered out.
|
|
125
128
|
- **Config fallback**: Detects Next.js/Vite/Nuxt from config files when not in `package.json` (monorepo support)
|
|
126
129
|
- **Deep directory fallback**: For React/CRA/Vite/Vue/RN projects, scans `**/components/*/`, `**/views/*/`, `**/screens/*/`, `**/containers/*/`, `**/pages/*/`, `**/routes/*/`, `**/modules/*/`, `**/domains/*/` at any depth
|
|
130
|
+
- **Shared ignore lists (v2.0.0)**: All scanners share `BUILD_IGNORE_DIRS` (`node_modules`, `build`, `dist`, `out`, `.next`, `.nuxt`, `.svelte-kit`, `.angular`, `.turbo`, `.cache`, `.parcel-cache`, `coverage`, `storybook-static`, `.vercel`, `.netlify`) and `TEST_FILE_IGNORE` (spec/test/stories/e2e/cy + `__snapshots__`/`__tests__`) so build outputs and test fixtures don't inflate per-domain file counts.
|
|
131
|
+
|
|
132
|
+
### Scanner Overrides (v2.0.0)
|
|
133
|
+
|
|
134
|
+
Drop an optional `.claudeos-scan.json` at your project root to extend scanner defaults without editing the toolkit. All fields are **additive** — user entries extend defaults, never replace:
|
|
135
|
+
|
|
136
|
+
```json
|
|
137
|
+
{
|
|
138
|
+
"frontendScan": {
|
|
139
|
+
"platformKeywords": ["kiosk"],
|
|
140
|
+
"skipSubappNames": ["legacy"],
|
|
141
|
+
"minSubappFiles": 3
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
| Field | Default | Purpose |
|
|
147
|
+
|---|---|---|
|
|
148
|
+
| `platformKeywords` | built-in list above | Additional `{platform}` keywords for the platform scan (e.g., `kiosk`, `vr`, `embedded`) |
|
|
149
|
+
| `skipSubappNames` | structural dirs only | Additional subapp names to exclude from platform-scan domain emission |
|
|
150
|
+
| `minSubappFiles` | `2` | Override the minimum file count required before a subapp becomes a domain |
|
|
151
|
+
|
|
152
|
+
Missing file or malformed JSON → silently falls back to defaults (no crash). Typical use: opt-in a short abbreviation (`adm`, `bo`) that the built-in list excludes as too ambiguous, or raise `minSubappFiles` for noisy monorepos.
|
|
127
153
|
|
|
128
154
|
---
|
|
129
155
|
|
|
@@ -196,7 +222,7 @@ npx claudeos-core init --lang en # English (default)
|
|
|
196
222
|
|
|
197
223
|
> **Note:** This sets the language for generated documentation files only. Code analysis (Pass 1–2) always runs in English; generated output (Pass 3) is written in your chosen language. Code examples inside the generated files remain in their original programming language syntax.
|
|
198
224
|
|
|
199
|
-
That's it. After 5–
|
|
225
|
+
That's it. After 5–20 minutes (Pass 1×N + Pass 2 + Pass 3 + Pass 4 memory scaffolding), all documentation is generated and ready to use. The CLI shows a progress bar with percentage, elapsed time, and ETA for each pass.
|
|
200
226
|
|
|
201
227
|
### Manual Step-by-Step Installation
|
|
202
228
|
|
|
@@ -214,8 +240,8 @@ cd claudeos-core-tools && npm install && cd ..
|
|
|
214
240
|
#### Step 2: Create directory structure
|
|
215
241
|
|
|
216
242
|
```bash
|
|
217
|
-
# Rules
|
|
218
|
-
mkdir -p .claude/rules/{00.core,10.backend,20.frontend,30.security-db,40.infra,50.sync}
|
|
243
|
+
# Rules (v2.0.0: added 60.memory)
|
|
244
|
+
mkdir -p .claude/rules/{00.core,10.backend,20.frontend,30.security-db,40.infra,50.sync,60.memory}
|
|
219
245
|
|
|
220
246
|
# Standards
|
|
221
247
|
mkdir -p claudeos-core/standard/{00.core,10.backend-api,20.frontend-ui,30.security-db,40.infra,50.verification,90.optional}
|
|
@@ -223,9 +249,9 @@ mkdir -p claudeos-core/standard/{00.core,10.backend-api,20.frontend-ui,30.securi
|
|
|
223
249
|
# Skills
|
|
224
250
|
mkdir -p claudeos-core/skills/{00.shared,10.backend-crud/scaffold-crud-feature,20.frontend-page/scaffold-page-feature,50.testing,90.experimental}
|
|
225
251
|
|
|
226
|
-
# Guide, Plan, Database, MCP, Generated
|
|
252
|
+
# Guide, Plan, Database, MCP, Generated, Memory (v2.0.0: added memory)
|
|
227
253
|
mkdir -p claudeos-core/guide/{01.onboarding,02.usage,03.troubleshooting,04.architecture}
|
|
228
|
-
mkdir -p claudeos-core/{plan,database,mcp-guide,generated}
|
|
254
|
+
mkdir -p claudeos-core/{plan,database,mcp-guide,generated,memory}
|
|
229
255
|
```
|
|
230
256
|
|
|
231
257
|
#### Step 3: Run plan-installer (project analysis)
|
|
@@ -241,7 +267,8 @@ node claudeos-core-tools/plan-installer/index.js
|
|
|
241
267
|
- `domain-groups.json` — domain groups for Pass 1
|
|
242
268
|
- `pass1-backend-prompt.md` / `pass1-frontend-prompt.md` — analysis prompts
|
|
243
269
|
- `pass2-prompt.md` — merge prompt
|
|
244
|
-
- `pass3-prompt.md` — generation prompt
|
|
270
|
+
- `pass3-prompt.md` — generation prompt (wrapped with `staging-override.md` directive — see Step 6 note)
|
|
271
|
+
- `pass4-prompt.md` — L4 memory scaffolding prompt (v2.0.0; uses the same `staging-override.md` for `60.memory/` rule writes)
|
|
245
272
|
|
|
246
273
|
You can inspect these files to verify detection accuracy before proceeding.
|
|
247
274
|
|
|
@@ -257,19 +284,31 @@ cat claudeos-core/generated/domain-groups.json | node -e "
|
|
|
257
284
|
"
|
|
258
285
|
|
|
259
286
|
# Run Pass 1 for each group (replace domains and group number)
|
|
287
|
+
# Note: v1.6.1+ uses Node.js String.replace() instead of perl — perl is no
|
|
288
|
+
# longer required, and replacement-function semantics prevent regex injection
|
|
289
|
+
# from $/&/$1 characters that may appear in domain names.
|
|
290
|
+
#
|
|
260
291
|
# For group 1:
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
292
|
+
DOMAIN_LIST="user, order, product" PASS_NUM=1 node -e "
|
|
293
|
+
const fs = require('fs');
|
|
294
|
+
const tpl = fs.readFileSync('claudeos-core/generated/pass1-backend-prompt.md','utf-8');
|
|
295
|
+
const out = tpl
|
|
296
|
+
.replace(/\{\{DOMAIN_GROUP\}\}/g, () => process.env.DOMAIN_LIST)
|
|
297
|
+
.replace(/\{\{PASS_NUM\}\}/g, () => process.env.PASS_NUM);
|
|
298
|
+
process.stdout.write(out);
|
|
299
|
+
" | claude -p --dangerously-skip-permissions
|
|
265
300
|
|
|
266
301
|
# For group 2 (if exists):
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
302
|
+
DOMAIN_LIST="payment, system, delivery" PASS_NUM=2 node -e "
|
|
303
|
+
const fs = require('fs');
|
|
304
|
+
const tpl = fs.readFileSync('claudeos-core/generated/pass1-backend-prompt.md','utf-8');
|
|
305
|
+
const out = tpl
|
|
306
|
+
.replace(/\{\{DOMAIN_GROUP\}\}/g, () => process.env.DOMAIN_LIST)
|
|
307
|
+
.replace(/\{\{PASS_NUM\}\}/g, () => process.env.PASS_NUM);
|
|
308
|
+
process.stdout.write(out);
|
|
309
|
+
" | claude -p --dangerously-skip-permissions
|
|
271
310
|
|
|
272
|
-
# For frontend groups,
|
|
311
|
+
# For frontend groups, swap pass1-backend-prompt.md → pass1-frontend-prompt.md
|
|
273
312
|
```
|
|
274
313
|
|
|
275
314
|
**Verify:** `ls claudeos-core/generated/pass1-*.json` should show one JSON per group.
|
|
@@ -290,9 +329,22 @@ cat claudeos-core/generated/pass3-prompt.md \
|
|
|
290
329
|
| claude -p --dangerously-skip-permissions
|
|
291
330
|
```
|
|
292
331
|
|
|
293
|
-
**Verify:** `CLAUDE.md` should exist in your project root.
|
|
332
|
+
**Verify:** `CLAUDE.md` should exist in your project root, and `claudeos-core/generated/pass3-complete.json` marker should be written.
|
|
333
|
+
|
|
334
|
+
> **Note (v2.0.0):** Pass 3 writes rule files to `claudeos-core/generated/.staged-rules/` first because Claude Code's sensitive-path policy blocks direct writes to `.claude/`. The automated pipeline (`npx claudeos-core init`) handles the move automatically. If you run this step manually, you'll need to move the staged tree yourself: `mv claudeos-core/generated/.staged-rules/* .claude/rules/` (preserve subpaths).
|
|
335
|
+
|
|
336
|
+
#### Step 7: Pass 4 — Memory scaffolding
|
|
337
|
+
|
|
338
|
+
```bash
|
|
339
|
+
cat claudeos-core/generated/pass4-prompt.md \
|
|
340
|
+
| claude -p --dangerously-skip-permissions
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
**Verify:** `claudeos-core/memory/` should contain 4 files (`decision-log.md`, `failure-patterns.md`, `compaction.md`, `auto-rule-update.md`), `.claude/rules/60.memory/` should contain 4 rule files, `claudeos-core/plan/50.memory-master.md` should exist, and `CLAUDE.md` should now have a `## Memory (L4)` section appended. Marker: `claudeos-core/generated/pass4-memory.json`.
|
|
294
344
|
|
|
295
|
-
|
|
345
|
+
> **Note:** If `claude -p` fails or `pass4-prompt.md` is missing, the automated pipeline falls back to a static scaffold via `lib/memory-scaffold.js` (with Claude-driven translation when `--lang` is non-English). The static fallback runs only inside `npx claudeos-core init` — manual mode requires Pass 4 to succeed.
|
|
346
|
+
|
|
347
|
+
#### Step 8: Run verification tools
|
|
296
348
|
|
|
297
349
|
```bash
|
|
298
350
|
# Generate metadata (required before other checks)
|
|
@@ -304,11 +356,11 @@ node claudeos-core-tools/health-checker/index.js
|
|
|
304
356
|
# Or run individual checks:
|
|
305
357
|
node claudeos-core-tools/plan-validator/index.js --check # Plan ↔ disk consistency
|
|
306
358
|
node claudeos-core-tools/sync-checker/index.js # Unregistered/orphaned files
|
|
307
|
-
node claudeos-core-tools/content-validator/index.js # File quality checks
|
|
308
|
-
node claudeos-core-tools/pass-json-validator/index.js # Pass JSON
|
|
359
|
+
node claudeos-core-tools/content-validator/index.js # File quality checks (incl. memory/ section [9/9])
|
|
360
|
+
node claudeos-core-tools/pass-json-validator/index.js # Pass 1–4 JSON + completion marker checks
|
|
309
361
|
```
|
|
310
362
|
|
|
311
|
-
#### Step
|
|
363
|
+
#### Step 9: Verify the results
|
|
312
364
|
|
|
313
365
|
```bash
|
|
314
366
|
# Count generated files
|
|
@@ -339,7 +391,7 @@ ls .claude/rules/*/
|
|
|
339
391
|
|
|
340
392
|
---
|
|
341
393
|
|
|
342
|
-
## How It Works —
|
|
394
|
+
## How It Works — 4-Pass Pipeline
|
|
343
395
|
|
|
344
396
|
```
|
|
345
397
|
npx claudeos-core init
|
|
@@ -362,16 +414,24 @@ npx claudeos-core init
|
|
|
362
414
|
├── [6] Pass 3 × 1 (claude -p) ← Generate everything (~3-5min)
|
|
363
415
|
│ └── Combined prompt (backend + frontend targets)
|
|
364
416
|
│
|
|
365
|
-
|
|
417
|
+
├── [7] Pass 4 × 1 (claude -p) ← Memory scaffolding (~30s)
|
|
418
|
+
│ ├── Seed memory/ (decision-log, failure-patterns, …)
|
|
419
|
+
│ ├── Generate 60.memory/ rules
|
|
420
|
+
│ ├── Append "Memory (L4)" section to CLAUDE.md
|
|
421
|
+
│ └── Build 50.memory-master.md plan
|
|
422
|
+
│
|
|
423
|
+
└── [8] Verification ← Auto-run health checker
|
|
366
424
|
```
|
|
367
425
|
|
|
368
|
-
### Why
|
|
426
|
+
### Why 4 Passes?
|
|
369
427
|
|
|
370
428
|
**Pass 1** is the only pass that reads your source code. It selects representative files per domain and extracts patterns across 55–95 analysis categories (per stack). For large projects, Pass 1 runs multiple times — one per domain group. In multi-stack projects (e.g., Java backend + React frontend), backend and frontend domains use **different analysis prompts** tailored to each stack.
|
|
371
429
|
|
|
372
430
|
**Pass 2** merges all Pass 1 results into a unified analysis: common patterns (100% shared), majority patterns (50%+ shared), domain-specific patterns, anti-patterns by severity, and cross-cutting concerns (naming, security, DB, testing, logging, performance). Backend and frontend results are merged together.
|
|
373
431
|
|
|
374
|
-
**Pass 3** takes the merged analysis and generates the entire file ecosystem. It never reads source code — only the analysis JSON. In multi-stack mode, the generation prompt combines backend and frontend targets so both sets of standards are generated in a single pass.
|
|
432
|
+
**Pass 3** takes the merged analysis and generates the entire file ecosystem (CLAUDE.md, rules, standards, skills, guides). It never reads source code — only the analysis JSON. In multi-stack mode, the generation prompt combines backend and frontend targets so both sets of standards are generated in a single pass.
|
|
433
|
+
|
|
434
|
+
**Pass 4** scaffolds the L4 Memory layer: persistent team knowledge files (decision-log, failure-patterns, compaction policy, auto-rule-update) plus the `60.memory/` rules that tell future sessions when and how to read/write those files. The memory layer is what lets Claude Code accumulate lessons across sessions instead of re-discovering them each time. When `--lang` is non-English, the fallback static content is translated via Claude before being written.
|
|
375
435
|
|
|
376
436
|
---
|
|
377
437
|
|
|
@@ -389,46 +449,75 @@ your-project/
|
|
|
389
449
|
│ ├── 20.frontend/
|
|
390
450
|
│ ├── 30.security-db/
|
|
391
451
|
│ ├── 40.infra/
|
|
392
|
-
│
|
|
452
|
+
│ ├── 50.sync/ ← Sync reminder rules
|
|
453
|
+
│ └── 60.memory/ ← L4 memory on-demand scope rules (v2.0.0)
|
|
393
454
|
│
|
|
394
455
|
├── claudeos-core/ ← Main output directory
|
|
395
|
-
│ ├── generated/ ← Analysis JSON + dynamic prompts
|
|
456
|
+
│ ├── generated/ ← Analysis JSON + dynamic prompts + Pass markers (gitignore this)
|
|
396
457
|
│ │ ├── project-analysis.json ← Stack info (multi-stack aware)
|
|
397
458
|
│ │ ├── domain-groups.json ← Groups with type: backend/frontend
|
|
398
459
|
│ │ ├── pass1-backend-prompt.md ← Backend analysis prompt
|
|
399
460
|
│ │ ├── pass1-frontend-prompt.md ← Frontend analysis prompt (if detected)
|
|
400
461
|
│ │ ├── pass2-prompt.md ← Merge prompt
|
|
401
|
-
│ │
|
|
462
|
+
│ │ ├── pass3-prompt.md ← Generation prompt (combined)
|
|
463
|
+
│ │ ├── pass4-prompt.md ← Memory scaffolding prompt (v2.0.0)
|
|
464
|
+
│ │ ├── pass3-complete.json ← Pass 3 completion marker (skip on resume)
|
|
465
|
+
│ │ ├── pass4-memory.json ← Pass 4 completion marker (skip on resume)
|
|
466
|
+
│ │ ├── .i18n-cache-<lang>.json ← Translation cache (non-English `--lang`)
|
|
467
|
+
│ │ └── .staged-rules/ ← Transient staging dir for `.claude/rules/` writes (auto-moved + cleaned)
|
|
402
468
|
│ ├── standard/ ← Coding standards (15-19 files)
|
|
403
469
|
│ │ ├── 00.core/ ← Overview, architecture, naming
|
|
404
470
|
│ │ ├── 10.backend-api/ ← API patterns (stack-specific)
|
|
405
471
|
│ │ ├── 20.frontend-ui/ ← Frontend patterns (if detected)
|
|
406
472
|
│ │ ├── 30.security-db/ ← Security, DB schema, utilities
|
|
407
473
|
│ │ ├── 40.infra/ ← Config, logging, CI/CD
|
|
408
|
-
│ │
|
|
474
|
+
│ │ ├── 50.verification/ ← Build verification, testing
|
|
475
|
+
│ │ └── 90.optional/ ← Optional conventions (stack-specific extras)
|
|
409
476
|
│ ├── skills/ ← CRUD scaffolding skills
|
|
410
477
|
│ ├── guide/ ← Onboarding, FAQ, troubleshooting (9 files)
|
|
411
478
|
│ ├── plan/ ← Master plans (backup/restore)
|
|
412
479
|
│ ├── database/ ← DB schema, migration guide
|
|
413
|
-
│
|
|
480
|
+
│ ├── mcp-guide/ ← MCP server integration guide
|
|
481
|
+
│ └── memory/ ← L4: team knowledge (4 files) — commit these
|
|
482
|
+
│ ├── decision-log.md ← "Why" behind design decisions
|
|
483
|
+
│ ├── failure-patterns.md ← Recurring errors & fixes (auto-scored — `npx claudeos-core memory score`)
|
|
484
|
+
│ ├── compaction.md ← 4-stage compaction strategy (run `npx claudeos-core memory compact`)
|
|
485
|
+
│ └── auto-rule-update.md ← Rule improvement proposals (`npx claudeos-core memory propose-rules`)
|
|
414
486
|
│
|
|
415
487
|
└── claudeos-core-tools/ ← This toolkit (don't modify)
|
|
416
488
|
```
|
|
417
489
|
|
|
418
490
|
Every standard file includes ✅ correct examples, ❌ incorrect examples, and a rules summary table — all derived from your actual code patterns, not generic templates.
|
|
419
491
|
|
|
492
|
+
### Gitignore recommendations
|
|
493
|
+
|
|
494
|
+
**Do commit** (team knowledge — meant to be shared):
|
|
495
|
+
- `CLAUDE.md` — Claude Code entry point
|
|
496
|
+
- `.claude/rules/**` — auto-loaded rules
|
|
497
|
+
- `claudeos-core/standard/**`, `skills/**`, `guide/**`, `database/**`, `mcp-guide/**`, `plan/**` — generated documentation
|
|
498
|
+
- `claudeos-core/memory/**` — decision history, failure patterns, rule proposals
|
|
499
|
+
|
|
500
|
+
**Do NOT commit** (regeneratable build artifacts):
|
|
501
|
+
|
|
502
|
+
```gitignore
|
|
503
|
+
# ClaudeOS-Core — generated analysis & translation cache
|
|
504
|
+
claudeos-core/generated/
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
The `generated/` directory contains analysis JSON (`pass1-*.json`, `pass2-merged.json`), prompts (`pass1/2/3/4-prompt.md`), Pass completion markers (`pass3-complete.json`, `pass4-memory.json`), translation cache (`.i18n-cache-<lang>.json`), and the transient staging directory (`.staged-rules/`) — all rebuildable by re-running `npx claudeos-core init`.
|
|
508
|
+
|
|
420
509
|
---
|
|
421
510
|
|
|
422
511
|
## Auto-scaling by Project Size
|
|
423
512
|
|
|
424
513
|
| Size | Domains | Pass 1 Runs | Total `claude -p` | Est. Time |
|
|
425
514
|
|---|---|---|---|---|
|
|
426
|
-
| Small | 1–4 | 1 | 3 | ~
|
|
427
|
-
| Medium | 5–8 | 2 |
|
|
428
|
-
| Large | 9–16 | 3–4 |
|
|
429
|
-
| X-Large | 17+ | 5+ |
|
|
515
|
+
| Small | 1–4 | 1 | 4 (Pass 1 + 2 + 3 + 4) | ~5–6min |
|
|
516
|
+
| Medium | 5–8 | 2 | 5 | ~8–9min |
|
|
517
|
+
| Large | 9–16 | 3–4 | 6–7 | ~12–13min |
|
|
518
|
+
| X-Large | 17+ | 5+ | 8+ | ~18min+ |
|
|
430
519
|
|
|
431
|
-
For multi-stack projects (e.g., Java + React), backend and frontend domains are counted together. A project with 6 backend + 4 frontend domains = 10 total, scaling as "Large".
|
|
520
|
+
Pass 4 (memory scaffolding) adds ~30s on top of the analysis passes. For multi-stack projects (e.g., Java + React), backend and frontend domains are counted together. A project with 6 backend + 4 frontend domains = 10 total, scaling as "Large".
|
|
432
521
|
|
|
433
522
|
---
|
|
434
523
|
|
|
@@ -454,11 +543,11 @@ node claudeos-core-tools/sync-checker/index.js
|
|
|
454
543
|
|
|
455
544
|
| Tool | What It Does |
|
|
456
545
|
|---|---|
|
|
457
|
-
| **manifest-generator** | Builds metadata JSON (rule-manifest, sync-map, plan-manifest) |
|
|
546
|
+
| **manifest-generator** | Builds metadata JSON (rule-manifest, sync-map, plan-manifest); indexes 7 directories including `memory/` (`totalMemory` in summary) |
|
|
458
547
|
| **plan-validator** | Compares Master Plan `<file>` blocks against disk — 3 modes: check, refresh, restore |
|
|
459
|
-
| **sync-checker** | Detects unregistered files (on disk but not in plan) and orphaned entries |
|
|
460
|
-
| **content-validator** |
|
|
461
|
-
| **pass-json-validator** | Validates Pass 1–
|
|
548
|
+
| **sync-checker** | Detects unregistered files (on disk but not in plan) and orphaned entries — covers 7 directories (added `memory/` in v2.0.0) |
|
|
549
|
+
| **content-validator** | 9-section quality check — empty files, missing ✅/❌ examples, required sections, plus L4 memory scaffold integrity (decision-log heading dates, failure-pattern required fields, fence-aware parsing) |
|
|
550
|
+
| **pass-json-validator** | Validates Pass 1–4 JSON structure plus the `pass3-complete.json` and `pass4-memory.json` completion markers |
|
|
462
551
|
|
|
463
552
|
---
|
|
464
553
|
|
|
@@ -473,9 +562,11 @@ ClaudeOS-Core generates documentation that Claude Code actually reads — here's
|
|
|
473
562
|
| `CLAUDE.md` | Every conversation start | Always |
|
|
474
563
|
| `.claude/rules/00.core/*` | When any file is edited (`paths: ["**/*"]`) | Always |
|
|
475
564
|
| `.claude/rules/10.backend/*` | When any file is edited (`paths: ["**/*"]`) | Always |
|
|
565
|
+
| `.claude/rules/20.frontend/*` | When any frontend file is edited (scoped to component/page/style paths) | Conditional |
|
|
476
566
|
| `.claude/rules/30.security-db/*` | When any file is edited (`paths: ["**/*"]`) | Always |
|
|
477
567
|
| `.claude/rules/40.infra/*` | Only when editing config/infra files (scoped paths) | Conditional |
|
|
478
568
|
| `.claude/rules/50.sync/*` | Only when editing claudeos-core files (scoped paths) | Conditional |
|
|
569
|
+
| `.claude/rules/60.memory/*` | When `claudeos-core/memory/*` is edited (scoped to memory paths) — instructs **how** to read/write the on-demand memory layer | Conditional (v2.0.0) |
|
|
479
570
|
|
|
480
571
|
### What Claude Code reads on-demand via rule references
|
|
481
572
|
|
|
@@ -483,6 +574,7 @@ Each rule file links to its corresponding standard via a `## Reference` section.
|
|
|
483
574
|
|
|
484
575
|
- `claudeos-core/standard/**` — coding patterns, ✅/❌ examples, naming conventions
|
|
485
576
|
- `claudeos-core/database/**` — DB schema (for queries, mappers, migrations)
|
|
577
|
+
- `claudeos-core/memory/**` (v2.0.0) — L4 team knowledge layer; **not** auto-loaded (would be too noisy on every conversation). Instead, the `60.memory/*` rules tell Claude *when* to Read these files: at session start (skim recent `decision-log.md` + high-importance `failure-patterns.md`), and append-on-demand when making decisions or hitting recurring errors.
|
|
486
578
|
|
|
487
579
|
The `00.standard-reference.md` serves as a directory of all standard files for discovering standards that have no corresponding rule.
|
|
488
580
|
|
|
@@ -493,9 +585,10 @@ These folders are explicitly excluded via the `DO NOT Read` section in the stand
|
|
|
493
585
|
| Folder | Why excluded |
|
|
494
586
|
|---|---|
|
|
495
587
|
| `claudeos-core/plan/` | Master Plan backups (~340KB). Use `npx claudeos-core refresh` to sync. |
|
|
496
|
-
| `claudeos-core/generated/` | Build metadata JSON
|
|
588
|
+
| `claudeos-core/generated/` | Build metadata JSON, prompts, Pass markers, translation cache, `.staged-rules/`. Not for coding. |
|
|
497
589
|
| `claudeos-core/guide/` | Onboarding guides for humans. |
|
|
498
590
|
| `claudeos-core/mcp-guide/` | MCP server docs. Not for coding. |
|
|
591
|
+
| `claudeos-core/memory/` (auto-load) | **Auto-load disabled** by design — would balloon context on every conversation. Read on-demand via the `60.memory/*` rules instead (e.g. session-start scan of `failure-patterns.md`). Always commit these files. |
|
|
499
592
|
|
|
500
593
|
---
|
|
501
594
|
|
|
@@ -527,12 +620,46 @@ npx claudeos-core health
|
|
|
527
620
|
npx claudeos-core restore
|
|
528
621
|
```
|
|
529
622
|
|
|
623
|
+
### Memory Layer Maintenance (v2.0.0)
|
|
624
|
+
|
|
625
|
+
The L4 Memory layer (`claudeos-core/memory/`) accumulates team knowledge across sessions. Three CLI subcommands keep it healthy:
|
|
626
|
+
|
|
627
|
+
```bash
|
|
628
|
+
# Compact: enforce 4-stage compaction policy (run periodically — e.g. monthly)
|
|
629
|
+
npx claudeos-core memory compact
|
|
630
|
+
# Stage 1: summarize aged entries (>30 days, body → one-line)
|
|
631
|
+
# Stage 2: merge duplicate headings (frequency summed, latest fix kept)
|
|
632
|
+
# Stage 3: drop low-importance + aged (importance <3 AND lastSeen >60 days)
|
|
633
|
+
# Stage 4: enforce 400-line cap per file (oldest low-importance dropped first)
|
|
634
|
+
|
|
635
|
+
# Score: re-rank failure-patterns.md entries by importance
|
|
636
|
+
npx claudeos-core memory score
|
|
637
|
+
# importance = round(frequency × 1.5 + recency × 5), capped at 10
|
|
638
|
+
# Run after appending several new failure patterns
|
|
639
|
+
|
|
640
|
+
# Propose-rules: surface candidate rule additions from recurring failures
|
|
641
|
+
npx claudeos-core memory propose-rules
|
|
642
|
+
# Reads failure-patterns.md entries with frequency ≥ 3
|
|
643
|
+
# Computes confidence (sigmoid on weighted evidence × anchor multiplier)
|
|
644
|
+
# Writes proposals to memory/auto-rule-update.md (NOT auto-applied)
|
|
645
|
+
# Confidence ≥ 0.70 deserves serious review; accept → edit rule + log decision
|
|
646
|
+
```
|
|
647
|
+
|
|
648
|
+
When to write to memory (Claude does this on-demand, but you can edit manually too):
|
|
649
|
+
- **`decision-log.md`** — append a new entry whenever you choose between competing patterns, select a library, define a team convention, or decide NOT to do something. Append-only; never edit historical entries.
|
|
650
|
+
- **`failure-patterns.md`** — append on the **second occurrence** of a recurring error or non-obvious root cause. First-time errors don't need an entry.
|
|
651
|
+
- `compaction.md` and `auto-rule-update.md` — generated/managed by the CLI subcommands above; don't edit by hand.
|
|
652
|
+
|
|
530
653
|
### CI/CD Integration
|
|
531
654
|
|
|
532
655
|
```yaml
|
|
533
656
|
# GitHub Actions example
|
|
534
657
|
- run: npx claudeos-core validate
|
|
535
658
|
# Exit code 1 blocks the PR
|
|
659
|
+
|
|
660
|
+
# Optional: monthly memory housekeeping (separate cron workflow)
|
|
661
|
+
- run: npx claudeos-core memory compact
|
|
662
|
+
- run: npx claudeos-core memory score
|
|
536
663
|
```
|
|
537
664
|
|
|
538
665
|
---
|
|
@@ -554,6 +681,7 @@ npx claudeos-core restore
|
|
|
554
681
|
| **Post-generation verification** | ✅ 5 automated validators | ❌ | ❌ | ❌ | ❌ |
|
|
555
682
|
| **Multi-language output** | ✅ 10 languages | ❌ | ❌ | ❌ | ❌ |
|
|
556
683
|
| **Multi-stack** | ✅ Backend + Frontend simultaneous | ❌ Stack-agnostic | ❌ | ❌ | Partial |
|
|
684
|
+
| **Persistent memory layer** | ✅ L4 — decision log + failure patterns + auto-scored rule proposals (v2.0.0) | ❌ | ❌ | ❌ | ❌ |
|
|
557
685
|
| **Agent orchestration** | ❌ | ✅ 28 agents | ✅ 6 patterns | ❌ | ❌ |
|
|
558
686
|
|
|
559
687
|
### The key difference in one sentence
|
|
@@ -579,7 +707,7 @@ You can use ClaudeOS-Core to generate your project's rules, then use ECC or Harn
|
|
|
579
707
|
No. It only creates `CLAUDE.md`, `.claude/rules/`, and `claudeos-core/`. Your existing code is never modified.
|
|
580
708
|
|
|
581
709
|
**Q: How much does it cost?**
|
|
582
|
-
It calls `claude -p`
|
|
710
|
+
It calls `claude -p` 4–8 times (Pass 1 × N + Pass 2 + Pass 3 + Pass 4). This is within normal Claude Code usage. When `--lang` is non-English, the static fallback path may invoke a few additional `claude -p` calls for translation; results are cached in `claudeos-core/generated/.i18n-cache-<lang>.json` so subsequent runs reuse them.
|
|
583
711
|
|
|
584
712
|
**Q: Should I commit the generated files to Git?**
|
|
585
713
|
Yes, recommended. Your team can share the same Claude Code standards. Consider adding `claudeos-core/generated/` to `.gitignore` (analysis JSON is regeneratable).
|
|
@@ -608,26 +736,43 @@ Fully supported for Kotlin multi-module projects. ClaudeOS-Core reads `settings.
|
|
|
608
736
|
**Q: What about Gradle multi-module monorepos?**
|
|
609
737
|
ClaudeOS-Core scans all submodules (`**/src/main/kotlin/**/*.kt`) regardless of nesting depth. Module types are inferred from naming conventions (e.g., `reservation-command-server` → domain: `reservation`, type: `command`). Shared libraries (`shared-lib`, `integration-lib`) are also detected.
|
|
610
738
|
|
|
739
|
+
**Q: What is the L4 Memory layer (v2.0.0)? Should I commit `claudeos-core/memory/`?**
|
|
740
|
+
Yes — **always commit** `claudeos-core/memory/`. It's persistent team knowledge: `decision-log.md` records the *why* behind architectural choices (append-only), `failure-patterns.md` registers recurring errors with importance scores so future sessions avoid them, `compaction.md` defines the 4-stage compaction policy, and `auto-rule-update.md` collects machine-generated rule improvement proposals. Unlike rules (auto-loaded by path), memory files are **on-demand** — Claude reads them only when the `60.memory/*` rules direct it to (e.g. session-start scan of high-importance failures). This keeps context cost low while preserving long-term knowledge.
|
|
741
|
+
|
|
742
|
+
**Q: What if Pass 4 fails?**
|
|
743
|
+
The automated pipeline (`npx claudeos-core init`) has a static fallback: if `claude -p` fails or `pass4-prompt.md` is missing, it scaffolds the memory layer directly via `lib/memory-scaffold.js`. When `--lang` is non-English, the static fallback **must** translate via the `claude` CLI — if that fails too, the run aborts with `InitError` (no silent English fallback). Re-run when `claude` is authenticated, or use `--lang en` to skip translation. Translation results are cached in `claudeos-core/generated/.i18n-cache-<lang>.json` so subsequent runs reuse them.
|
|
744
|
+
|
|
745
|
+
**Q: What do `memory compact` / `memory score` / `memory propose-rules` do?**
|
|
746
|
+
See the [Memory Layer Maintenance](#memory-layer-maintenance-v200) section above. Short version: `compact` runs the 4-stage policy (summarize aged, merge duplicates, drop low-importance aged, enforce 400-line cap); `score` re-ranks `failure-patterns.md` by importance (frequency × recency); `propose-rules` surfaces candidate rule additions from recurring failures into `auto-rule-update.md` (not auto-applied — review and accept/reject manually).
|
|
747
|
+
|
|
748
|
+
**Q: Why does `--force` (or "fresh" resume mode) delete `.claude/rules/`?**
|
|
749
|
+
v2.0.0 added three Pass 3 silent-failure guards (Guard 3 covers two incomplete-output variants: H2 for `guide/` and H1 for `standard/skills/plan`). Guard 1 ("partial staged-rules move") and Guard 3 ("incomplete output — missing/empty guide files or missing standard sentinel / empty skills / empty plan") don't depend on existing rules, but Guard 2 ("zero rules detected") does — it fires when Claude ignored the `staging-override.md` directive and tried to write directly to `.claude/` (where Claude Code's sensitive-path policy blocks it). Stale rules from a prior run would let Guard 2 false-negative — so `--force`/`fresh` wipes `.claude/rules/` to ensure a clean detection. **Manual edits to rule files will be lost** under `--force`/`fresh`; back them up first if needed.
|
|
750
|
+
|
|
751
|
+
**Q: What is `claudeos-core/generated/.staged-rules/` and why does it exist?**
|
|
752
|
+
Claude Code's sensitive-path policy refuses direct writes to `.claude/` from the `claude -p` subprocess (even with `--dangerously-skip-permissions`). v2.0.0 works around this by having Pass 3/4 prompts redirect all `.claude/rules/` writes to the staging directory; the Node.js orchestrator (not subject to that policy) then moves the staged tree into `.claude/rules/` after each pass. This is transparent to the user — the directory is auto-created, auto-cleaned, and auto-moved. If a prior run crashed mid-move, the next run wipes the staging dir before retrying.
|
|
753
|
+
|
|
611
754
|
---
|
|
612
755
|
|
|
613
756
|
## Template Structure
|
|
614
757
|
|
|
615
758
|
```
|
|
616
759
|
pass-prompts/templates/
|
|
617
|
-
├── common/ # Shared header/footer
|
|
760
|
+
├── common/ # Shared header/footer + pass4 + staging-override
|
|
618
761
|
├── java-spring/ # Java / Spring Boot
|
|
619
762
|
├── kotlin-spring/ # Kotlin / Spring Boot (CQRS, BFF, multi-module)
|
|
620
763
|
├── node-express/ # Node.js / Express
|
|
621
764
|
├── node-nestjs/ # Node.js / NestJS (Module, DI, Guard, Pipe, Interceptor)
|
|
622
765
|
├── node-fastify/ # Node.js / Fastify
|
|
623
|
-
├── node-nextjs/ # Next.js / React
|
|
766
|
+
├── node-nextjs/ # Next.js / React (App Router, RSC)
|
|
767
|
+
├── node-vite/ # Vite SPA (React, client-side routing, VITE_ env, Vitest)
|
|
624
768
|
├── vue-nuxt/ # Vue / Nuxt (Composition API, Pinia, Nitro)
|
|
625
769
|
├── angular/ # Angular
|
|
626
770
|
├── python-django/ # Python / Django (DRF)
|
|
627
|
-
|
|
771
|
+
├── python-fastapi/ # Python / FastAPI
|
|
772
|
+
└── python-flask/ # Python / Flask (Blueprint, app factory, Jinja2)
|
|
628
773
|
```
|
|
629
774
|
|
|
630
|
-
`plan-installer` auto-detects your stack(s), then assembles type-specific prompts. NestJS
|
|
775
|
+
`plan-installer` auto-detects your stack(s), then assembles type-specific prompts. NestJS, Vue/Nuxt, Vite SPA, and Flask each use dedicated templates with framework-specific analysis categories (e.g., `@Module`/`@Injectable`/Guards for NestJS; `<script setup>`/Pinia/useFetch for Vue; client-side routing/`VITE_` env for Vite; Blueprint/`app.factory`/Flask-SQLAlchemy for Flask). For multi-stack projects, separate `pass1-backend-prompt.md` and `pass1-frontend-prompt.md` are generated, while `pass3-prompt.md` combines both stacks' generation targets. Pass 4 uses the shared `common/pass4.md` template (memory scaffolding) regardless of stack.
|
|
631
776
|
|
|
632
777
|
---
|
|
633
778
|
|
|
@@ -691,15 +836,38 @@ my-monorepo/ ← Run here: npx claudeos-core init
|
|
|
691
836
|
|
|
692
837
|
**"CQRS not detected"** — Architecture detection relies on module names containing `command` and `query` keywords. If your modules use different naming (e.g., `write-server`, `read-server`), the CQRS architecture won't be auto-detected. You can manually adjust the generated prompts after plan-installer runs.
|
|
693
838
|
|
|
839
|
+
**"Pass 3 produced 0 rule files under .claude/rules/" (v2.0.0)** — Guard 2 fired: Claude ignored the `staging-override.md` directive and tried to write directly to `.claude/`, where Claude Code's sensitive-path policy blocks writes. Re-run with `npx claudeos-core init --force`. If the error persists, inspect `claudeos-core/generated/pass3-prompt.md` to verify the `staging-override.md` block is at the top.
|
|
840
|
+
|
|
841
|
+
**"Pass 3 finished but N rule file(s) could not be moved from staging" (v2.0.0)** — Guard 1 fired: the staging move hit a transient file lock (typically Windows antivirus or file-watcher). The marker is NOT written, so the next `init` run automatically retries Pass 3. Just re-run `npx claudeos-core init`.
|
|
842
|
+
|
|
843
|
+
**"Pass 3 produced CLAUDE.md and rules but N/9 guide files are missing or empty" (v2.0.0)** — Guard 3 (H2) fired: Claude truncated mid-response after writing CLAUDE.md + rules but before finishing (or starting) the `claudeos-core/guide/` section (9 files expected). Also fires on a BOM-only or whitespace-only file (heading was written but the body was truncated). Without this guard the completion marker would still be written, leaving `guide/` permanently empty on subsequent runs. The marker is NOT written here, so the next `init` run retries Pass 3 from the same Pass 2 results. If it keeps repeating, re-run with `npx claudeos-core init --force` to regenerate from scratch.
|
|
844
|
+
|
|
845
|
+
**"Pass 3 finished but the following required output(s) are missing or empty" (v2.0.0)** — Guard 3 (H1) fired: Claude truncated AFTER `claudeos-core/guide/` but before (or during) `claudeos-core/standard/`, `claudeos-core/skills/`, or `claudeos-core/plan/`. Requirements: (a) `standard/00.core/01.project-overview.md` exists and is non-empty (sentinel written by every stack's Pass 3 prompt), (b) `skills/` has ≥1 non-empty `.md`, (c) `plan/` has ≥1 non-empty `.md`. `database/` and `mcp-guide/` are intentionally excluded (some stacks legitimately produce zero files). Same recovery path as Guard 3 (H2): re-run `init`, or `--force` if it persists.
|
|
846
|
+
|
|
847
|
+
**"pass2-merged.json exists but is malformed or incomplete (<5 top-level keys), re-running" (v2.0.0)** — Info log, not an error. On resume, `init` now parses and validates `pass2-merged.json` (≥5 top-level keys required, mirroring `pass-json-validator`'s `INSUFFICIENT_KEYS` threshold). Skeleton `{}` or malformed JSON from a prior crashed run is automatically deleted and Pass 2 re-runs. No manual action needed — the pipeline self-heals. If it keeps recurring, inspect `claudeos-core/generated/pass2-prompt.md` and retry with `--force`.
|
|
848
|
+
|
|
849
|
+
**"Static fallback failed while translating to lang='ko'" (v2.0.0)** — When `--lang` is non-English, Pass 4 / static fallback / gap-fill all require `claude` CLI to translate. If translation fails (CLI not authenticated, network timeout, or strict validation rejected the output: <40% length, broken code fences, lost frontmatter, etc.), the run aborts rather than silently writing English. Fix: ensure `claude` is authenticated, or re-run with `--lang en` to skip translation.
|
|
850
|
+
|
|
851
|
+
**"pass4-memory.json exists but memory/ is empty" (v2.0.0)** — A previous run wrote the marker but the user (or a cleanup script) deleted `claudeos-core/memory/`. The CLI auto-detects this stale marker and re-runs Pass 4 on the next `init`. No manual action needed.
|
|
852
|
+
|
|
853
|
+
**"pass4-memory.json exists but is malformed (missing passNum/memoryFiles) — re-running Pass 4" (v2.0.0)** — Info log, not an error. The Pass 4 marker content is now validated (`passNum === 4` + non-empty `memoryFiles` array), not just its existence. A partial Claude failure that emitted something like `{"error":"timeout"}` as the marker body would previously be accepted as success forever; now the marker is deleted and Pass 4 re-runs automatically.
|
|
854
|
+
|
|
855
|
+
**"Could not delete stale pass3-complete.json / pass4-memory.json" InitError (v2.0.0)** — `init` detected a stale marker (Pass 3: CLAUDE.md was externally deleted; Pass 4: memory/ empty or marker body malformed) and tried to remove it, but the `unlinkSync` call failed — typically because Windows antivirus or a file-watcher (editor, IDE indexer) is holding the file handle. Previously this was silently ignored, causing the pipeline to skip the pass and re-use the stale marker. Now it fails loudly. Fix: close any editor/AV scanner that might have the file open, then re-run `npx claudeos-core init`.
|
|
856
|
+
|
|
857
|
+
**"CLAUDEOS_SKIP_TRANSLATION=1 is set but --lang='ko' requires translation" InitError (v2.0.0)** — You have the test-only env var `CLAUDEOS_SKIP_TRANSLATION=1` set in your shell (likely a leftover from CI/test setup) AND picked a non-English `--lang`. This env var short-circuits the translation path that Pass 4's static-fallback and gap-fill depend on for non-English output. `init` detects the conflict at language-selection time and aborts immediately (rather than crashing mid-Pass-4 with a confusing nested error). Fix: either `unset CLAUDEOS_SKIP_TRANSLATION` before running, or use `npx claudeos-core init --lang en`.
|
|
858
|
+
|
|
694
859
|
---
|
|
695
860
|
|
|
696
861
|
## Contributing
|
|
697
862
|
|
|
698
863
|
Contributions are welcome! Areas where help is most needed:
|
|
699
864
|
|
|
700
|
-
- **New stack templates** — Ruby/Rails, Go/
|
|
701
|
-
- **
|
|
702
|
-
- **
|
|
865
|
+
- **New stack templates** — Ruby/Rails, Go (Gin/Fiber/Echo), PHP (Laravel/Symfony), Rust (Axum/Actix), Svelte/SvelteKit, Remix
|
|
866
|
+
- **IDE integration** — VS Code extension, IntelliJ plugin
|
|
867
|
+
- **CI/CD templates** — GitLab CI, CircleCI, Jenkins examples (GitHub Actions already shipped — see `.github/workflows/test.yml`)
|
|
868
|
+
- **Test coverage** — Expanding test suite (currently 489 tests across 24 test files covering scanners, stack detection, domain grouping, plan parsing, prompt generation, CLI selectors, monorepo detection, Vite SPA detection, verification tools, L4 memory scaffold, Pass 2 resume validation, Pass 3 Guards 1/2/3 (H1 sentinel + H2 BOM-aware empty-file + strict stale-marker unlink), Pass 4 marker content validation + stale-marker unlink strictness, translation env-skip guard + early fail-fast + CI workflow, staged-rules move, lang-aware translation fallback, and AI Work Rules template structure)
|
|
869
|
+
|
|
870
|
+
See [`CONTRIBUTING.md`](./CONTRIBUTING.md) for the full list of areas, code style, commit convention, and the step-by-step guide for adding a new stack template.
|
|
703
871
|
|
|
704
872
|
---
|
|
705
873
|
|