@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.
- package/AGENTS.md +1 -1
- package/CLAUDE.md +1 -1
- package/CONTRIBUTING.md +5 -0
- package/cli/install.js +160 -0
- package/dist/rcode.js +254 -234
- package/package.json +1 -1
- package/rcode/agents/rcode-planner.md +1 -0
- package/rcode/agents/rcode-project-researcher.md +2 -1
- package/rcode/agents/rcode-roadmapper.md +1 -0
- package/rcode/agents/rcode-sprint-checker.md +1 -0
- package/rcode/agents/rcode-ux-designer.md +2 -0
- package/rcode/agents/rcode-verifier.md +2 -2
- package/rcode/agents/rules/planner/common-patterns.md +2 -1
- package/rcode/agents/rules/planner/goal-backward-thinking.md +33 -0
- package/rcode/agents/rules/planner/sprint-verification.md +1 -0
- package/rcode/agents/rules/planner/task-templates.md +20 -1
- package/rcode/agents/rules/project-researcher/detailed-guide.md +10 -0
- package/rcode/agents/rules/sprint-checker/dimensions.md +129 -0
- package/rcode/agents/rules/sprint-checker/process.md +12 -0
- package/rcode/agents/rules/verifier/behavioral-spot-checks.md +5 -1
- package/rcode/agents/rules/verifier/gap-output.md +5 -0
- package/rcode/agents/rules/verifier/reachability-check.md +69 -0
- package/rcode/bin/rcode-tools.cjs +91 -8
- package/rcode/commands/ui-phase.md +1 -1
- package/rcode/references/design-library/LICENSE +21 -0
- package/rcode/references/design-library/README.md +37 -0
- package/rcode/references/design-library/charts.csv +26 -0
- package/rcode/references/design-library/colors.csv +97 -0
- package/rcode/references/design-library/icons.csv +101 -0
- package/rcode/references/design-library/styles.csv +68 -0
- package/rcode/references/design-library/typography.csv +58 -0
- package/rcode/references/design-library/ui-reasoning.csv +101 -0
- package/rcode/references/design-library/ux-guidelines.csv +100 -0
- package/rcode/references/design-library/web-interface.csv +31 -0
- package/rcode/references/domain-probes.md +8 -0
- package/rcode/references/project-types.yaml +29 -0
- package/rcode/references/questioning.md +3 -0
- package/rcode/references/roadmapper-playbook.md +90 -0
- package/rcode/references/source-of-truth-grounding.md +80 -0
- package/rcode/references/sprint-checker-playbook.md +14 -0
- package/rcode/references/verifier-playbook.md +20 -7
- package/rcode/skills/actions/2-plan/rcode-create-epics-and-stories/workflow.md +1 -1
- package/rcode/skills/actions/2-plan/rcode-create-prd/workflow.md +9 -1
- package/rcode/workflows/autonomous.md +78 -16
- package/rcode/workflows/complete-milestone.md +1 -1
- package/rcode/workflows/council.md +51 -6
- package/rcode/workflows/discuss-phase.md +10 -2
- package/rcode/workflows/execute-sprint.md +35 -7
- package/rcode/workflows/execute-waves.md +2 -2
- package/rcode/workflows/execute.md +21 -6
- package/rcode/workflows/help.md +1 -1
- package/rcode/workflows/new-milestone.md +5 -1
- package/rcode/workflows/new-project-research.md +22 -0
- package/rcode/workflows/new-project-roadmap.md +19 -0
- package/rcode/workflows/plan-research-validation.md +1 -1
- package/rcode/workflows/plan.md +49 -3
- package/rcode/workflows/ship.md +22 -0
- package/rcode/workflows/ui-phase.md +187 -23
- package/rcode/workflows/ui-review.md +9 -1
- package/rcode/workflows/verify-work.md +1 -1
- 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}
|
|
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 | ✓
|
|
522
|
-
| CP | plan-03 | ✓
|
|
523
|
-
| 2 | plan-04 | ✓
|
|
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>
|
package/rcode/workflows/help.md
CHANGED
|
@@ -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`:**
|
|
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
|
```
|
package/rcode/workflows/plan.md
CHANGED
|
@@ -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 (
|
|
628
|
+
**Thinking partner for architectural tradeoffs (default ON in guided mode, OFF in yolo/autonomous):**
|
|
598
629
|
```bash
|
|
599
|
-
|
|
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 `
|
|
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
|
|
package/rcode/workflows/ship.md
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
128
|
+
description: "Generate design variants"
|
|
66
129
|
prompt: |
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
3
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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 (
|
|
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
|
-
-
|
|
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
|
-
-
|
|
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.
|
package/server/lib/scanner.js
CHANGED
|
@@ -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:
|
|
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 :
|
|
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
|
-
|
|
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
|
-
|
|
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) ----
|