@hanzlaa/rcode 3.6.7 → 3.6.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/cli/generate-command-skills.cjs +5 -12
  2. package/package.json +1 -1
  3. package/rihal/bin/rihal-hooks.cjs +154 -39
  4. package/rihal/bin/rihal-tools.cjs +25 -24
  5. package/rihal/commands/execute-milestone.md +2 -2
  6. package/rihal/commands/plan-milestone.md +2 -2
  7. package/rihal/commands/scaffold-milestone.md +2 -2
  8. package/rihal/references/continuation-format.md +5 -6
  9. package/rihal/references/research-synthesis-playbook.md +1 -1
  10. package/rihal/skills/actions/2-plan/rihal-create-milestone/steps/step-06-phase-stubs.md +1 -1
  11. package/rihal/skills/actions/2-plan/rihal-create-milestone/steps/step-10-complete.md +1 -1
  12. package/rihal/skills/actions/4-implementation/rihal-debug/SKILL.md +2 -0
  13. package/rihal/workflows/analyze-dependencies.md +4 -4
  14. package/rihal/workflows/audit-fix.md +3 -3
  15. package/rihal/workflows/audit-milestone.md +12 -11
  16. package/rihal/workflows/audit-worktrees.md +163 -0
  17. package/rihal/workflows/audit.md +18 -3
  18. package/rihal/workflows/correct-course.md +3 -3
  19. package/rihal/workflows/create-architecture.md +3 -3
  20. package/rihal/workflows/create-epics-and-stories.md +3 -3
  21. package/rihal/workflows/discuss-phase-power.md +1 -1
  22. package/rihal/workflows/document-project.md +3 -3
  23. package/rihal/workflows/edit-prd.md +3 -3
  24. package/rihal/workflows/execute-milestone.md +3 -3
  25. package/rihal/workflows/execute-sprint.md +1 -1
  26. package/rihal/workflows/execute-waves.md +27 -2
  27. package/rihal/workflows/forensics.md +3 -3
  28. package/rihal/workflows/health.md +23 -8
  29. package/rihal/workflows/help.md +0 -1
  30. package/rihal/workflows/new-project-roadmap.md +2 -2
  31. package/rihal/workflows/plan-research-validation.md +2 -2
  32. package/rihal/workflows/plan.md +7 -7
  33. package/rihal/workflows/retrospective.md +3 -3
  34. package/rihal/workflows/review-adversarial.md +8 -6
  35. package/rihal/workflows/review.md +2 -2
  36. package/rihal/workflows/scaffold-project.md +3 -3
  37. package/rihal/workflows/secure-phase.md +4 -4
  38. package/rihal/workflows/session-report.md +1 -1
  39. package/rihal/workflows/status.md +6 -10
  40. package/rihal/workflows/validate-prd.md +3 -3
  41. package/rihal/workflows/verify-phase.md +3 -3
  42. package/rihal/workflows/workstream.md +3 -3
@@ -40,18 +40,11 @@ const path = require('path');
40
40
  * functional). Power users running niche commands like /rihal-prfaq or
41
41
  * /rihal-ui-phase still get them — they just don't show up in the sidebar.
42
42
  */
43
- const SIDEBAR_COMMANDS = new Set([
44
- // Navigation & status (the daily check-in)
45
- 'do', 'status', 'next',
46
- // Core lifecycle (the workflow loop)
47
- 'plan', 'execute', 'ship',
48
- // Strategic
49
- 'council',
50
- // Quality gate
51
- 'audit', 'verify-phase',
52
- // Utility
53
- 'note',
54
- ]);
43
+ // Empty sidebar stubs with user-invocable:false block direct /rihal-* invocation
44
+ // in Claude Code 2.x. Commands in .claude/commands/ already appear in slash autocomplete.
45
+ // The VS Code sidebar also shows commands directly in CC 2.x, so stubs are redundant.
46
+ // Issue #710: sidebar stubs caused "can only be invoked by Claude" error for users.
47
+ const SIDEBAR_COMMANDS = new Set([]);
55
48
 
56
49
  function parseFrontmatter(text) {
57
50
  if (!text.startsWith('---\n')) return {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hanzlaa/rcode",
3
- "version": "3.6.7",
3
+ "version": "3.6.14",
4
4
  "description": "rcode — the AI team that never forgets. Persistent memory, specialist agents, and slash commands for AI IDEs. Works in Claude Code, Cursor, Gemini, VS Code, and Antigravity.",
5
5
  "main": "cli/index.js",
6
6
  "bin": {
@@ -321,69 +321,184 @@ async function bashGuard() {
321
321
  }
322
322
 
323
323
  /**
324
- * pre-compact: Refresh HANDOFF.json before context compaction (#743).
324
+ * pre-compact: Capture rihal session state before context compaction.
325
325
  *
326
- * Triggered by the PreCompact hook. Reads .rihal/state.json from the current
327
- * working directory and, if a phase is active, writes a HANDOFF.json pointer
328
- * so a post-compaction agent can resume cleanly. No-op when no phase is
329
- * active. Never blocks compaction.
326
+ * Triggered by the PreCompact hook. Enriched version (#743 + enhancement):
327
+ * 1. Reads .rihal/state.json + .planning/STATE.md + active SPRINT.md
328
+ * 2. Collects recent git commits and in-progress task checkboxes
329
+ * 3. Writes enriched .rihal/HANDOFF.json (machine-readable resume file)
330
+ * 4. Writes .rihal/.continue-here.md (paste-ready resume prompt)
331
+ * 5. Outputs { systemMessage } so Claude sees context immediately after
332
+ * compaction — enabling /rihal-resume-work to restore full context.
333
+ *
334
+ * Never blocks compaction — any error exits 1 (non-blocking per spec).
330
335
  */
331
336
  async function preCompact() {
332
337
  try {
333
338
  const path = require('path');
339
+ const { execSync } = require('child_process');
334
340
  await readInputJson(); // drain the PreCompact event payload
335
341
 
336
342
  const cwd = process.cwd();
343
+
344
+ // ── 1. Load state.json ──────────────────────────────────────────────
337
345
  const statePath = path.join(cwd, '.rihal', 'state.json');
338
- if (!fs.existsSync(statePath)) {
339
- process.exit(0);
346
+ let state = null;
347
+ if (fs.existsSync(statePath)) {
348
+ try { state = JSON.parse(fs.readFileSync(statePath, 'utf8')); } catch {}
340
349
  }
341
350
 
342
- let state;
343
- try {
344
- state = JSON.parse(fs.readFileSync(statePath, 'utf8'));
345
- } catch {
346
- process.exit(0);
351
+ // ── 2. Determine active phase ────────────────────────────────────────
352
+ const phases = Array.isArray(state?.phases) ? state.phases : [];
353
+ const executing = phases.find((p) => p && p.status === 'executing');
354
+ const matched = phases.find(
355
+ (p) => p && (p.name === state?.current_phase || p.number === state?.current_phase)
356
+ );
357
+ const activePhase = executing || matched || null;
358
+ const phaseLabel = activePhase
359
+ ? (activePhase.number || activePhase.name || state?.current_phase)
360
+ : (state?.current_phase || null);
361
+
362
+ // ── 3. Read active SPRINT.md (incomplete tasks) ──────────────────────
363
+ const incompleteTasks = [];
364
+ const completedCount = { done: 0, total: 0 };
365
+ const planningBase = path.join(cwd, '.planning', 'phases');
366
+ if (phaseLabel && fs.existsSync(planningBase)) {
367
+ try {
368
+ const phaseDirs = fs.readdirSync(planningBase)
369
+ .filter(d => d.startsWith(String(phaseLabel)));
370
+ for (const pd of phaseDirs) {
371
+ const pdPath = path.join(planningBase, pd);
372
+ if (!fs.statSync(pdPath).isDirectory()) continue;
373
+ const sprintFiles = fs.readdirSync(pdPath)
374
+ .filter(f => f.endsWith('-SPRINT.md'))
375
+ .sort()
376
+ .reverse(); // most recent first
377
+ if (sprintFiles.length === 0) continue;
378
+ const sprintText = fs.readFileSync(path.join(pdPath, sprintFiles[0]), 'utf8');
379
+ for (const line of sprintText.split('\n')) {
380
+ const done = /^\s*-\s*\[x\]/i.test(line);
381
+ const pending = /^\s*-\s*\[ \]/.test(line);
382
+ if (done || pending) completedCount.total++;
383
+ if (done) completedCount.done++;
384
+ if (pending) {
385
+ const task = line.replace(/^\s*-\s*\[ \]\s*/, '').trim();
386
+ if (task) incompleteTasks.push(task);
387
+ }
388
+ }
389
+ break; // use first matching phase dir only
390
+ }
391
+ } catch {}
347
392
  }
348
393
 
349
- const phases = Array.isArray(state.phases) ? state.phases : [];
350
- const hasActivePhase =
351
- !!state.current_phase &&
352
- phases.length > 0 &&
353
- phases.some(
354
- (p) =>
355
- p &&
356
- (p.status === 'executing' ||
357
- p.name === state.current_phase ||
358
- p.number === state.current_phase)
359
- );
394
+ // ── 4. Recent git commits ────────────────────────────────────────────
395
+ let recentCommits = [];
396
+ try {
397
+ const log = execSync('git log --oneline -5 --no-decorate 2>/dev/null', {
398
+ cwd, encoding: 'utf8', timeout: 3000,
399
+ }).trim();
400
+ recentCommits = log ? log.split('\n').filter(Boolean) : [];
401
+ } catch {}
360
402
 
361
- if (!hasActivePhase) {
362
- process.exit(0);
403
+ // ── 5. Read milestone / roadmap headline ────────────────────────────
404
+ let milestoneHint = state?.milestone || null;
405
+ if (!milestoneHint) {
406
+ for (const rp of ['.planning/ROADMAP.md', '.planning/milestones/ROADMAP.md']) {
407
+ const full = path.join(cwd, rp);
408
+ if (!fs.existsSync(full)) continue;
409
+ const m = fs.readFileSync(full, 'utf8').match(/^##\s+Milestone\s+(M\d+[^\n]*)/m);
410
+ if (m) { milestoneHint = m[1].trim(); break; }
411
+ }
363
412
  }
364
413
 
365
- const executing = phases.find((p) => p && p.status === 'executing');
366
- const matched = phases.find(
367
- (p) => p && (p.name === state.current_phase || p.number === state.current_phase)
368
- );
369
- const activePhase = executing || matched;
370
- const phaseLabel = activePhase
371
- ? activePhase.number || activePhase.name || state.current_phase
372
- : state.current_phase;
414
+ // ── 6. Read last 3 decisions from STATE.md ───────────────────────────
415
+ let recentDecisions = [];
416
+ const stateFile = path.join(cwd, '.planning', 'STATE.md');
417
+ if (fs.existsSync(stateFile)) {
418
+ try {
419
+ const stateText = fs.readFileSync(stateFile, 'utf8');
420
+ const decSection = stateText.match(/##\s+(?:Recent\s+)?Decisions[\s\S]*?(?=\n##|\Z)/i);
421
+ if (decSection) {
422
+ recentDecisions = decSection[0]
423
+ .split('\n')
424
+ .filter(l => /^\s*[-*]/.test(l))
425
+ .slice(0, 3)
426
+ .map(l => l.replace(/^\s*[-*]\s*/, '').trim())
427
+ .filter(Boolean);
428
+ }
429
+ } catch {}
430
+ }
373
431
 
432
+ // ── 7. Build enriched HANDOFF.json ───────────────────────────────────
374
433
  const handoff = {
375
434
  generated_at: new Date().toISOString(),
376
435
  reason: 'pre-compact',
377
436
  phase: phaseLabel,
378
- current_plan: state.current_plan ?? null,
379
- current_sprint: state.current_sprint ?? null,
437
+ milestone: milestoneHint,
438
+ current_plan: state?.current_plan ?? null,
439
+ current_sprint: state?.current_sprint ?? null,
440
+ progress: completedCount.total > 0
441
+ ? `${completedCount.done}/${completedCount.total} tasks done`
442
+ : null,
443
+ incomplete_tasks: incompleteTasks.slice(0, 10),
444
+ recent_commits: recentCommits,
445
+ recent_decisions: recentDecisions,
380
446
  };
381
447
 
382
- const handoffPath = path.join(cwd, 'HANDOFF.json');
383
- const tmpPath = handoffPath + '.tmp';
384
- fs.writeFileSync(tmpPath, JSON.stringify(handoff, null, 2) + '\n');
385
- fs.renameSync(tmpPath, handoffPath);
448
+ const rihalDir = path.join(cwd, '.rihal');
449
+ if (!fs.existsSync(rihalDir)) {
450
+ process.exit(0); // not a rihal project
451
+ }
452
+
453
+ const handoffPath = path.join(rihalDir, 'HANDOFF.json');
454
+ fs.writeFileSync(handoffPath + '.tmp', JSON.stringify(handoff, null, 2) + '\n');
455
+ fs.renameSync(handoffPath + '.tmp', handoffPath);
456
+
457
+ // ── 8. Write .continue-here.md (paste-ready resume prompt) ───────────
458
+ const resumeLines = [
459
+ '# Rihal Session Resume',
460
+ '',
461
+ `**Compacted:** ${handoff.generated_at}`,
462
+ phaseLabel ? `**Phase:** ${phaseLabel}` : null,
463
+ milestoneHint ? `**Milestone:** ${milestoneHint}` : null,
464
+ handoff.progress ? `**Progress:** ${handoff.progress}` : null,
465
+ '',
466
+ ].filter(l => l !== null);
467
+
468
+ if (incompleteTasks.length > 0) {
469
+ resumeLines.push('**Next tasks:**');
470
+ incompleteTasks.slice(0, 5).forEach(t => resumeLines.push(`- [ ] ${t}`));
471
+ resumeLines.push('');
472
+ }
473
+ if (recentCommits.length > 0) {
474
+ resumeLines.push('**Recent commits:**');
475
+ recentCommits.forEach(c => resumeLines.push(`- ${c}`));
476
+ resumeLines.push('');
477
+ }
478
+ if (recentDecisions.length > 0) {
479
+ resumeLines.push('**Recent decisions:**');
480
+ recentDecisions.forEach(d => resumeLines.push(`- ${d}`));
481
+ resumeLines.push('');
482
+ }
483
+ resumeLines.push('---');
484
+ resumeLines.push('Run `/rihal-resume-work` to restore full project context.');
485
+
486
+ fs.writeFileSync(
487
+ path.join(rihalDir, '.continue-here.md'),
488
+ resumeLines.join('\n') + '\n'
489
+ );
490
+
491
+ // ── 9. Emit systemMessage for Claude post-compaction ─────────────────
492
+ const msgParts = ['**Rihal context compacted.**'];
493
+ if (phaseLabel) msgParts.push(`Active phase: **${phaseLabel}**`);
494
+ if (milestoneHint) msgParts.push(`Milestone: ${milestoneHint}`);
495
+ if (handoff.progress) msgParts.push(`Progress: ${handoff.progress}`);
496
+ if (incompleteTasks.length > 0) {
497
+ msgParts.push(`Next task: ${incompleteTasks[0]}`);
498
+ }
499
+ msgParts.push('Run `/rihal-resume-work` to restore full context, or `/clear` then paste `.rihal/.continue-here.md`.');
386
500
 
501
+ process.stdout.write(JSON.stringify({ systemMessage: msgParts.join(' | ') }) + '\n');
387
502
  process.exit(0);
388
503
  } catch (err) {
389
504
  console.error(`Hook error: ${err.message}`);
@@ -6070,7 +6070,7 @@ function cmdProgress(args) {
6070
6070
  return insights;
6071
6071
  }
6072
6072
 
6073
- function deriveRoutes(state, roadmapPhases, diskByNum) {
6073
+ function deriveRoutes(state, roadmapPhases, diskByNum, insights) {
6074
6074
  const routes = [];
6075
6075
  const statePhases = (state && (state.state?.phases || state.phases)) || [];
6076
6076
 
@@ -6092,26 +6092,18 @@ function cmdProgress(args) {
6092
6092
  }).slice(0, 3);
6093
6093
  for (const p of pendingExec) {
6094
6094
  const k = phaseKey(p);
6095
- routes.push({
6096
- letter: 'A',
6097
- label: `Execute phase ${k} — unfinished plans`,
6098
- command: `/rihal-execute ${k}`,
6099
- });
6095
+ routes.push({ letter: 'A', label: '', command: `/rihal-execute ${k}` });
6100
6096
  }
6101
6097
 
6102
6098
  // Route B — phases with research but no plans
6103
6099
  const researchOnly = Object.entries(diskByNum)
6104
6100
  .filter(([num, d]) => d.has_research && d.plan_count === 0)
6105
6101
  .slice(0, 3);
6106
- for (const [num, d] of researchOnly) {
6107
- routes.push({
6108
- letter: 'B',
6109
- label: `Plan phase ${num} — researched, awaiting plan`,
6110
- command: `/rihal-plan-phase ${num}`,
6111
- });
6102
+ for (const [num] of researchOnly) {
6103
+ routes.push({ letter: 'B', label: '', command: `/rihal-plan ${num}` });
6112
6104
  }
6113
6105
 
6114
- // Route B' — in-progress phases without plans (the user is actively working but no SPRINT.md exists yet)
6106
+ // Route B' — in-progress phases without plans
6115
6107
  const inProgressNoPlan = statePhases
6116
6108
  .filter(p => (p.status === 'in_progress' || p.status === 'in-progress'))
6117
6109
  .filter(p => {
@@ -6121,24 +6113,32 @@ function cmdProgress(args) {
6121
6113
  .slice(0, 2);
6122
6114
  for (const p of inProgressNoPlan) {
6123
6115
  const k = phaseKey(p);
6124
- routes.push({
6125
- letter: 'B',
6126
- label: `Plan phase ${k} — in progress without SPRINT.md`,
6127
- command: `/rihal-plan ${k}`,
6128
- });
6116
+ routes.push({ letter: 'B', label: '', command: `/rihal-plan ${k}` });
6129
6117
  }
6130
6118
 
6131
6119
  // Route C — close out milestone if everything seems done
6132
6120
  const allDone = statePhases.length > 0 && statePhases.every(p => p.status === 'complete' || p.completed);
6133
6121
  if (allDone) {
6134
- routes.push({ letter: 'C', label: 'Audit current milestone', command: '/rihal-audit-milestone' });
6135
- routes.push({ letter: 'C', label: 'Complete current milestone', command: '/rihal-complete-milestone' });
6122
+ // Count unverified phases (complete but no VERIFICATION.md on disk)
6123
+ const unverifiedCount = statePhases.filter(p => {
6124
+ const disk = diskByNum[phaseKey(p)];
6125
+ return (p.status === 'complete' || p.completed) && disk && !disk.has_verification;
6126
+ }).length;
6127
+ const hasDrift = (insights || []).some(i => i.kind === 'roadmap-drift' || (i.message && i.message.includes('ROADMAP')));
6128
+ const auditArgs = [];
6129
+ if (unverifiedCount > 0) auditArgs.push(String(unverifiedCount));
6130
+ if (hasDrift) auditArgs.push('--fix-drift');
6131
+ const auditCmd = auditArgs.length > 0
6132
+ ? `/rihal-audit-milestone ${auditArgs.join(' ')}`
6133
+ : '/rihal-audit-milestone';
6134
+ routes.push({ letter: 'C', label: '', command: auditCmd });
6135
+ routes.push({ letter: 'C', label: '', command: '/rihal-complete-milestone' });
6136
6136
  }
6137
6137
 
6138
6138
  // Fallback — nothing obvious: offer status
6139
6139
  if (routes.length === 0) {
6140
- routes.push({ letter: 'A', label: 'Check progress detail', command: '/rihal-progress' });
6141
- routes.push({ letter: 'B', label: 'Start a council on what to do next', command: '/rihal-council' });
6140
+ routes.push({ letter: 'A', label: '', command: '/rihal-progress' });
6141
+ routes.push({ letter: 'B', label: '', command: '/rihal-council' });
6142
6142
  }
6143
6143
 
6144
6144
  return routes;
@@ -6208,14 +6208,15 @@ function cmdProgress(args) {
6208
6208
  }
6209
6209
 
6210
6210
  if (sub === 'routes') {
6211
- return { ok: true, routes: deriveRoutes(state, roadmapPhases, diskByNum) };
6211
+ const routeInsights = detectInsights(state, roadmapPhases, diskByNum);
6212
+ return { ok: true, routes: deriveRoutes(state, roadmapPhases, diskByNum, routeInsights) };
6212
6213
  }
6213
6214
 
6214
6215
  // sub === 'init' (default) — full snapshot
6215
6216
  const currentPhase = state && state.current_phase;
6216
6217
  const insights = detectInsights(state, roadmapPhases, diskByNum);
6217
6218
  enforceStrictGate(insights);
6218
- const routes = deriveRoutes(state, roadmapPhases, diskByNum);
6219
+ const routes = deriveRoutes(state, roadmapPhases, diskByNum, insights);
6219
6220
  const { weighted: weightedCompleted, pct: weightedPct } = computeWeightedProgress(statePhases, diskByNum);
6220
6221
 
6221
6222
  return {
@@ -10,9 +10,9 @@ Execute all phases in the current milestone in dependency order, with verify gat
10
10
  </objective>
11
11
 
12
12
  <execution_context>
13
- @.rihal/workflows/execute-milestone.md
13
+ @rihal/workflows/execute-milestone.md
14
14
  </execution_context>
15
15
 
16
16
  <process>
17
- Execute the execute-milestone workflow from @.rihal/workflows/execute-milestone.md end-to-end.
17
+ Execute the execute-milestone workflow from @rihal/workflows/execute-milestone.md end-to-end.
18
18
  </process>
@@ -10,9 +10,9 @@ Plan all phases for a milestone using parallel dependency-wave execution. Group
10
10
  </objective>
11
11
 
12
12
  <execution_context>
13
- @.rihal/workflows/plan-milestone.md
13
+ @rihal/workflows/plan-milestone.md
14
14
  </execution_context>
15
15
 
16
16
  <process>
17
- Execute the plan-milestone workflow from @.rihal/workflows/plan-milestone.md end-to-end.
17
+ Execute the plan-milestone workflow from @rihal/workflows/plan-milestone.md end-to-end.
18
18
  </process>
@@ -10,9 +10,9 @@ Execute scaffold-milestone workflow
10
10
  </objective>
11
11
 
12
12
  <execution_context>
13
- @.rihal/workflows/scaffold-milestone.md
13
+ @rihal/workflows/scaffold-milestone.md
14
14
  </execution_context>
15
15
 
16
16
  <process>
17
- Execute the scaffold-milestone workflow from @.rihal/workflows/scaffold-milestone.md end-to-end.
17
+ Execute the scaffold-milestone workflow from @rihal/workflows/scaffold-milestone.md end-to-end.
18
18
  </process>
@@ -52,7 +52,6 @@ Standard format for presenting next steps after completing a command or workflow
52
52
 
53
53
  **Also available:**
54
54
  - Review plan before executing
55
- - `/rihal-list-phase-assumptions 2` — check assumptions
56
55
 
57
56
  ---
58
57
  ```
@@ -91,7 +90,7 @@ Add note that this is the last plan and what comes after:
91
90
 
92
91
  **Phase 2: Authentication** — JWT login flow with refresh tokens
93
92
 
94
- `/rihal-plan-phase 2`
93
+ `/rihal-plan 2`
95
94
 
96
95
  <sub>`/clear` first → fresh context window</sub>
97
96
 
@@ -120,7 +119,7 @@ Show completion status before next action:
120
119
 
121
120
  **Phase 3: Core Features** — User dashboard, settings, and data export
122
121
 
123
- `/rihal-plan-phase 3`
122
+ `/rihal-plan 3`
124
123
 
125
124
  <sub>`/clear` first → fresh context window</sub>
126
125
 
@@ -145,7 +144,7 @@ When there's no clear primary action:
145
144
 
146
145
  **Phase 3: Core Features** — User dashboard, settings, and data export
147
146
 
148
- **To plan directly:** `/rihal-plan-phase 3`
147
+ **To plan directly:** `/rihal-plan 3`
149
148
 
150
149
  **To discuss context first:** `/rihal-discuss-phase 3`
151
150
 
@@ -222,7 +221,7 @@ User has no idea what 02-03 is about.
222
221
  ### Don't: Missing /clear explanation
223
222
 
224
223
  ```
225
- `/rihal-plan-phase 3`
224
+ `/rihal-plan 3`
226
225
 
227
226
  Run /clear first.
228
227
  ```
@@ -242,7 +241,7 @@ Sounds like an afterthought. Use "Also available:" instead.
242
241
 
243
242
  ```
244
243
  ```
245
- /rihal-plan-phase 3
244
+ /rihal-plan 3
246
245
  ```
247
246
  ```
248
247
 
@@ -70,7 +70,7 @@ This is the most important section. Based on combined research:
70
70
  - Which pitfalls it must avoid
71
71
 
72
72
  **Add research flags:**
73
- - Which phases likely need `/rihal-research` during planning?
73
+ - Which phases likely need `/rihal-research-phase` during planning?
74
74
  - Which phases have well-documented patterns (skip research)?
75
75
 
76
76
  ## Step 5: Assess Confidence
@@ -9,7 +9,7 @@ For each milestone, list the phases it contains as **stubs** (number + name + on
9
9
  ## MANDATORY RULES
10
10
 
11
11
  - 🛑 Phase numbers follow Rihal's NN convention (01, 02, ..., 99, then 999.x for parking lot).
12
- - 🛑 Do NOT generate plan content here. That's `/rihal-plan-phase`.
12
+ - 🛑 Do NOT generate plan content here. That's `/rihal-plan`.
13
13
  - 🛑 Each phase has one-sentence goal, max.
14
14
  - ⏸️ HALT at menu.
15
15
 
@@ -42,7 +42,7 @@ What's next?
42
42
  → /rihal-create-epics-and-stories
43
43
 
44
44
  [B] Plan the first phase in detail
45
- → /rihal-plan-phase 01
45
+ → /rihal-plan 01
46
46
 
47
47
  [C] Review the roadmap with the team
48
48
  → /rihal-council "Is this roadmap realistic?"
@@ -44,6 +44,8 @@ If you have not completed Phase 1, you cannot propose a fix. "It seems to work"
44
44
 
45
45
  Debugging is investigation, not pattern-matching. Each iteration narrows the problem space — never widens it. The skill enforces a written hypothesis, an experiment that distinguishes "yes" from "no", and a captured observation. Random fixes are not allowed — the bug must be understood before the fix is written.
46
46
 
47
+ ## Workflow
48
+
47
49
  ## Phase 1 — Root Cause Investigation
48
50
 
49
51
  **BEFORE attempting ANY fix:**
@@ -1,7 +1,7 @@
1
1
  # Workflow: rihal-analyze-dependencies
2
2
 
3
3
  <purpose>
4
- Analyze ROADMAP.md phases for dependency relationships before execution. Detect file overlap between phases, semantic API/data-flow dependencies, and suggest `Depends on` entries to prevent merge conflicts during parallel execution by `/rihal-manager`.
4
+ Analyze ROADMAP.md phases for dependency relationships before execution. Detect file overlap between phases, semantic API/data-flow dependencies, and suggest `Depends on` entries to prevent merge conflicts during parallel execution.
5
5
  </purpose>
6
6
 
7
7
 
@@ -119,7 +119,7 @@ When writing:
119
119
  - Preserve all other phase content unchanged
120
120
  - Do not reorder phases
121
121
 
122
- After applying: "ROADMAP.md updated. Run `/rihal-manager` to execute phases in the correct order."
122
+ After applying: "ROADMAP.md updated. Run `/rihal-execute-milestone` to execute phases in the correct order."
123
123
 
124
124
  ## Success Criteria
125
125
 
@@ -140,5 +140,5 @@ After applying: "ROADMAP.md updated. Run `/rihal-manager` to execute phases in t
140
140
  ## ▶ Next Up
141
141
 
142
142
  - **Circular deps found:** Fix dependency cycle, then re-run analysis
143
- - **Ready to execute:** `/rihal-execute {phase}` — run with dependency awareness
144
- - **Review roadmap:** `/rihal-progress` — see full project state
143
+ - /rihal-execute {phase}
144
+ - /rihal-progress
@@ -199,6 +199,6 @@ If arguments are invalid, missing files, or subagent fails:
199
199
 
200
200
  ## ▶ Next Up
201
201
 
202
- - **Fixes applied:** `/rihal-verify-phase {phase}` — re-verify after fixes
203
- - **More issues:** `/rihal-audit {phase}` — run audit again to confirm
204
- - **All clean:** `/rihal-progress` — check project state
202
+ - /rihal-verify-phase {phase}
203
+ - /rihal-audit {phase}
204
+ - /rihal-progress
@@ -4,22 +4,23 @@
4
4
  Cross-phase audit of milestone completion. Reads all SUMMARY.md files from completed phases, compares their outcomes to the original ROADMAP goals, flags gaps, and generates an audit report showing completion percentage and decision traceability.
5
5
  </purpose>
6
6
 
7
- ## Step 0 — Usage check
7
+ ## Step 0 — Parse arguments
8
8
 
9
- If `$ARGUMENTS` contains only `--help` or `-h`:
9
+ Parse `$ARGUMENTS`:
10
+ - `--help` or `-h` → print usage and stop:
11
+ ```
12
+ /rihal-audit-milestone [<unverified-count>] [--fix-drift] [--strict] [--report]
13
+ ```
14
+ - A bare integer (e.g. `28`) → `HINT_UNVERIFIED_COUNT = 28` (pre-computed by rihal-status for display; use as expected minimum in the scan)
15
+ - `--fix-drift` → `FIX_DRIFT = true` (after audit, suggest the drift sync command)
16
+ - `--strict` → `STRICT = true`
17
+ - `--report` → `WRITE_REPORT = true`
10
18
 
19
+ If `HINT_UNVERIFIED_COUNT` is set, print at the top of the audit output:
11
20
  ```
12
- /rihal-audit-milestone [--strict] [--report]
21
+ ℹ Expecting ~{HINT_UNVERIFIED_COUNT} phases to verify (from rihal-status)
13
22
  ```
14
23
 
15
- **Examples:**
16
- ```
17
- /rihal-audit-milestone
18
- /rihal-audit-milestone --strict --report
19
- ```
20
-
21
- STOP — do not proceed.
22
-
23
24
  ## Step 1 — Locate milestone context
24
25
 
25
26
  Determine the active milestone. Check: