@hanzlaa/rcode 2.7.2 → 3.1.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.
Files changed (135) hide show
  1. package/AGENTS.md +11 -1
  2. package/CONTRIBUTING.md +7 -0
  3. package/README.md +39 -20
  4. package/package.json +2 -2
  5. package/rihal/agents/rihal-advisor-researcher.md +1 -1
  6. package/rihal/agents/rihal-assumptions-analyzer.md +1 -1
  7. package/rihal/agents/rihal-codebase-mapper.md +1 -1
  8. package/rihal/agents/rihal-docs-auditor.md +3 -3
  9. package/rihal/agents/rihal-executor.md +10 -0
  10. package/rihal/agents/rihal-fatima.md +31 -101
  11. package/rihal/agents/rihal-haitham.md +125 -57
  12. package/rihal/agents/rihal-hanzla.md +23 -98
  13. package/rihal/agents/rihal-hussain-pm.md +33 -102
  14. package/rihal/agents/rihal-integration-checker.md +1 -1
  15. package/rihal/agents/rihal-mariam.md +26 -94
  16. package/rihal/agents/rihal-noor.md +2 -2
  17. package/rihal/agents/rihal-omar.md +112 -31
  18. package/rihal/agents/rihal-phase-researcher.md +1 -1
  19. package/rihal/agents/rihal-planner.md +25 -0
  20. package/rihal/agents/rihal-project-researcher.md +1 -1
  21. package/rihal/agents/rihal-research-synthesizer.md +1 -1
  22. package/rihal/agents/rihal-roadmapper.md +1 -1
  23. package/rihal/agents/rihal-sadiq.md +30 -95
  24. package/rihal/agents/rihal-sprint-checker.md +19 -1
  25. package/rihal/agents/rihal-verifier.md +1 -1
  26. package/rihal/agents/rihal-waleed.md +34 -98
  27. package/rihal/agents/rihal-yousef.md +111 -52
  28. package/rihal/commands/code-review.md +1 -1
  29. package/rihal/commands/memory-audit.md +10 -0
  30. package/rihal/commands/memory-distill.md +11 -0
  31. package/rihal/commands/memory-init.md +12 -0
  32. package/rihal/commands/memory-update.md +12 -0
  33. package/rihal/config/model-profiles.json +5 -5
  34. package/rihal/references/agent-shared-rules.md +81 -0
  35. package/rihal/references/karpathy-guidelines-full.md +1 -1
  36. package/rihal/references/no-unauthorized-git-ops.md +1 -1
  37. package/rihal/references/verb-dictionary.md +1 -1
  38. package/rihal/skills/actions/2-plan/rihal-frontend-design/SKILL.md +49 -139
  39. package/rihal/skills/actions/2-plan/rihal-frontend-design/references.md +79 -0
  40. package/rihal/skills/actions/4-implementation/rihal-browser-verify/SKILL.md +70 -0
  41. package/rihal/skills/actions/4-implementation/rihal-checkpoint-preview/SKILL.md +1 -1
  42. package/rihal/skills/actions/4-implementation/rihal-ci/SKILL.md +108 -0
  43. package/rihal/skills/actions/4-implementation/rihal-debug/SKILL.md +78 -0
  44. package/rihal/skills/actions/4-implementation/rihal-git-flow/SKILL.md +90 -0
  45. package/rihal/skills/actions/4-implementation/rihal-harden/SKILL.md +91 -0
  46. package/rihal/skills/actions/4-implementation/rihal-incremental/SKILL.md +50 -0
  47. package/rihal/skills/actions/4-implementation/rihal-migrate/SKILL.md +86 -0
  48. package/rihal/skills/actions/4-implementation/rihal-perf/SKILL.md +96 -0
  49. package/rihal/skills/actions/4-implementation/rihal-prove-it/SKILL.md +64 -0
  50. package/rihal/skills/actions/4-implementation/rihal-source-truth/SKILL.md +76 -0
  51. package/rihal/skills/actions/4-implementation/rihal-trim/SKILL.md +73 -0
  52. package/rihal/skills/agents/dalil-scout/SKILL.md +43 -125
  53. package/rihal/skills/agents/dalil-scout/references.md +67 -0
  54. package/rihal/skills/agents/fatima-qa/SKILL.md +21 -0
  55. package/rihal/skills/agents/hanzla-engineer/SKILL.md +22 -0
  56. package/rihal/skills/agents/hussain-pm/SKILL.md +21 -0
  57. package/rihal/skills/agents/majlis-council/SKILL.md +50 -144
  58. package/rihal/skills/agents/majlis-council/references.md +90 -0
  59. package/rihal/skills/agents/mariam-marketing/SKILL.md +19 -0
  60. package/rihal/skills/agents/raees-orchestrator/SKILL.md +56 -117
  61. package/rihal/skills/agents/raees-orchestrator/references.md +47 -0
  62. package/rihal/skills/agents/sadiq-analyst/SKILL.md +30 -0
  63. package/rihal/skills/agents/waleed-architect/SKILL.md +20 -0
  64. package/rihal/skills/core/rihal-advanced-elicitation/SKILL.md +36 -136
  65. package/rihal/skills/core/rihal-advanced-elicitation/references.md +101 -0
  66. package/rihal/skills/core/rihal-auth-audit/SKILL.md +93 -0
  67. package/rihal/skills/core/rihal-brainstorming/SKILL.md +5 -0
  68. package/rihal/skills/core/rihal-client-gate/SKILL.md +91 -0
  69. package/rihal/skills/core/rihal-clone-website/SKILL.md +30 -371
  70. package/rihal/skills/core/rihal-clone-website/references.md +213 -0
  71. package/rihal/skills/core/rihal-deploy-unify/SKILL.md +87 -0
  72. package/rihal/skills/core/rihal-distillator/SKILL.md +37 -187
  73. package/rihal/skills/core/rihal-distillator/references.md +118 -0
  74. package/rihal/skills/core/rihal-editorial-review-prose/SKILL.md +5 -0
  75. package/rihal/skills/core/rihal-editorial-review-structure/SKILL.md +45 -183
  76. package/rihal/skills/core/rihal-editorial-review-structure/references.md +110 -0
  77. package/rihal/skills/core/rihal-help/SKILL.md +6 -1
  78. package/rihal/skills/core/rihal-incident-record/SKILL.md +161 -0
  79. package/rihal/skills/core/rihal-index-docs/SKILL.md +5 -0
  80. package/rihal/skills/core/rihal-init/SKILL.md +5 -0
  81. package/rihal/skills/core/rihal-memory-audit/SKILL.md +88 -0
  82. package/rihal/skills/core/rihal-memory-distill/SKILL.md +87 -0
  83. package/rihal/skills/core/rihal-memory-init/SKILL.md +77 -0
  84. package/rihal/skills/core/rihal-memory-update/SKILL.md +73 -0
  85. package/rihal/skills/core/rihal-mvp-graduate/SKILL.md +116 -0
  86. package/rihal/skills/core/rihal-ocr-consistency/SKILL.md +106 -0
  87. package/rihal/skills/core/rihal-party-mode/SKILL.md +5 -0
  88. package/rihal/skills/core/rihal-rebrand/SKILL.md +133 -0
  89. package/rihal/skills/core/rihal-review-adversarial-general/SKILL.md +5 -0
  90. package/rihal/skills/core/rihal-review-edge-case-hunter/SKILL.md +5 -0
  91. package/rihal/skills/core/rihal-shard-doc/SKILL.md +5 -0
  92. package/rihal/skills/core/rihal-theme-system/SKILL.md +113 -0
  93. package/rihal/team.yaml +3 -22
  94. package/rihal/templates/memory/INDEX.md +46 -0
  95. package/rihal/templates/memory/change-records/.gitkeep +4 -0
  96. package/rihal/templates/memory/distillates/project.distillate.md +11 -0
  97. package/rihal/templates/memory/distillates/stack.distillate.md +11 -0
  98. package/rihal/templates/memory/incidents/known-issues.md +27 -0
  99. package/rihal/templates/memory/incidents/post-mortems/.gitkeep +3 -0
  100. package/rihal/templates/memory/milestones/archive/.gitkeep +2 -0
  101. package/rihal/templates/memory/milestones/current.md +39 -0
  102. package/rihal/templates/memory/people/stakeholders.md +25 -0
  103. package/rihal/templates/memory/people/team.md +35 -0
  104. package/rihal/templates/memory/project/decisions.md +32 -0
  105. package/rihal/templates/memory/project/glossary.md +16 -0
  106. package/rihal/templates/memory/project/stack.md +46 -0
  107. package/rihal/workflows/audit.md +3 -3
  108. package/rihal/workflows/code-review.md +32 -1
  109. package/rihal/workflows/council.md +1 -1
  110. package/rihal/workflows/discuss-phase-power.md +3 -3
  111. package/rihal/workflows/do.md +1 -1
  112. package/rihal/workflows/docs-update.md +4 -4
  113. package/rihal/workflows/execute.md +61 -5
  114. package/rihal/workflows/help.md +5 -5
  115. package/rihal/workflows/karpathy-audit.md +9 -9
  116. package/rihal/workflows/memory-audit.md +83 -0
  117. package/rihal/workflows/memory-distill.md +103 -0
  118. package/rihal/workflows/memory-init.md +102 -0
  119. package/rihal/workflows/memory-update.md +83 -0
  120. package/rihal/workflows/plan.md +66 -1
  121. package/server/dashboard.js +6 -1
  122. package/server/lib/api.js +8 -2
  123. package/server/lib/html/client.js +63 -0
  124. package/server/lib/html/shell.js +5 -0
  125. package/server/lib/scanner.js +76 -1
  126. package/rihal/agents/rihal-architect.md +0 -79
  127. package/rihal/agents/rihal-tech-writer.md +0 -80
  128. package/rihal/commands/check-implementation-readiness.md +0 -8
  129. package/rihal/commands/discuss-phase-power.md +0 -11
  130. package/rihal/commands/karpathy-audit.md +0 -12
  131. package/rihal/commands/new-project-research.md +0 -11
  132. package/rihal/commands/new-project-roadmap.md +0 -11
  133. package/rihal/commands/report.md +0 -10
  134. package/rihal/commands/review-adversarial.md +0 -8
  135. package/rihal/commands/review-edge-case-hunter.md +0 -8
@@ -507,11 +507,17 @@ Execute each selected wave in sequence. Within a wave: parallel if `PARALLELIZAT
507
507
  </worktree_branch_check>
508
508
 
509
509
  <parallel_execution>
510
- You are running as a PARALLEL executor agent. Use --no-verify on all git
511
- commits to avoid pre-commit hook contention with other agents. The
512
- orchestrator validates hooks once after all agents complete.
513
- For rihal-tools commits: add --no-verify flag.
514
- For direct git commits: use git commit --no-verify -m "..."
510
+ You are running as a PARALLEL executor agent. To avoid pre-commit hook
511
+ contention with other agents, acquire a file-based lock before each
512
+ commit and release it immediately after:
513
+
514
+ while ! mkdir .rihal/.commit-lock 2>/dev/null; do sleep 0.5; done
515
+ git commit -m "..." # hooks run normally
516
+ rmdir .rihal/.commit-lock
517
+
518
+ Hooks run as designed for every commit. AGENTS.md forbids --no-verify;
519
+ hook failures must be fixed at the source, not bypassed. The orchestrator
520
+ still validates state once after all agents complete.
515
521
  </parallel_execution>
516
522
 
517
523
  <execution_context>
@@ -1291,6 +1297,56 @@ Also: `/rihal:verify-work {X} ${Rihal_WS}` — manual testing first
1291
1297
  Gap closure cycle: `/rihal:plan {X} --gaps ${Rihal_WS}` reads VERIFICATION.md → creates gap plans with `gap_closure: true` → user runs `/rihal:execute {X} --gaps-only ${Rihal_WS}` → verifier re-runs.
1292
1298
  </step>
1293
1299
 
1300
+ <step name="uat_gate" priority="blocker">
1301
+ **UAT gate (added in v3.1.0 after #443 / #448):**
1302
+
1303
+ Before marking the phase complete, verify a passing VERIFICATION.md exists for this phase. Without it, the phase advances to `status: executed` (work done, awaiting verification) — not `status: complete`.
1304
+
1305
+ ```bash
1306
+ VERIFICATION_FILE=$(ls "${PHASE_DIR}"/*-VERIFICATION.md 2>/dev/null | head -1)
1307
+
1308
+ if [ -z "$VERIFICATION_FILE" ]; then
1309
+ VERIFICATION_STATUS="missing"
1310
+ elif grep -q "^status:\s*pass\b" "$VERIFICATION_FILE" 2>/dev/null; then
1311
+ VERIFICATION_STATUS="pass"
1312
+ elif grep -q "^status:\s*fail\b" "$VERIFICATION_FILE" 2>/dev/null; then
1313
+ VERIFICATION_STATUS="fail"
1314
+ else
1315
+ VERIFICATION_STATUS="indeterminate"
1316
+ fi
1317
+ ```
1318
+
1319
+ **If `VERIFICATION_STATUS` is `missing` or `indeterminate`:**
1320
+
1321
+ 1. Mark the phase as `status: executed` (NOT `complete`) via:
1322
+ ```bash
1323
+ node ".rihal/bin/rihal-tools.cjs" phase set-status "${PHASE_NUMBER}" executed
1324
+ ```
1325
+ 2. Print the mandatory UAT checklist:
1326
+ ```
1327
+ ⚠ Phase {X} EXECUTED but not yet verified.
1328
+
1329
+ The following acceptance criteria require human verification before
1330
+ the phase can advance to `status: complete`:
1331
+
1332
+ {list AC items from SPRINT.md}
1333
+
1334
+ Run /rihal:verify-work {X} to perform UAT and produce VERIFICATION.md.
1335
+ /rihal:next will refuse to advance until this gate passes.
1336
+ ```
1337
+ 3. STOP the workflow. Do NOT proceed to `update_roadmap`. Do NOT call `phase complete`.
1338
+
1339
+ **If `VERIFICATION_STATUS` is `fail`:**
1340
+
1341
+ 1. Mark the phase as `status: executed` (so /rihal:plan --gaps can run a closure cycle).
1342
+ 2. Surface the failed AC items.
1343
+ 3. STOP. Don't mark complete on a failing verification.
1344
+
1345
+ **Only when `VERIFICATION_STATUS` is `pass`** — proceed to `update_roadmap` below.
1346
+
1347
+ The previous behaviour (printing "Next Up: /rihal:verify-work" without state-gating) caused phases to reach `status: complete` without any human-verified UAT — see #443 for the failure mode.
1348
+ </step>
1349
+
1294
1350
  <step name="update_roadmap">
1295
1351
  **Mark phase complete and update all tracking files:**
1296
1352
 
@@ -174,18 +174,18 @@ init → new-project → plan → execute → next → status → ship
174
174
  | `/rihal:add-tests <n>` | Generate unit + E2E tests based on SPRINT/SUMMARY/CONTEXT. |
175
175
  | `/rihal:audit-uat` | Cross-phase audit of all outstanding UAT items. |
176
176
  | `/rihal:audit-fix` | Autonomous audit-to-fix pipeline — find, classify, fix, test, commit. |
177
- | `/rihal:karpathy-audit` | Audit recent code against Karpathy's 4 LLM coding principles. |
177
+ | `/rihal:code-review --karpathy` | Audit recent code against Karpathy's 4 LLM coding principles. |
178
178
  | `/rihal:ui-phase <n>` | Generate UI design contract (UI-SPEC.md) for frontend phases. |
179
179
  | `/rihal:ui-review` | Retroactive 6-pillar visual audit of completed UI work. |
180
- | `/rihal:review-adversarial` | Hostile-perspective report — vulnerabilities, race conditions, abuse. |
181
- | `/rihal:review-edge-case-hunter` | Enumerate edge cases by category and severity. |
180
+ | `/rihal:code-review --attack` | Hostile-perspective report — vulnerabilities, race conditions, abuse. |
181
+ | `/rihal:code-review --edge-cases` | Enumerate edge cases by category and severity. |
182
182
  | `/rihal:review` | Cross-AI peer review — invoke external AI CLIs to review plans. |
183
183
 
184
184
  ## Council variants & strategy power tools
185
185
 
186
186
  | Command | Use |
187
187
  |---------|-----|
188
- | `/rihal:discuss-phase-power` | Bulk question generation with async UI for context-heavy phases. |
188
+ | `/rihal:discuss-phase --power` | Bulk question generation with async UI for context-heavy phases. |
189
189
  | `/rihal:chain <preset> <topic>` | Sequential agent pipeline (research → scope → build), typed artifacts. |
190
190
  | `/rihal:brainstorm` | Guided brainstorming — pick a method, generate ideas systematically. |
191
191
  | `/rihal:why <decision>` | Explain reasoning behind a decision, classification, or panel pick. |
@@ -213,7 +213,7 @@ init → new-project → plan → execute → next → status → ship
213
213
  | `/rihal:create-epics-and-stories` | Parse a PRD into numbered epic + story files. |
214
214
  | `/rihal:create-story` | Prepare a dev-ready STORY.md with full implementation context. |
215
215
  | `/rihal:dev-story <file>` | Execute an approved STORY by writing tests + code per AC. |
216
- | `/rihal:check-implementation-readiness` | Verify PRD + architecture + epics aligned before build. |
216
+ | (internal) `check-implementation-readiness` | Guard called by `/rihal:plan` and `/rihal:execute` to verify PRD + architecture aligned before build. |
217
217
  | `/rihal:create-architecture` | Write an Architecture Decision Record (ADR). |
218
218
  | `/rihal:create-ux-design` | Realize a UX design that informs architecture and implementation. |
219
219
  | `/rihal:correct-course` | Course-correct mid-sprint when major change is discovered. |
@@ -14,15 +14,15 @@ If `$ARGUMENTS` is empty or contains only `--help` or `-h`:
14
14
 
15
15
  **Usage:**
16
16
  ```
17
- /rihal:karpathy-audit <phase> [--files=path1,path2]
18
- /rihal:karpathy-audit <git-ref>..HEAD
17
+ /rihal:code-review --karpathy <phase> [--files=path1,path2]
18
+ /rihal:code-review --karpathy <git-ref>..HEAD
19
19
  ```
20
20
 
21
21
  **Examples:**
22
22
  ```
23
- /rihal:karpathy-audit 03
24
- /rihal:karpathy-audit 02 --files=src/
25
- /rihal:karpathy-audit HEAD~5..HEAD
23
+ /rihal:code-review --karpathy 03
24
+ /rihal:code-review --karpathy 02 --files=src/
25
+ /rihal:code-review --karpathy HEAD~5..HEAD
26
26
  ```
27
27
 
28
28
  <process>
@@ -44,7 +44,7 @@ Parse: `phase_found`, `phase_dir`, `phase_number`, `padded_phase`.
44
44
 
45
45
  If phase_found is false:
46
46
  ```
47
- Error: Phase ${PHASE_ARG} not found. Try /rihal:karpathy-audit HEAD~5..HEAD to audit recent commits instead.
47
+ Error: Phase ${PHASE_ARG} not found. Try /rihal:code-review --karpathy HEAD~5..HEAD to audit recent commits instead.
48
48
  ```
49
49
 
50
50
  If git ref format (contains ".." or has no digit at start):
@@ -343,7 +343,7 @@ Aggregate all findings into a structured report:
343
343
  ---
344
344
 
345
345
  **Generated:** {date}
346
- **Run:** /rihal:karpathy-audit {original_arguments}
346
+ **Run:** /rihal:code-review --karpathy {original_arguments}
347
347
  ```
348
348
 
349
349
  Write report to stdout and optionally to file `{phase_dir}/{padded_phase}-KARPATHY-AUDIT.md` if phase mode.
@@ -375,7 +375,7 @@ Review the full report above. Use /rihal:code-review-fix to auto-fix some issues
375
375
  **Next steps:**
376
376
  ```
377
377
  View full report: {report file path}
378
- Rerun: /rihal:karpathy-audit {arguments}
378
+ Rerun: /rihal:code-review --karpathy {arguments}
379
379
  Auto-fix some issues: /rihal:code-review-fix {phase}
380
380
  ```
381
381
  </step>
@@ -395,7 +395,7 @@ Auto-fix some issues: /rihal:code-review-fix {phase}
395
395
 
396
396
  ## On Error
397
397
 
398
- - **Phase not found:** suggest `/rihal:karpathy-audit HEAD~5..HEAD` as the git-ref fallback.
398
+ - **Phase not found:** suggest `/rihal:code-review --karpathy HEAD~5..HEAD` as the git-ref fallback.
399
399
  - **No source files in diff:** report "no auditable changes in range" and STOP — do not invent findings.
400
400
  - **karpathy-guidelines.md missing:** print "Reference doc missing. Run: npx @hanzlaa/rcode install ." and STOP.
401
401
  - **Empty diff:** STOP gracefully, do not run principle checks against an empty input.
@@ -0,0 +1,83 @@
1
+ # Workflow: rcode-memory-audit
2
+
3
+ Read-only audit of the Memory Bank. Produces a severity-tagged report. Never modifies files.
4
+
5
+ ---
6
+
7
+ ## Inputs
8
+
9
+ None required. Optional `--severity {critical|warn|info}` to filter output.
10
+
11
+ ## Preconditions
12
+
13
+ - `.rihal/memory/INDEX.md` exists
14
+
15
+ ## Halt conditions
16
+
17
+ - Memory Bank not initialised → instruct to run `/rcode:memory-init` first
18
+
19
+ ---
20
+
21
+ ## Steps
22
+
23
+ ### Step 1 — Catalogue files
24
+
25
+ Walk `.rihal/memory/` and build a list of every file plus its size and modification time. Include `.gitkeep` files for empty-subdir detection.
26
+
27
+ ### Step 2 — Check 1: Stale milestone
28
+
29
+ Read `milestones/current.md`. Parse the "Target close" date. If `(today - target_close).days >= 30`, emit a `warn` finding.
30
+
31
+ ### Step 3 — Check 2: Resolved issues lingering
32
+
33
+ For each entry in `incidents/known-issues.md`:
34
+ - Parse "Real fix planned for" field
35
+ - If it names a milestone that has been moved to `milestones/archive/`, emit a `warn` finding
36
+
37
+ ### Step 4 — Check 3: Template placeholders unfilled
38
+
39
+ For each `*.md` file under `.rihal/memory/`:
40
+ - Count occurrences of `{{` literally (template placeholders)
41
+ - Count occurrences of `_(e.g.` (italicised template hints)
42
+ - If either is non-zero, emit an `info` finding listing the file and count
43
+
44
+ ### Step 5 — Check 4: Stack vs decisions contradiction
45
+
46
+ For each decision entry in `project/decisions.md` that mentions a technology name:
47
+ - Extract candidate tech terms (proper nouns, capitalised + version)
48
+ - Search `project/stack.md` for the term
49
+ - If not found, emit a `critical` finding
50
+
51
+ ### Step 6 — Check 5: Empty subdirectories
52
+
53
+ For `change-records/`, `incidents/post-mortems/`, `milestones/archive/`:
54
+ - If only file is `.gitkeep`, emit an `info` finding (not a problem, just visibility)
55
+
56
+ ### Step 7 — Check 6: Distillate freshness
57
+
58
+ For each `distillates/*.distillate.md`:
59
+ - Read frontmatter `source-digest`
60
+ - Recompute digest of current source files (per `rcode-memory-distill` rules)
61
+ - If mismatch, emit a `warn` finding suggesting `/rcode:memory-distill`
62
+
63
+ ### Step 8 — Render report
64
+
65
+ Group findings by severity (critical → warn → info), then by file within each severity group. For each finding, print:
66
+ - File path
67
+ - One-line description
68
+ - One-line `Fix:` suggestion (which skill to run, or manual action)
69
+
70
+ If `--severity` filter passed, hide findings below the threshold.
71
+
72
+ If zero findings: print `✓ Memory Bank is healthy. 0 findings.`
73
+
74
+ ---
75
+
76
+ ## Post-conditions
77
+
78
+ - No files modified
79
+ - Report printed to stdout
80
+
81
+ ## Reversibility
82
+
83
+ Read-only — no state to revert.
@@ -0,0 +1,103 @@
1
+ # Workflow: rcode-memory-distill
2
+
3
+ Regenerate Memory Bank distillates with lossless compression. Idempotent.
4
+
5
+ ---
6
+
7
+ ## Inputs
8
+
9
+ - `--force` (optional) — regenerate even when source files are unchanged
10
+ - `--target {project|stack|all}` (optional, default `all`) — limit which distillate to regenerate
11
+
12
+ ## Preconditions
13
+
14
+ - `.rihal/memory/` exists
15
+ - `.rihal/memory/distillates/` exists (created by `rcode-memory-init`)
16
+
17
+ ## Halt conditions
18
+
19
+ - `.rihal/memory/` missing → instruct to run `/rcode:memory-init` first
20
+ - All sources empty (only template placeholders) → warn and exit; no point distilling empty content
21
+
22
+ ---
23
+
24
+ ## Steps
25
+
26
+ ### Step 1 — Resolve source set
27
+
28
+ For `target = project`:
29
+ - `project/stack.md`, `project/decisions.md`, `project/glossary.md`
30
+ - `people/stakeholders.md`, `people/team.md`
31
+ - `milestones/current.md`
32
+ - `incidents/known-issues.md`
33
+
34
+ For `target = stack`:
35
+ - `project/stack.md` only
36
+
37
+ ### Step 2 — Compute digest
38
+
39
+ ```
40
+ digest = sha1(concat(file_path + ":" + mtime for each source file in sorted order))
41
+ ```
42
+
43
+ If `--force` not passed and existing distillate's `source-digest:` matches, skip regeneration for that target.
44
+
45
+ ### Step 3 — Compress per target
46
+
47
+ For each target's source set:
48
+
49
+ 1. Read all source files
50
+ 2. Extract: facts, decisions, constraints, relationships, named entities, dates
51
+ 3. Produce a dense markdown document organised by topic (not by source file)
52
+ 4. Strip overhead: pleasantries, redundant headings, examples that don't add new facts, template placeholders that weren't filled
53
+ 5. Preserve: every concrete claim, every decision, every link, every name, every date
54
+
55
+ Compression target: ~30% of source token count. If output is larger, the source had a lot of substance and that's fine.
56
+
57
+ ### Step 4 — Losslessness check
58
+
59
+ Walk each source file and confirm every "fact" (sentence containing a name, date, decision, or technical term) appears in the distillate either verbatim or via a directly-equivalent phrase. List any potential drops as warnings; user can `--force` past warnings if confident.
60
+
61
+ ### Step 5 — Write output
62
+
63
+ For each target distillate, write:
64
+
65
+ ```markdown
66
+ ---
67
+ generated: true
68
+ do-not-edit: true
69
+ regenerate-with: /rcode:memory-distill
70
+ source-digest: <hash>
71
+ generated-at: <ISO datetime>
72
+ source-files:
73
+ - project/stack.md
74
+ - project/decisions.md
75
+ ...
76
+ token-estimate: <approximate>
77
+ ---
78
+
79
+ # Project Distillate — <project-name>
80
+
81
+ <compressed content>
82
+ ```
83
+
84
+ ### Step 6 — Summary
85
+
86
+ Print per-target:
87
+ - Source file count
88
+ - Output token estimate
89
+ - Digest
90
+ - Skip notice (if no-op)
91
+
92
+ ---
93
+
94
+ ## Post-conditions
95
+
96
+ - `distillates/project.distillate.md` updated (if target includes project)
97
+ - `distillates/stack.distillate.md` updated (if target includes stack)
98
+ - Frontmatter `source-digest` matches the current source set
99
+ - No source files modified
100
+
101
+ ## Reversibility
102
+
103
+ Distillates are derived artefacts. Reverting a regeneration: `git checkout .rihal/memory/distillates/`.
@@ -0,0 +1,102 @@
1
+ # Workflow: rcode-memory-init
2
+
3
+ Bootstraps the rcode Memory Bank in the current project. Idempotent — re-running on an initialised project switches to a gap report instead of overwriting.
4
+
5
+ ---
6
+
7
+ ## Inputs
8
+
9
+ - **Project root** — current working directory; must contain a `.rihal/` folder (created by `rcode install`)
10
+ - **Templates source** — `.rihal/templates/memory/` (copied from `rihal/templates/memory/` on install)
11
+
12
+ ## Preconditions
13
+
14
+ - `.rihal/` exists (rcode is installed in this project)
15
+ - `.rihal/templates/memory/` exists (templates ship with rcode)
16
+
17
+ ## Halt conditions
18
+
19
+ - `.rihal/` missing → ask user to run `npx @hanzlaa/rcode install` first, then halt.
20
+ - `.rihal/templates/memory/` missing → report bug, halt.
21
+ - User cancels at any question → leave `.rihal/memory/` partially populated (whatever was seeded) and exit cleanly.
22
+
23
+ ---
24
+
25
+ ## Steps
26
+
27
+ ### Step 1 — Detect existing Memory Bank
28
+
29
+ ```bash
30
+ if [ -f ".rihal/memory/INDEX.md" ]; then
31
+ # Switch to gap-report mode
32
+ exit_with_gap_report
33
+ fi
34
+ ```
35
+
36
+ If `INDEX.md` exists:
37
+ - List every file under `.rihal/memory/`
38
+ - For each, count non-template lines (lines that don't start with `<!--` or contain `_(...)_` placeholders)
39
+ - Print which files are empty / template-only and which are populated
40
+ - Suggest `/rcode:memory-update` for surgical edits and exit
41
+
42
+ ### Step 2 — Copy templates
43
+
44
+ ```bash
45
+ mkdir -p .rihal/memory
46
+ cp -R .rihal/templates/memory/. .rihal/memory/
47
+ ```
48
+
49
+ Preserves the directory structure. Includes `.gitkeep` files in empty subdirs.
50
+
51
+ ### Step 3 — Substitute placeholders
52
+
53
+ Replace in every `*.md` file under `.rihal/memory/`:
54
+ - `{{PROJECT_NAME}}` → derived from `package.json` `name`, fallback to directory basename
55
+ - `{{INIT_DATE}}` → today's date in `YYYY-MM-DD` format
56
+
57
+ ### Step 4 — Five init questions
58
+
59
+ Ask each via AskUserQuestion. Accept short answers; do not push for paragraphs.
60
+
61
+ **Q1.** What is the one-sentence project goal? *(saved to `milestones/current.md` → Goal)*
62
+
63
+ **Q2.** Primary stack — frontend / backend / database? *(parsed into `project/stack.md` Runtime table)*
64
+
65
+ **Q3.** What is the current milestone name? *(saved to `milestones/current.md` → Milestone Name; default `M1 — Initial`)*
66
+
67
+ **Q4.** Primary external stakeholder name and role? *(appended to `people/stakeholders.md`)*
68
+
69
+ **Q5.** Any known production issue you'd warn a new teammate about today? *(appended to `incidents/known-issues.md`; "none" is acceptable)*
70
+
71
+ ### Step 5 — Update state.json
72
+
73
+ Add or update the `memory_bank` block in `.rihal/state.json`:
74
+
75
+ ```json
76
+ {
77
+ "memory_bank": {
78
+ "initialised_at": "<ISO datetime>",
79
+ "version": 1
80
+ }
81
+ }
82
+ ```
83
+
84
+ ### Step 6 — Print summary
85
+
86
+ Show:
87
+ - File tree of `.rihal/memory/`
88
+ - Files seeded vs files still empty
89
+ - Suggested next command: `/rcode:memory-distill`
90
+
91
+ ---
92
+
93
+ ## Post-conditions
94
+
95
+ - `.rihal/memory/INDEX.md` exists with project name + date filled in
96
+ - 4–5 of the seeded files have user-supplied content
97
+ - `.rihal/state.json` records initialisation
98
+ - The Diwan dashboard `/memory` route now renders content (Phase 3 dashboard work)
99
+
100
+ ## Reversibility
101
+
102
+ Removing a botched init: `rm -rf .rihal/memory/` and `git checkout -- .rihal/state.json`. No external side effects.
@@ -0,0 +1,83 @@
1
+ # Workflow: rcode-memory-update
2
+
3
+ Append-only surgical update to a single Memory Bank file. Never rewrites, never deletes.
4
+
5
+ ---
6
+
7
+ ## Inputs
8
+
9
+ - **content** — the thing to remember, in plain English
10
+ - **target** (optional) — explicit file path; if omitted, auto-detected from content
11
+
12
+ ## Preconditions
13
+
14
+ - `.rihal/memory/` exists (run `/rcode:memory-init` first)
15
+
16
+ ## Halt conditions
17
+
18
+ - `.rihal/memory/` missing → instruct user to init first
19
+ - User asks to *change* (not append) an existing entry → refuse, redirect to direct file edit
20
+ - Detected target file does not exist → report and halt (don't create new files in this workflow)
21
+
22
+ ---
23
+
24
+ ## Steps
25
+
26
+ ### Step 1 — Auto-detect target
27
+
28
+ Match keywords in the user's content against this routing table:
29
+
30
+ | Signal | Target |
31
+ |---|---|
32
+ | "decision", "we chose", "ADR", "decided" | `project/decisions.md` |
33
+ | "bug", "issue", "broken", "workaround" | `incidents/known-issues.md` |
34
+ | "stakeholder", "client", "contact", "rep" | `people/stakeholders.md` |
35
+ | "milestone", "sprint", "phase", "blocker" | `milestones/current.md` |
36
+ | "stack", "framework", "library", "switched to" | `project/stack.md` |
37
+ | "term", "glossary", "what does X mean" | `project/glossary.md` |
38
+ | "team", "who owns", "engineer", "responsibility" | `people/team.md` |
39
+ | "change record", "deployment", "rollback" | `change-records/` (creates new file) |
40
+
41
+ If ambiguous, ask the user to pick from the top 2 candidates.
42
+
43
+ ### Step 2 — Confirm with user
44
+
45
+ Show:
46
+ - Target file path
47
+ - Proposed entry, formatted to match the file's existing entry style
48
+ - A "Apply / cancel / edit format" choice
49
+
50
+ ### Step 3 — Append
51
+
52
+ For appendable files (`decisions.md`, `known-issues.md`, `stakeholders.md`, `team.md`, `glossary.md`):
53
+ - Insert above the `<!-- Append new entries above this line -->` marker if present
54
+ - Otherwise append to end of file with a blank line separator
55
+
56
+ For `milestones/current.md`:
57
+ - Allow only field-level updates (Goal, Active phase, Blockers, Recent decisions)
58
+ - Replace the field's value, not the whole file
59
+
60
+ For `change-records/`:
61
+ - Create a new file `YYYYMMDD-NNN.md` where `NNN` is the next sequence number
62
+ - Use the change-record template format
63
+
64
+ ### Step 4 — Stamp and verify
65
+
66
+ - Add `YYYY-MM-DD` date (today, ISO format) to every appended entry
67
+ - Print a diff preview (last 20 lines of the file) so the user can confirm the change landed
68
+
69
+ ### Step 5 — Suggest distillate refresh
70
+
71
+ If the change was to `project/`, `milestones/current.md`, or `incidents/`, suggest `/rcode:memory-distill` to refresh distillates. Optional, not enforced.
72
+
73
+ ---
74
+
75
+ ## Post-conditions
76
+
77
+ - Exactly one file changed (or one new change-record file created)
78
+ - File still parses as valid markdown
79
+ - No content removed
80
+
81
+ ## Reversibility
82
+
83
+ `git diff .rihal/memory/` shows exactly one append — easy to revert with `git checkout`.
@@ -999,7 +999,27 @@ Track `stall_reentry_count` (starts at 0; incremented each time "Adjust approach
999
999
 
1000
1000
  **If iteration_count < 3:**
1001
1001
 
1002
- Parse issue count from checker return: count BLOCKER + WARNING entries in the YAML issues block (structured output from rihal-sprint-checker). If the checker's return contains no YAML issues block (i.e., the plan was approved with no issues), treat `issue_count` as 0 and skip the stall check — the plan passed. Proceed to step 13.
1002
+ **Sprint-checker malfunction guard (BLOCKER-class added in v3.1.0 after #440):**
1003
+
1004
+ Before parsing issues, verify the checker actually invoked tools. The checker MUST exhibit at least one of these evidence markers in its return:
1005
+
1006
+ - A YAML `issues:` block (even an empty one — `issues: []`)
1007
+ - A YAML `verified_files:` block listing files it read
1008
+ - At least one `path:` field in any block (e.g. `path: src/components/Foo.tsx:42`)
1009
+ - A summary line of the form `Verified N of M files` or `Checked N symbols`
1010
+
1011
+ If NONE of these evidence markers are present, the checker malfunctioned (returned narrative without invoking tools — see #440). BLOCK execution:
1012
+
1013
+ ```
1014
+ Display: "Sprint-checker returned without evidence of tool use — likely
1015
+ malfunctioned (cf. issue #440). Refusing to advance the plan
1016
+ on unverified output. Re-run /rihal:plan or inspect the agent."
1017
+ Halt the workflow with a non-zero exit signal.
1018
+ ```
1019
+
1020
+ Do NOT treat empty / narrative-only checker output as "plan approved". An empty checker output is a malfunction, not a pass.
1021
+
1022
+ Parse issue count from checker return: count BLOCKER + WARNING entries in the YAML issues block (structured output from rihal-sprint-checker). If the checker's return contains a populated YAML issues block with `issues: []` (i.e., the plan was approved with no issues AFTER actual checking), treat `issue_count` as 0 and skip the stall check — the plan passed. Proceed to step 13.
1003
1023
 
1004
1024
  Display: `Revision iteration {N}/3 -- {blocker_count} blockers, {warning_count} warnings`
1005
1025
 
@@ -1064,6 +1084,51 @@ Display: `Max iterations reached. {N} issues remain:` + issue list
1064
1084
 
1065
1085
  Offer: 1) Force proceed, 2) Provide guidance and retry, 3) Abandon
1066
1086
 
1087
+ ## 12.5. Wave Parallelism File-Overlap Check (added in v3.1.0 after #442)
1088
+
1089
+ Before declaring plans ready, validate the wave-parallelism rule the planner declares: **same wave + overlapping `files_modified` = sequential, not parallel**. If two plans share `depends_on` (same wave) and both list the same file in `files_modified`, the planner should have marked the later one `sequential: true`. Catch the cases where it didn't.
1090
+
1091
+ ```bash
1092
+ # For every pair of plans (A, B) with the same depends_on:
1093
+ # if files_modified(A) ∩ files_modified(B) is non-empty:
1094
+ # - the later plan (by sprint id) MUST declare sequential: true
1095
+ # - and must list the conflicting files in its frontmatter
1096
+
1097
+ node ".rihal/bin/rihal-tools.cjs" plan check-wave-overlaps "${PHASE_NUMBER}"
1098
+ ```
1099
+
1100
+ The CLI helper returns a JSON report:
1101
+
1102
+ ```json
1103
+ {
1104
+ "conflicts": [
1105
+ {
1106
+ "wave": 2,
1107
+ "plan_a": "96.2",
1108
+ "plan_b": "96.3",
1109
+ "shared_files": ["src/components/LeadDetailPanel.tsx", "src/styles/inbox.css"],
1110
+ "plan_b_sequential": false
1111
+ }
1112
+ ]
1113
+ }
1114
+ ```
1115
+
1116
+ **If `conflicts` is non-empty:**
1117
+
1118
+ 1. For each conflict, edit the later plan's SPRINT.md frontmatter to add:
1119
+ ```yaml
1120
+ sequential: true
1121
+ sequential_after: <plan_a id>
1122
+ conflicting_files: [<shared_files...>]
1123
+ ```
1124
+ 2. Recompute waves: the formerly-parallel plan now depends on the earlier one, so its wave is `max(waves of dependencies) + 1`.
1125
+ 3. Re-run the checker to confirm the updated frontmatter.
1126
+ 4. Display: `Wave parallelism: {N} conflict(s) auto-corrected to sequential.`
1127
+
1128
+ **If `conflicts` is empty:** Display `Wave parallelism: ✓ no file-overlap conflicts.` and proceed.
1129
+
1130
+ This closes the gap from #442 — the rule was stated in `rihal-planner.md` but not enforced. Now it's enforced automatically.
1131
+
1067
1132
  ## 13. Requirements Coverage Gate
1068
1133
 
1069
1134
  After plans pass the checker (or checker is skipped), verify that all phase requirements are covered by at least one plan.
@@ -24,7 +24,7 @@ const http = require('http');
24
24
  const path = require('path');
25
25
 
26
26
  const { scanState } = require('./lib/scanner');
27
- const { handleApiState, handleApiFiles, handleApiFile, handleApiHierarchy } = require('./lib/api');
27
+ const { handleApiState, handleApiFiles, handleApiFile, handleApiHierarchy, handleApiMemory } = require('./lib/api');
28
28
  const { renderHtml } = require('./lib/html/shell');
29
29
 
30
30
  // ---------- Configuration ----------
@@ -62,6 +62,11 @@ const server = http.createServer((req, res) => {
62
62
  return;
63
63
  }
64
64
 
65
+ if (url === '/api/memory') {
66
+ handleApiMemory(req, res, RIHAL_DIR);
67
+ return;
68
+ }
69
+
65
70
  if (url === '/' || url === '/index.html') {
66
71
  const state = scanState(RIHAL_DIR);
67
72
  const html = renderHtml(state);
package/server/lib/api.js CHANGED
@@ -3,7 +3,7 @@
3
3
  */
4
4
  const fs = require('fs');
5
5
  const path = require('path');
6
- const { scanState } = require('./scanner');
6
+ const { scanState, scanMemoryBank } = require('./scanner');
7
7
 
8
8
  function handleApiState(req, res, rihalDir) {
9
9
  const state = scanState(rihalDir);
@@ -120,4 +120,10 @@ function handleApiHierarchy(req, res, rihalDir) {
120
120
  res.end(JSON.stringify(hierarchy, null, 2));
121
121
  }
122
122
 
123
- module.exports = { handleApiState, handleApiFiles, handleApiFile, handleApiHierarchy };
123
+ function handleApiMemory(req, res, rihalDir) {
124
+ const memory = scanMemoryBank(rihalDir);
125
+ res.writeHead(200, { 'Content-Type': 'application/json' });
126
+ res.end(JSON.stringify(memory, null, 2));
127
+ }
128
+
129
+ module.exports = { handleApiState, handleApiFiles, handleApiFile, handleApiHierarchy, handleApiMemory };