claude-prism 1.5.0 → 1.6.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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-prism",
3
- "version": "1.5.0",
3
+ "version": "1.6.0",
4
4
  "description": "AI agent harness implementing the EUDEC methodology",
5
5
  "author": { "name": "lazysaturday91" },
6
6
  "repository": "https://github.com/lazysaturday91/claude-prism",
package/CHANGELOG.md CHANGED
@@ -5,6 +5,38 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.6.0] — 2026-03-05
9
+
10
+ ### Added
11
+ - **Session Bootstrap** — `<!-- PRISM:BOOT -->` block auto-injected into CLAUDE.md; instructs agents to read `docs/PROJECT-MEMORY.md`, `docs/HANDOFF.md`, active plans, and `.prism/registry.json` on session start
12
+ - **Plan Frontmatter** — plans support YAML frontmatter (`status`, `created`, `depends_on`); `/plan list` shows status icons (📋 active, ✅ completed, 📦 archived, 🚫 blocked)
13
+ - **Plan Check** — `/plan check` subcommand detects file overlaps across active plans (cross-plan conflict detection)
14
+ - **Docs Scaffolding** — `prism init --docs` creates `docs/` structure with `PROJECT-MEMORY.md`, `HANDOFF.md` templates and `.prism/registry.json` (auto-scans existing docs)
15
+ - **Project Registry** — `.prism/registry.json` catalogs SSOT documents, session files, and reference/archive paths
16
+ - **Lightweight Recording** — lightweight tasks now record a 1-line summary to `docs/PROJECT-MEMORY.md`
17
+ - **HANDOFF Auto-triggers** — rules.md documents PreCompact/SessionEnd hook auto-generation of HANDOFF.md
18
+
19
+ ### Changed
20
+ - `getActivePlanInfo()` now filters by frontmatter `status: active` (backward-compatible: no frontmatter = active)
21
+ - `dryRun()` shows docs scaffolding actions when `--docs` is used
22
+ - `stats.md` plan list shows frontmatter status icons
23
+ - `rules-lean.md` Session Handoff section updated with auto-generation info
24
+
25
+ ### New exports
26
+ - `parseFrontmatter(content)` — parse YAML-like frontmatter from markdown
27
+ - `getAllPlans(projectRoot)` — list all plans with frontmatter + progress info merged
28
+ - `detectPlanConflicts(projectRoot)` — find file overlaps across active plans
29
+
30
+ ## [1.6.0-beta.1] — 2026-03-04
31
+
32
+ ### Added
33
+ - **Lean Router** — `rulesMode: "lean"` in `.prism/config.json` injects ~80-line behavioral modifiers instead of the full ~500-line methodology
34
+ - Core principle, Adaptive Weight routing, Bugfix Fast Path, Scope Guard, Verification Fallback Ladder, Self-correction triggers, Rationalization Defense, Completion Declaration
35
+ - Standard/Full tasks routed to `/claude-prism:prism` slash command for full EUDEC guidance
36
+ - Fallback: if `rules-lean.md` missing, automatically uses `rules.md`
37
+ - `getRulesMode()` export in `lib/config.mjs`
38
+ - 5 new lean mode tests
39
+
8
40
  ## [1.5.0] — 2026-03-04
9
41
 
10
42
  ### Changed
package/README.md CHANGED
@@ -90,6 +90,12 @@ Injected into `CLAUDE.md`, EUDEC is a behavioral framework that corrects how AI
90
90
  - **Streamlined verification**: 3-level fallback ladder (Tests → Build → Diff)
91
91
  - **Adaptive checkpoints**: no pause for small tasks, summary for medium, full for large
92
92
 
93
+ **New in v1.6.0:**
94
+ - **Session Bootstrap** — agents auto-read `PROJECT-MEMORY.md`, `HANDOFF.md`, active plans, and registry on session start
95
+ - **Plan Lifecycle** — frontmatter (`status`, `created`, `depends_on`), `/plan check` for cross-plan file conflict detection
96
+ - **Docs Scaffolding** — `prism init --docs` creates `docs/` with templates + `.prism/registry.json`
97
+ - **Lightweight Recording** — even small tasks append a 1-line summary to `docs/PROJECT-MEMORY.md`
98
+
93
99
  **New in v1.4.0:**
94
100
  - **Native Claude Code plugin** — `claude plugin install claude-prism` for zero-config setup
95
101
  - **4 new hook events** — PreCompact (auto-HANDOFF), SessionEnd (session protection), SubagentStart (scope injection), TaskCompleted (plan auto-update)
@@ -187,6 +193,7 @@ Plugin mode auto-registers hooks and skills. Run `prism init` additionally if yo
187
193
 
188
194
  ```bash
189
195
  npx claude-prism init # Install with hooks (prompts for HUD)
196
+ npx claude-prism init --docs # Install + docs scaffolding (PROJECT-MEMORY, HANDOFF, registry)
190
197
  npx claude-prism init --hud # Install + auto-enable HUD
191
198
  npx claude-prism init --no-hooks # Methodology only, no hooks
192
199
  npx claude-prism init --global # Global skill (all projects)
@@ -246,15 +253,32 @@ Edit `.prism/config.json`:
246
253
  | Setting | Default | Description |
247
254
  |---------|---------|-------------|
248
255
  | `version` | 1 | Config schema version (for future migrations) |
256
+ | `rulesMode` | `"full"` | `"full"` injects the complete ~500-line EUDEC methodology; `"lean"` injects ~80-line behavioral modifiers and routes to `/claude-prism:prism` for full guidance |
249
257
  | `commit-guard.maxTestAge` | 300 | Seconds before test run is considered stale |
250
258
  | `plan-enforcement.warnAt` | 6 | Unique source file count that triggers plan warning |
251
259
  | `task-plan-sync.matchThreshold` | 0.3 | Keyword overlap ratio for fuzzy task matching |
252
260
  | `webhooks` | `[]` | HTTP endpoints for event notifications |
253
261
 
262
+ ### Lean Router (beta)
263
+
264
+ By default, Prism injects the full EUDEC methodology (~500 lines) into `CLAUDE.md`. This provides passive absorption — the agent always has the complete framework in context.
265
+
266
+ **Lean mode** injects only ~80 lines of behavioral modifiers (Scope Guard, Verification Ladder, Bugfix Fast Path, etc.) and routes Standard/Full tasks to the `/claude-prism:prism` slash command for on-demand full guidance. This saves context window for code.
267
+
268
+ ```bash
269
+ # Switch to lean mode
270
+ echo '{"version":1,"rulesMode":"lean"}' > .prism/config.json
271
+ prism update
272
+
273
+ # Switch back to full mode
274
+ echo '{"version":1,"rulesMode":"full"}' > .prism/config.json
275
+ prism update
276
+ ```
277
+
254
278
  ## CLI Commands
255
279
 
256
280
  ```bash
257
- prism init [--no-hooks] [--global] [--dry-run] # Install
281
+ prism init [--no-hooks] [--docs] [--global] [--dry-run] # Install
258
282
  prism init --hud # Install + auto-enable HUD
259
283
  prism check [--ci] # Verify installation
260
284
  prism doctor # Diagnose issues
package/bin/cli.mjs CHANGED
@@ -44,9 +44,11 @@ switch (command) {
44
44
 
45
45
  const hooks = !hasFlag('no-hooks');
46
46
 
47
+ const docs = hasFlag('docs');
48
+
47
49
  if (hasFlag('dry-run')) {
48
50
  const { dryRun } = await import('../lib/installer.mjs');
49
- const result = dryRun(cwd, { hooks });
51
+ const result = dryRun(cwd, { hooks, docs });
50
52
  console.log('🌈 claude-prism init --dry-run\n');
51
53
  console.log(' Files that would be created/updated:\n');
52
54
  for (const action of result.actions) {
@@ -58,7 +60,7 @@ switch (command) {
58
60
  }
59
61
 
60
62
  console.log('🌈 claude-prism init\n');
61
- await init(cwd, { hooks });
63
+ await init(cwd, { hooks, docs });
62
64
 
63
65
  console.log('✅ EUDEC methodology → CLAUDE.md');
64
66
  console.log('✅ Commands → /prism, /checkpoint, /plan');
@@ -67,6 +69,10 @@ switch (command) {
67
69
  } else {
68
70
  console.log('⏭️ Hooks skipped (--no-hooks)');
69
71
  }
72
+ if (docs) {
73
+ console.log('✅ Docs scaffolding → docs/PROJECT-MEMORY.md, docs/HANDOFF.md');
74
+ console.log('✅ Registry → .prism/registry.json');
75
+ }
70
76
 
71
77
  // HUD prompt — only ask interactively if not already installed and no flag given
72
78
  if (!hasFlag('no-hud') && process.stdin.isTTY) {
@@ -308,7 +314,7 @@ switch (command) {
308
314
  console.log(`🌈 claude-prism — EUDEC methodology framework for AI coding agents
309
315
 
310
316
  Usage:
311
- prism init [--no-hooks] Install prism in current project
317
+ prism init [--no-hooks] [--docs] Install prism in current project
312
318
  prism init --global Install globally (~/.claude/) + OMC skill
313
319
  prism check [--ci] Verify installation
314
320
  prism doctor Diagnose issues with fix suggestions
@@ -325,6 +331,7 @@ Usage:
325
331
 
326
332
  Options:
327
333
  --no-hooks Skip commit guard hook
334
+ --docs Create docs/ scaffolding (PROJECT-MEMORY.md, HANDOFF.md, registry.json)
328
335
  --hud Auto-enable HUD during init (no prompt)
329
336
  --no-hud Skip HUD prompt during init
330
337
  --dry-run Show what init would do without making changes
package/lib/config.mjs CHANGED
@@ -7,6 +7,7 @@ import { readFileSync, existsSync } from 'fs';
7
7
  import { join } from 'path';
8
8
 
9
9
  const DEFAULTS = {
10
+ rulesMode: 'full',
10
11
  sourceExtensions: ['ts', 'tsx', 'js', 'jsx', 'py', 'go', 'rs', 'java', 'c', 'cpp', 'h', 'svelte', 'vue', 'rb', 'kt', 'swift', 'php', 'cs', 'scala', 'ex', 'clj', 'zig', 'lua', 'dart'],
11
12
  testPatterns: ['test', 'spec', '_test'],
12
13
  customRules: [],
@@ -70,4 +71,9 @@ export function buildTestPattern(patterns) {
70
71
  return new RegExp(`\\.(${escaped.join('|')})\\.`);
71
72
  }
72
73
 
74
+ export function getRulesMode(projectRoot) {
75
+ const config = loadConfig(projectRoot);
76
+ return config.rulesMode === 'lean' ? 'lean' : 'full';
77
+ }
78
+
73
79
  export { DEFAULTS };
package/lib/handoff.mjs CHANGED
@@ -70,23 +70,61 @@ export function generateHandoff(projectRoot) {
70
70
  }
71
71
 
72
72
  /**
73
- * Read active plan file and extract progress info
73
+ * Parse YAML-like frontmatter from markdown content
74
+ * @param {string} content - Markdown file content
75
+ * @returns {Object} Parsed frontmatter key-value pairs
74
76
  */
75
- export function getActivePlanInfo(projectRoot) {
76
- const plansDir = join(projectRoot, '.prism', 'plans');
77
- if (!existsSync(plansDir)) return null;
77
+ export function parseFrontmatter(content) {
78
+ const match = content.match(/^---\n([\s\S]*?)\n---/);
79
+ if (!match) return {};
80
+ const fm = {};
81
+ for (const line of match[1].split('\n')) {
82
+ const [key, ...rest] = line.split(':');
83
+ if (key && rest.length) {
84
+ const val = rest.join(':').trim();
85
+ if (val.startsWith('[')) {
86
+ try { fm[key.trim()] = JSON.parse(val); } catch { fm[key.trim()] = val; }
87
+ } else {
88
+ fm[key.trim()] = val;
89
+ }
90
+ }
91
+ }
92
+ return fm;
93
+ }
78
94
 
79
- const planFiles = readdirSync(plansDir)
80
- .filter(f => f.endsWith('.md'))
81
- .sort()
82
- .reverse();
95
+ /**
96
+ * Get all plans with frontmatter and progress info
97
+ * @param {string} projectRoot - Project root directory
98
+ * @returns {Array<Object>} Array of plan objects
99
+ */
100
+ export function getAllPlans(projectRoot) {
101
+ const plansDir = join(projectRoot, '.prism', 'plans');
102
+ if (!existsSync(plansDir)) return [];
103
+ const files = readdirSync(plansDir).filter(f => f.endsWith('.md')).sort().reverse();
104
+ return files.map(f => {
105
+ const content = readFileSync(join(plansDir, f), 'utf8');
106
+ const fm = parseFrontmatter(content);
107
+ const parsed = parsePlanContent(content, f);
108
+ return { file: f, content, ...fm, ...parsed };
109
+ });
110
+ }
83
111
 
84
- if (planFiles.length === 0) return null;
112
+ /**
113
+ * Read active plan file and extract progress info
114
+ * Now uses frontmatter status to find active plans
115
+ */
116
+ export function getActivePlanInfo(projectRoot) {
117
+ const plans = getAllPlans(projectRoot);
118
+ if (plans.length === 0) return null;
85
119
 
86
- const planName = planFiles[0];
87
- const content = readFileSync(join(plansDir, planName), 'utf8');
120
+ // Find the most recent plan with status: active (or no frontmatter = default active)
121
+ const activePlan = plans.find(p => (p.status || 'active') === 'active');
122
+ if (!activePlan) return null;
88
123
 
89
- return parsePlanContent(content, planName);
124
+ return parsePlanContent(
125
+ readFileSync(join(projectRoot, '.prism', 'plans', activePlan.file), 'utf8'),
126
+ activePlan.file
127
+ );
90
128
  }
91
129
 
92
130
  /**
@@ -170,6 +208,49 @@ export function parsePlanContent(content, planName) {
170
208
  return { planName, total, done, nextBatch, nextTasks, currentBatchFiles };
171
209
  }
172
210
 
211
+ /**
212
+ * Detect file overlaps across active plans
213
+ * @param {string} projectRoot - Project root directory
214
+ * @returns {Array<{file: string, plans: string[]}>} Conflicting files
215
+ */
216
+ export function detectPlanConflicts(projectRoot) {
217
+ const plans = getAllPlans(projectRoot).filter(p => (p.status || 'active') === 'active');
218
+ const fileMap = new Map();
219
+
220
+ for (const plan of plans) {
221
+ const files = extractFilesInScope(plan.content || '');
222
+ for (const f of files) {
223
+ if (!fileMap.has(f)) fileMap.set(f, []);
224
+ fileMap.get(f).push(plan.file);
225
+ }
226
+ }
227
+
228
+ const conflicts = [];
229
+ for (const [file, planList] of fileMap) {
230
+ if (planList.length > 1) {
231
+ conflicts.push({ file, plans: planList });
232
+ }
233
+ }
234
+ return conflicts;
235
+ }
236
+
237
+ /**
238
+ * Extract file paths from "Files in Scope" section
239
+ * @param {string} content - Plan markdown content
240
+ * @returns {string[]} File paths found
241
+ */
242
+ function extractFilesInScope(content) {
243
+ const scopeMatch = content.match(/##\s+Files\s+in\s+Scope\s*\n([\s\S]*?)(?=\n##|\n---|\s*$)/i);
244
+ if (!scopeMatch) return [];
245
+ const paths = [];
246
+ const backtickRegex = /`([^`]+\.[a-z]+)`/g;
247
+ let m;
248
+ while ((m = backtickRegex.exec(scopeMatch[1])) !== null) {
249
+ paths.push(m[1]);
250
+ }
251
+ return paths;
252
+ }
253
+
173
254
  /**
174
255
  * Get git status info
175
256
  */
package/lib/installer.mjs CHANGED
@@ -8,6 +8,7 @@ import { join, dirname } from 'path';
8
8
  import { fileURLToPath } from 'url';
9
9
  import { tmpdir, homedir } from 'os';
10
10
  import { detectOmc } from './omc.mjs';
11
+ import { getRulesMode } from './config.mjs';
11
12
 
12
13
  const __dirname = dirname(fileURLToPath(import.meta.url));
13
14
  const TEMPLATES_DIR = join(__dirname, '..', 'templates');
@@ -19,7 +20,7 @@ const TEMPLATES_DIR = join(__dirname, '..', 'templates');
19
20
  * @param {boolean} options.hooks - Install commit-guard hook
20
21
  */
21
22
  export async function init(projectDir, options = {}) {
22
- const { hooks = true } = options;
23
+ const { hooks = true, docs = false } = options;
23
24
 
24
25
  // 1. Create directories
25
26
  const claudeDir = join(projectDir, '.claude');
@@ -107,6 +108,26 @@ export async function init(projectDir, options = {}) {
107
108
  if (!existsSync(prismGitignore)) {
108
109
  writeFileSync(prismGitignore, '.version\n');
109
110
  }
111
+
112
+ // 7. Docs scaffolding (optional)
113
+ if (docs) {
114
+ const docsDir = join(projectDir, 'docs');
115
+ mkdirSync(docsDir, { recursive: true });
116
+ mkdirSync(join(docsDir, 'reference'), { recursive: true });
117
+ mkdirSync(join(docsDir, 'archive'), { recursive: true });
118
+
119
+ const memoryPath = join(docsDir, 'PROJECT-MEMORY.md');
120
+ if (!existsSync(memoryPath)) {
121
+ writeFileSync(memoryPath, PROJECT_MEMORY_TEMPLATE);
122
+ }
123
+
124
+ const handoffPath = join(docsDir, 'HANDOFF.md');
125
+ if (!existsSync(handoffPath)) {
126
+ writeFileSync(handoffPath, HANDOFF_TEMPLATE);
127
+ }
128
+
129
+ createRegistry(projectDir);
130
+ }
110
131
  }
111
132
 
112
133
  /**
@@ -371,10 +392,12 @@ export async function update(projectDir) {
371
392
  }
372
393
  }
373
394
 
374
- // Migrate config: add version field if missing
395
+ // Migrate config: add version field if missing, preserve rulesMode
396
+ let preservedRulesMode;
375
397
  if (existsSync(configPath)) {
376
398
  try {
377
399
  const existingConfig = JSON.parse(readFileSync(configPath, 'utf8'));
400
+ preservedRulesMode = existingConfig.rulesMode;
378
401
  if (!existingConfig.version) {
379
402
  existingConfig.version = 1;
380
403
  writeFileSync(configPath, JSON.stringify(existingConfig, null, 2) + '\n');
@@ -385,10 +408,23 @@ export async function update(projectDir) {
385
408
 
386
409
  await init(projectDir, { hooks });
387
410
 
411
+ // Restore rulesMode if it was set before migration
412
+ if (preservedRulesMode && preservedRulesMode !== 'full') {
413
+ const newConfig = JSON.parse(readFileSync(configPath, 'utf8'));
414
+ newConfig.rulesMode = preservedRulesMode;
415
+ writeFileSync(configPath, JSON.stringify(newConfig, null, 2) + '\n');
416
+ // Re-inject rules with restored mode
417
+ injectRules(projectDir);
418
+ }
419
+
388
420
  // Source repo: re-inject rules from local templates (overrides the npx version)
389
421
  if (sourceRepo) {
390
- const localRulesPath = join(projectDir, 'templates', 'rules.md');
391
- injectRules(projectDir, localRulesPath);
422
+ const mode = getRulesMode(projectDir);
423
+ const fileName = mode === 'lean' ? 'rules-lean.md' : 'rules.md';
424
+ const localRulesPath = join(projectDir, 'templates', fileName);
425
+ if (existsSync(localRulesPath)) {
426
+ injectRules(projectDir, localRulesPath);
427
+ }
392
428
  }
393
429
 
394
430
  return sourceRepo ? { sourceRepo: true } : undefined;
@@ -598,7 +634,7 @@ export function uninstallGlobal(options = {}) {
598
634
  * @returns {{ actions: Array<{type: string, path: string, status: string}> }}
599
635
  */
600
636
  export function dryRun(projectDir, options = {}) {
601
- const { hooks = true } = options;
637
+ const { hooks = true, docs = false } = options;
602
638
  const claudeDir = join(projectDir, '.claude');
603
639
  const actions = [];
604
640
 
@@ -658,6 +694,19 @@ export function dryRun(projectDir, options = {}) {
658
694
  actions.push({ type: 'config', path: '.prism/config.json', status: 'create' });
659
695
  }
660
696
 
697
+ // Docs scaffolding
698
+ if (docs) {
699
+ const docsDir = join(projectDir, 'docs');
700
+ for (const sub of ['', 'reference/', 'archive/']) {
701
+ actions.push({ type: 'docs', path: `docs/${sub}`, status: existsSync(join(docsDir, sub)) ? 'exists' : 'create' });
702
+ }
703
+ const memoryPath = join(docsDir, 'PROJECT-MEMORY.md');
704
+ actions.push({ type: 'docs', path: 'docs/PROJECT-MEMORY.md', status: existsSync(memoryPath) ? 'exists' : 'create' });
705
+ const handoffPath = join(docsDir, 'HANDOFF.md');
706
+ actions.push({ type: 'docs', path: 'docs/HANDOFF.md', status: existsSync(handoffPath) ? 'exists' : 'create' });
707
+ actions.push({ type: 'docs', path: '.prism/registry.json', status: 'create' });
708
+ }
709
+
661
710
  return { actions };
662
711
  }
663
712
 
@@ -743,11 +792,80 @@ export function hudStatus(options = {}) {
743
792
  return { enabled, scriptExists: existsSync(scriptPath), command: cmd };
744
793
  }
745
794
 
795
+ // ─── templates ───
796
+
797
+ const PROJECT_MEMORY_TEMPLATE = `# Project Memory
798
+
799
+ Cumulative knowledge that survives session transitions.
800
+
801
+ ## Architectural Decisions
802
+ <!-- [date] [decision] — [rationale] -->
803
+
804
+ ## Conventions
805
+ <!-- [naming, patterns, file structure rules] -->
806
+
807
+ ## Environment Gotchas
808
+ <!-- [quirks, workarounds, version constraints] -->
809
+
810
+ ## Package Constraints
811
+ <!-- [package@version — why pinned] -->
812
+ `;
813
+
814
+ const HANDOFF_TEMPLATE = `# Handoff
815
+
816
+ ## Status
817
+ [What's done, what's remaining]
818
+
819
+ ## Current State
820
+ [Branch name, last commit, any uncommitted changes]
821
+
822
+ ## Next Steps
823
+ [Exact next action to take, with file paths]
824
+
825
+ ## Decisions Made
826
+ [Key choices and why]
827
+
828
+ ## Known Issues
829
+ [Anything broken or incomplete]
830
+ `;
831
+
832
+ function createRegistry(projectDir) {
833
+ const registryPath = join(projectDir, '.prism', 'registry.json');
834
+ const registry = {
835
+ ssot: [],
836
+ session: {
837
+ handoff: 'docs/HANDOFF.md',
838
+ memory: 'docs/PROJECT-MEMORY.md'
839
+ },
840
+ reference: [],
841
+ archive: 'docs/archive/'
842
+ };
843
+
844
+ const docsDir = join(projectDir, 'docs');
845
+ if (existsSync(docsDir)) {
846
+ const files = readdirSync(docsDir).filter(f => f.endsWith('.md'));
847
+ for (const f of files) {
848
+ if (f === 'HANDOFF.md' || f === 'PROJECT-MEMORY.md') continue;
849
+ registry.ssot.push({ path: `docs/${f}`, role: 'unknown' });
850
+ }
851
+ }
852
+
853
+ writeFileSync(registryPath, JSON.stringify(registry, null, 2) + '\n');
854
+ }
855
+
746
856
  // ─── internal helpers ───
747
857
 
748
858
  function injectRules(projectDir, overrideRulesPath) {
749
859
  const claudeMdPath = join(projectDir, 'CLAUDE.md');
750
- const rulesPath = overrideRulesPath || join(TEMPLATES_DIR, 'rules.md');
860
+ let rulesPath;
861
+ if (overrideRulesPath) {
862
+ rulesPath = overrideRulesPath;
863
+ } else {
864
+ const mode = getRulesMode(projectDir);
865
+ const fileName = mode === 'lean' ? 'rules-lean.md' : 'rules.md';
866
+ rulesPath = join(TEMPLATES_DIR, fileName);
867
+ if (!existsSync(rulesPath)) rulesPath = join(TEMPLATES_DIR, 'rules.md');
868
+ }
751
869
  if (!existsSync(rulesPath)) return;
752
870
 
753
871
  const rules = readFileSync(rulesPath, 'utf8');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-prism",
3
- "version": "1.5.0",
3
+ "version": "1.6.0",
4
4
  "description": "AI agent harness implementing the EUDEC methodology — Essence, Understand, Decompose, Execute, Checkpoint.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -6,11 +6,17 @@ When this command is invoked:
6
6
 
7
7
  1. **Check** if `.prism/plans/` exists. If not, report "No plans directory found. Create one with `/claude-prism:plan create <topic>`."
8
8
  2. **Scan** `.prism/plans/` for all `.md` files
9
- 3. **Show each plan** with:
10
- - Filename and date
9
+ 3. **Parse frontmatter** for each plan (between `---` markers at file start):
10
+ - `status: active` → 📋
11
+ - `status: completed` → ✅
12
+ - `status: archived` → 📦
13
+ - `status: blocked` → 🚫
14
+ - No frontmatter → 📋 (default: active)
15
+ 4. **Show each plan** with:
16
+ - Status icon, filename and date
11
17
  - Goal (first line after `## Goal`)
12
18
  - Progress: count [x] vs [ ] tasks
13
- - Status: Complete / In Progress / Not Started
19
+ - Frontmatter status + task-based progress
14
20
 
15
21
  ## Create New Plan
16
22
 
@@ -18,9 +24,15 @@ If user requests a new plan:
18
24
 
19
25
  1. **Determine topic** from user's description
20
26
  2. **Create file** at `.prism/plans/YYYY-MM-DD-<topic>.md`
21
- 3. **Use EUDEC template**:
27
+ 3. **Use EUDEC template** (with frontmatter):
22
28
 
23
29
  ```
30
+ ---
31
+ status: active
32
+ created: YYYY-MM-DD
33
+ depends_on: []
34
+ ---
35
+
24
36
  ## Goal
25
37
  One sentence: what we're building and why.
26
38
 
@@ -53,6 +65,20 @@ Tech stack, key decisions, 2-3 sentences max.
53
65
 
54
66
  4. **Announce**: "Plan file created. Use /claude-prism:prism to start execution."
55
67
 
68
+ ## Check (file overlap detection)
69
+
70
+ If user requests a conflict check:
71
+
72
+ 1. **Read all active plans** from `.prism/plans/` (frontmatter `status: active` or no frontmatter)
73
+ 2. **Parse "Files in Scope"** section from each plan — extract backtick-wrapped file paths
74
+ 3. **Detect file overlaps** across plans
75
+ 4. **Report**:
76
+ - ⚠️ File overlap: `path/to/file`
77
+ ← plan-a.md (active)
78
+ ← plan-b.md (active)
79
+ - Recommendation: check dependency order or merge plans
80
+ 5. If no overlaps found: "✅ No file conflicts across active plans."
81
+
56
82
  ## View Specific Plan
57
83
 
58
84
  If user specifies a plan file:
@@ -30,7 +30,7 @@ When this command is invoked:
30
30
  ✅ scope-guard (warn: 4/8, block: 7/12)
31
31
 
32
32
  Plans:
33
- 📋 2026-02-15-p3-inspector.md [3/5] 60%
34
- 📋 2026-02-15-p8-templates.md [5/5] 100%
35
- 📋 2026-02-16-p4-token.md [0/4] 0%
33
+ 📋 2026-02-15-p3-inspector.md [3/5] 60% (active)
34
+ 2026-02-15-p8-templates.md [5/5] 100% (completed)
35
+ 🚫 2026-02-16-p4-token.md [0/4] 0% (blocked)
36
36
  ```
@@ -0,0 +1,106 @@
1
+
2
+ <!-- PRISM:START -->
3
+ <!-- PRISM:BOOT -->
4
+ ## Session Bootstrap (auto-generated by Prism)
5
+
6
+ On session start, read in order:
7
+ 1. `docs/PROJECT-MEMORY.md` (if exists) — persistent architectural decisions and conventions
8
+ 2. `docs/HANDOFF.md` (if exists) — previous session's state and next steps
9
+ 3. `.prism/plans/` — scan for active plans (frontmatter `status: active`)
10
+ 4. `.prism/registry.json` (if exists) — project document registry
11
+
12
+ After reading, verify described state matches reality (git status, file contents).
13
+ <!-- PRISM:BOOT:END -->
14
+
15
+ # Prism — EUDEC Methodology (Lean Mode)
16
+
17
+ **EUDEC = Essence, Understand, Decompose, Execute, Checkpoint** — the core cycle.
18
+
19
+ > **Never implement what you haven't understood. Never understand what you haven't distilled to its essence.**
20
+
21
+ For the full methodology, run `/claude-prism:prism`.
22
+
23
+ ---
24
+
25
+ ## Adaptive Weight (Task Size Routing)
26
+
27
+ | Weight | Criteria | Path |
28
+ |--------|----------|------|
29
+ | **Lightweight** | 1-2 files, <50 LOC, clear scope | Essence (1 line) → Execute → Verify → Record (1-line to `docs/PROJECT-MEMORY.md`) → Done |
30
+ | **Standard** | 3-5 files, 50-200 LOC | Run `/claude-prism:prism` for full EUDEC guidance |
31
+ | **Full** | 6+ files, 200+ LOC, or unclear scope | Run `/claude-prism:prism` for full EUDEC with plan file |
32
+
33
+ ## Task Type Derivation
34
+
35
+ | Essence Character | Type | Path |
36
+ |-------------------|------|------|
37
+ | "X is broken" | Bugfix | Fast Path (below) |
38
+ | "X should be possible" | Feature | `/claude-prism:prism` |
39
+ | "All X must become Y" | Migration | Pattern → batch apply → verify |
40
+ | "X's structure must change" | Refactor | `/claude-prism:prism` |
41
+
42
+ ## Bugfix Fast Path
43
+
44
+ 1. Reproduce the symptom
45
+ 2. Trace to root cause
46
+ 3. Minimal fix (smallest change that resolves the cause)
47
+ 4. Verify (test/build/diff)
48
+
49
+ After 3 failed fixes: STOP. Discuss with user.
50
+
51
+ ## Scope Guard
52
+
53
+ **Only change what was requested. Nothing more, nothing less.**
54
+
55
+ 1. Was this change explicitly requested? → proceed
56
+ 2. Is it required to make the requested change work? → proceed
57
+ 3. Is it an improvement I noticed while working? → STOP. Note it, don't do it.
58
+ 4. Is it "while I'm here" cleanup? → STOP. Not your job right now.
59
+
60
+ ## Verification & Fallback Ladder
61
+
62
+ | Level | Method | When |
63
+ |-------|--------|------|
64
+ | 1. Tests | Automated tests | Test infrastructure exists |
65
+ | 2. Build | Compiles + lint without new errors | No tests for this area |
66
+ | 3. Diff | `git diff` reviewed for regressions | No build tooling |
67
+
68
+ **Every change must have SOME verification.** Never claim completion without evidence.
69
+
70
+ ## Self-Correction Triggers
71
+
72
+ - Same file edited 3+ times → investigate root cause
73
+ - Editing file not in plan → scope change needed?
74
+ - 3 consecutive test failures → back to essence
75
+ - 5 turns autonomous → report progress before continuing
76
+ - Adding workarounds to fix workarounds → design problem, step back
77
+
78
+ ## Rationalization Defense
79
+
80
+ | Excuse | Reality |
81
+ |--------|---------|
82
+ | "I know what they mean" | Verify. Assumption is the root of all bugs |
83
+ | "While I'm here, let me also..." | Scope creep. Note it for later |
84
+ | "Too simple to decompose" | Check file count and coupling |
85
+ | "I'll add tests later" | High-risk: tests come first |
86
+
87
+ ## Checkpoint Frequency
88
+
89
+ - **Lightweight**: report completion with evidence, no pause
90
+ - **Standard/Full**: run `/claude-prism:prism` for guided checkpoints
91
+ - **Blocker encountered**: always stop
92
+
93
+ ## Session Handoff
94
+
95
+ Prism hooks auto-generate `docs/HANDOFF.md` on compaction and session end.
96
+ `docs/PROJECT-MEMORY.md` is auto-appended on session end.
97
+ For manual handoff: Status, Current State, Next Steps, Decisions Made, Known Issues.
98
+
99
+ ## Completion Declaration
100
+
101
+ Before declaring completion:
102
+ 1. **IDENTIFY** — What proves completion?
103
+ 2. **RUN** — Execute the relevant test/build
104
+ 3. **READ** — Check the output directly
105
+ 4. **CLAIM** — Only declare based on evidence
106
+ <!-- PRISM:END -->
@@ -1,5 +1,17 @@
1
1
 
2
2
  <!-- PRISM:START -->
3
+ <!-- PRISM:BOOT -->
4
+ ## Session Bootstrap (auto-generated by Prism)
5
+
6
+ On session start, read in order:
7
+ 1. `docs/PROJECT-MEMORY.md` (if exists) — persistent architectural decisions and conventions
8
+ 2. `docs/HANDOFF.md` (if exists) — previous session's state and next steps
9
+ 3. `.prism/plans/` — scan for active plans (frontmatter `status: active`)
10
+ 4. `.prism/registry.json` (if exists) — project document registry
11
+
12
+ After reading, verify described state matches reality (git status, file contents).
13
+ <!-- PRISM:BOOT:END -->
14
+
3
15
  # Prism — EUDEC Methodology Framework
4
16
 
5
17
  **EUDEC = Essence, Understand, Decompose, Execute, Checkpoint** — the core cycle.
@@ -76,7 +88,7 @@ After extracting essence and task type, assess task weight to select the appropr
76
88
  | **Standard** | 3-5 files, 50-200 LOC | Full EUDEC, summary checkpoints |
77
89
  | **Full** | 6+ files, 200+ LOC, or unclear scope | Full EUDEC with plan file + full checkpoints |
78
90
 
79
- **Lightweight path** skips formal UNDERSTAND (sufficiency assessment, question rounds, alignment confirmation) and DECOMPOSE. The essence statement still grounds the work but takes one line, not a full section.
91
+ **Lightweight path** skips formal UNDERSTAND (sufficiency assessment, question rounds, alignment confirmation) and DECOMPOSE. The essence statement still grounds the work but takes one line, not a full section. Record: append 1-line summary to `docs/PROJECT-MEMORY.md` (what was changed and why).
80
92
 
81
93
  **Bugfix fast path** (regardless of file count):
82
94
  1. Reproduce the symptom
@@ -419,6 +431,11 @@ User says "stop here" → clean exit
419
431
  - Task is multi-session by nature (multi-day refactor, large migration)
420
432
  - Switching to a different task mid-session
421
433
 
434
+ **Auto-triggers (via Prism hooks):**
435
+ - PreCompact hook → auto-generates `docs/HANDOFF.md`
436
+ - SessionEnd hook → auto-generates `docs/HANDOFF.md` + appends to `docs/PROJECT-MEMORY.md`
437
+ - `/compact` 실행 전 → HANDOFF 자동 저장 (hook으로 처리됨)
438
+
422
439
  ### 6-2. Handoff Document
423
440
 
424
441
  Create `docs/HANDOFF.md` with: