@hanzlaa/rcode 4.10.0 → 4.10.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hanzlaa/rcode",
3
- "version": "4.10.0",
3
+ "version": "4.10.1",
4
4
  "description": "rcode — the AI team that never forgets. Persistent memory, specialist agents, and slash commands for AI IDEs. Works in Claude Code, Cursor, Gemini, VS Code, and Antigravity.",
5
5
  "main": "cli/index.js",
6
6
  "bin": {
@@ -19,6 +19,7 @@ color: cyan
19
19
  @.rcode/references/response-style.md
20
20
  @.rcode/references/codebase-grounding.md
21
21
  @.rcode/references/karpathy-guidelines.md
22
+ @.rcode/references/persona-executor-mode.md
22
23
  @.rcode/references/persona-engineer-shared.md
23
24
  @.rcode/skills/agents/haitham-frontend/SKILL.md
24
25
 
@@ -15,4 +15,5 @@ color: green
15
15
  @.rcode/references/agent-shared-rules.md
16
16
  @.rcode/references/codebase-grounding.md
17
17
  @.rcode/references/karpathy-guidelines.md
18
+ @.rcode/references/persona-executor-mode.md
18
19
  @.rcode/skills/agents/hanzla-engineer/SKILL.md
@@ -17,6 +17,7 @@ color: green
17
17
  @.rcode/references/response-style.md
18
18
  @.rcode/references/codebase-grounding.md
19
19
  @.rcode/references/karpathy-guidelines.md
20
+ @.rcode/references/persona-executor-mode.md
20
21
  @.rcode/references/persona-engineer-shared.md
21
22
 
22
23
  # Omar (عمر) — Software Engineer (generalist)
@@ -17,6 +17,7 @@ color: green
17
17
  @.rcode/references/agent-shared-rules.md
18
18
  @.rcode/references/codebase-grounding.md
19
19
  @.rcode/references/karpathy-guidelines.md
20
+ @.rcode/references/persona-executor-mode.md
20
21
  @.rcode/skills/agents/waleed-architect/SKILL.md
21
22
 
22
23
  ## Grounding rule (mandatory)
@@ -18,6 +18,7 @@ color: blue
18
18
  @.rcode/references/response-style.md
19
19
  @.rcode/references/codebase-grounding.md
20
20
  @.rcode/references/karpathy-guidelines.md
21
+ @.rcode/references/persona-executor-mode.md
21
22
  @.rcode/references/persona-engineer-shared.md
22
23
  @.rcode/skills/agents/yousef-backend/SKILL.md
23
24
 
@@ -404,11 +404,21 @@ function normalize(question) {
404
404
  .trim();
405
405
  }
406
406
 
407
+ function escapeRegExp(s) {
408
+ return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
409
+ }
410
+
411
+ function matchesKeyword(text, word) {
412
+ // Word-boundary match, not substring — avoids collisions like
413
+ // "storage" containing "rag" (#1034 follow-up).
414
+ return new RegExp('\\b' + escapeRegExp(word) + '\\b').test(text);
415
+ }
416
+
407
417
  function scoreAgent(agentId, normalizedQuestion) {
408
418
  const keywords = KEYWORDS[agentId] || [];
409
419
  let score = 0;
410
420
  for (const { word, weight } of keywords) {
411
- if (normalizedQuestion.includes(word)) score += weight;
421
+ if (matchesKeyword(normalizedQuestion, word)) score += weight;
412
422
  }
413
423
  const names = AGENT_NAMES[agentId] || [];
414
424
  for (const name of names) {
@@ -419,30 +429,30 @@ function scoreAgent(agentId, normalizedQuestion) {
419
429
  }
420
430
 
421
431
  function applyPriorityBoosts(scores, normalizedQuestion) {
422
- if (SADIQ_TRIGGERS.some((t) => normalizedQuestion.includes(t))) {
432
+ if (SADIQ_TRIGGERS.some((t) => matchesKeyword(normalizedQuestion, t))) {
423
433
  scores.sadiq = (scores.sadiq || 0) + 5;
424
434
  }
425
- if (PM_TRIGGERS.some((t) => normalizedQuestion.includes(t))) {
435
+ if (PM_TRIGGERS.some((t) => matchesKeyword(normalizedQuestion, t))) {
426
436
  scores['hussain-pm'] = (scores['hussain-pm'] || 0) + 3;
427
437
  }
428
- if (MARKET_TRIGGERS.some((t) => normalizedQuestion.includes(t))) {
438
+ if (MARKET_TRIGGERS.some((t) => matchesKeyword(normalizedQuestion, t))) {
429
439
  scores.mariam = (scores.mariam || 0) + 6; // Mariam leads market questions
430
440
  scores['hussain-pm'] = (scores['hussain-pm'] || 0) + 3; // PM follows for scoping
431
441
  }
432
442
  // Domain boosts — lift the right technical expert when signal is clear
433
- if (FE_TRIGGERS.some((t) => normalizedQuestion.includes(t))) {
443
+ if (FE_TRIGGERS.some((t) => matchesKeyword(normalizedQuestion, t))) {
434
444
  scores.haitham = (scores.haitham || 0) + 4;
435
445
  }
436
- if (BE_TRIGGERS.some((t) => normalizedQuestion.includes(t))) {
446
+ if (BE_TRIGGERS.some((t) => matchesKeyword(normalizedQuestion, t))) {
437
447
  scores.yousef = (scores.yousef || 0) + 4;
438
448
  }
439
- if (ML_TRIGGERS.some((t) => normalizedQuestion.includes(t))) {
449
+ if (ML_TRIGGERS.some((t) => matchesKeyword(normalizedQuestion, t))) {
440
450
  scores.zayd = (scores.zayd || 0) + 4;
441
451
  }
442
- if (DEPLOY_TRIGGERS.some((t) => normalizedQuestion.includes(t))) {
452
+ if (DEPLOY_TRIGGERS.some((t) => matchesKeyword(normalizedQuestion, t))) {
443
453
  scores.khalid = (scores.khalid || 0) + 4;
444
454
  }
445
- if (QUALITY_TRIGGERS.some((t) => normalizedQuestion.includes(t))) {
455
+ if (QUALITY_TRIGGERS.some((t) => matchesKeyword(normalizedQuestion, t))) {
446
456
  scores.fatima = (scores.fatima || 0) + 4;
447
457
  }
448
458
  return scores;
@@ -453,16 +463,16 @@ function applyPriorityBoosts(scores, normalizedQuestion) {
453
463
  * Returns: 'fe' | 'be' | 'ml' | 'deploy' | 'quality' | 'market' | 'strategic' | 'general'
454
464
  */
455
465
  function detectDomain(normalizedQuestion, scores) {
456
- const isMarket = MARKET_TRIGGERS.some((t) => normalizedQuestion.includes(t));
466
+ const isMarket = MARKET_TRIGGERS.some((t) => matchesKeyword(normalizedQuestion, t));
457
467
  if (isMarket) return 'market';
458
468
 
459
- const isStrategic = SADIQ_TRIGGERS.some((t) => normalizedQuestion.includes(t));
469
+ const isStrategic = SADIQ_TRIGGERS.some((t) => matchesKeyword(normalizedQuestion, t));
460
470
 
461
- const feTrigger = FE_TRIGGERS.some((t) => normalizedQuestion.includes(t));
462
- const beTrigger = BE_TRIGGERS.some((t) => normalizedQuestion.includes(t));
463
- const mlTrigger = ML_TRIGGERS.some((t) => normalizedQuestion.includes(t));
464
- const deployTrigger = DEPLOY_TRIGGERS.some((t) => normalizedQuestion.includes(t));
465
- const qualityTrigger = QUALITY_TRIGGERS.some((t) => normalizedQuestion.includes(t));
471
+ const feTrigger = FE_TRIGGERS.some((t) => matchesKeyword(normalizedQuestion, t));
472
+ const beTrigger = BE_TRIGGERS.some((t) => matchesKeyword(normalizedQuestion, t));
473
+ const mlTrigger = ML_TRIGGERS.some((t) => matchesKeyword(normalizedQuestion, t));
474
+ const deployTrigger = DEPLOY_TRIGGERS.some((t) => matchesKeyword(normalizedQuestion, t));
475
+ const qualityTrigger = QUALITY_TRIGGERS.some((t) => matchesKeyword(normalizedQuestion, t));
466
476
 
467
477
  // Multiple technical domains present — fall back to top-scoring agent
468
478
  const technicalCount = [feTrigger, beTrigger, mlTrigger, deployTrigger, qualityTrigger].filter(Boolean).length;
@@ -566,12 +576,12 @@ function explainSelection(question, opts = {}) {
566
576
  const panel = selectPanel(question, opts);
567
577
  return {
568
578
  question, normalized, scores, panel, domain,
569
- sadiq_triggered: SADIQ_TRIGGERS.some((t) => normalized.includes(t)),
570
- pm_triggered: PM_TRIGGERS.some((t) => normalized.includes(t)),
571
- fe_triggered: FE_TRIGGERS.some((t) => normalized.includes(t)),
572
- be_triggered: BE_TRIGGERS.some((t) => normalized.includes(t)),
573
- ml_triggered: ML_TRIGGERS.some((t) => normalized.includes(t)),
574
- deploy_triggered: DEPLOY_TRIGGERS.some((t) => normalized.includes(t)),
579
+ sadiq_triggered: SADIQ_TRIGGERS.some((t) => matchesKeyword(normalized, t)),
580
+ pm_triggered: PM_TRIGGERS.some((t) => matchesKeyword(normalized, t)),
581
+ fe_triggered: FE_TRIGGERS.some((t) => matchesKeyword(normalized, t)),
582
+ be_triggered: BE_TRIGGERS.some((t) => matchesKeyword(normalized, t)),
583
+ ml_triggered: ML_TRIGGERS.some((t) => matchesKeyword(normalized, t)),
584
+ deploy_triggered: DEPLOY_TRIGGERS.some((t) => matchesKeyword(normalized, t)),
575
585
  };
576
586
  }
577
587
 
@@ -74,6 +74,7 @@ depends_on: [sprint-id, ...]
74
74
  files_modified: [paths...]
75
75
  autonomous: true | false # false if has checkpoints
76
76
  requirements: [REQ-01, REQ-02] # MUST NOT be empty
77
+ owner: yousef # OPTIONAL — see below
77
78
 
78
79
  must_haves:
79
80
  truths: [...] # Observable outcomes from user perspective
@@ -82,6 +83,8 @@ must_haves:
82
83
  ---
83
84
  ```
84
85
 
86
+ **`owner:` field.** If this plan is grounded in a council session (a `.planning/council-sessions/council-*.md` file is referenced in `<context>` as the authoritative decision), set `owner:` to the id of that session's lead/highest-consensus technical persona for THIS sprint's dominant work — one of `haitham`, `hanzla`, `omar`, `waleed`, `yousef` (the engineer personas with execute permission; `sadiq`/`fatima`/others are advisory-only and never valid here). Pick by domain match: a sprint whose `files_modified` is mostly `src/routes|services|models` → `yousef` (backend); mostly `src/components|pages` → `haitham` (frontend); architecture-level, cross-cutting → `waleed`; general/full-stack with no clear split → `hanzla`. If there was no council session, or the domain split is genuinely ambiguous, omit `owner:` entirely — `execute-sprint.md` defaults to the generic `rcode-executor` when the field is absent. Do not guess an owner just to fill the field; an absent `owner:` is the correct, safe default.
87
+
85
88
  ## Dependency Graph Rules
86
89
 
87
90
  **For each story:**
@@ -170,6 +173,19 @@ requirements: [...]
170
173
  must_haves: {truths, artifacts, key_links}
171
174
  ---
172
175
 
176
+ ## Sprint {phase}.{plan}: {one-line sprint goal, plain English, no jargon}
177
+
178
+ {2-4 sentence plain-English recap: what this sprint builds and why, written for someone who will never open the XML tags below}
179
+
180
+ **Tasks:**
181
+ 1. {task 1 title, plain English — copy the <title> text verbatim, no XML}
182
+ 2. {task 2 title}
183
+ 3. {task N title}
184
+
185
+ _Below this line is the execution prompt the agent reads — task bodies, read-first file lists, verification commands. Not meant for skimming._
186
+
187
+ ---
188
+
173
189
  <objective>...</objective>
174
190
  <execution_context>
175
191
  @.rcode/workflows/execute-sprint.md
@@ -192,6 +208,8 @@ must_haves: {truths, artifacts, key_links}
192
208
  <output>Create `.planning/phases/{phase-dir}/{phase}-{plan}-SUMMARY.md`</output>
193
209
  ```
194
210
 
211
+ **Summary block cost/rule:** the plain-English recap above the `---` divider is 1 title line + 2-4 sentences + a numbered list of task titles you're already writing for each `<title>` tag — copy, don't re-derive. Do not summarize `<action>` bodies, do not restate `<verify>` commands, do not add anything not already stated elsewhere in the file. If a sprint has more than ~10 tasks, list only the first 8 titles plus `...and N more (see tasks below)` rather than growing the summary unboundedly.
212
+
195
213
  ## Common Planning Mistakes to Avoid
196
214
 
197
215
  1. **Empty requirements:** Every plan MUST list requirement IDs from ROADMAP. No empty requirements field.
@@ -274,7 +274,18 @@ Selected: {panel agents}
274
274
  Excluded (0 score): {agents with score=0, comma-separated}
275
275
  ```
276
276
 
277
- **If `config.mode === 'guided'`:** confirm with the user:
277
+ **Inline yolo override (checked before `config.mode`):** council can be invoked directly by a user OR dispatched by `/rcode-do` after it already detected yolo intent (literal `--auto` flag, persisted `config.mode: yolo`, or natural-language phrasing like "yolo mode" / "autonomous mode" / "without pausing" — see `do.md`'s `parse_args` step). Check `$ARGUMENTS` for the same signal here, since council can run standalone and never pass through `do.md`:
278
+
279
+ ```bash
280
+ INLINE_YOLO=false
281
+ if echo "$ARGUMENTS" | grep -qiE '(--auto\b|\byolo\b|\bautonomous(ly)? mode\b|\bno pauses?\b|\bwithout (asking|stopping|pausing)\b)'; then
282
+ INLINE_YOLO=true
283
+ fi
284
+ ```
285
+
286
+ **If `INLINE_YOLO=true` OR `config.mode === 'yolo'`:** print the panel one-liner and proceed without confirmation.
287
+
288
+ **Else (`config.mode === 'guided'` and no inline signal):** confirm with the user:
278
289
 
279
290
  ```
280
291
  Panel for this question: <comma-separated display names>
@@ -283,8 +294,6 @@ Proceed? [Y/n]
283
294
 
284
295
  Use the AskUserQuestion tool (not raw stdin) for the confirmation.
285
296
 
286
- **If `config.mode === 'yolo'`:** print the panel one-liner and proceed without confirmation.
287
-
288
297
  ## Step 4 — Spawn the panel in parallel (two rounds)
289
298
 
290
299
  ### Round 1 — Independent perspectives
@@ -619,5 +628,12 @@ node .rcode/bin/rcode-tools.cjs state record-session
619
628
 
620
629
  ## Next Up
621
630
 
622
- - `/rcode-plan` — plan implementation based on the council's recommendation
631
+ Check `project-status` before suggesting `/rcode-plan`:
632
+
633
+ ```bash
634
+ PROJECT_STATUS=$(node .rcode/bin/rcode-tools.cjs project-status 2>/dev/null || echo uninitialized)
635
+ ```
636
+
637
+ - If `PROJECT_STATUS` is `real` (a phase already exists): `/rcode-plan {phase-number}` — plan implementation based on the council's recommendation
638
+ - Otherwise (`uninstalled`/`uninitialized`/`stub`, no phase exists yet): `/rcode-add-phase` — create a phase for this work first, then `/rcode-plan` will work
623
639
  - `/rcode-decisions` — review decisions the council produced
@@ -28,6 +28,12 @@ if [[ "$ARGUMENTS" == *"--auto"* ]]; then
28
28
  AUTO_MODE=true
29
29
  QUESTION=$(echo "$ARGUMENTS" | sed 's/--auto[[:space:]]*//' | xargs)
30
30
  fi
31
+ # Natural-language yolo intent — users say "on yolo mode" / "yolo mode" /
32
+ # "in autonomous mode" in free text far more often than they type --auto.
33
+ # Detect it the same way as the literal flag (#1034/#1035 follow-up).
34
+ if echo "$ARGUMENTS" | grep -qiE '(\byolo\b|\bautonomous(ly)? mode\b|\bno pauses?\b|\bwithout (asking|stopping|pausing)\b)'; then
35
+ AUTO_MODE=true
36
+ fi
31
37
  # Also auto-dispatch in yolo mode
32
38
  CONFIG_MODE=$(node .rcode/bin/rcode-tools.cjs config-get mode 2>/dev/null || echo "guided")
33
39
  if [[ "$CONFIG_MODE" == "yolo" ]]; then
@@ -143,6 +149,45 @@ LAST_SHIPPED_VERSION=$(grep -m1 -oE 'v[0-9]+\.[0-9]+' .planning/MILESTONES.md 2>
143
149
  These flags drive the greenfield guard AND the explicit_intent_check below. `.planning/` existing alone is not enough — we need to know whether the methodology chain has actually run (PRD → milestone → epics → phases) AND which milestone is currently open.
144
150
  </step>
145
151
 
152
+ <step name="compound_chain_preflight" priority="first-match">
153
+ **Detect compound/chained requests and preflight the whole chain before dispatching step one.**
154
+
155
+ `/rcode-do` is a single-dispatch router by design — it normally picks ONE command and hands off. But real input often chains several actions in one sentence (e.g. "scan and init my project & get council decision on X and plan and execute on yolo mode"). If the router just dispatches to the first-matched command and lets each downstream skill discover its own missing prerequisites, the user sees red errors scattered mid-flight instead of one clear picture up front (issue #1034/#1035).
156
+
157
+ **Detection:** `$QUESTION` matches this step if it contains 2+ pipeline-stage signals joined by `and`/`&`/`then`/`,`. Pipeline-stage signals: `scan`/`map`, `init`, `council`/`decide`/`architect`, `plan`, `execute`/`build`/`implement`/`yolo`.
158
+
159
+ **If detected, run one consolidated readiness check before dispatching anything:**
160
+
161
+ ```bash
162
+ PROJECT_STATUS=$(node .rcode/bin/rcode-tools.cjs project-status 2>/dev/null || echo uninitialized)
163
+ ```
164
+
165
+ Using `$PROJECT_STATUS`, `$HAS_PRD`, `$HAS_PHASES` (already computed in `check_project`), and any `--agents=` list the user named, build the ordered stage list implied by the request and check each stage's precondition against state already on hand — do not re-derive it per stage, and do not spawn anything yet:
166
+
167
+ | Stage (if requested) | Precondition | If unmet |
168
+ |---|---|---|
169
+ | scan/map | none | always runnable |
170
+ | init | none — auto-init guard already ran | always runnable |
171
+ | council | none, BUT if the user passed an explicit `--agents=` list, validate every id against the roster now: `sadiq, hussain-pm, waleed, ahmed-hassani, nasser, layla, zahra, haitham, yousef, zayd, fatima, khalid, mariam, noor` | flag unknown ids and show the valid list in the preflight report — do not let council fail on this mid-run |
172
+ | plan | a phase must exist (`$PROJECT_STATUS == real` OR `$HAS_PHASES == true`) after council — since council alone does not create a phase | note that `/rcode-add-phase` will run between council and plan to create one |
173
+ | execute | a plan (SPRINT.md) must exist for the phase — this is always true after a successful plan stage in the same chain | n/a within a single chain |
174
+
175
+ Print one consolidated block before touching any subagent:
176
+
177
+ ```
178
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
179
+ rcode ► CHAIN PREFLIGHT
180
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
181
+ Detected stages: {ordered list, e.g. scan → init → council → add-phase → plan → execute}
182
+ {✓ or ⚠ per stage, with the one-line reason for any ⚠}
183
+ {if --agents had unknown ids: "⚠ Unknown agent id(s): {ids}. Valid: {roster list}. Continuing with the corrected/auto-selected panel."}
184
+ ```
185
+
186
+ Then dispatch the stages in order via the `Skill` tool, one at a time, re-using this preflight's state instead of letting each stage rediscover it. If a stage's precondition is genuinely unmet and nothing in the chain fixes it (e.g. user asked to `plan` but not `council`/`add-phase` and no phase exists), stop before dispatching that stage and tell the user which single command to run first — do not let it fail loudly mid-chain.
187
+
188
+ This step does not replace `greenfield_guard` or `explicit_intent_check` below — it only applies when a *chain* is detected. Single-verb requests fall through to those steps as before.
189
+ </step>
190
+
146
191
  <step name="greenfield_guard" priority="first-match">
147
192
  **Block methodology inversion.**
148
193
 
@@ -12,9 +12,28 @@ Read config.yaml for planning behavior settings.
12
12
 
13
13
  <available_agent_types>
14
14
  Valid rcode subagent types (use exact names — do not fall back to 'general-purpose'):
15
- - rcode-executor — Executes plan tasks, commits, creates SUMMARY.md
15
+ - rcode-executor — Executes plan tasks, commits, creates SUMMARY.md (default)
16
+ - rcode-haitham / rcode-hanzla / rcode-omar / rcode-waleed / rcode-yousef — same execution contract as rcode-executor (via `@.rcode/references/persona-executor-mode.md`), used ONLY when `owner:` in SPRINT.md frontmatter names one of them (see `owner_agent_resolution` below)
16
17
  </available_agent_types>
17
18
 
19
+ <step name="owner_agent_resolution">
20
+ **Resolve which agent actually executes this plan.**
21
+
22
+ Read the `owner:` field from the SPRINT.md frontmatter (set by `/rcode-plan` from the council decision's lead persona, when one exists — see `plan.md`'s `owner_field` step). This is a plain frontmatter read, not a new tool call.
23
+
24
+ ```bash
25
+ SPRINT_OWNER=$(grep -m1 '^owner:' .planning/phases/XX-name/{phase}-{plan}-SPRINT.md 2>/dev/null | sed 's/^owner:[[:space:]]*//' | tr -d '"' | xargs)
26
+ VALID_OWNERS="haitham hanzla omar waleed yousef"
27
+ if [[ -n "$SPRINT_OWNER" ]] && echo "$VALID_OWNERS" | grep -qw "$SPRINT_OWNER"; then
28
+ EXEC_AGENT="rcode-${SPRINT_OWNER}"
29
+ else
30
+ EXEC_AGENT="rcode-executor"
31
+ fi
32
+ ```
33
+
34
+ Use `$EXEC_AGENT` as the `subagent_type` in every Task spawn below (Pattern A, Pattern B subagent route). No other change to the spawn prompt is needed — the persona file's own conditional clause tells it to load the full executor playbook when it sees `subagent_type` = itself and a SPRINT.md path in the prompt. If `$EXEC_AGENT` is a persona and that persona is not installed (agent file missing), fall back to `rcode-executor` and note the fallback in SUMMARY.md's Deviations section — do not fail the sprint over this.
35
+ </step>
36
+
18
37
  <process>
19
38
 
20
39
  <preflight name="dependency_check">
@@ -122,9 +141,9 @@ grep -n "type=\"checkpoint" .planning/phases/XX-name/{phase}-{plan}-SPRINT.md
122
141
  | Verify-only | B (segmented) | Segments between checkpoints. After none/human-verify → SUBAGENT. After decision/human-action → MAIN |
123
142
  | Decision | C (main) | Execute entirely in main context |
124
143
 
125
- **Pattern A:** init_agent_tracking → capture `EXPECTED_BASE=$(git rev-parse HEAD)` → spawn Task(subagent_type="rcode-executor", model=executor_model) with prompt: execute plan at [path], autonomous, all tasks + SUMMARY + commit, follow deviation/auth rules, report: plan name, tasks, SUMMARY path, commit hash → track agent_id → wait → update tracking → report. **Include `isolation="worktree"` only if `workflow.use_worktrees` is not `false`** (read via `config-get workflow.use_worktrees`). **When using `isolation="worktree"`, include a `<worktree_branch_check>` block in the prompt** instructing the executor to run `git merge-base HEAD {EXPECTED_BASE}` and, if the result differs from `{EXPECTED_BASE}`, reset the branch base with `git reset --soft {EXPECTED_BASE}` before starting work. This corrects a known issue on Windows where `EnterWorktree` creates branches from `main` instead of the feature branch HEAD.
144
+ **Pattern A:** init_agent_tracking → capture `EXPECTED_BASE=$(git rev-parse HEAD)` → run `owner_agent_resolution` to get `$EXEC_AGENT` → spawn Task(subagent_type="$EXEC_AGENT", model=executor_model) with prompt: execute plan at [path], autonomous, all tasks + SUMMARY + commit, follow deviation/auth rules, report: plan name, tasks, SUMMARY path, commit hash → track agent_id → wait → update tracking → report. **Include `isolation="worktree"` only if `workflow.use_worktrees` is not `false`** (read via `config-get workflow.use_worktrees`). **When using `isolation="worktree"`, include a `<worktree_branch_check>` block in the prompt** instructing the executor to run `git merge-base HEAD {EXPECTED_BASE}` and, if the result differs from `{EXPECTED_BASE}`, reset the branch base with `git reset --soft {EXPECTED_BASE}` before starting work. This corrects a known issue on Windows where `EnterWorktree` creates branches from `main` instead of the feature branch HEAD.
126
145
 
127
- **Post-install namespace fallback:** If `Task(subagent_type="rcode-executor")` fails with "Agent type not found", the runtime has not yet registered the agent (requires IDE reload after install). Retry with `subagent_type="rihal-executor"`. If that also fails, fall back to Pattern C (execute in main context) and log `[execute-sprint] rcode-executor not available — reload IDE or executing in main context`.
146
+ **Post-install namespace fallback:** If `Task(subagent_type="$EXEC_AGENT")` fails with "Agent type not found": if `$EXEC_AGENT` was a persona (not `rcode-executor`), retry once with `subagent_type="rcode-executor"` (the persona may not be installed in this project) and note the fallback in SUMMARY.md. If `rcode-executor` itself fails "Agent type not found", the runtime has not yet registered the agent (requires IDE reload after install) retry with `subagent_type="rihal-executor"`. If that also fails, fall back to Pattern C (execute in main context) and log `[execute-sprint] ${EXEC_AGENT} not available — reload IDE or executing in main context`.
128
147
 
129
148
  **Pattern B:** Execute segment-by-segment. Autonomous segments: spawn subagent for assigned tasks only (no SUMMARY/commit). Checkpoints: main context. After all segments: aggregate, create SUMMARY, commit. See segment_execution.
130
149
 
@@ -52,13 +52,20 @@ End with closure banner + top findings summary:
52
52
  If `$ARGUMENTS` is empty or contains only `--help` or `-h`:
53
53
 
54
54
  ```
55
- /rcode-map-codebase <argument-here>
55
+ /rcode-map-codebase <a short description of the codebase or why you're mapping it>
56
56
  ```
57
57
 
58
- **Examples:**
58
+ The description isn't used to scope or filter what gets mapped — all 4 mapper
59
+ agents (tech, architecture, conventions, concerns) always cover the whole
60
+ codebase regardless of what you write here. It exists as an intentional
61
+ non-empty confirmation, not a topic filter — `/rcode-scan --focus <topic>` is
62
+ the command for a narrower, single-topic pass.
63
+
64
+ **Examples (any of these work identically — the text just needs to be non-empty):**
59
65
  ```
60
- /rcode-map-codebase example 1
61
- /rcode-map-codebase example 2
66
+ /rcode-map-codebase full codebase
67
+ /rcode-map-codebase onboarding a new engineer, need the full picture
68
+ /rcode-map-codebase before a major refactor
62
69
  ```
63
70
 
64
71
  STOP — do not proceed.
@@ -81,7 +81,7 @@ PROJECT_STATUS=$(node .rcode/bin/rcode-tools.cjs project-status 2>/dev/null || e
81
81
  If `PROJECT_STATUS` is `uninstalled`, `uninitialized`, or `stub`:
82
82
 
83
83
  ```
84
- Project not initialized. Run /rcode-init first (or /rcode-new-project for a greenfield project), then return here.
84
+ Project not initialized for planning. Run /rcode-new-project (full roadmap) or /rcode-add-phase (if you just want to add one phase), then return here.
85
85
  ```
86
86
 
87
87
  Stop. Do not proceed until `project-status` returns `real`.