@hanzlaa/rcode 4.10.6 → 4.12.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 (61) hide show
  1. package/AGENTS.md +1 -1
  2. package/CLAUDE.md +1 -1
  3. package/CONTRIBUTING.md +5 -0
  4. package/cli/install.js +160 -0
  5. package/dist/rcode.js +254 -234
  6. package/package.json +1 -1
  7. package/rcode/agents/rcode-planner.md +1 -0
  8. package/rcode/agents/rcode-project-researcher.md +2 -1
  9. package/rcode/agents/rcode-roadmapper.md +1 -0
  10. package/rcode/agents/rcode-sprint-checker.md +1 -0
  11. package/rcode/agents/rcode-ux-designer.md +2 -0
  12. package/rcode/agents/rcode-verifier.md +2 -2
  13. package/rcode/agents/rules/planner/common-patterns.md +2 -1
  14. package/rcode/agents/rules/planner/goal-backward-thinking.md +33 -0
  15. package/rcode/agents/rules/planner/sprint-verification.md +1 -0
  16. package/rcode/agents/rules/planner/task-templates.md +20 -1
  17. package/rcode/agents/rules/project-researcher/detailed-guide.md +10 -0
  18. package/rcode/agents/rules/sprint-checker/dimensions.md +129 -0
  19. package/rcode/agents/rules/sprint-checker/process.md +12 -0
  20. package/rcode/agents/rules/verifier/behavioral-spot-checks.md +5 -1
  21. package/rcode/agents/rules/verifier/gap-output.md +5 -0
  22. package/rcode/agents/rules/verifier/reachability-check.md +69 -0
  23. package/rcode/bin/rcode-tools.cjs +91 -8
  24. package/rcode/commands/ui-phase.md +1 -1
  25. package/rcode/references/design-library/LICENSE +21 -0
  26. package/rcode/references/design-library/README.md +37 -0
  27. package/rcode/references/design-library/charts.csv +26 -0
  28. package/rcode/references/design-library/colors.csv +97 -0
  29. package/rcode/references/design-library/icons.csv +101 -0
  30. package/rcode/references/design-library/styles.csv +68 -0
  31. package/rcode/references/design-library/typography.csv +58 -0
  32. package/rcode/references/design-library/ui-reasoning.csv +101 -0
  33. package/rcode/references/design-library/ux-guidelines.csv +100 -0
  34. package/rcode/references/design-library/web-interface.csv +31 -0
  35. package/rcode/references/domain-probes.md +8 -0
  36. package/rcode/references/project-types.yaml +29 -0
  37. package/rcode/references/questioning.md +3 -0
  38. package/rcode/references/roadmapper-playbook.md +90 -0
  39. package/rcode/references/source-of-truth-grounding.md +80 -0
  40. package/rcode/references/sprint-checker-playbook.md +14 -0
  41. package/rcode/references/verifier-playbook.md +20 -7
  42. package/rcode/skills/actions/2-plan/rcode-create-epics-and-stories/workflow.md +1 -1
  43. package/rcode/skills/actions/2-plan/rcode-create-prd/workflow.md +9 -1
  44. package/rcode/workflows/autonomous.md +78 -16
  45. package/rcode/workflows/complete-milestone.md +1 -1
  46. package/rcode/workflows/council.md +51 -6
  47. package/rcode/workflows/discuss-phase.md +10 -2
  48. package/rcode/workflows/execute-sprint.md +35 -7
  49. package/rcode/workflows/execute-waves.md +2 -2
  50. package/rcode/workflows/execute.md +21 -6
  51. package/rcode/workflows/help.md +1 -1
  52. package/rcode/workflows/new-milestone.md +5 -1
  53. package/rcode/workflows/new-project-research.md +22 -0
  54. package/rcode/workflows/new-project-roadmap.md +19 -0
  55. package/rcode/workflows/plan-research-validation.md +1 -1
  56. package/rcode/workflows/plan.md +49 -3
  57. package/rcode/workflows/ship.md +22 -0
  58. package/rcode/workflows/ui-phase.md +187 -23
  59. package/rcode/workflows/ui-review.md +9 -1
  60. package/rcode/workflows/verify-work.md +1 -1
  61. package/server/lib/scanner.js +25 -4
@@ -202,7 +202,12 @@ Per-agent completion:
202
202
  ✓ rcode-executor complete: {plan-id} → SUMMARY.md ({N} commits)
203
203
  ```
204
204
 
205
- Closure:
205
+ Closure: this banner is NOT printed here, right after the wave loop. It is
206
+ gated behind `uat_gate` — see that step's "Only when `VERIFICATION_STATUS`
207
+ is `pass`" branch, which is the only point in `<process>` where phase
208
+ completion is actually confirmed (after code_review_gate, run_verify_commands,
209
+ close_parent_artifacts, the regression gate, and verify_phase_goal have all
210
+ passed):
206
211
  ```
207
212
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
208
213
  rcode ► PHASE {NN} COMPLETE ✓
@@ -514,13 +519,15 @@ After all waves:
514
519
  ```markdown
515
520
  ## Phase {X}: {Name} Execution Complete
516
521
 
517
- **Waves:** {N} | **Plans:** {M}/{total} complete
522
+ **Waves:** {N} | **Plans:** {M}/{total} executed
523
+
524
+ Verification gates (run_verify_commands, code_review_gate, regression gate, uat_gate) have not run yet — this table reflects agent execution only, not verification.
518
525
 
519
526
  | Wave | Plans | Status |
520
527
  |------|-------|--------|
521
- | 1 | plan-01, plan-02 | ✓ Complete |
522
- | CP | plan-03 | ✓ Verified |
523
- | 2 | plan-04 | ✓ Complete |
528
+ | 1 | plan-01, plan-02 | ✓ Executed |
529
+ | CP | plan-03 | ✓ Checkpoint passed |
530
+ | 2 | plan-04 | ✓ Executed |
524
531
 
525
532
  ### Plan Details
526
533
  1. **03-01**: [one-liner from SUMMARY.md]
@@ -823,7 +830,15 @@ fi
823
830
  2. Surface the tasks whose `<done>` criteria failed human verification.
824
831
  3. STOP. Don't mark complete on a failing verification.
825
832
 
826
- **Only when `VERIFICATION_STATUS` is `pass`** — proceed to `update_roadmap` below.
833
+ **Only when `VERIFICATION_STATUS` is `pass`** — print the closure banner, then proceed to `update_roadmap` below:
834
+ ```
835
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
836
+ rcode ► PHASE {NN} COMPLETE ✓
837
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
838
+ ```
839
+ This is the only point in `<process>` where the banner may be emitted — never
840
+ print it right after the wave loop finishes, and never before this gate
841
+ resolves to `pass`.
827
842
 
828
843
  The previous behaviour (printing "Next Up: /rcode-verify-work" without state-gating) caused phases to reach `status: complete` without any human-verified UAT.
829
844
  </step>
@@ -198,7 +198,7 @@ init → new-project → plan → execute → next → status → ship
198
198
  | `/rcode-check-implementation-readiness` | Verify a feature is fully ready to implement before writing code. |
199
199
  | `/rcode-review-edge-case-hunter` | Hunt for edge cases and boundary conditions before execution. |
200
200
  | `/rcode-diagnose-issues` | Triage and diagnose systemic issues before a debug session. |
201
- | `/rcode-ui-phase <n>` | Generate UI design contract (UI-SPEC.md) for frontend phases. |
201
+ | `/rcode-ui-phase <n>` | Generate UI design contract (UI-SPEC.md) and screen inventory (WIREFRAMES.md) for frontend phases. |
202
202
  | `/rcode-ui-review` | Retroactive 6-pillar visual audit of completed UI work. |
203
203
  | `/rcode-review --attack` | Hostile-perspective report — vulnerabilities, race conditions, abuse. |
204
204
  | `/rcode-review --edge-cases` | Enumerate edge cases by category and severity. |
@@ -541,7 +541,11 @@ Write files first, then return.
541
541
 
542
542
  **If `## ROADMAP BLOCKED`:** present the blocker, collect resolution from user, re-spawn the roadmapper with revision context.
543
543
 
544
- **If `## ROADMAP CREATED`:** read ROADMAP.md, present inline:
544
+ **If `## ROADMAP CREATED`:**
545
+
546
+ **Team review pass (once per roadmap draft; skip in auto/yolo mode — see `new-project-roadmap.md`'s identical step for the full rationale):** spawn `rcode-waleed` and `rcode-fatima` in parallel, same prompts as `new-project-roadmap.md`'s team review pass (feasibility sanity check / release-risk sanity check, 3 bullets max or "no concerns" in one line). Fold genuine concerns into a **Team Review Notes** section in the presentation below, before the phase table — skip the section if both say no concerns.
547
+
548
+ Read ROADMAP.md, present inline:
545
549
 
546
550
  ```
547
551
  ## Proposed Roadmap
@@ -310,6 +310,28 @@ Display research complete banner and key findings:
310
310
  Files: `.planning/research/`
311
311
  ```
312
312
 
313
+ **Mandatory stack-choice confirmation (before proceeding to roadmap):**
314
+ Tech stack is the single most foundational, hardest-to-reverse decision in
315
+ the project — every phase gets built on top of it, and un-picking it later
316
+ means rework, not a config change. Do not let it get silently locked in.
317
+
318
+ Check `.planning/research/STACK.md` for language indicating this was a
319
+ judgment call, not a forced single-option pick — phrases like "judgment
320
+ call," "flagging explicitly," a comparison table between 2+ named
321
+ platforms/frameworks, or an explicit confidence caveat on the top-level
322
+ choice. (A stack choice with genuinely no alternative — e.g. "must integrate
323
+ with the client's existing Salesforce" — doesn't need this; skip only in
324
+ that case, and say why.)
325
+
326
+ If it's a judgment call, use AskUserQuestion before continuing:
327
+ - **question:** "Research recommends {stack} over {alternative(s)} for {one-line reason}. Confirm, or pick differently?"
328
+ - **options:** "Confirm {stack}" / "Use {alternative}" / "Something else — I'll specify"
329
+
330
+ If the user picks differently, note the override as a decision and don't
331
+ silently keep researching the original recommendation — the chosen stack
332
+ from here on is whatever the user picked, not STACK.md's original
333
+ recommendation, and downstream phases/roadmap should reflect that.
334
+
313
335
  **If "Skip research":** Continue to Step 7.
314
336
 
315
337
 
@@ -215,6 +215,25 @@ Write files first, then return. This ensures artifacts persist even if context i
215
215
 
216
216
  **If `## ROADMAP CREATED`:**
217
217
 
218
+ **Team review pass (once per roadmap draft, not per phase — keep this cheap; skip entirely in auto/yolo mode — an unattended loop shouldn't pay this round-trip on every roadmap, and there's no user present to read the notes anyway):**
219
+ Before presenting the roadmap for approval, spawn two focused reviewers in
220
+ parallel against the freshly-written ROADMAP.md — a single async round, not a
221
+ council debate, so this adds one round-trip, not multiple:
222
+
223
+ ```
224
+ Task(prompt="Read .planning/ROADMAP.md and .planning/PROJECT.md. As Waleed (CTO/architect), flag ONLY real feasibility/scalability concerns you'd actually block a real project over — a phase sequencing a schema-breaking change after the API that depends on it, a scale ceiling the phase structure doesn't account for, a missing foundational/shell phase for a UI project. If there are none, say so in one line. Keep it to 3 bullets max — this is a sanity check, not a full architecture review.", subagent_type="rcode-waleed", model="{roadmapper_model}", description="Architecture sanity check")
225
+
226
+ Task(prompt="Read .planning/ROADMAP.md and .planning/PROJECT.md. As Fatima (QA Lead), flag ONLY real release-risk concerns — a phase with no way to verify its success criteria, a security/compliance-sensitive area with no phase covering it, a dependency ordering that makes a phase unverifiable until a later one lands. If there are none, say so in one line. Keep it to 3 bullets max — this is a sanity check, not a full QA strategy doc.", subagent_type="rcode-fatima", model="{roadmapper_model}", description="Release-risk sanity check")
227
+ ```
228
+
229
+ Run both, collect their one-line-or-3-bullets responses. If either flags a
230
+ concern that would make the roadmap actually wrong (not a nitpick), add a
231
+ **Team Review Notes** section to the presentation below, before the phase
232
+ table, so the user sees it as part of deciding whether to approve — don't
233
+ silently drop it, and don't block on it either; the approval gate right
234
+ after this is where the user decides what to do with it. If both reviewers
235
+ say "no concerns," skip the section entirely — don't manufacture filler.
236
+
218
237
  Read the created ROADMAP.md and present it nicely inline:
219
238
 
220
239
  ```
@@ -204,7 +204,7 @@ HAS_UI=$?
204
204
 
205
205
  **If `HAS_UI` is 0 (frontend indicators found):**
206
206
 
207
- Check for existing UI-SPEC:
207
+ Check for existing UI-SPEC (rcode-ui-phase produces this alongside WIREFRAMES.md as a pair, so its presence is a reliable proxy for both):
208
208
  ```bash
209
209
  UI_SPEC_FILE=$(ls "${PHASE_DIR}"/*-UI-SPEC.md 2>/dev/null | head -1)
210
210
  ```
@@ -86,6 +86,37 @@ Project not initialized for planning. Run /rcode-new-project (full roadmap) or /
86
86
 
87
87
  Stop. Do not proceed until `project-status` returns `real`.
88
88
 
89
+ ## 0.6. Detect Frontend Keywords and Suggest UI Safety Gate
90
+
91
+ ```bash
92
+ FRONTEND_KEYWORDS=$(node .rcode/bin/rcode-tools.cjs classify-tech --keywords "react,next.js,vue,tailwind,css,ui,component,design,frontend" "$ARGUMENTS")
93
+ ```
94
+
95
+ **If `FRONTEND_KEYWORDS.has_frontend == true` AND `.rcode/UI-SPEC.md` is missing:**
96
+
97
+ Check `config.yaml` for `workflow.ui_safety_gate` (default `true`). If enabled, print:
98
+
99
+ ```
100
+ ⚠ Frontend project detected. Before planning, create a design contract:
101
+
102
+ /rcode-ui-phase
103
+
104
+ This ensures consistent UI patterns, accessibility, and design tokens across all components.
105
+ ```
106
+
107
+ Offer via AskUserQuestion:
108
+ ```
109
+ header: "UI Safety Gate"
110
+ question: "Should we define UI-SPEC.md before planning component development?"
111
+ options:
112
+ - "Yes, run /rcode-ui-phase first"
113
+ - "Skip for now, continue planning"
114
+ ```
115
+
116
+ If "Yes, run /rcode-ui-phase first": run `/rcode-ui-phase`, then return here and continue at Step 1. If skipped, or `ui_safety_gate` is disabled, or no frontend keywords detected: proceed directly to Step 1.
117
+
118
+ See `rcode/workflows/ui-phase.md` Step 4 for the source of this step — this is the applied instance of that one-time setup instruction.
119
+
89
120
  ## 1. Initialize
90
121
 
91
122
  Load all context in one call (paths only to minimize orchestrator context):
@@ -594,12 +625,27 @@ Task(
594
625
  - **`## VERIFICATION PASSED`:** Display confirmation, proceed to step 13.
595
626
  - **`## ISSUES FOUND`:** Display issues, check iteration count, proceed to step 12.
596
627
 
597
- **Thinking partner for architectural tradeoffs (conditional):**
628
+ **Thinking partner for architectural tradeoffs (default ON in guided mode, OFF in yolo/autonomous):**
598
629
  ```bash
599
- THINKING_PARTNER_ENABLED=$(node ".rcode/bin/rcode-tools.cjs" config-get features.thinking_partner 2>/dev/null || echo "false")
630
+ THINKING_PARTNER_CONFIG=$(node ".rcode/bin/rcode-tools.cjs" config-get features.thinking_partner 2>/dev/null || echo "")
631
+ if [ -n "$THINKING_PARTNER_CONFIG" ]; then
632
+ THINKING_PARTNER_ENABLED="$THINKING_PARTNER_CONFIG"
633
+ elif [ "$MODE" = "yolo" ] || [ -n "$AUTONOMOUS" ]; then
634
+ THINKING_PARTNER_ENABLED="false"
635
+ else
636
+ THINKING_PARTNER_ENABLED="true"
637
+ fi
600
638
  ```
601
639
  ${THINKING_PARTNER_ENABLED === 'true' ? '@.rcode/references/plan-thinking-partner.md' : ''}
602
- If `features.thinking_partner` is disabled: skip this block entirely.
640
+ If `THINKING_PARTNER_ENABLED` is `false`: skip this block entirely. An explicit
641
+ `features.thinking_partner` in config.yaml always wins over the mode-based
642
+ default (set it `false` to silence even in guided mode, or `true` to keep it
643
+ on during autonomous runs if you want that). The check itself is cheap — a
644
+ keyword scan over the checker's existing issues, not a new agent spawn —
645
+ which is why it defaults on for guided/interactive planning: a second-opinion
646
+ sanity check on architectural tradeoffs is exactly the kind of thing "does
647
+ this actually get built right" needs, and it only activates when the checker
648
+ already flagged a tradeoff-shaped issue.
603
649
 
604
650
  ## 12. Revision Loop (Max 3 Iterations, 1 in autonomous/yolo mode)
605
651
 
@@ -121,6 +121,17 @@ Verify the work is ready to ship:
121
121
  Check for `status: passed` or `status: human_needed` (with human approval).
122
122
  If no VERIFICATION.md or status is `gaps_found`: warn and ask user to confirm.
123
123
 
124
+ **If proceeding with anything other than a clean `status: passed`** (i.e.
125
+ `human_needed` or a user-confirmed `gaps_found`): the generated PR body
126
+ (step below) MUST include a `## Known Gaps` section listing every
127
+ unresolved human-verification item or gap from VERIFICATION.md — mirroring
128
+ `complete-milestone.md`'s `### Known Gaps` pattern. This is not optional
129
+ cosmetic detail: a PR shipped on `human_needed`/`gaps_found` without this
130
+ section reads to a reviewer as fully verified when it isn't. Do not rely on
131
+ the `## Verification` section's item list alone (below) to carry this —
132
+ that section is easy to skim past; `## Known Gaps` must be its own
133
+ clearly-labeled heading.
134
+
124
135
  2. **Clean working tree?**
125
136
  ```bash
126
137
  git status --short
@@ -215,6 +226,17 @@ For each SUMMARY.md in the phase directory:
215
226
  - {human verification items from VERIFICATION.md, if any}
216
227
  ```
217
228
 
229
+ **5b. Known Gaps section (only when VERIFICATION.md status is not a clean `passed`):**
230
+ ```markdown
231
+ ## Known Gaps
232
+
233
+ This PR ships with `status: {human_needed|gaps_found}` per VERIFICATION.md, confirmed by the user in preflight.
234
+
235
+ - {gap/human-verification item 1 — file/truth + what's unconfirmed}
236
+ - {gap/human-verification item 2}
237
+ ```
238
+ Omit this section entirely when VERIFICATION.md status is a clean `passed` with zero open items.
239
+
218
240
  **6. Decisions section:**
219
241
  ```markdown
220
242
  ## Key Decisions
@@ -1,11 +1,11 @@
1
1
  # Workflow: rcode-ui-phase
2
2
 
3
3
  <purpose>
4
- Produce UI-SPEC.md with formalized design contract: color tokens, typography system, component inventory, interaction states, accessibility requirements. Detects frontend keywords (React, Next.js, Vue, Tailwind, CSS, UI) and suggests this workflow early if UI-SPEC.md is absent.
4
+ Produce two artifacts before any UI code gets written: UI-SPEC.md (formalized design contract color tokens, typography, component inventory, interaction states, accessibility requirements) and WIREFRAMES.md (per-role screen inventory — what exists, who sees it, loading/empty/error states for each). Grounds design choices in `rcode/references/design-library/` (vendored style/palette/typography/UX-rules data — see that directory's README) instead of an agent inventing tokens from nothing. Detects frontend keywords (React, Next.js, Vue, Tailwind, CSS, UI) and suggests this workflow early if UI-SPEC.md is absent.
5
5
  </purpose>
6
6
 
7
7
 
8
- ## Step 0 — Usage check
8
+ ## Step 0a — Usage check
9
9
 
10
10
  If `$ARGUMENTS` is empty or contains only `--help` or `-h`:
11
11
 
@@ -25,7 +25,7 @@ STOP — do not proceed.
25
25
  - `rcode-ux-designer` — UI specification generator
26
26
  </available_agent_types>
27
27
 
28
- ## Step 0 — Initialize
28
+ ## Step 0b — Initialize
29
29
 
30
30
  ```bash
31
31
  INIT=$(node .rcode/bin/rcode-tools.cjs init ui-phase "$ARGUMENTS" 2>/dev/null)
@@ -41,6 +41,7 @@ Parse:
41
41
  - `flags.existing_ui` — path to existing design system or Figma export
42
42
  - `flags.design_system` — path to design tokens file
43
43
  - `ui_spec_path` — `.rcode/UI-SPEC.md` (output location)
44
+ - `wireframes_path` — `.rcode/WIREFRAMES.md` (output location)
44
45
 
45
46
  ## Step 1 — Detect Existing UI Assets
46
47
 
@@ -49,47 +50,194 @@ If `flags.existing_ui` or `flags.design_system` provided:
49
50
  EXISTING=$(node .rcode/bin/rcode-tools.cjs find-files --type=design-tokens)
50
51
  ```
51
52
 
52
- Load existing design system, extract:
53
+ Load existing design system, extract into `EXISTING_DESIGN_SYSTEM_DATA` (a text block passed verbatim into Step 2b's prompt):
53
54
  - Color palette (hex, variable names)
54
55
  - Typography scales (font family, sizes, weights, line heights)
55
56
  - Component list (buttons, forms, layouts, modals, etc.)
56
57
  - Interaction patterns (hover, focus, active, disabled states)
57
58
 
58
- ## Step 2 Spawn UI Designer
59
+ If `$EXISTING` is empty or extraction finds nothing usable, treat this the
60
+ same as "no existing system found" and fall through to Step 1b — don't leave
61
+ `EXISTING_DESIGN_SYSTEM_DATA` half-populated.
62
+
63
+ If an existing design system was found and `EXISTING_DESIGN_SYSTEM_DATA` is
64
+ populated, there's nothing to choose between — skip Step 1b, Step 1c, AND
65
+ Step 2 (variant generation + user confirmation) entirely, and go straight to
66
+ Step 2b using `EXISTING_DESIGN_SYSTEM_DATA` as the chosen direction.
67
+
68
+ ## Step 1b — Ground the design in the reference library (no existing system found)
69
+
70
+ Don't let the agent invent a palette/style from nothing. If PROJECT.md and
71
+ ROADMAP.md are both missing, stop here and say so: "No PROJECT.md/ROADMAP.md
72
+ found — run `/rcode-new-project-research` or `/rcode-new-project-roadmap`
73
+ first so there's a project category to ground the design in." Otherwise look up:
74
+
75
+ 1. **Category match** — grep the project's category (from PROJECT.md/ROADMAP.md — e.g. "B2B SaaS Enterprise", "Analytics Dashboard", "Fintech (Banking)") against `rcode/references/design-library/ui-reasoning.csv`'s `UI_Category` column. This returns a recommended style/color-mood/typography-mood and explicit anti-patterns to avoid — read the row, don't guess a category if none matches closely; fall back to the closest match and say so. Capture the result as `CATEGORY_MATCH`.
76
+ 2. **Style detail** — take the recommended style name from step 1 and look it up in `styles.csv` for concrete hex values, effects, accessibility rating, and an implementation checklist. Capture as `STYLE_DETAIL`.
77
+ 3. **UX rules** — grep `ux-guidelines.csv` for the categories relevant to this project's screens (Navigation, Forms, etc.) for concrete do/don't rules with code examples. Capture as `UX_RULES`.
78
+
79
+ `CATEGORY_MATCH` + `STYLE_DETAIL` + `UX_RULES` together are what Step 1c and
80
+ Step 2 below call `DESIGN_LOOKUP_RESULT` — assemble them into one text block.
81
+
82
+ ## Step 1c — Look at real reference sites (skip only if Step 1 found an existing system)
83
+
84
+ A CSV row is a starting hypothesis, not a substitute for actually looking at
85
+ what real sites in this space look like. A style-data table can't tell you
86
+ that every competitor uses a specific hero-image treatment, or that the
87
+ category's "expected" look has drifted since the data was written. Do this
88
+ before committing to a direction:
89
+
90
+ 1. **Find real reference sites.** WebSearch for the project's actual
91
+ industry/niche (from PROJECT.md — e.g. "best interior design websites
92
+ Pakistan", "top mobile repair shop websites", not a generic "SaaS
93
+ landing page examples" search unrelated to the real domain). Aim for
94
+ 3-5 real, currently-live sites — direct competitors if findable, strong
95
+ examples in the same category otherwise.
96
+ 2. **Actually look at them**, don't just read search-result snippets. If a
97
+ browser tool is available in this session, navigate to each and take a
98
+ screenshot. If not, WebFetch each URL and read the rendered content/
99
+ structure description it returns. Note concretely, per site: layout
100
+ pattern (hero style, nav placement, content density), color mood, type
101
+ feel (serif/sans, weight, size), imagery style (photography vs.
102
+ illustration vs. none), and anything that reads as dated or as a
103
+ red flag to avoid repeating.
104
+ 3. Capture this as `REFERENCE_SITE_FINDINGS` — a short per-site note, not a
105
+ full audit. This feeds variant generation next, not a standalone report.
106
+
107
+ If WebSearch/WebFetch/browser tools are genuinely unavailable in this
108
+ session, skip with an explicit note ("Step 1c skipped — no web/browser
109
+ tools available; design-library data only") rather than silently omitting
110
+ real-site grounding — this is a real reduction in design quality and should
111
+ be visible, not silent.
112
+
113
+ ## Step 2 — Generate design variants, get user confirmation (mandatory — do not skip to a single locked-in direction)
114
+
115
+ Visual design direction is the same class of decision as tech-stack choice:
116
+ foundational, expensive to redo once screens are built against it, and a
117
+ matter of taste as much as data — it must not get silently locked in by an
118
+ agent picking "the" recommended style. Generate 2-3 concrete, genuinely
119
+ distinct variants (not the same direction with a different accent color),
120
+ each grounded in `DESIGN_LOOKUP_RESULT` (Step 1b) and `REFERENCE_SITE_FINDINGS`
121
+ (Step 1c), before writing anything to UI-SPEC.md:
59
122
 
60
123
  Spawn `rcode-ux-designer` subagent:
61
124
 
62
125
  ```
63
126
  Task tool call:
64
127
  subagent_type: "rcode-ux-designer"
65
- description: "Generate UI-SPEC.md"
128
+ description: "Generate design variants"
66
129
  prompt: |
67
- Generate a UI-SPEC.md file with the following structure:
68
-
69
- 1. **Color Tokens** — semantic variable names, hex values, accessibility contrast ratios
70
- 2. **Typography** — font family, scales (12px, 14px, 16px, 18px, 20px, 24px, etc.), weights, line heights
71
- 3. **Component Inventory** list of UI components with property variants (size, color, state, disabled)
72
- 4. **Interaction States** — hover, focus, active, disabled, loading for interactive elements
73
- 5. **Accessibility** — WCAG 2.1 AA compliance checklist, color contrast requirements, keyboard navigation rules
74
- 6. **Responsive Breakpoints** mobile, tablet, desktop breakpoints and stacking rules
75
-
76
- {existing_design_system_data_if_provided}
77
-
130
+ Ground every variant in {EXISTING_DESIGN_SYSTEM_DATA if Step 1 found one, else DESIGN_LOOKUP_RESULT + REFERENCE_SITE_FINDINGS} —
131
+ do not invent a palette/style from nothing when reference data or real
132
+ reference sites were found.
133
+
134
+ Propose 2-3 genuinely distinct design variants for this project. For each:
135
+ - **Name** (short, e.g. "Warm Editorial", "Minimal Trust", "Bold Craft")
136
+ - **One-paragraph description** — mood, layout approach, what it borrows from
137
+ the reference sites found (name which one(s)) vs. the design-library data
138
+ - **Color direction** — 2-3 representative hex values, not a full token system yet
139
+ - **Typography direction** — font pairing feel (serif/sans, weight)
140
+ - **Best for / worst for** — one line each, honest tradeoffs
141
+
142
+ Do NOT pick a winner or rank them — present as genuine options. Do NOT
143
+ write UI-SPEC.md yet.
144
+
145
+ Return the variants as your response text (not a file write).
146
+ ```
147
+
148
+ Present the variants to the user via AskUserQuestion:
149
+ - **question:** "Which design direction fits this project?"
150
+ - **options:** one per variant (label = variant name, description = the one-paragraph summary), plus the tool's built-in "Other" for a custom direction
151
+ - If the user picks "Other" and describes something different, treat their description as the chosen direction instead of any generated variant.
152
+
153
+ Only after the user picks does Step 2b below proceed — using the chosen
154
+ variant's color/typography direction as the seed for the full spec, not
155
+ re-deriving from scratch.
156
+
157
+ ## Step 2b — Spawn UI Designer (full spec, chosen direction)
158
+
159
+ Spawn `rcode-ux-designer` subagent:
160
+
161
+ ```
162
+ Task tool call:
163
+ subagent_type: "rcode-ux-designer"
164
+ description: "Generate UI-SPEC.md and WIREFRAMES.md"
165
+ prompt: |
166
+ Build out the full spec from {EXISTING_DESIGN_SYSTEM_DATA if Step 1 found
167
+ one, else the user-chosen variant's full description, color direction,
168
+ and typography direction from Step 2}.
169
+ Ground every choice in {EXISTING_DESIGN_SYSTEM_DATA if Step 1 found one, else DESIGN_LOOKUP_RESULT from Step 1b} —
170
+ do not invent a palette/style from nothing when reference data or an existing system exists.
171
+
172
+ Write UI-SPEC.md with:
173
+ 1. **Design Direction** — which style/category this follows (from the reference library lookup) and why, one paragraph
174
+ 2. **Color Tokens** — semantic variable names, hex values, accessibility contrast ratios
175
+ 3. **Typography** — font family, scales (12px, 14px, 16px, 18px, 20px, 24px, etc.), weights, line heights
176
+ 4. **Component Inventory** — list of UI components with property variants (size, color, state, disabled)
177
+ 5. **Interaction States** — hover, focus, active, disabled, loading for interactive elements
178
+ 6. **Accessibility** — WCAG 2.1 AA compliance checklist, color contrast requirements, keyboard navigation rules
179
+ 7. **Responsive Breakpoints** — mobile, tablet, desktop breakpoints and stacking rules
180
+
78
181
  Write to: {ui_spec_path}
79
182
  ```
80
183
 
184
+ ## Step 2c — Spawn Wireframes (per-role screen inventory)
185
+
186
+ Read REQUIREMENTS.md/PROJECT.md for the project's user roles (if any) and the
187
+ IA decision — `roadmapper-playbook.md`'s Information Architecture step (Workflow
188
+ step 3b) says this is persisted as either a standalone `.planning/IA.md` or a
189
+ `## Information Architecture` section in ROADMAP.md, so check both locations,
190
+ not just ROADMAP.md. If neither has an IA decision, this step cannot produce a
191
+ real result — stop and say so: "No Information Architecture decision found in
192
+ ROADMAP.md or IA.md — the roadmapper needs to produce one first
193
+ (`/rcode-new-project-roadmap` for a brand-new project, `/rcode-new-milestone`
194
+ to regenerate the roadmap for an existing one — both invoke rcode-roadmapper,
195
+ which owns the IA step)."
196
+
197
+ Spawn `rcode-ux-designer` subagent (same agent, second artifact):
198
+
199
+ ```
200
+ Task tool call:
201
+ subagent_type: "rcode-ux-designer"
202
+ description: "Generate WIREFRAMES.md"
203
+ prompt: |
204
+ For each top-level IA section and each screen it contains, write one entry:
205
+
206
+ ### {Screen name} — {route/path}
207
+ **Roles that see it:** {role list, or "all authenticated users"}
208
+ **Purpose:** {one line — what the user accomplishes here}
209
+ **Layout:** {ASCII or textual wireframe — header/nav placement, primary content
210
+ area, key actions, not a pixel-perfect mockup}
211
+ **Required states** (do not omit any that apply):
212
+ - Loading: {what renders while data is fetching}
213
+ - Empty: {what renders when there's no data yet — never a blank screen}
214
+ - Error: {what renders on fetch/action failure — never a silent failure}
215
+ - Success/populated: {the normal case}
216
+ **Primary actions:** {buttons/links a user takes from here, and where they go}
217
+
218
+ Cover EVERY screen implied by the roadmap's phases, not just Phase 1's.
219
+ A screen with no role that can see it, or with only a "populated" state and
220
+ no loading/empty/error state defined, is an incomplete entry — fix it before
221
+ writing, don't ship the gap.
222
+
223
+ Write to: {wireframes_path}
224
+ ```
225
+
81
226
  ## Step 3 — Store Reference in State
82
227
 
83
- Update state with UI-SPEC.md location:
228
+ Update state with both artifact locations:
84
229
  ```bash
85
230
  node .rcode/bin/rcode-tools.cjs state set --ui-spec-path ".rcode/UI-SPEC.md"
231
+ node .rcode/bin/rcode-tools.cjs state set --wireframes-path ".rcode/WIREFRAMES.md"
86
232
  ```
87
233
 
88
234
  Print:
89
235
  ```
90
236
  ✓ UI-SPEC.md generated: {ui_spec_path}
237
+ ✓ WIREFRAMES.md generated: {wireframes_path}
91
238
 
92
- Contains:
239
+ UI-SPEC.md contains:
240
+ • Design Direction (grounded in design-library lookup, not invented)
93
241
  • Color Tokens
94
242
  • Typography System
95
243
  • Component Inventory
@@ -97,10 +245,22 @@ Contains:
97
245
  • Accessibility Checklist
98
246
  • Responsive Breakpoints
99
247
 
100
- This spec will guide component development and design consistency.
248
+ WIREFRAMES.md contains:
249
+ • Every screen from the roadmap's IA, with role visibility
250
+ • Loading/empty/error/success state for each screen — no screen ships
251
+ without all four defined
252
+
253
+ These specs guide component development, design consistency, and give
254
+ sprint-checker something concrete to verify state-completeness against.
101
255
  ```
102
256
 
103
- ## Step 4 — Modify plan.md Detection (referenced in plan workflow)
257
+ ## Step 4 — Modify plan.md Detection (one-time setup, not per-invocation)
258
+
259
+ This step is setup documentation for `plan.md`, not part of `/rcode-ui-phase`'s
260
+ own run sequence — it does not re-run every time `/rcode-ui-phase` is
261
+ invoked. Before applying it, check whether `plan.md` already has this
262
+ detection step (grep for "ui_safety_gate" or "Detect frontend keywords");
263
+ skip if present.
104
264
 
105
265
  In plan.md workflow, add Step 0.6 — **Detect frontend keywords and suggest UI safety gate**
106
266
 
@@ -141,17 +301,21 @@ Run /rcode-ui-phase, then return to /rcode-plan
141
301
 
142
302
  ## Success Criteria
143
303
 
144
- - UI-SPEC.md created with all 6 sections
304
+ - Real reference sites looked at (Step 1c), not just design-library data alone — or explicitly noted as skipped with a reason
305
+ - 2-3 genuinely distinct design variants presented and the user explicitly picked one via AskUserQuestion — no direction silently locked in (skipped only when Step 1 found an existing design system, where there's nothing to choose between)
306
+ - UI-SPEC.md created with all 7 sections, design direction grounded in the chosen variant / `design-library/` lookup / real reference sites (or an existing design system), not invented
145
307
  - Color tokens documented with contrast ratios
146
308
  - Component inventory complete with variants
147
309
  - Accessibility checklist included
148
- - State updated with UI-SPEC.md path
310
+ - WIREFRAMES.md created covering every screen implied by the roadmap's IA, each with role visibility and all four states (loading/empty/error/success) defined
311
+ - State updated with both UI-SPEC.md and WIREFRAMES.md paths
149
312
 
150
313
  ## On Error
151
314
 
152
315
  - If subagent fails: provide template UI-SPEC.md
153
316
  - If frontend detection fails: skip suggestion
154
317
  - If config.yaml missing ui_safety_gate: default to true (suggest)
318
+ - If no IA decision exists in ROADMAP.md or IA.md yet: WIREFRAMES.md cannot be produced meaningfully — stop Step 2c and say so rather than writing a screen list with no basis
155
319
 
156
320
  ## Next Up
157
321
 
@@ -1,7 +1,7 @@
1
1
  # Workflow: rcode-ui-review
2
2
 
3
3
  <purpose>
4
- Retroactively audit completed UI work against the UI-SPEC.md contract. Validates across 6 pillars: color consistency, typography compliance, component inventory coverage, accessibility requirements, responsive behavior, and design coherence. Produces audit report with pass/fail per pillar.
4
+ Retroactively audit completed UI work against the UI-SPEC.md contract (and WIREFRAMES.md, when present, for per-screen state coverage). Validates across 6 pillars: color consistency, typography compliance, component inventory coverage, accessibility requirements, responsive behavior, and design coherence. Produces audit report with pass/fail per pillar.
5
5
  </purpose>
6
6
 
7
7
 
@@ -41,6 +41,7 @@ Parse:
41
41
  - `flags.phase` — audit specific phase (optional, default: all completed phases)
42
42
  - `flags.detailed` — include detailed findings per component
43
43
  - `spec_path` — load UI-SPEC.md if exists
44
+ - `wireframes_path` — load WIREFRAMES.md if exists (optional; used for per-screen state coverage)
44
45
  - `phase_name` — phase to audit
45
46
 
46
47
  ## Step 1 — Validate UI-SPEC.md Exists
@@ -65,6 +66,10 @@ Read UI-SPEC.md for:
65
66
  - Accessibility requirements
66
67
  - Responsive breakpoints
67
68
 
69
+ If `.rcode/WIREFRAMES.md` exists, also read it for the per-role screen inventory and
70
+ required states (loading/empty/error/success) — missing states become findings under
71
+ Component Inventory or Design Coherence.
72
+
68
73
  Scan phase/codebase for:
69
74
  - Component files (*.tsx, *.jsx, *.vue)
70
75
  - CSS/styling files (*.css, *.module.css, tailwind.config.js, etc.)
@@ -85,6 +90,9 @@ Task tool call:
85
90
  **UI-SPEC.md Reference:**
86
91
  {contents_of_ui_spec_md}
87
92
 
93
+ **WIREFRAMES.md Reference (if present):**
94
+ {contents_of_wireframes_md}
95
+
88
96
  **Codebase to Audit:**
89
97
  {component_files_list}
90
98
  {styling_rules}
@@ -117,7 +117,7 @@ UI_SPEC_FILE=$(ls "${PHASE_DIR}"/*-UI-SPEC.md 2>/dev/null | head -1)
117
117
  **If Playwright-MCP tools are available in this session (`mcp__playwright__*` tools
118
118
  respond to tool calls) AND (`UI_PHASE_FLAG` is `true` OR `UI_SPEC_FILE` is non-empty):**
119
119
 
120
- For each UI checkpoint listed in the phase's UI-SPEC.md (or inferred from SUMMARY.md):
120
+ For each UI checkpoint listed in the phase's UI-SPEC.md and WIREFRAMES.md (screen states — loading/empty/error/success), or inferred from SUMMARY.md if neither exists:
121
121
 
122
122
  1. Use `mcp__playwright__navigate` (or equivalent) to open the component's URL.
123
123
  2. Use `mcp__playwright__screenshot` to capture a screenshot.
@@ -133,6 +133,16 @@ function buildPhaseTree(projectDir, rawPhases, listCached, overrides) {
133
133
  if (!sprintFiles.length) return p;
134
134
 
135
135
  const phaseComplete = /complete|done/i.test(p.status || '');
136
+ // Story status must not cascade blindly from the phase's self-reported
137
+ // status (#gap: dashboard-truthfulness). A phase marked 'complete' in
138
+ // state.json is unverified until its own VERIFICATION.md says so — only
139
+ // then do we let stories inherit 'done'. Otherwise stories stay 'todo'
140
+ // even if the phase claims completion, so the board never shows a green
141
+ // checkmark with zero independent evidence behind it.
142
+ const verificationFile = files.find(f => /-VERIFICATION\.md$/i.test(f));
143
+ const verificationText = verificationFile ? (safeReadText(path.join(phasesDir, dir.name, verificationFile)) || '') : '';
144
+ const phaseVerified = phaseComplete && /status:\s*passed/i.test(verificationText);
145
+ const storyStatus = phaseVerified ? 'done' : 'todo';
136
146
  const sprints = sprintFiles.map(f => {
137
147
  const m = f.match(/^(\d+)-(\d+)-SPRINT\.md$/i);
138
148
  const num = m ? parseInt(m[2], 10) : 0;
@@ -163,7 +173,7 @@ function buildPhaseTree(projectDir, rawPhases, listCached, overrides) {
163
173
  const story = {
164
174
  id: idM ? idM[1] : `${sid}-task-${stories.length + 1}`,
165
175
  title: (titleAttrM && titleAttrM[1].trim()) || (titleTagM && titleTagM[1].trim()) || `Task ${stories.length + 1}`,
166
- status: phaseComplete ? 'done' : 'todo',
176
+ status: storyStatus,
167
177
  };
168
178
  if (ov[story.id]) story.status = ov[story.id].status;
169
179
  if (acM && acM[1].trim()) story.acceptance = acM[1].trim();
@@ -187,7 +197,7 @@ function buildPhaseTree(projectDir, rawPhases, listCached, overrides) {
187
197
  stories.push({
188
198
  id: hId,
189
199
  title: hm[2].trim(),
190
- status: ov[hId] ? ov[hId].status : (phaseComplete ? 'done' : 'todo'),
200
+ status: ov[hId] ? ov[hId].status : storyStatus,
191
201
  });
192
202
  }
193
203
  }
@@ -217,7 +227,11 @@ function buildPhaseTree(projectDir, rawPhases, listCached, overrides) {
217
227
  }).filter(depId => depId !== null && depId !== intId)
218
228
  )];
219
229
 
220
- return { ...p, sprints, dependsOn: phaseDependsOn };
230
+ // Surface the same verification check at the phase level so consumers of
231
+ // the tree (phases list, progress %, currentPhase, milestones) can also
232
+ // avoid trusting a self-reported 'complete' status blindly — not just the
233
+ // per-story cascade above. null when the phase doesn't claim completion.
234
+ return { ...p, sprints, dependsOn: phaseDependsOn, verified: phaseComplete ? phaseVerified : null };
221
235
  });
222
236
  }
223
237
 
@@ -278,7 +292,14 @@ function buildDashboard(state) {
278
292
  const range = started || completed
279
293
  ? [fmtShort(started), fmtShort(completed)].filter(Boolean).join(' – ')
280
294
  : '';
281
- return { ...p, name: p.name || p.slug || String(p.id || ''), range, state: toState(p.status) };
295
+ // A phase self-reporting 'complete' without a passing *-VERIFICATION.md
296
+ // (p.verified === false, set by buildPhaseTree) is downgraded to 'active'
297
+ // rather than shown as 'done' — the dashboard must not render a green
298
+ // checkmark, fill the progress bar, or skip a phase as currentPhase on
299
+ // an unconfirmed status alone (same drift class as the sprint-level check).
300
+ let phaseState = toState(p.status);
301
+ if (phaseState === 'done' && p.verified === false) phaseState = 'active';
302
+ return { ...p, name: p.name || p.slug || String(p.id || ''), range, state: phaseState };
282
303
  }).sort((a, b) => (parseFloat(a.id ?? a.number) || 0) - (parseFloat(b.id ?? b.number) || 0));
283
304
 
284
305
  // ---- progress (prefer story counts; fall back to phase-level counts) ----