@hanzlaa/rcode 4.8.0 → 4.9.1
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/CONTRIBUTING.md +3 -0
- package/README.md +7 -5
- package/cli/doctor.js +4 -2
- package/cli/github-sync.js +26 -17
- package/cli/install.js +59 -34
- package/cli/lib/namespace-migrate.cjs +62 -4
- package/cli/migrate-namespace.js +4 -0
- package/dist/rcode.js +207 -207
- package/package.json +1 -1
- package/rcode/agents/rcode-code-reviewer.md +1 -1
- package/rcode/agents/rcode-docs-auditor.md +1 -1
- package/rcode/agents/rcode-edge-case-hunter.md +1 -1
- package/rcode/agents/rcode-security-adversary.md +1 -1
- package/rcode/agents/rcode-security-auditor.md +1 -1
- package/rcode/agents/rcode-sprint-checker.md +1 -1
- package/rcode/agents/rcode-verifier.md +1 -1
- package/rcode/bin/lib/brain.cjs +16 -1
- package/rcode/bin/lib/gitignore.cjs +3 -5
- package/rcode/bin/rcode-hooks.cjs +22 -5
- package/rcode/bin/rcode-tools.cjs +166 -14
- package/rcode/data/intent-table.json +1 -1
- package/rcode/references/git-preflight.md +5 -2
- package/rcode/references/output-format.md +5 -5
- package/rcode/workflows/add-phase.md +33 -14
- package/rcode/workflows/do.md +33 -1
- package/rcode/workflows/execute-sprint.md +3 -4
- package/rcode/workflows/execute-waves.md +25 -32
- package/rcode/workflows/execute.md +80 -21
- package/rcode/workflows/init.md +28 -6
- package/rcode/workflows/plan-research-validation.md +10 -5
- package/rcode/workflows/plan-spawn-planner.md +9 -13
- package/rcode/workflows/plan.md +2 -2
- package/rcode/workflows/scaffold-skill.md +19 -1
- package/rcode/workflows/scan.md +22 -1
- package/rcode/workflows/secure-phase.md +7 -1
- package/rcode/workflows/validate-phase.md +7 -1
- package/server/lib/html/client/components/Sidebar.js +8 -5
- package/server/lib/html/client/views/PhasesView.js +1 -1
- package/server/lib/html/css.js +4 -0
- package/server/lib/scanner.js +4 -1
|
@@ -198,11 +198,10 @@ Deviations are normal — handle via rules below.
|
|
|
198
198
|
- `type="auto"`: if `tdd="true"` → TDD execution. Implement with deviation rules + auth gates. Verify done criteria. Commit (see task_commit). Track hash for Summary.
|
|
199
199
|
- `type="checkpoint:*"`: STOP → checkpoint_protocol → wait for user → continue only after confirmation.
|
|
200
200
|
- **Task completion precedence (when signals conflict):**
|
|
201
|
-
1. `<verify><automated>` — machine-executable shell commands. **Highest authority.** If these pass, the task is done. If these fail, the task is NOT done — regardless of what `<
|
|
201
|
+
1. `<verify><automated>` — machine-executable shell commands. **Highest authority.** If these pass, the task is done. If these fail, the task is NOT done — regardless of what `<done>` says.
|
|
202
202
|
2. `<done>` — single observable sentence. Use as the human-readable confirmation once automated checks pass.
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
- **MANDATORY acceptance_criteria check:** After completing each task, if it has `<acceptance_criteria>`, verify EVERY criterion before moving to the next task. Use grep, file reads, or CLI commands to confirm each criterion. If any criterion fails, fix the implementation before proceeding. Do not skip criteria or mark them as "will verify later".
|
|
203
|
+
- If `<verify><automated>` is absent: fall back to `<done>` alone. `<evidence>` (grep hits, line ranges, or a creates-justification recorded by the planner per issue #649) is supporting grounding, not a completion signal to re-check here — the real plan schema (planner-playbook.md, sprint.md) has no such tag.
|
|
204
|
+
- **MANDATORY completion check:** After completing each task, confirm `<verify><automated>` passes (or, if absent, that the task's `<done>` sentence is observably true). Use grep, file reads, or CLI commands to confirm. If any check fails, fix the implementation before proceeding. Do not skip this or mark it as "will verify later".
|
|
206
205
|
3. Run `<verification>` checks
|
|
207
206
|
4. Confirm `<success_criteria>` met
|
|
208
207
|
5. Document deviations in Summary
|
|
@@ -73,45 +73,38 @@ Execute each selected wave in sequence. Within a wave: parallel if `PARALLELIZAT
|
|
|
73
73
|
|
|
74
74
|
**Classify plan and select subagent_type (BEFORE spawning, once per plan):**
|
|
75
75
|
|
|
76
|
-
|
|
77
|
-
|
|
76
|
+
This used to be prose pseudocode the orchestrating LLM was expected to hand-apply
|
|
77
|
+
(FRONTEND_GLOBS/BACKEND_GLOBS matching + keyword fallback). A live execution run showed
|
|
78
|
+
that computation was never actually carried out — a plan whose `files_modified` clearly
|
|
79
|
+
matched the backend glob rule (a path containing `db`) still fell back to `rcode-executor`.
|
|
80
|
+
Classification is now a deterministic CLI call — do not hand-compute it.
|
|
78
81
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
touches_frontend = any(file matches FRONTEND_GLOBS for file in files_modified)
|
|
84
|
-
touches_backend = any(file matches BACKEND_GLOBS for file in files_modified)
|
|
85
|
-
|
|
86
|
-
if touches_frontend and touches_backend:
|
|
87
|
-
classification = "full-stack"
|
|
88
|
-
elif touches_frontend:
|
|
89
|
-
classification = "frontend"
|
|
90
|
-
elif touches_backend:
|
|
91
|
-
classification = "backend"
|
|
92
|
-
else:
|
|
93
|
-
classification = "other" # files_modified empty/absent, or no glob matched
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
**If `classification` is `"other"`** (ambiguous, or `files_modified` empty/absent), fall back
|
|
97
|
-
to keyword-matching the plan's `<objective>` text before giving up:
|
|
98
|
-
- Frontend keywords (React, component, UI, CSS, Tailwind, frontend, client-side, accessibility, a11y) → `classification = "frontend"`
|
|
99
|
-
- Backend keywords (API, endpoint, database, schema, service, queue, backend, server-side) → `classification = "backend"`
|
|
100
|
-
- Neither matches (pure docs/config/infra plan) → `classification` stays `"other"`
|
|
82
|
+
Call `classify-plan` with the phase and this plan's id (it reads `files_modified` and the
|
|
83
|
+
`<objective>` directly from the plan's SPRINT.md, so no need to re-parse step 1's overlap
|
|
84
|
+
data yourself):
|
|
101
85
|
|
|
102
|
-
|
|
86
|
+
```bash
|
|
87
|
+
CLASSIFY_JSON=$(node ".rcode/bin/rcode-tools.cjs" classify-plan "$PHASE" "$PLAN_ID" 2>/dev/null)
|
|
88
|
+
SUBAGENT_TYPE=$(echo "$CLASSIFY_JSON" | node -e "let d='';process.stdin.on('data',c=>d+=c).on('end',()=>{try{console.log(JSON.parse(d).subagent_type)}catch{console.log('rcode-executor')}})")
|
|
89
|
+
SUBAGENT_TYPE=${SUBAGENT_TYPE:-rcode-executor}
|
|
90
|
+
```
|
|
103
91
|
|
|
104
|
-
|
|
105
|
-
|---|---|
|
|
106
|
-
| frontend | rcode-haitham |
|
|
107
|
-
| backend | rcode-yousef |
|
|
108
|
-
| full-stack | rcode-hanzla |
|
|
109
|
-
| other | rcode-executor |
|
|
92
|
+
Use the literal `subagent_type` value returned — do not second-guess or override it.
|
|
110
93
|
|
|
111
94
|
This decision is computed once per plan, before that plan's Task() spawn(s) below, and the
|
|
112
95
|
resulting `subagent_type` value is used in the Task() call template (worktree and sequential
|
|
113
96
|
modes both reuse this same value — see "Sequential mode" further below).
|
|
114
97
|
|
|
98
|
+
**Resolve executor model (once per wave, before spawning):**
|
|
99
|
+
|
|
100
|
+
`executor_model` from `init` is the raw `model_profile` string (e.g. `balanced`), not a
|
|
101
|
+
resolved model id — it must be passed through `resolve-model` first, the same way
|
|
102
|
+
`code_review_gate` in execute.md resolves `REVIEWER_MODEL` before its Task() spawn.
|
|
103
|
+
```bash
|
|
104
|
+
EXECUTOR_MODEL=$(node ".rcode/bin/rcode-tools.cjs" resolve-model executor 2>/dev/null | node -e "let d='';process.stdin.on('data',c=>d+=c).on('end',()=>{try{console.log(JSON.parse(d).model)}catch{console.log('')}})" || echo "sonnet")
|
|
105
|
+
EXECUTOR_MODEL=${EXECUTOR_MODEL:-sonnet}
|
|
106
|
+
```
|
|
107
|
+
|
|
115
108
|
**Worktree mode** (`USE_WORKTREES` is not `false`):
|
|
116
109
|
|
|
117
110
|
Before spawning, capture the current HEAD:
|
|
@@ -139,7 +132,7 @@ Execute each selected wave in sequence. Within a wave: parallel if `PARALLELIZAT
|
|
|
139
132
|
Task(
|
|
140
133
|
subagent_type="{subagent_type}",
|
|
141
134
|
description="Execute plan {plan_number} of phase {phase_number}",
|
|
142
|
-
model="{
|
|
135
|
+
model="${EXECUTOR_MODEL}",
|
|
143
136
|
isolation="worktree",
|
|
144
137
|
prompt="
|
|
145
138
|
<objective>
|
|
@@ -35,11 +35,12 @@ route back to the user.
|
|
|
35
35
|
4. **Branch check**: confirm current git branch is appropriate
|
|
36
36
|
for the work. Two checks, both blocking:
|
|
37
37
|
|
|
38
|
-
a. **Not on main/master without consent
|
|
39
|
-
|
|
40
|
-
`
|
|
41
|
-
|
|
42
|
-
|
|
38
|
+
a. **Not on main/master without consent** (skip entirely when `git.branching_strategy`
|
|
39
|
+
config is `none` — check via `node .rcode/bin/rcode-tools.cjs config-get
|
|
40
|
+
git.branching_strategy`): if `git branch --show-current` returns `main` or
|
|
41
|
+
`master`, refuse to execute. Suggest: `git switch -c <phase>-<plan>-<slug>`
|
|
42
|
+
(e.g. `git switch -c 8-1-aria`). User can override only by passing `--on-main`
|
|
43
|
+
to /rcode-execute and explicitly typing the override on this turn.
|
|
43
44
|
|
|
44
45
|
b. **Working tree clean enough**: if `git status --porcelain` shows
|
|
45
46
|
modified files unrelated to this phase's `files_modified` frontmatter,
|
|
@@ -49,8 +50,7 @@ route back to the user.
|
|
|
49
50
|
|
|
50
51
|
The branch name should align with the phase/plan IDs from state — check
|
|
51
52
|
`workflow.branch_pattern` config (default `<phase>-<plan>-<slug>`).
|
|
52
|
-
5. **Worktree config**: read `workflow.use_worktrees` — if true + parallelization
|
|
53
|
-
is true + no file overlaps, plans in a wave run parallel via worktrees
|
|
53
|
+
5. **Worktree config**: read `workflow.use_worktrees` — if true + no file overlaps, plans in a wave run parallel via worktrees. (`parallelization` is not a real field in `init execute`'s output — see the "initialize" step below; don't gate on it.)
|
|
54
54
|
</pre_flight>
|
|
55
55
|
|
|
56
56
|
<insight_block>
|
|
@@ -98,7 +98,41 @@ CONFIG_MODE=$(node .rcode/bin/rcode-tools.cjs config-get mode 2>/dev/null || ech
|
|
|
98
98
|
|
|
99
99
|
**If `CONFIG_MODE == "yolo"` or `$ARGUMENTS` contains `--auto`:** Skip the menu. Auto-select **A) Autonomous run** and print one line: `▶ Auto-selecting Autonomous run (yolo mode). /rcode-settings set mode guided to change.`
|
|
100
100
|
|
|
101
|
-
|
|
101
|
+
**herdr availability check (cached).** Before offering options, determine whether a 4th
|
|
102
|
+
option (**D) herdr multi-agent orchestration**) should be shown. This uses the same
|
|
103
|
+
cached-boolean idiom as `workflow._auto_chain_active` above — read with a safe default,
|
|
104
|
+
write back once resolved, and skip the live check on subsequent runs:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
HERDR_NAMED_EXPLICITLY=$([[ "$ARGUMENTS" =~ herdr ]] && echo true || echo false)
|
|
108
|
+
|
|
109
|
+
HERDR_CHECKED=$(node .rcode/bin/rcode-tools.cjs config-get workflow._herdr_checked 2>/dev/null || echo "false")
|
|
110
|
+
HERDR_CHECKED=${HERDR_CHECKED:-false} # config-get exits 0 with empty output when key absent
|
|
111
|
+
|
|
112
|
+
if [[ "$HERDR_CHECKED" != "true" || "$HERDR_NAMED_EXPLICITLY" == "true" ]]; then
|
|
113
|
+
# Live re-check: first time ever, OR user named herdr explicitly this run
|
|
114
|
+
# (herdr may have been installed since the last negative cache hit).
|
|
115
|
+
if command -v herdr >/dev/null 2>&1; then
|
|
116
|
+
HERDR_AVAILABLE=true
|
|
117
|
+
else
|
|
118
|
+
HERDR_AVAILABLE=false
|
|
119
|
+
fi
|
|
120
|
+
node .rcode/bin/rcode-tools.cjs config-set workflow._herdr_available "$HERDR_AVAILABLE" 2>/dev/null
|
|
121
|
+
node .rcode/bin/rcode-tools.cjs config-set workflow._herdr_checked true 2>/dev/null
|
|
122
|
+
else
|
|
123
|
+
# Cached negative (or positive) result from a prior run — skip the check entirely.
|
|
124
|
+
HERDR_AVAILABLE=$(node .rcode/bin/rcode-tools.cjs config-get workflow._herdr_available 2>/dev/null || echo "false")
|
|
125
|
+
HERDR_AVAILABLE=${HERDR_AVAILABLE:-false}
|
|
126
|
+
fi
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Do **not** re-run `command -v herdr` on every invocation once `_herdr_checked` is `true` —
|
|
130
|
+
that defeats the point of caching. The only exception is `HERDR_NAMED_EXPLICITLY`: if the
|
|
131
|
+
user's request names herdr by name (e.g. "use herdr for this", "orchestrate via herdr"),
|
|
132
|
+
always re-check live regardless of the cached value, since herdr may have been installed
|
|
133
|
+
since the negative result was cached.
|
|
134
|
+
|
|
135
|
+
Otherwise, offer modes via AskUserQuestion. Each option names the tradeoff explicitly:
|
|
102
136
|
|
|
103
137
|
**A) Autonomous run** — Spawn subagent per plan in sequence/parallel per
|
|
104
138
|
wave rules. Checkpoints still pause for user. Fastest wall-clock.
|
|
@@ -112,9 +146,31 @@ Otherwise, offer three modes via AskUserQuestion. Each option names the tradeoff
|
|
|
112
146
|
later waves in a separate session. Good for staged rollout / review
|
|
113
147
|
gates.
|
|
114
148
|
|
|
149
|
+
**D) herdr multi-agent orchestration** (only shown if `HERDR_AVAILABLE == "true"`) —
|
|
150
|
+
Fan this phase's plans out to parallel `herdr` panes/tabs, each running its own
|
|
151
|
+
Claude agent in an isolated git worktree, then merge their work back. Be specific
|
|
152
|
+
about the tradeoff, not a one-liner: separate terminal panes you can watch
|
|
153
|
+
independently, genuinely parallel wall-clock (not wave-sequenced), noticeably
|
|
154
|
+
higher token cost than A/B/C since each pane runs a full agent session, and a
|
|
155
|
+
merge step at the end. Best fit is plans that are truly independent (no shared
|
|
156
|
+
`files_modified`, no cross-plan sequencing) — for plans with overlaps or a single
|
|
157
|
+
linear wave, herdr adds coordination overhead for no benefit; prefer A or C instead.
|
|
158
|
+
Selecting this option invokes the `rcode-herdr-orchestration` skill — it does not
|
|
159
|
+
replace this workflow's execution, it's a different way to run the same plans.
|
|
160
|
+
|
|
161
|
+
**Never auto-select D, even in yolo/`--auto` mode.** Orchestrating via herdr requires
|
|
162
|
+
explicit user confirmation on this turn — if `CONFIG_MODE == "yolo"` skipped the menu
|
|
163
|
+
above, herdr is simply not offered this run; the autonomous-run auto-selection must
|
|
164
|
+
never silently switch into herdr mode.
|
|
165
|
+
|
|
115
166
|
Include a recommendation line: "My recommendation: {letter} because {reason
|
|
116
167
|
in one clause}." Then ask which option to proceed with — do NOT silently
|
|
117
|
-
pick one.
|
|
168
|
+
pick one. If the user selects D, confirm once more in plain language what
|
|
169
|
+
will happen (parallel panes, worktrees, higher cost) before invoking
|
|
170
|
+
`Skill(skill="rcode-herdr-orchestration", ...)` — do not invoke it on the same
|
|
171
|
+
turn as the AskUserQuestion answer without that confirmation being part of
|
|
172
|
+
the answer itself (i.e. selecting the option IS the confirmation only if its
|
|
173
|
+
label made the tradeoff explicit, which it does above).
|
|
118
174
|
</three_options>
|
|
119
175
|
|
|
120
176
|
<output_format>
|
|
@@ -238,14 +294,16 @@ If `INIT` is empty or `INIT.ok` is false, print error and exit:
|
|
|
238
294
|
Error: rcode-tools init failed. Verify .rcode/ is installed and state.json is valid.
|
|
239
295
|
```
|
|
240
296
|
|
|
241
|
-
Parse JSON for: `executor_model`, `verifier_model`, `
|
|
297
|
+
Parse JSON for these real, top-level fields: `executor_model`, `verifier_model`, `phase_dir`, `plans`, `state_exists`, `response_language`. Fields commonly assumed to exist but that are NOT top-level (verified live this session against `init execute`'s real output, `cmdInitExecute` in rcode-tools.cjs): `branching_strategy` is nested under `config.branching_strategy`; `commit_docs` doesn't exist (closest real value is `config.commit_planning`, a `"true"`/`"false"` string); `parallelization` has no source anywhere (not top-level, not under `config`, not in `phase-plan-index`'s output either); `branch_name` isn't returned (the `handle_branching` step below now computes it from config instead); `phase_name` isn't derivable either (`phase_dir`'s basename is a slug, not the human-readable name — read ROADMAP.md if a step needs it); `incomplete_plans`/`incomplete_count` don't exist (`plans[]` items only carry `{path, depends_on, wave, plan}`, no completion field); `roadmap_exists`/`phase_req_ids` are returned only by the separate `init sprint-plan` command, not `init execute`.
|
|
298
|
+
Derivable, not literal: `phase_found` as `phase_dir !== null`; `phase_number` as the `target` field (the raw phase argument as passed, e.g. `"45"`); `phase_slug` from `phase_dir`'s basename (the part after the first `-`); `plan_count` as `plans.length`. Downstream `${PHASE_NUMBER}`/`${PLAN_COUNT}` references later in this workflow (snapshot tag, review prompts, `phase complete`, etc.) resolve from `target`/`plans.length` per these derivations; `${PHASE_NAME}` and `${INCOMPLETE_COUNT}` have no source here — read `PHASE_NAME` from ROADMAP.md if a later step needs it, and treat `INCOMPLETE_COUNT` as unknown until `phase-plan-index` runs in `discover_and_group_plans` (which does return a real per-plan `has_summary` completion signal).
|
|
242
299
|
|
|
243
300
|
**If `response_language` is set:** Include `response_language: {value}` in all spawned subagent prompts so any user-facing output stays in the configured language.
|
|
244
301
|
|
|
245
302
|
Read worktree config:
|
|
246
303
|
|
|
247
304
|
```bash
|
|
248
|
-
USE_WORKTREES=$(node ".rcode/bin/rcode-tools.cjs" config-get workflow.use_worktrees 2>/dev/null
|
|
305
|
+
USE_WORKTREES=$(node ".rcode/bin/rcode-tools.cjs" config-get workflow.use_worktrees 2>/dev/null)
|
|
306
|
+
USE_WORKTREES=${USE_WORKTREES:-true} # config-get exits 0 with empty output when key absent; || fallback won't fire
|
|
249
307
|
```
|
|
250
308
|
|
|
251
309
|
When `USE_WORKTREES` is `false`, all executor agents run without `isolation="worktree"` — they execute sequentially on the main working tree instead of in parallel worktrees.
|
|
@@ -265,16 +323,17 @@ When `CONTEXT_WINDOW >= 500000` (1M-class models), subagent prompts include rich
|
|
|
265
323
|
- Verifier agents receive all SPRINT.md, SUMMARY.md, CONTEXT.md files plus REQUIREMENTS.md
|
|
266
324
|
- This enables cross-phase awareness and history-aware verification
|
|
267
325
|
|
|
268
|
-
**If `
|
|
269
|
-
**If `
|
|
326
|
+
**If `phase_dir` is `null` (derived `phase_found` false):** Error — phase directory not found. Run `/rcode-status` to inspect state or `/rcode-plan {N}` to create the phase.
|
|
327
|
+
**If `plans.length` is 0 (derived `plan_count` 0):** Error — no plans found in phase. Run `/rcode-plan {N}` to generate plans or `/rcode-help` for the command surface.
|
|
270
328
|
**If `state_exists` is false but `.planning/` exists:** Offer reconstruct or continue.
|
|
271
329
|
|
|
272
|
-
|
|
330
|
+
`parallelization` is not a real field in `init execute`'s output (see the "initialize" step's field notes above) — this line currently documents behavior with no data source; don't treat it as a working toggle until a real source is wired in.
|
|
273
331
|
|
|
274
332
|
**Runtime detection for Copilot:**
|
|
275
333
|
Check if the current runtime is Copilot by testing for the `@rcode-executor` agent pattern
|
|
276
334
|
or absence of the `Task()` subagent API. If running under Copilot, force sequential inline
|
|
277
|
-
execution
|
|
335
|
+
execution unconditionally (there is no real `parallelization` toggle to override — see the
|
|
336
|
+
"initialize" step's field notes above) — Copilot's subagent completion
|
|
278
337
|
signals are unreliable (see `<runtime_compatibility>`). Set `COPILOT_SEQUENTIAL=true`
|
|
279
338
|
internally and skip the `execute_waves` step in favor of `check_interactive_mode`'s
|
|
280
339
|
inline path for each plan.
|
|
@@ -352,7 +411,7 @@ Check `branching_strategy` from init:
|
|
|
352
411
|
|
|
353
412
|
**"none":** Skip, continue on current branch.
|
|
354
413
|
|
|
355
|
-
**"phase" or "milestone":**
|
|
414
|
+
**"phase" or "milestone":** `init execute` does not return `branch_name` (see the "initialize" step's field notes above) — compute `BRANCH_NAME` from `workflow.branch_pattern` config (default `<phase>-<plan>-<slug>`) before running:
|
|
356
415
|
```bash
|
|
357
416
|
git checkout -b "$BRANCH_NAME" 2>/dev/null || git checkout "$BRANCH_NAME"
|
|
358
417
|
```
|
|
@@ -361,7 +420,7 @@ All subsequent commits go to this branch. User handles merging.
|
|
|
361
420
|
</step>
|
|
362
421
|
|
|
363
422
|
<step name="validate_phase">
|
|
364
|
-
From init JSON: `phase_dir
|
|
423
|
+
From init JSON: `phase_dir` (real); `plan_count` derives as `plans.length`; `incomplete_count` has no source at this point (see the "initialize" step's field notes) — treat as unknown until `phase-plan-index` runs.
|
|
365
424
|
|
|
366
425
|
Report: "Found {plan_count} plans in {phase_dir} ({incomplete_count} incomplete)"
|
|
367
426
|
|
|
@@ -527,7 +586,7 @@ Selected wave finished successfully. This phase still has incomplete plans, so p
|
|
|
527
586
|
<step name="run_verify_commands">
|
|
528
587
|
**Run per-task `<verify>` shell commands from all completed SPRINT.md plans.**
|
|
529
588
|
|
|
530
|
-
After all executor agents finish, extract and run any `<verify>` blocks defined in plan tasks. These are the machine-executable
|
|
589
|
+
After all executor agents finish, extract and run any `<verify>` blocks defined in plan tasks. These are the machine-executable proof that a task's `<done>` criteria are met — the plan schema has no such tag; `<verify><automated>` plus `<evidence>` grounding are what the planner and executor actually emit and enforce.
|
|
531
590
|
|
|
532
591
|
```bash
|
|
533
592
|
# Extract all <verify> blocks from all SPRINT.md files for this phase
|
|
@@ -745,10 +804,10 @@ fi
|
|
|
745
804
|
```
|
|
746
805
|
⚠ Phase {X} EXECUTED but not yet verified.
|
|
747
806
|
|
|
748
|
-
The following
|
|
807
|
+
The following task completion criteria require human verification before
|
|
749
808
|
the phase can advance to `status: complete`:
|
|
750
809
|
|
|
751
|
-
{list
|
|
810
|
+
{list each task's <done> sentence from SPRINT.md}
|
|
752
811
|
|
|
753
812
|
Recommended next steps:
|
|
754
813
|
/rcode-add-tests {X} — generate unit + E2E tests before UAT
|
|
@@ -761,7 +820,7 @@ fi
|
|
|
761
820
|
**If `VERIFICATION_STATUS` is `fail`:**
|
|
762
821
|
|
|
763
822
|
1. Mark the phase as `status: executed` (so /rcode-plan --gaps can run a closure cycle).
|
|
764
|
-
2. Surface the failed
|
|
823
|
+
2. Surface the tasks whose `<done>` criteria failed human verification.
|
|
765
824
|
3. STOP. Don't mark complete on a failing verification.
|
|
766
825
|
|
|
767
826
|
**Only when `VERIFICATION_STATUS` is `pass`** — proceed to `update_roadmap` below.
|
package/rcode/workflows/init.md
CHANGED
|
@@ -42,6 +42,12 @@ Run detection in parallel:
|
|
|
42
42
|
test -f .rcode/config.yaml && echo "rcode-configured: yes" || echo "rcode-configured: no"
|
|
43
43
|
test -f .rcode/state.json && echo "state-present: yes" || echo "state-present: no"
|
|
44
44
|
test -f .rcode/JOURNEY.md && echo "rihla-present: yes" || echo "rihla-present: no"
|
|
45
|
+
# #1028: config.yaml is written by the installer itself, so it exists on the
|
|
46
|
+
# very first /rcode-init run after a fresh install — not just on a genuine
|
|
47
|
+
# "returning" session. state.json's installer-seeded _seeded_stub marker
|
|
48
|
+
# (cleared once a real init/new-project run completes) is what actually
|
|
49
|
+
# distinguishes "normal first brownfield run" from "prior init was interrupted".
|
|
50
|
+
grep -q '"_seeded_stub"[[:space:]]*:[[:space:]]*true' .rcode/state.json 2>/dev/null && echo "seeded-stub: yes" || echo "seeded-stub: no"
|
|
45
51
|
|
|
46
52
|
# Project presence
|
|
47
53
|
# Use git rev-parse instead of test -d .git — in git worktrees .git is a FILE not a dir
|
|
@@ -83,12 +89,20 @@ If `state === "returning"` and `--reset` not passed:
|
|
|
83
89
|
Or run with --reset to reconfigure.
|
|
84
90
|
```
|
|
85
91
|
|
|
86
|
-
- If `rihla-present: no` —
|
|
92
|
+
- If `rihla-present: no` and `seeded-stub: yes` — this is the normal, expected first `/rcode-init` run on a brownfield project: `config.yaml` was seeded by the installer, but no real init has happened yet. Nothing was broken; do NOT use "recovery" language. Print a plain first-run notice and continue to Steps 4 and 4b to write the baseline:
|
|
93
|
+
|
|
94
|
+
```
|
|
95
|
+
✓ rcode is configured. Writing the JOURNEY.md baseline now...
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Skip Steps 2 and 3 (config already exists). Jump directly to Step 4.
|
|
99
|
+
|
|
100
|
+
- If `rihla-present: no` and `seeded-stub: no` — a genuine prior init/new-project run completed (the stub marker was cleared) but JOURNEY.md is missing, meaning that prior run was interrupted before writing it. This is an actual recovery case. Print a recovery notice and continue to Steps 4 and 4b to write the missing baseline:
|
|
87
101
|
|
|
88
102
|
```
|
|
89
103
|
✓ rcode is already configured here.
|
|
90
104
|
|
|
91
|
-
JOURNEY.md baseline is missing — completing
|
|
105
|
+
JOURNEY.md baseline is missing from a prior interrupted init — completing it now...
|
|
92
106
|
```
|
|
93
107
|
|
|
94
108
|
Skip Steps 2 and 3 (config already exists). Jump directly to Step 4.
|
|
@@ -279,10 +293,10 @@ if [ -s .rcode/context/active.md ] && ! grep -q "Run \`/rcode" .rcode/context/ac
|
|
|
279
293
|
fi
|
|
280
294
|
```
|
|
281
295
|
|
|
282
|
-
After writing both files, refresh the memory bank fingerprint so staleness checks see the project as fresh:
|
|
296
|
+
After writing both files, refresh the memory bank fingerprint so staleness checks see the project as fresh. `context refresh` reads `.rcode/sources.yaml`, but nothing in rcode ever creates that file (the installer only scaffolds the unrelated `.rcode/brain/sources.yaml`, used by `brain pull`) — so on every fresh project this call is a guaranteed no-op. Skip it when the file is known not to exist rather than spending a call to learn that (#1018):
|
|
283
297
|
|
|
284
298
|
```bash
|
|
285
|
-
node .rcode/bin/rcode-tools.cjs context refresh >/dev/null 2>&1 || true
|
|
299
|
+
test -f .rcode/sources.yaml && node .rcode/bin/rcode-tools.cjs context refresh >/dev/null 2>&1 || true
|
|
286
300
|
```
|
|
287
301
|
|
|
288
302
|
## Step 4c — Scaffold CLAUDE.md / AGENTS.md if missing
|
|
@@ -290,12 +304,12 @@ node .rcode/bin/rcode-tools.cjs context refresh >/dev/null 2>&1 || true
|
|
|
290
304
|
`generate-claude-md` (the command routing rule + project rules block every agent needs at session start) previously only ran via the `/rcode-new-project` roadmap flow — a project set up with `/rcode-init` alone (the common "add rcode to an existing codebase" path) never got it, so agents had no ambient instruction to check `do.md` before acting ad-hoc. Close that gap here, unconditionally (not just on `fresh`):
|
|
291
305
|
|
|
292
306
|
```bash
|
|
293
|
-
if [ ! -f CLAUDE.md ]; then
|
|
307
|
+
if [ ! -f CLAUDE.md ] || [ ! -f AGENTS.md ]; then
|
|
294
308
|
node .rcode/bin/rcode-tools.cjs generate-claude-md
|
|
295
309
|
fi
|
|
296
310
|
```
|
|
297
311
|
|
|
298
|
-
Never pass `--force` here — an existing `CLAUDE.md` is the user's own file (or was already generated by a prior init/new-project run) and must not be overwritten. Silent no-op when
|
|
312
|
+
Never pass `--force` here — an existing `CLAUDE.md` or `AGENTS.md` is the user's own file (or was already generated by a prior init/new-project run) and must not be overwritten. `cmdGenerateClaudeMd` gates each file's write on that file's own existence, so this backfills whichever one is missing (#1025). Silent no-op when both files already exist.
|
|
299
313
|
|
|
300
314
|
## Step 5 — Suggest the next step
|
|
301
315
|
|
|
@@ -327,6 +341,14 @@ Or strategic question about the codebase:
|
|
|
327
341
|
/rcode-council {your question}
|
|
328
342
|
```
|
|
329
343
|
|
|
344
|
+
**In all three cases, append this tip:**
|
|
345
|
+
```
|
|
346
|
+
Tip: run /rcode-enable-hooks to turn on a one-line project status primer at
|
|
347
|
+
the start of every session, plus 9 other opt-in guardrails (read-before-edit
|
|
348
|
+
checks, dangerous-command blocking, auto-formatting). Off by default so a
|
|
349
|
+
fresh install never surprises you.
|
|
350
|
+
```
|
|
351
|
+
|
|
330
352
|
**If `returning` with `--reset`:**
|
|
331
353
|
```
|
|
332
354
|
✓ rcode reconfigured. Prior state preserved in state.json.
|
|
@@ -157,9 +157,12 @@ test -f "${PHASE_DIR}/${PADDED_PHASE}-VALIDATION.md" && echo "VALIDATION_CREATED
|
|
|
157
157
|
> Skip if `workflow.security_enforcement` is explicitly `false`. Absent = enabled.
|
|
158
158
|
|
|
159
159
|
```bash
|
|
160
|
-
SECURITY_CFG=$(node ".rcode/bin/rcode-tools.cjs" config-get workflow.security_enforcement --raw 2>/dev/null
|
|
161
|
-
|
|
162
|
-
|
|
160
|
+
SECURITY_CFG=$(node ".rcode/bin/rcode-tools.cjs" config-get workflow.security_enforcement --raw 2>/dev/null)
|
|
161
|
+
SECURITY_CFG=${SECURITY_CFG:-true} # config-get exits 0 with empty output when key absent; || fallback won't fire
|
|
162
|
+
SECURITY_ASVS=$(node ".rcode/bin/rcode-tools.cjs" config-get workflow.security_asvs_level --raw 2>/dev/null)
|
|
163
|
+
SECURITY_ASVS=${SECURITY_ASVS:-1} # config-get exits 0 with empty output when key absent; || fallback won't fire
|
|
164
|
+
SECURITY_BLOCK=$(node ".rcode/bin/rcode-tools.cjs" config-get workflow.security_block_on --raw 2>/dev/null)
|
|
165
|
+
SECURITY_BLOCK=${SECURITY_BLOCK:-high} # config-get exits 0 with empty output when key absent; || fallback won't fire
|
|
163
166
|
```
|
|
164
167
|
|
|
165
168
|
**If `SECURITY_CFG` is `false`:** Skip to step 5.6.
|
|
@@ -183,8 +186,10 @@ Continue to step 5.6. Security config is passed to the planner in step 8.
|
|
|
183
186
|
> Skip if `workflow.ui_phase` is explicitly `false` AND `workflow.ui_safety_gate` is explicitly `false` in `.rcode/config.yaml`. If keys are absent, treat as enabled.
|
|
184
187
|
|
|
185
188
|
```bash
|
|
186
|
-
UI_PHASE_CFG=$(node ".rcode/bin/rcode-tools.cjs" config-get workflow.ui_phase 2>/dev/null
|
|
187
|
-
|
|
189
|
+
UI_PHASE_CFG=$(node ".rcode/bin/rcode-tools.cjs" config-get workflow.ui_phase 2>/dev/null)
|
|
190
|
+
UI_PHASE_CFG=${UI_PHASE_CFG:-true} # config-get exits 0 with empty output when key absent; || fallback won't fire
|
|
191
|
+
UI_GATE_CFG=$(node ".rcode/bin/rcode-tools.cjs" config-get workflow.ui_safety_gate 2>/dev/null)
|
|
192
|
+
UI_GATE_CFG=${UI_GATE_CFG:-true} # config-get exits 0 with empty output when key absent; || fallback won't fire
|
|
188
193
|
```
|
|
189
194
|
|
|
190
195
|
**If both are `false`:** Skip to step 6.
|
|
@@ -114,7 +114,7 @@ ${AGENT_SKILLS_PLANNER}
|
|
|
114
114
|
<downstream_consumer>
|
|
115
115
|
Output consumed by /rcode-execute. Plans need:
|
|
116
116
|
- Frontmatter (wave, depends_on, autonomous, **files_modified** — aggregated list of all file paths from `<files>` blocks across every task; used by executor for intra-wave parallel-safety overlap detection)
|
|
117
|
-
- Tasks in XML format with read_first, files,
|
|
117
|
+
- Tasks in XML format with read_first, files, evidence, verify (with `<automated>` child), and done fields (MANDATORY on every task)
|
|
118
118
|
- Verification criteria
|
|
119
119
|
- must_haves for goal-backward verification
|
|
120
120
|
- **`## Files Touched`** section (see below) — required on every SPRINT.md
|
|
@@ -257,17 +257,13 @@ Every task MUST include these fields — they are NOT optional:
|
|
|
257
257
|
- Executor checkpoint (knows what to stage after each task)
|
|
258
258
|
- Example: `src/auth/auth.service.ts`, `tests/auth/auth.service.test.ts`
|
|
259
259
|
|
|
260
|
-
3. **`<
|
|
261
|
-
-
|
|
262
|
-
-
|
|
263
|
-
-
|
|
264
|
-
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
- Docs: `README.md contains '## Installation'` / `API.md lists all endpoints`
|
|
268
|
-
- Infra: `deploy.yml has rollback step` / `docker-compose.yml has healthcheck for db`
|
|
269
|
-
|
|
270
|
-
4. **`<verify>`** — Shell commands that PROVE the acceptance criteria are met. Run by executor after task completes and by verifier during post-execution check. The block MUST contain an `<automated>` child with the exact commands to run (Dimension 8 hard-blocks without it). Rules:
|
|
260
|
+
3. **`<evidence>`** — REQUIRED (issue #649). Must show codebase grounding proving the task is real, not theoretical. At minimum one of:
|
|
261
|
+
- `grep:` a literal grep/Glob pattern + count of matches that justified this task (e.g. `` `rg '\.alert' apps/web/src` → 13 hits across 9 files ``)
|
|
262
|
+
- `lines:` exact `path:line-line` ranges of code being modified
|
|
263
|
+
- `creates:` the file paths being created from scratch (with one-line justification why no existing file fits)
|
|
264
|
+
A task without `<evidence>` is theoretical and MUST NOT be written. (Matches `rcode/references/planner-playbook.md`'s "Task Anatomy" section — single source of truth for this rule.)
|
|
265
|
+
|
|
266
|
+
4. **`<verify>`** — Shell commands that PROVE the `<done>` criteria are met. Run by executor after task completes and by verifier during post-execution check. The block MUST contain an `<automated>` child with the exact commands to run (Dimension 8 hard-blocks without it). Rules:
|
|
271
267
|
- `<automated>` commands must exit 0 on success, non-zero on failure
|
|
272
268
|
- Prefer `grep -q` for presence checks, `test -f` for file existence, project test runner for behavior
|
|
273
269
|
- Keep commands short and composable — one check per line
|
|
@@ -325,7 +321,7 @@ Every task MUST include these fields — they are NOT optional:
|
|
|
325
321
|
- [ ] Tasks are specific and actionable
|
|
326
322
|
- [ ] Every task has `<read_first>` with at least the file being modified
|
|
327
323
|
- [ ] Every task has `<files>` listing exact files this task will modify or create
|
|
328
|
-
- [ ] Every task has `<
|
|
324
|
+
- [ ] Every task has `<evidence>` with grep/lines/creates codebase grounding per issue #649 — not a prose checklist tag (none exists in the real plan schema)
|
|
329
325
|
- [ ] Every task has `<verify>` with an `<automated>` child containing at least one shell command (Dimension 8 blocker)
|
|
330
326
|
- [ ] Every task has `<done>` with a single observable acceptance sentence (Dimension 2 requirement)
|
|
331
327
|
- [ ] Every `<action>` contains concrete values (no "align X with Y" without specifying what)
|
package/rcode/workflows/plan.md
CHANGED
|
@@ -49,8 +49,8 @@ Read all files referenced by the invoking prompt's execution_context before star
|
|
|
49
49
|
${PHASE_GOAL_HAS_UI ? '@.rcode/references/ui-brand.md' : ''}
|
|
50
50
|
@.rcode/references/karpathy-guidelines.md
|
|
51
51
|
<!-- Read .rcode/references/agent-contracts.md only if defining or debugging agent contracts -->
|
|
52
|
-
<!-- Read .rcode/references/gates.md only if implementing or troubleshooting gate logic -->
|
|
53
|
-
@.rcode/references/thinking-models-planning.md
|
|
52
|
+
<!-- Read .rcode/references/gates.md only if implementing or troubleshooting gate logic; thinking-models-planning.md (127 lines) only if features.thinking_partner is enabled -->
|
|
53
|
+
${THINKING_PARTNER_ENABLED === 'true' ? '@.rcode/references/thinking-models-planning.md' : ''}
|
|
54
54
|
</required_reading>
|
|
55
55
|
|
|
56
56
|
<available_agent_types>
|
|
@@ -117,6 +117,21 @@ if [ -n "$fails" ]; then
|
|
|
117
117
|
fi
|
|
118
118
|
```
|
|
119
119
|
|
|
120
|
+
## Step 3.5 — Prove It Moved the Needle
|
|
121
|
+
|
|
122
|
+
Passing the 5-component check in Step 3 only proves the file has the right shape — a triggers block, an Overview, a Workflow, an Output Format, and Examples. It says nothing about whether loading the skill actually changes what an agent does. A skill can be structurally perfect and still be a no-op in practice: the model reads it, nods along, and then falls back to its untrained default the moment a real scenario hits.
|
|
123
|
+
|
|
124
|
+
Do not mark a new or edited skill as ready to ship until you've run this gate:
|
|
125
|
+
|
|
126
|
+
1. **Write the pressure scenario.** Take the exact situation the skill's triggers describe — the moment the skill is supposed to change the agent's behavior — and phrase it as a concrete task an agent could be handed cold, with no mention of the skill.
|
|
127
|
+
2. **Run the control.** Spawn a fresh subagent with no memory of this conversation and the skill NOT loaded (do not mention it, do not point at its path). Give it the pressure scenario. Record what it does by default — this is almost always the suboptimal or wrong behavior the skill exists to correct.
|
|
128
|
+
3. **Run the treatment.** Spawn a second fresh subagent, same scenario, this time with the skill loaded (either by having it available for the model to invoke, or by including its content directly in the prompt). Record what it does.
|
|
129
|
+
4. **Compare.** The treatment run must diverge from the control run in the specific direction the skill claims to produce. "Both agents produced fine-looking output" is not a pass — the question is whether the skill was the reason for the difference. If the two runs land on the same behavior, the skill has no measurable effect yet, no matter how clean its markdown is.
|
|
130
|
+
|
|
131
|
+
If the comparison shows no behavioral difference, the skill is not done. Go back and sharpen the Workflow section, the triggers, or the examples — whichever part failed to actually steer the model — and rerun this gate. Do not ship on structural compliance alone.
|
|
132
|
+
|
|
133
|
+
Skip this gate only when scaffolding a brand-new, still-empty skill (Step 2's placeholders haven't been filled in yet — there's no behavior to test). Once real content replaces the placeholders, this gate becomes mandatory before the skill is considered ready.
|
|
134
|
+
|
|
120
135
|
## Step 4 — Confirm and Next Up
|
|
121
136
|
|
|
122
137
|
Print:
|
|
@@ -127,13 +142,16 @@ Print:
|
|
|
127
142
|
|
|
128
143
|
All 5 required components are present (triggers, Overview, Workflow,
|
|
129
144
|
Output Format, Examples). The placeholders need real content before
|
|
130
|
-
the skill becomes useful.
|
|
145
|
+
the skill becomes useful — and once they're filled in, run Step 3.5
|
|
146
|
+
(Prove It Moved the Needle) before calling the skill done.
|
|
131
147
|
|
|
132
148
|
▶ Next Up
|
|
133
149
|
$EDITOR rcode/skills/actions/<group>/rcode-<NAME>/SKILL.md
|
|
134
150
|
# fill in placeholders
|
|
135
151
|
npx @hanzlaa/rcode install --force # install to .claude/skills/
|
|
136
152
|
node --test test/compliance.test.cjs # verify compliance
|
|
153
|
+
# then: control vs. treatment
|
|
154
|
+
# subagent run (Step 3.5)
|
|
137
155
|
```
|
|
138
156
|
|
|
139
157
|
## Next Up
|
package/rcode/workflows/scan.md
CHANGED
|
@@ -14,10 +14,12 @@ Valid rcode subagent types (use exact names — do not fall back to 'general-pur
|
|
|
14
14
|
|
|
15
15
|
## Step 0 — Usage check
|
|
16
16
|
|
|
17
|
-
If `$ARGUMENTS`
|
|
17
|
+
If `$ARGUMENTS` contains `--help` or `-h`:
|
|
18
18
|
- Print the usage block below
|
|
19
19
|
- STOP — do not proceed
|
|
20
20
|
|
|
21
|
+
If `$ARGUMENTS` is empty, do NOT stop — proceed to Step 1, which defaults focus to `tech+arch`.
|
|
22
|
+
|
|
21
23
|
**Usage:**
|
|
22
24
|
```
|
|
23
25
|
/rcode-scan [--focus tech|arch|quality|concerns|tech+arch] [--refresh] [--reset]
|
|
@@ -339,6 +341,25 @@ This file tracks structural changes between scans. Each entry is auto-written by
|
|
|
339
341
|
|
|
340
342
|
This file is **read by future `/rcode-scan --refresh` runs** as additional anchor context — the memory bank is self-improving across scans.
|
|
341
343
|
|
|
344
|
+
## Step 6.6: Propagate scan findings into PROJECT.md / STATE.md stubs
|
|
345
|
+
|
|
346
|
+
After the RETURNED banner, check whether `.planning/PROJECT.md` and `.planning/STATE.md` are still install stubs (contain the `<!-- INSTALL STUB` banner). If real, non-stub content already exists, skip this step entirely — never overwrite user-authored planning docs.
|
|
347
|
+
|
|
348
|
+
```bash
|
|
349
|
+
grep -q '<!-- INSTALL STUB' .planning/PROJECT.md 2>/dev/null && echo "PROJECT_IS_STUB"
|
|
350
|
+
grep -q '<!-- INSTALL STUB' .planning/STATE.md 2>/dev/null && echo "STATE_IS_STUB"
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
If `PROJECT.md` is a stub: replace its `**One-line:**` sentence with a brief, grounded one-line summary derived from the scan output just written (e.g. from STACK.md/ARCHITECTURE.md's opening lines — language, framework, primary purpose). Keep the rest of the stub structure (Vision/Stack sections) intact; do not attempt a full rewrite. Use Read then Edit — never blind-overwrite.
|
|
354
|
+
|
|
355
|
+
If `STATE.md` is a stub: update `**Current phase:**` line to read:
|
|
356
|
+
```
|
|
357
|
+
**Current phase:** none — existing project scanned, see .planning/codebase/ — no phases planned yet
|
|
358
|
+
```
|
|
359
|
+
and add one line under `## Next Action` noting the scan already ran: `Codebase scanned via /rcode-scan — run /rcode-new-project or /rcode-add-phase to plan phases.`
|
|
360
|
+
|
|
361
|
+
This is a minimal, targeted edit — not a full PROJECT.md content-generation system. The goal is closing the "user opens STATE.md and sees zero acknowledgment a scan already ran" gap.
|
|
362
|
+
|
|
342
363
|
## Step 7: Final cue (orchestrator-level, after RETURNED banner)
|
|
343
364
|
|
|
344
365
|
The RETURNED banner above is Dalil's voice. After it, the orchestrator may add ONE neutral cue line if the user might want a deeper scan:
|
|
@@ -3,7 +3,8 @@ Verify threat mitigations for a completed phase. Confirm SPRINT.md threat regist
|
|
|
3
3
|
</purpose>
|
|
4
4
|
|
|
5
5
|
<required_reading>
|
|
6
|
-
|
|
6
|
+
<!-- ui-brand.md (254 lines): only load when the phase goal/CONTEXT.md contains UI signals — mirrors plan.md:49's PHASE_GOAL_HAS_UI pattern -->
|
|
7
|
+
${PHASE_GOAL_HAS_UI ? '@.rcode/references/ui-brand.md' : ''}
|
|
7
8
|
</required_reading>
|
|
8
9
|
|
|
9
10
|
<available_agent_types>
|
|
@@ -50,6 +51,11 @@ Parse: `phase_dir`, `phase_number`, `phase_name`, `phase_slug`, `padded_phase`,
|
|
|
50
51
|
```bash
|
|
51
52
|
AUDITOR_MODEL=$(node ".rcode/bin/rcode-tools.cjs" resolve-model rcode-security-auditor --raw)
|
|
52
53
|
SECURITY_CFG=$(node ".rcode/bin/rcode-tools.cjs" config-get workflow.security_enforcement --raw 2>/dev/null || echo "true")
|
|
54
|
+
|
|
55
|
+
# Detect UI signals in phase goal + CONTEXT.md to decide whether to load ui-brand.md (254 lines)
|
|
56
|
+
PHASE_GOAL_HAS_UI=$(grep -iEl "frontend|ui|component|design|style|brand" \
|
|
57
|
+
.planning/phases/*${phase_number}*/*-CONTEXT.md \
|
|
58
|
+
.planning/ROADMAP.md 2>/dev/null | head -1)
|
|
53
59
|
```
|
|
54
60
|
|
|
55
61
|
If `SECURITY_CFG` is `false`: exit with "Security enforcement disabled. Enable via /rcode-settings."
|
|
@@ -3,7 +3,8 @@ Audit Nyquist validation gaps for a completed phase. Generate missing tests. Upd
|
|
|
3
3
|
</purpose>
|
|
4
4
|
|
|
5
5
|
<required_reading>
|
|
6
|
-
|
|
6
|
+
<!-- ui-brand.md (254 lines): only load when the phase goal/CONTEXT.md contains UI signals — mirrors plan.md:49's PHASE_GOAL_HAS_UI pattern -->
|
|
7
|
+
${PHASE_GOAL_HAS_UI ? '@.rcode/references/ui-brand.md' : ''}
|
|
7
8
|
@.rcode/references/karpathy-guidelines.md
|
|
8
9
|
</required_reading>
|
|
9
10
|
|
|
@@ -32,6 +33,11 @@ Parse: `phase_dir`, `phase_number`, `phase_name`, `phase_slug`, `padded_phase`.
|
|
|
32
33
|
```bash
|
|
33
34
|
AUDITOR_MODEL=$(node ".rcode/bin/rcode-tools.cjs" resolve-model rcode-nyquist-auditor --raw)
|
|
34
35
|
NYQUIST_CFG=$(node ".rcode/bin/rcode-tools.cjs" config-get workflow.nyquist_validation --raw)
|
|
36
|
+
|
|
37
|
+
# Detect UI signals in phase goal + CONTEXT.md to decide whether to load ui-brand.md (254 lines)
|
|
38
|
+
PHASE_GOAL_HAS_UI=$(grep -iEl "frontend|ui|component|design|style|brand" \
|
|
39
|
+
.planning/phases/*${phase_number}*/*-CONTEXT.md \
|
|
40
|
+
.planning/ROADMAP.md 2>/dev/null | head -1)
|
|
35
41
|
```
|
|
36
42
|
|
|
37
43
|
If `NYQUIST_CFG` is `false`: exit with "Nyquist validation is disabled. Enable via /rcode-settings."
|
|
@@ -63,11 +63,14 @@ export function Sidebar({ activeView, projectName }) {
|
|
|
63
63
|
const name = project.name || projectName || 'No project';
|
|
64
64
|
const user = (project.user && project.user.name) ? project.user : null;
|
|
65
65
|
|
|
66
|
-
// Full store subscription for live health badge counts.
|
|
66
|
+
// Full store subscription for live health badge counts. Derived from
|
|
67
|
+
// activeSessions (the /api/sessions poll) — same source of truth as the
|
|
68
|
+
// OrchPanel footer and NotifyCenter — not the static store.blockers list
|
|
69
|
+
// (PROJECT.md-backed, unrelated to live orchestrator state; see #965).
|
|
67
70
|
// Re-renders on every setState (sessions poll every 4 s, state refresh every 30 s).
|
|
68
|
-
const { activeSessions
|
|
69
|
-
const sessionCount = (activeSessions || []).filter(s => s.status === 'running').length;
|
|
70
|
-
const blockerCount = (
|
|
71
|
+
const { activeSessions } = useStore();
|
|
72
|
+
const sessionCount = (activeSessions || []).filter(s => s.status === 'running' && !s.waiting).length;
|
|
73
|
+
const blockerCount = (activeSessions || []).filter(s => s.status === 'blocked' || s.waiting).length;
|
|
71
74
|
|
|
72
75
|
return html`
|
|
73
76
|
<aside class="sidebar" id="sidebar">
|
|
@@ -93,7 +96,7 @@ export function Sidebar({ activeView, projectName }) {
|
|
|
93
96
|
</span>
|
|
94
97
|
<span
|
|
95
98
|
class=${'health-badge' + (blockerCount > 0 ? ' health-badge--alert' : ' health-badge--zero')}
|
|
96
|
-
title=${blockerCount + '
|
|
99
|
+
title=${blockerCount + ' blocked orchestration session' + (blockerCount === 1 ? '' : 's')}
|
|
97
100
|
>
|
|
98
101
|
<${Icon} name="alert-triangle" size=${12} />
|
|
99
102
|
${blockerCount} blocked
|