@hanzlaa/rcode 4.7.2 → 4.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/AGENTS.md +1 -1
  2. package/CLAUDE.md +1 -1
  3. package/CONTRIBUTING.md +4 -0
  4. package/cli/github-sync.js +17 -201
  5. package/cli/lib/config.cjs +1 -1
  6. package/cli/lib/github-sync-discover.cjs +304 -0
  7. package/cli/lib/namespace-migrate.cjs +16 -1
  8. package/cli/uninstall.js +7 -2
  9. package/dist/rcode.js +194 -194
  10. package/package.json +1 -1
  11. package/rcode/agents/rcode-haitham.md +1 -1
  12. package/rcode/agents/rcode-hanzla.md +1 -1
  13. package/rcode/agents/rcode-hussain-pm.md +1 -1
  14. package/rcode/agents/rcode-nyquist-auditor.md +1 -1
  15. package/rcode/agents/rcode-omar.md +1 -1
  16. package/rcode/agents/rcode-remediation-planner.md +1 -1
  17. package/rcode/agents/rcode-waleed.md +1 -1
  18. package/rcode/agents/rcode-yousef.md +1 -1
  19. package/rcode/agents/rules/planner/task-templates.md +24 -22
  20. package/rcode/agents/rules/verifier/verification-report.md +2 -2
  21. package/rcode/bin/lib/roadmap.cjs +80 -4
  22. package/rcode/bin/rcode-tools.cjs +18 -1
  23. package/rcode/brain/best-practices/state-sync-rule.md +1 -1
  24. package/rcode/references/council-protocol.md +9 -4
  25. package/rcode/references/execute-auto-copy-learnings.md +15 -0
  26. package/rcode/references/execute-close-parent-artifacts.md +49 -0
  27. package/rcode/references/execute-interactive-mode.md +44 -0
  28. package/rcode/references/execute-notify-webhooks.md +22 -0
  29. package/rcode/references/execution-protocol.md +11 -11
  30. package/rcode/references/git-preflight.md +2 -2
  31. package/rcode/references/plan-gaps-mode.md +89 -0
  32. package/rcode/references/plan-thinking-partner.md +20 -0
  33. package/rcode/references/plan-windows-troubleshooting.md +25 -0
  34. package/rcode/references/planner-playbook.md +23 -29
  35. package/rcode/skills/_shared/state-sync-rule.md +1 -1
  36. package/rcode/skills/actions/1-analysis/rcode-document-project/SKILL.md +2 -0
  37. package/rcode/skills/actions/1-analysis/rcode-prfaq/SKILL.md +2 -0
  38. package/rcode/skills/actions/2-plan/rcode-create-epics-and-stories/SKILL.md +11 -0
  39. package/rcode/skills/actions/2-plan/rcode-create-prd/SKILL.md +2 -0
  40. package/rcode/skills/actions/2-plan/rcode-create-story/SKILL.md +11 -0
  41. package/rcode/skills/actions/2-plan/rcode-edit-prd/SKILL.md +2 -0
  42. package/rcode/skills/actions/2-plan/rcode-validate-prd/SKILL.md +2 -0
  43. package/rcode/skills/actions/3-solutioning/rcode-check-implementation-readiness/SKILL.md +2 -0
  44. package/rcode/skills/actions/3-solutioning/rcode-create-architecture/SKILL.md +2 -0
  45. package/rcode/skills/actions/4-implementation/rcode-checkpoint-preview/SKILL.md +2 -0
  46. package/rcode/skills/actions/4-implementation/rcode-code-review/SKILL.md +2 -0
  47. package/rcode/skills/actions/4-implementation/rcode-correct-course/SKILL.md +2 -0
  48. package/rcode/skills/actions/4-implementation/rcode-debug/SKILL.md +1 -1
  49. package/rcode/skills/actions/4-implementation/rcode-dev-story/SKILL.md +2 -0
  50. package/rcode/skills/actions/4-implementation/rcode-retrospective/SKILL.md +2 -0
  51. package/rcode/skills/actions/4-implementation/rcode-scaffold-project/SKILL.md +2 -0
  52. package/rcode/skills/actions/4-implementation/rcode-sprint-planning/SKILL.md +3 -2
  53. package/rcode/skills/actions/4-implementation/rcode-sprint-status/SKILL.md +2 -0
  54. package/rcode/skills/agents/haitham-frontend/SKILL.md +6 -0
  55. package/rcode/skills/agents/hanzla-engineer/SKILL.md +6 -0
  56. package/rcode/skills/agents/hussain-pm/SKILL.md +1 -1
  57. package/rcode/skills/agents/hussain-sm/SKILL.md +3 -3
  58. package/rcode/skills/agents/majlis-council/references.md +17 -7
  59. package/rcode/skills/agents/raees-orchestrator/SKILL.md +13 -11
  60. package/rcode/skills/agents/yousef-backend/SKILL.md +6 -0
  61. package/rcode/templates/github/epic-template.md +1 -1
  62. package/rcode/templates/github/feature-template.md +1 -1
  63. package/rcode/templates/github/task-template.md +1 -1
  64. package/rcode/templates/sprint.md +14 -3
  65. package/rcode/templates/verification-report.md +7 -4
  66. package/rcode/workflows/code-review-fix.md +5 -5
  67. package/rcode/workflows/code-review.md +1 -1
  68. package/rcode/workflows/council.md +1 -0
  69. package/rcode/workflows/create-epics-and-stories.md +12 -6
  70. package/rcode/workflows/dev-story.md +12 -14
  71. package/rcode/workflows/do.md +12 -9
  72. package/rcode/workflows/execute-sprint.md +4 -0
  73. package/rcode/workflows/execute-waves.md +44 -1
  74. package/rcode/workflows/execute.md +20 -119
  75. package/rcode/workflows/lens-audit.md +7 -7
  76. package/rcode/workflows/plan-spawn-planner.md +0 -1
  77. package/rcode/workflows/plan.md +25 -136
  78. package/rcode/workflows/quick.md +1 -1
  79. package/rcode/workflows/sprint-planning.md +14 -37
  80. package/server/lib/html/client/components/shared.js +21 -1
  81. package/server/lib/html/client/views/SprintsView.js +3 -3
  82. package/server/lib/scanner.js +7 -4
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hanzlaa/rcode",
3
- "version": "4.7.2",
3
+ "version": "4.8.0",
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": {
@@ -12,7 +12,7 @@ description: |
12
12
  typography / colour system (use Zahra), architecture decisions (use Waleed),
13
13
  backend / API (use Yousef), test strategy (use Fatima), strategic priority
14
14
  (use Sadiq).
15
- tools: Read, Grep, Glob, Bash, WebFetch
15
+ tools: Read, Grep, Glob, Bash, WebFetch, Write, Edit
16
16
  color: cyan
17
17
  ---
18
18
 
@@ -8,7 +8,7 @@ description: |
8
8
  Do NOT use for: architecture (Waleed), backend perf / queues (Yousef),
9
9
  frontend / RTL / a11y (Haitham), UX flows (Layla), test strategy (Fatima),
10
10
  deployment / CI (Khalid), scope (Hussain-PM).
11
- tools: Read, Grep, Glob, Bash
11
+ tools: Read, Grep, Glob, Bash, Write, Edit
12
12
  color: green
13
13
  ---
14
14
 
@@ -9,7 +9,7 @@ description: |
9
9
  Do NOT use for: technical feasibility (Waleed), implementation (Hanzla /
10
10
  Yousef / Haitham), market positioning (Mariam), strategic go/no-go and
11
11
  kill criteria (Sadiq), QA test strategy (Fatima), sprint scrum ops (Hussain-SM).
12
- tools: Read, Grep, Glob, WebFetch
12
+ tools: Read, Grep, Glob, WebFetch, Write, Edit
13
13
  color: orange
14
14
  ---
15
15
 
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: rcode-nyquist-auditor
3
3
  description: Fills Nyquist validation gaps by generating tests and verifying coverage for phase requirements
4
- tools: Read, Grep, Glob, Bash
4
+ tools: Read, Grep, Glob, Bash, Write, Edit
5
5
  color: purple
6
6
  ---
7
7
 
@@ -10,7 +10,7 @@ description: |
10
10
  deep frontend (use Haitham), deep backend perf (use Yousef), test strategy
11
11
  (use Fatima), scope / PRD (use Hussain-PM), strategic priority (use Sadiq),
12
12
  ML / RAG / embeddings (use Zayd), DevOps / deployment (use Khalid).
13
- tools: Read, Grep, Glob, Bash
13
+ tools: Read, Grep, Glob, Bash, Write, Edit
14
14
  color: green
15
15
  ---
16
16
 
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: rcode-remediation-planner
3
3
  description: Remediation Planner — spawned to plan remediation for issues, blockers, and failures. Creates action plans to recover from deviations, resolve blockers, and get back on track.
4
- tools: Read, Grep, Glob, Bash, Edit
4
+ tools: Read, Grep, Glob, Bash
5
5
  color: orange
6
6
  ---
7
7
 
@@ -10,7 +10,7 @@ description: |
10
10
  Do NOT use for: strategy / "should we build" (Sadiq), backend impl (Yousef),
11
11
  scope / PRD (Hussain-PM), test strategy (Fatima), market / GTM (Mariam),
12
12
  org-level multi-team coordination (Ahmed-Hassani-Director).
13
- tools: Read, Grep, Glob, Bash, WebFetch, WebSearch
13
+ tools: Read, Grep, Glob, Bash, WebFetch, WebSearch, Write, Edit
14
14
  color: green
15
15
  ---
16
16
 
@@ -11,7 +11,7 @@ description: |
11
11
  (use Haitham), test methodology (use Fatima), strategic priority (use Sadiq),
12
12
  scope / PRD (use Hussain-PM), implementation across the full stack
13
13
  (use Hanzla / Omar), deployment / CI (use Khalid).
14
- tools: Read, Grep, Glob, Bash, WebFetch
14
+ tools: Read, Grep, Glob, Bash, WebFetch, Write, Edit
15
15
  color: blue
16
16
  ---
17
17
 
@@ -1,10 +1,12 @@
1
1
  # rcode Planner: Task Templates by Type
2
2
 
3
+ <!-- id= and <title> are REQUIRED across every template below — this is what server/lib/scanner.js's buildPhaseTree actually parses. Do not use a `name` child tag or a bare title attribute; both are legacy/unsupported paths. -->
4
+
3
5
  ## Standard Task Template
4
6
 
5
7
  ```xml
6
- <task type="auto">
7
- <name>Task: [Action-oriented name]</name>
8
+ <task id="{sprint-id}.{NN}" type="auto">
9
+ <title>Task: [Action-oriented name]</title>
8
10
  <files>path/to/file.ext, path/to/another.ts</files>
9
11
  <action>[Specific implementation with what to avoid and WHY]</action>
10
12
  <verify>
@@ -21,8 +23,8 @@
21
23
  Use when you can write `expect(fn(input)).toBe(output)` before implementing.
22
24
 
23
25
  ```xml
24
- <task type="auto" tdd="true">
25
- <name>Task: [name]</name>
26
+ <task id="{sprint-id}.{NN}" type="auto" tdd="true">
27
+ <title>Task: [name]</title>
26
28
  <files>src/feature.ts, src/feature.test.ts</files>
27
29
  <behavior>
28
30
  - Test 1: [expected behavior]
@@ -44,8 +46,8 @@ Use when you can write `expect(fn(input)).toBe(output)` before implementing.
44
46
  Use for visual/functional verification (90% of checkpoints).
45
47
 
46
48
  ```xml
47
- <task type="checkpoint:human-verify" gate="blocking">
48
- <name>Verify: [Feature name works]</name>
49
+ <task id="{sprint-id}.{NN}" type="checkpoint:human-verify" gate="blocking">
50
+ <title>Verify: [Feature name works]</title>
49
51
  <what-built>[What the agent automated]</what-built>
50
52
  <how-to-verify>
51
53
  1. Navigate to http://localhost:3000/login
@@ -65,8 +67,8 @@ Use for visual/functional verification (90% of checkpoints).
65
67
  Use for implementation choices (9% of checkpoints).
66
68
 
67
69
  ```xml
68
- <task type="checkpoint:decision" gate="blocking">
69
- <name>Decide: Database schema for messages</name>
70
+ <task id="{sprint-id}.{NN}" type="checkpoint:decision" gate="blocking">
71
+ <title>Decide: Database schema for messages</title>
70
72
  <what-youre-deciding>
71
73
  Where to store user-to-message relationships:
72
74
 
@@ -94,8 +96,8 @@ Use for implementation choices (9% of checkpoints).
94
96
  Use for unavoidable manual steps (1% of checkpoints).
95
97
 
96
98
  ```xml
97
- <task type="checkpoint:human-action" gate="blocking">
98
- <name>Set up Stripe API key</name>
99
+ <task id="{sprint-id}.{NN}" type="checkpoint:human-action" gate="blocking">
100
+ <title>Set up Stripe API key</title>
99
101
  <what-needed>
100
102
  The next task implements Stripe payment processing, which requires your API key.
101
103
  </what-needed>
@@ -115,8 +117,8 @@ Use for unavoidable manual steps (1% of checkpoints).
115
117
  ## Database Migration Task Template
116
118
 
117
119
  ```xml
118
- <task type="auto">
119
- <name>Task: Add role field to users table</name>
120
+ <task id="{sprint-id}.{NN}" type="auto">
121
+ <title>Task: Add role field to users table</title>
120
122
  <files>prisma/schema.prisma, prisma/migrations/[timestamp]_add_role.sql</files>
121
123
  <action>
122
124
  1. Update User model in schema: add `role String @default("user")`
@@ -136,8 +138,8 @@ Use for unavoidable manual steps (1% of checkpoints).
136
138
  ## API Endpoint Task Template
137
139
 
138
140
  ```xml
139
- <task type="auto">
140
- <name>Task: Implement POST /api/users endpoint</name>
141
+ <task id="{sprint-id}.{NN}" type="auto">
142
+ <title>Task: Implement POST /api/users endpoint</title>
141
143
  <files>src/app/api/users/route.ts, src/types/user.ts</files>
142
144
  <action>
143
145
  Create POST endpoint accepting { email, password, name }:
@@ -167,8 +169,8 @@ Use for unavoidable manual steps (1% of checkpoints).
167
169
  ## UI Component Task Template
168
170
 
169
171
  ```xml
170
- <task type="auto">
171
- <name>Task: Create LoginForm component</name>
172
+ <task id="{sprint-id}.{NN}" type="auto">
173
+ <title>Task: Create LoginForm component</title>
172
174
  <files>src/components/LoginForm.tsx, src/components/LoginForm.test.tsx</files>
173
175
  <action>
174
176
  Create form component with:
@@ -195,8 +197,8 @@ Use for unavoidable manual steps (1% of checkpoints).
195
197
  ## Configuration Task Template
196
198
 
197
199
  ```xml
198
- <task type="auto">
199
- <name>Task: Configure environment variables</name>
200
+ <task id="{sprint-id}.{NN}" type="auto">
201
+ <title>Task: Configure environment variables</title>
200
202
  <files>.env.example, .env.local (local only)</files>
201
203
  <action>
202
204
  1. Create .env.example with template (no real values):
@@ -219,8 +221,8 @@ Use for unavoidable manual steps (1% of checkpoints).
219
221
  ## Documentation Task Template
220
222
 
221
223
  ```xml
222
- <task type="auto">
223
- <name>Task: Document authentication flow</name>
224
+ <task id="{sprint-id}.{NN}" type="auto">
225
+ <title>Task: Document authentication flow</title>
224
226
  <files>docs/AUTHENTICATION.md</files>
225
227
  <action>
226
228
  Document in docs/AUTHENTICATION.md:
@@ -242,8 +244,8 @@ Use for unavoidable manual steps (1% of checkpoints).
242
244
  ## Refactoring Task Template
243
245
 
244
246
  ```xml
245
- <task type="auto">
246
- <name>Task: Extract auth validation to utility</name>
247
+ <task id="{sprint-id}.{NN}" type="auto">
248
+ <title>Task: Extract auth validation to utility</title>
247
249
  <files>src/lib/auth-validation.ts, src/api/auth/login/route.ts</files>
248
250
  <action>
249
251
  1. Create src/lib/auth-validation.ts with functions:
@@ -4,7 +4,7 @@
4
4
 
5
5
  **ALWAYS use the Write tool to create files** — never use `Bash(cat << 'EOF')` or heredoc commands for file creation.
6
6
 
7
- Create `.rcode/phases/{phase_dir}/{phase_num}-VERIFICATION.md`:
7
+ Create `.planning/phases/{phase_dir}/{phase_num}-VERIFICATION.md`:
8
8
 
9
9
  ```markdown
10
10
  ---
@@ -108,7 +108,7 @@ Return with:
108
108
 
109
109
  **Status:** {passed | gaps_found | human_needed}
110
110
  **Score:** {N}/{M} must-haves verified
111
- **Report:** .rcode/phases/{phase_dir}/{phase_num}-VERIFICATION.md
111
+ **Report:** .planning/phases/{phase_dir}/{phase_num}-VERIFICATION.md
112
112
 
113
113
  {If passed:}
114
114
  All must-haves verified. Phase goal achieved. Ready to proceed.
@@ -326,7 +326,12 @@ function cmdUpdatePlanProgress(projectRoot, phaseNum, planId, status) {
326
326
  if (!phaseNum) {
327
327
  throw new Error('Usage: roadmap update-plan-progress <phase> [<plan-id> <status>]');
328
328
  }
329
- // 1-arg form: auto-detect progress from disk
329
+ // 1-arg form: auto-detect progress from disk and persist it into the
330
+ // phase's **Status:**/**Plans:** prose block in ROADMAP.md.
331
+ // Fix #1013: this branch used to only *compute* status from disk and
332
+ // return it — it never read/wrote ROADMAP.md at all, so it always
333
+ // reported `updated: false` even when the computed status genuinely
334
+ // differed from the stale prose already in the file.
330
335
  if (!planId && !status) {
331
336
  const planningDir = path.join(projectRoot, '.planning', 'phases');
332
337
  let phaseDir = null;
@@ -344,12 +349,83 @@ function cmdUpdatePlanProgress(projectRoot, phaseNum, planId, status) {
344
349
  const planFiles = files.filter(f => /(?:^|-)(SPRINT|PLAN)\.md$/i.test(f));
345
350
  const summaryFiles = files.filter(f => /(?:^|-)SUMMARY\.md$/i.test(f));
346
351
  const allDone = planFiles.length > 0 && summaryFiles.length >= planFiles.length;
352
+ const computedStatus = allDone ? 'complete' : 'in_progress';
353
+ const note = `phase ${phaseNum}: ${planFiles.length} plan(s), ${summaryFiles.length} summary(s) — ${allDone ? 'complete' : 'in progress'}`;
354
+
355
+ const { path: rp } = resolveRoadmapPath(projectRoot);
356
+ if (!fs.existsSync(rp)) {
357
+ return { updated: false, note, plan_count: planFiles.length, summary_count: summaryFiles.length, status: computedStatus, error: 'ROADMAP.md not found' };
358
+ }
359
+ const content = fs.readFileSync(rp, 'utf8');
360
+ const phases = extractPhases(content);
361
+ const phase = phases.find((p) => normalizePhaseNum(p.number) === normalizePhaseNum(phaseNum));
362
+ if (!phase) {
363
+ return { updated: false, note, plan_count: planFiles.length, summary_count: summaryFiles.length, status: computedStatus, error: `phase ${phaseNum} not found in ROADMAP.md` };
364
+ }
365
+
366
+ const planIdRe = /^(\d+[A-Z]?(?:\.\d+)?-\d+)-(?:SPRINT|PLAN)\.md$/i;
367
+ const summaryIdRe = /^(\d+[A-Z]?(?:\.\d+)?-\d+)-SUMMARY\.md$/i;
368
+ const summarizedIds = new Set(
369
+ summaryFiles.map((f) => { const m = f.match(summaryIdRe); return m ? m[1] : null; }).filter(Boolean)
370
+ );
371
+ const planIds = [...new Set(
372
+ planFiles.map((f) => { const m = f.match(planIdRe); return m ? m[1] : null; }).filter(Boolean)
373
+ )].sort();
374
+
375
+ const section = content.slice(phase.headerIndex, phase.sectionEnd);
376
+ let newSection = section;
377
+ let changed = false;
378
+
379
+ // Update **Status:** — only when the computed status actually differs
380
+ // from what the prose says, so re-running this after completion is a
381
+ // no-op instead of rewriting the completion date every time.
382
+ const statusLineRe = /(\*\*Status(?::\*\*|\*\*:)\s*)([^\n]+)/i;
383
+ const statusMatch = section.match(statusLineRe);
384
+ if (statusMatch) {
385
+ const currentStatusNorm = statusMatch[2].trim().toLowerCase();
386
+ if (computedStatus === 'complete' && !currentStatusNorm.startsWith('complete')) {
387
+ const today = new Date().toISOString().slice(0, 10);
388
+ newSection = newSection.replace(statusLineRe, `$1Complete (${today})`);
389
+ changed = true;
390
+ } else if (computedStatus === 'in_progress' && currentStatusNorm.startsWith('planned')) {
391
+ newSection = newSection.replace(statusLineRe, `$1In Progress`);
392
+ changed = true;
393
+ }
394
+ }
395
+
396
+ // Replace a placeholder **Plans:** list (`- _TBD_` or empty) with the
397
+ // plan IDs actually found on disk. Leave already-populated lists alone.
398
+ if (planIds.length > 0) {
399
+ const plansBlockRe = /(\*\*Plans(?::\*\*|\*\*:)\s*\n)((?:\s*-\s*[^\n]+\n?)+)/i;
400
+ const plansMatch = newSection.match(plansBlockRe);
401
+ if (plansMatch) {
402
+ const isPlaceholder = /^\s*-\s*_TBD_\s*$/im.test(plansMatch[2]) || plansMatch[2].trim() === '';
403
+ if (isPlaceholder) {
404
+ const plansList = planIds
405
+ .map((id) => `- ${id} — ${summarizedIds.has(id) ? 'SUMMARY shipped' : 'in progress'}`)
406
+ .join('\n') + '\n';
407
+ newSection = newSection.replace(plansBlockRe, `$1${plansList}`);
408
+ changed = true;
409
+ }
410
+ }
411
+ }
412
+
413
+ if (!changed) {
414
+ return { updated: false, note: `${note} (ROADMAP.md already reflects this)`, plan_count: planFiles.length, summary_count: summaryFiles.length, status: computedStatus };
415
+ }
416
+
417
+ const newContent = content.slice(0, phase.headerIndex) + newSection + content.slice(phase.sectionEnd);
418
+ const tmp = rp + '.tmp';
419
+ fs.writeFileSync(tmp, newContent, 'utf8');
420
+ fs.renameSync(tmp, rp);
421
+
347
422
  return {
348
- updated: false,
349
- note: `phase ${phaseNum}: ${planFiles.length} plan(s), ${summaryFiles.length} summary(s) — ${allDone ? 'complete' : 'in progress'}`,
423
+ updated: true,
424
+ phase: phaseNum,
425
+ status: computedStatus,
350
426
  plan_count: planFiles.length,
351
427
  summary_count: summaryFiles.length,
352
- status: allDone ? 'complete' : 'in_progress',
428
+ note: `ROADMAP.md phase ${phaseNum} block updated to ${computedStatus}`,
353
429
  };
354
430
  }
355
431
 
@@ -381,6 +381,7 @@ function cmdInit(workflowName, rawArgs) {
381
381
 
382
382
  let panel = [];
383
383
  let scores = {};
384
+ let domain = null;
384
385
 
385
386
  let agent_id = null;
386
387
 
@@ -395,8 +396,12 @@ function cmdInit(workflowName, rawArgs) {
395
396
  // Don't pad when user explicitly specified the agent list — their
396
397
  // choice is the final word.
397
398
  panel = filterPanelToInstalled(ideal, councilAgents, { pad: flags.agents.length === 0 });
399
+ // #1010 — domain must populate on every council session, not just
400
+ // --explain, because council.md's <output_format> banner prints
401
+ // Domain: unconditionally.
402
+ const explained = scorer.explainSelection(question, opts);
403
+ domain = explained.domain || null;
398
404
  if (flags.explain) {
399
- const explained = scorer.explainSelection(question, opts);
400
405
  scores = explained.scores || {};
401
406
  }
402
407
  }
@@ -426,9 +431,14 @@ function cmdInit(workflowName, rawArgs) {
426
431
  flags,
427
432
  panel,
428
433
  scores,
434
+ domain,
429
435
  question_type: questionClassification.type,
430
436
  question_signals: questionClassification.signals,
431
437
  mode: config.mode || null,
438
+ // #1010 — response_language was only ever populated for phase-op/
439
+ // sprint-plan below; council.md documents it as a top-level init field
440
+ // and gates language pass-through to subagents on it being set.
441
+ response_language: config.response_language || config.language || null,
432
442
  config,
433
443
  installed_agents: installedAgents,
434
444
  paths: {
@@ -1519,6 +1529,10 @@ function cmdState(subArgs) {
1519
1529
  // =====================================================================
1520
1530
 
1521
1531
  // --- sprint add --phase NN --goal "Sprint goal" ---
1532
+ // NOTE: this populates entry.sprints[] (an array). A separate code path,
1533
+ // 'planned-phase' below (~line 3152), populates entry.plans (a plain count).
1534
+ // These two fields are never reconciled with each other — see AUDIT-redundant-work.md
1535
+ // finding 1 cross-check. Do not assume one implies the other is populated.
1522
1536
  if (sub === 'sprint' && subArgs[1] === 'add') {
1523
1537
  const flags = parseFlags(2);
1524
1538
  const state = readState() || defaultState();
@@ -3149,6 +3163,9 @@ function cmdState(subArgs) {
3149
3163
  // Execution-lifecycle phase state
3150
3164
  // =====================================================================
3151
3165
 
3166
+ // NOTE: entry.plans (a count) is disjoint from entry.sprints[] (an array,
3167
+ // set by 'sprint add' above) — see the comment there. Known schema divergence,
3168
+ // not yet unified; do not read one as evidence the other is in sync.
3152
3169
  if (sub === 'planned-phase') {
3153
3170
  const flags = parseFlags(1);
3154
3171
  if (!flags.phase) throw new Error('planned-phase requires --phase <N>');
@@ -8,7 +8,7 @@ Immediately after appending content to any of:
8
8
 
9
9
  - `.planning/ROADMAP.md` — milestones and phases
10
10
  - `.planning/epics.md` — epics and stories
11
- - `.rcode/phases/{phase}/sprint-{N}.md` — sprint commitments
11
+ - `.planning/phases/{phase-dir}/{phase}-{plan}-SPRINT.md` — sprint commitments
12
12
 
13
13
  Call the state-sync helper:
14
14
 
@@ -32,7 +32,7 @@ Agreements without new information are silence. If an agent genuinely has nothin
32
32
 
33
33
  ## Panel selection (deterministic scoring)
34
34
 
35
- rcode's council uses a pure-function keyword scorer (`cli/lib/council-panel.cjs`) instead of LLM judgment. This is intentional:
35
+ rcode's council uses a pure-function keyword scorer (`rcode/bin/lib/council-panel.cjs` source, installed at `.rcode/bin/lib/council-panel.cjs`) instead of LLM judgment. This is intentional:
36
36
 
37
37
  - **Deterministic:** same question produces same panel every time
38
38
  - **Testable:** the scoring function has unit tests
@@ -47,13 +47,18 @@ The scoring table is versioned with the package. Users who want different weight
47
47
  - Scope/feature questions (containing "scope", "feature", "roadmap", "prd") always include Hussain-PM.
48
48
  - If fewer than the minimum panel size (default 3) score non-zero, the panel is padded with the STRATEGIC_PADDING_ORDER list: sadiq, hussain-pm, waleed, fatima, nasser.
49
49
 
50
- **v2 prototype note:** only Sadiq, Waleed, and Fatima are installed as first-class subagents. The scorer may select agent ids that don't yet have subagent files — the orchestrator must filter to installed agents and fall back to the 3-agent panel.
50
+ **Installed roster:** the full agent roster (currently 45 agents under `rcode/agents/`) is installed as first-class subagents. The scorer may still select an agent id that isn't present in a given project's installed set — the orchestrator filters the scored panel down to `installed_agents` from `init council` and pads from the fallback order if needed.
51
51
 
52
52
  ## Response presentation
53
53
 
54
- Subagent responses are presented **verbatim and in panel order**. The orchestrator never summarizes, paraphrases, or condenses agent output. The user came to the council to hear the agents speak in their own voicessummary defeats the point.
54
+ Two presentation modes control how panel responses appear inline. The session artifact (see below) always stores the full verbatim text regardless of modeonly the inline presentation differs:
55
55
 
56
- After all verbatim responses, the orchestrator may add a single **Orchestrator Note** (max 3 sentences) that flags a disagreement worth following up on or recommends a second round. The Orchestrator Note is clearly labeled so it's not confused with agent speech.
56
+ - **Default (compact summary)** scannable in ~20 seconds: a one-sentence paraphrased position per agent, a convergence/divergence table, and Round 2 deltas. No verbatim transcripts inline.
57
+ - **Verbose** (`--verbose` flag or `output.verbose: true` in config) — full verbatim responses printed in panel order, no summarization.
58
+
59
+ The user came to the council to hear the agents' actual positions, not filler agreement — so even in compact mode, paraphrase the substance, not "I agree with X."
60
+
61
+ After the panel output, the orchestrator may add a single **Orchestrator Note** (max 2-3 sentences) that flags a disagreement worth following up on or recommends a second round. The Orchestrator Note is clearly labeled so it's not confused with agent speech.
57
62
 
58
63
  ## Session artifact format
59
64
 
@@ -0,0 +1,15 @@
1
+ # execute.md — auto_copy_learnings (global learnings store)
2
+
3
+ Extracted from `execute.md`'s `auto_copy_learnings` step. Only loaded when `features.global_learnings` is enabled (disabled by default) — see the conditional include at that point in `execute.md`.
4
+
5
+ **Auto-copy phase learnings to global store (when enabled).**
6
+
7
+ This step runs AFTER phase completion and SUMMARY.md is written. It copies any LEARNINGS.md
8
+ entries from the completed phase to the global learnings store at `.rcode/knowledge/`.
9
+
10
+ 1. Check if LEARNINGS.md exists in the phase directory (use the `phase_dir` value from init context)
11
+ 2. If found, copy to global store:
12
+ ```bash
13
+ node ".rcode/bin/rcode-tools.cjs" learnings copy 2>/dev/null || echo "⚠ Learnings copy failed — continuing"
14
+ ```
15
+ Copy failure must NOT block phase completion.
@@ -0,0 +1,49 @@
1
+ # execute.md — close_parent_artifacts (decimal/polish phases only)
2
+
3
+ Extracted from `execute.md`'s `close_parent_artifacts` step. Only loaded when `PHASE_NUMBER` contains a decimal (gap-closure phases like `4.1`, `03.1`) — see the conditional include at that point in `execute.md`.
4
+
5
+ For decimal/polish phases only (X.Y pattern): close the feedback loop by resolving parent UAT and debug artifacts.
6
+
7
+ **1. Detect decimal phase and derive parent:**
8
+ ```bash
9
+ # Check if phase_number contains a decimal
10
+ if [[ "$PHASE_NUMBER" == *.* ]]; then
11
+ PARENT_PHASE="${PHASE_NUMBER%%.*}"
12
+ fi
13
+ ```
14
+
15
+ **2. Find parent UAT file:**
16
+ ```bash
17
+ PARENT_INFO=$(node ".rcode/bin/rcode-tools.cjs" find-phase "${PARENT_PHASE}" --raw)
18
+ # Extract directory from PARENT_INFO JSON, then find UAT file in that directory
19
+ ```
20
+
21
+ **If no parent UAT found:** Skip this step (gap-closure may have been triggered by VERIFICATION.md instead).
22
+
23
+ **3. Update UAT gap statuses:**
24
+
25
+ Read the parent UAT file's `## Gaps` section. For each gap entry with `status: failed`:
26
+ - Update to `status: resolved`
27
+
28
+ **4. Update UAT frontmatter:**
29
+
30
+ If all gaps now have `status: resolved`:
31
+ - Update frontmatter `status: diagnosed` → `status: resolved`
32
+ - Update frontmatter `updated:` timestamp
33
+
34
+ **5. Resolve referenced debug sessions:**
35
+
36
+ For each gap that has a `debug_session:` field:
37
+ - Read the debug session file
38
+ - Update frontmatter `status:` → `resolved`
39
+ - Update frontmatter `updated:` timestamp
40
+ - Move to resolved directory:
41
+ ```bash
42
+ mkdir -p .planning/debug/resolved
43
+ mv .planning/debug/{slug}.md .planning/debug/resolved/
44
+ ```
45
+
46
+ **6. Commit updated artifacts:**
47
+ ```bash
48
+ node ".rcode/bin/rcode-tools.cjs" commit "docs(phase-${PARENT_PHASE}): resolve UAT gaps and debug sessions after ${PHASE_NUMBER} gap closure" --files .planning/phases/*${PARENT_PHASE}*/*-UAT.md .planning/debug/resolved/*.md
49
+ ```
@@ -0,0 +1,44 @@
1
+ # execute.md — Interactive Execution Mode
2
+
3
+ Extracted from `execute.md`'s `check_interactive_mode` step. Only loaded when the `--interactive` flag is present — see the conditional include at that point in `execute.md`.
4
+
5
+ Interactive mode executes plans sequentially **inline** (no subagent spawning) with user
6
+ checkpoints between tasks. The user can review, modify, or redirect work at any point.
7
+
8
+ **Interactive execution flow:**
9
+
10
+ 1. Load plan inventory as normal (discover_and_group_plans)
11
+ 2. For each plan (sequentially, ignoring wave grouping):
12
+
13
+ a. **Present the plan to the user:**
14
+ ```
15
+ ## Plan {plan_id}: {plan_name}
16
+
17
+ Objective: {from plan file}
18
+ Tasks: {task_count}
19
+
20
+ Options:
21
+ - Execute (proceed with all tasks)
22
+ - Review first (show task breakdown before starting)
23
+ - Skip (move to next plan)
24
+ - Stop (end execution, save progress)
25
+ ```
26
+
27
+ b. **If "Review first":** Read and display the full plan file. Ask again: Execute, Modify, Skip.
28
+
29
+ c. **If "Execute":** Read and follow `.rcode/workflows/execute-sprint.md` **inline**
30
+ (do NOT spawn a subagent). Execute tasks one at a time.
31
+
32
+ d. **After each task:** Pause briefly. If the user intervenes (types anything), stop and address
33
+ their feedback before continuing. Otherwise proceed to next task.
34
+
35
+ e. **After plan complete:** Show results, commit, create SUMMARY.md, then present next plan.
36
+ **Overwrite guard:** If the SUMMARY.md file already exists from a previous run, delete it first with `rm -f <path>` before writing the new version. Never append to or skip an existing SUMMARY.md — always overwrite with the current sprint's completion data.
37
+
38
+ 3. After all plans: proceed to verification (same as normal mode).
39
+
40
+ **Benefits of interactive mode:**
41
+ - No subagent overhead — dramatically lower token usage
42
+ - User catches mistakes early — saves costly verification cycles
43
+ - Maintains rcode's planning/tracking structure
44
+ - Best for: small phases, bug fixes, verification gaps, learning rcode
@@ -0,0 +1,22 @@
1
+ # execute.md — notify_on_completion (webhook notifications)
2
+
3
+ Extracted from `execute.md`'s `notify_on_completion` step. Only loaded when a webhook URL is configured — see the conditional include at that point in `execute.md`.
4
+
5
+ **Post phase completion to configured webhooks (Slack / Discord / MS Teams).**
6
+
7
+ ```bash
8
+ node ".rcode/bin/rcode-tools.cjs" notify send \
9
+ --title "Phase ${phase_number} complete — ${phase_name}" \
10
+ --body "$(basename "$PWD") · $(git rev-parse --short HEAD) · ${incomplete_count:-0} plan(s) remaining" \
11
+ --event "execute-done" 2>/dev/null || true
12
+ ```
13
+
14
+ Users configure webhooks by editing `.rcode/config.yaml`:
15
+
16
+ ```yaml
17
+ slack_webhook_url: "https://hooks.slack.com/services/..."
18
+ discord_webhook_url: "https://discord.com/api/webhooks/..."
19
+ teams_webhook_url: "https://outlook.office.com/webhook/..."
20
+ ```
21
+
22
+ Then verify with `/rcode-notify-test`.
@@ -10,13 +10,13 @@ Every plan file must have this frontmatter and structure:
10
10
 
11
11
  ```markdown
12
12
  ---
13
- id: "01.02" # full hierarchical ID
14
- phase: "01" # phase ID (2-digit, zero-padded)
15
- plan: "02" # plan ID within phase (2-digit, zero-padded)
16
- milestone: "M1" # optional, if assigned to milestone
17
- type: auto | tdd
18
- depends_on: [] # list of other plan IDs like ["01.01"]
19
- wave: 1 # auto-derived from depends_on
13
+ phase: "8" # phase ID (no leading zeros — issue #652)
14
+ plan_number: 1 # plan ID within phase (no leading zeros — issue #652)
15
+ wave: 1 # auto-derived from depends_on
16
+ depends_on: [] # list of other plan IDs like ["8-1"]
17
+ files_modified: [] # files this plan touches
18
+ autonomous: true # whether the plan runs without checkpoints
19
+ requirements: [] # requirement IDs mapped to this plan, if any
20
20
  ---
21
21
 
22
22
  ## Objective
@@ -41,10 +41,10 @@ type: checkpoint:human-verify
41
41
 
42
42
  **Hierarchical ID format:**
43
43
  - Milestone: `M{N}` (e.g., M1, M2)
44
- - Phase: `{NN}` 2-digit, zero-padded (e.g., 01, 02, 72)
45
- - Decimal phase (inserted): `{NN.M}` (e.g., 02.1, 72.3)
46
- - Plan within phase: `{NN.MM}` (e.g., 01.02)
47
- - Task within plan: `{NN.MM.TT}` (e.g., 01.02.03)
44
+ - Phase: `{N}` no leading zeros (issue #652), e.g. 1, 2, 72
45
+ - Decimal phase (inserted): `{N.M}` (e.g., 2.1, 72.3)
46
+ - Plan within phase: `{N.M}` (e.g., 1.2)
47
+ - Task within plan: `{N.M.T}` (e.g., 1.2.3)
48
48
 
49
49
  **Task types:**
50
50
  - `auto` — executor runs without pausing
@@ -19,8 +19,8 @@ BRANCH=$(git branch --show-current 2>/dev/null)
19
19
  PROTECTED="main master develop v2-prototype"
20
20
 
21
21
  # Check 3: branch follows naming convention
22
- # Allowed: feat/foo-bar, fix/123-baz, issue-123-name, task-123-slug
23
- BRANCH_OK=$(echo "$BRANCH" | grep -qE '^((feat|fix|docs|chore|refactor|test|perf|style|build|ci)/[a-z0-9][a-z0-9-]*|(issue|task)-[0-9]+-[a-z0-9-]+)$' && echo yes || echo no)
22
+ # Allowed: feat/foo-bar, fix/123-baz, issue-123-name, task-123-slug, 8-1-aria (phase-plan-slug)
23
+ BRANCH_OK=$(echo "$BRANCH" | grep -qE '^((feat|fix|docs|chore|refactor|test|perf|style|build|ci)/[a-z0-9][a-z0-9-]*|(issue|task)-[0-9]+-[a-z0-9-]+|[0-9]+-[0-9]+-[a-z0-9-]+)$' && echo yes || echo no)
24
24
 
25
25
  # Check 4: scope drift — files touched that don't belong to the active task
26
26
  # The workflow MUST pass $TASK_SCOPE_GLOB (e.g. ".planning/phases/8-*/" or "src/auth/")