@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.
- package/cli/generate-command-skills.cjs +5 -12
- package/package.json +1 -1
- package/rihal/bin/rihal-hooks.cjs +154 -39
- package/rihal/bin/rihal-tools.cjs +25 -24
- package/rihal/commands/execute-milestone.md +2 -2
- package/rihal/commands/plan-milestone.md +2 -2
- package/rihal/commands/scaffold-milestone.md +2 -2
- package/rihal/references/continuation-format.md +5 -6
- package/rihal/references/research-synthesis-playbook.md +1 -1
- package/rihal/skills/actions/2-plan/rihal-create-milestone/steps/step-06-phase-stubs.md +1 -1
- package/rihal/skills/actions/2-plan/rihal-create-milestone/steps/step-10-complete.md +1 -1
- package/rihal/skills/actions/4-implementation/rihal-debug/SKILL.md +2 -0
- package/rihal/workflows/analyze-dependencies.md +4 -4
- package/rihal/workflows/audit-fix.md +3 -3
- package/rihal/workflows/audit-milestone.md +12 -11
- package/rihal/workflows/audit-worktrees.md +163 -0
- package/rihal/workflows/audit.md +18 -3
- package/rihal/workflows/correct-course.md +3 -3
- package/rihal/workflows/create-architecture.md +3 -3
- package/rihal/workflows/create-epics-and-stories.md +3 -3
- package/rihal/workflows/discuss-phase-power.md +1 -1
- package/rihal/workflows/document-project.md +3 -3
- package/rihal/workflows/edit-prd.md +3 -3
- package/rihal/workflows/execute-milestone.md +3 -3
- package/rihal/workflows/execute-sprint.md +1 -1
- package/rihal/workflows/execute-waves.md +27 -2
- package/rihal/workflows/forensics.md +3 -3
- package/rihal/workflows/health.md +23 -8
- package/rihal/workflows/help.md +0 -1
- package/rihal/workflows/new-project-roadmap.md +2 -2
- package/rihal/workflows/plan-research-validation.md +2 -2
- package/rihal/workflows/plan.md +7 -7
- package/rihal/workflows/retrospective.md +3 -3
- package/rihal/workflows/review-adversarial.md +8 -6
- package/rihal/workflows/review.md +2 -2
- package/rihal/workflows/scaffold-project.md +3 -3
- package/rihal/workflows/secure-phase.md +4 -4
- package/rihal/workflows/session-report.md +1 -1
- package/rihal/workflows/status.md +6 -10
- package/rihal/workflows/validate-prd.md +3 -3
- package/rihal/workflows/verify-phase.md +3 -3
- 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
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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.
|
|
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:
|
|
324
|
+
* pre-compact: Capture rihal session state before context compaction.
|
|
325
325
|
*
|
|
326
|
-
* Triggered by the PreCompact hook.
|
|
327
|
-
*
|
|
328
|
-
*
|
|
329
|
-
*
|
|
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
|
-
|
|
339
|
-
|
|
346
|
+
let state = null;
|
|
347
|
+
if (fs.existsSync(statePath)) {
|
|
348
|
+
try { state = JSON.parse(fs.readFileSync(statePath, 'utf8')); } catch {}
|
|
340
349
|
}
|
|
341
350
|
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
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
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
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
|
-
|
|
362
|
-
|
|
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
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
)
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
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
|
-
|
|
379
|
-
|
|
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
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
6135
|
-
|
|
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: '
|
|
6141
|
-
routes.push({ letter: 'B', label: '
|
|
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
|
-
|
|
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
|
-
|
|
13
|
+
@rihal/workflows/execute-milestone.md
|
|
14
14
|
</execution_context>
|
|
15
15
|
|
|
16
16
|
<process>
|
|
17
|
-
Execute the execute-milestone workflow from
|
|
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
|
-
|
|
13
|
+
@rihal/workflows/plan-milestone.md
|
|
14
14
|
</execution_context>
|
|
15
15
|
|
|
16
16
|
<process>
|
|
17
|
-
Execute the plan-milestone workflow from
|
|
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
|
-
|
|
13
|
+
@rihal/workflows/scaffold-milestone.md
|
|
14
14
|
</execution_context>
|
|
15
15
|
|
|
16
16
|
<process>
|
|
17
|
-
Execute the scaffold-milestone workflow from
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
|
@@ -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
|
|
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-
|
|
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
|
-
-
|
|
144
|
-
-
|
|
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
|
-
-
|
|
203
|
-
-
|
|
204
|
-
-
|
|
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 —
|
|
7
|
+
## Step 0 — Parse arguments
|
|
8
8
|
|
|
9
|
-
|
|
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
|
-
|
|
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:
|