@hanzlaa/rcode 4.7.3 → 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.
- package/AGENTS.md +1 -1
- package/CLAUDE.md +1 -1
- package/CONTRIBUTING.md +3 -0
- package/cli/github-sync.js +17 -201
- package/cli/lib/config.cjs +1 -1
- package/cli/lib/github-sync-discover.cjs +304 -0
- package/cli/lib/namespace-migrate.cjs +16 -1
- package/cli/uninstall.js +7 -2
- package/dist/rcode.js +194 -194
- package/package.json +1 -1
- package/rcode/agents/rcode-haitham.md +1 -1
- package/rcode/agents/rcode-hanzla.md +1 -1
- package/rcode/agents/rcode-hussain-pm.md +1 -1
- package/rcode/agents/rcode-nyquist-auditor.md +1 -1
- package/rcode/agents/rcode-omar.md +1 -1
- package/rcode/agents/rcode-remediation-planner.md +1 -1
- package/rcode/agents/rcode-waleed.md +1 -1
- package/rcode/agents/rcode-yousef.md +1 -1
- package/rcode/agents/rules/planner/task-templates.md +24 -22
- package/rcode/agents/rules/verifier/verification-report.md +2 -2
- package/rcode/bin/lib/roadmap.cjs +80 -4
- package/rcode/bin/rcode-tools.cjs +18 -1
- package/rcode/brain/best-practices/state-sync-rule.md +1 -1
- package/rcode/references/council-protocol.md +9 -4
- package/rcode/references/execute-auto-copy-learnings.md +15 -0
- package/rcode/references/execute-close-parent-artifacts.md +49 -0
- package/rcode/references/execute-interactive-mode.md +44 -0
- package/rcode/references/execute-notify-webhooks.md +22 -0
- package/rcode/references/execution-protocol.md +11 -11
- package/rcode/references/git-preflight.md +2 -2
- package/rcode/references/plan-gaps-mode.md +89 -0
- package/rcode/references/plan-thinking-partner.md +20 -0
- package/rcode/references/plan-windows-troubleshooting.md +25 -0
- package/rcode/references/planner-playbook.md +23 -29
- package/rcode/skills/_shared/state-sync-rule.md +1 -1
- package/rcode/skills/actions/1-analysis/rcode-document-project/SKILL.md +2 -0
- package/rcode/skills/actions/1-analysis/rcode-prfaq/SKILL.md +2 -0
- package/rcode/skills/actions/2-plan/rcode-create-epics-and-stories/SKILL.md +11 -0
- package/rcode/skills/actions/2-plan/rcode-create-prd/SKILL.md +2 -0
- package/rcode/skills/actions/2-plan/rcode-create-story/SKILL.md +11 -0
- package/rcode/skills/actions/2-plan/rcode-edit-prd/SKILL.md +2 -0
- package/rcode/skills/actions/2-plan/rcode-validate-prd/SKILL.md +2 -0
- package/rcode/skills/actions/3-solutioning/rcode-check-implementation-readiness/SKILL.md +2 -0
- package/rcode/skills/actions/3-solutioning/rcode-create-architecture/SKILL.md +2 -0
- package/rcode/skills/actions/4-implementation/rcode-checkpoint-preview/SKILL.md +2 -0
- package/rcode/skills/actions/4-implementation/rcode-code-review/SKILL.md +2 -0
- package/rcode/skills/actions/4-implementation/rcode-correct-course/SKILL.md +2 -0
- package/rcode/skills/actions/4-implementation/rcode-debug/SKILL.md +1 -1
- package/rcode/skills/actions/4-implementation/rcode-dev-story/SKILL.md +2 -0
- package/rcode/skills/actions/4-implementation/rcode-retrospective/SKILL.md +2 -0
- package/rcode/skills/actions/4-implementation/rcode-scaffold-project/SKILL.md +2 -0
- package/rcode/skills/actions/4-implementation/rcode-sprint-planning/SKILL.md +3 -2
- package/rcode/skills/actions/4-implementation/rcode-sprint-status/SKILL.md +2 -0
- package/rcode/skills/agents/haitham-frontend/SKILL.md +6 -0
- package/rcode/skills/agents/hanzla-engineer/SKILL.md +6 -0
- package/rcode/skills/agents/hussain-pm/SKILL.md +1 -1
- package/rcode/skills/agents/hussain-sm/SKILL.md +3 -3
- package/rcode/skills/agents/majlis-council/references.md +17 -7
- package/rcode/skills/agents/raees-orchestrator/SKILL.md +13 -11
- package/rcode/skills/agents/yousef-backend/SKILL.md +6 -0
- package/rcode/templates/github/epic-template.md +1 -1
- package/rcode/templates/github/feature-template.md +1 -1
- package/rcode/templates/github/task-template.md +1 -1
- package/rcode/templates/sprint.md +14 -3
- package/rcode/templates/verification-report.md +7 -4
- package/rcode/workflows/code-review-fix.md +5 -5
- package/rcode/workflows/code-review.md +1 -1
- package/rcode/workflows/council.md +1 -0
- package/rcode/workflows/create-epics-and-stories.md +12 -6
- package/rcode/workflows/dev-story.md +12 -14
- package/rcode/workflows/do.md +12 -9
- package/rcode/workflows/execute-sprint.md +4 -0
- package/rcode/workflows/execute-waves.md +44 -1
- package/rcode/workflows/execute.md +20 -119
- package/rcode/workflows/lens-audit.md +7 -7
- package/rcode/workflows/plan-spawn-planner.md +0 -1
- package/rcode/workflows/plan.md +25 -136
- package/rcode/workflows/quick.md +1 -1
- package/rcode/workflows/sprint-planning.md +14 -37
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hanzlaa/rcode",
|
|
3
|
-
"version": "4.
|
|
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
|
|
|
@@ -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
|
|
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
|
-
<
|
|
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
|
-
<
|
|
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
|
-
<
|
|
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
|
-
<
|
|
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
|
-
<
|
|
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
|
-
<
|
|
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
|
-
<
|
|
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
|
-
<
|
|
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
|
-
<
|
|
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
|
-
<
|
|
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
|
-
<
|
|
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 `.
|
|
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:** .
|
|
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:
|
|
349
|
-
|
|
423
|
+
updated: true,
|
|
424
|
+
phase: phaseNum,
|
|
425
|
+
status: computedStatus,
|
|
350
426
|
plan_count: planFiles.length,
|
|
351
427
|
summary_count: summaryFiles.length,
|
|
352
|
-
|
|
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
|
-
- `.
|
|
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 (`
|
|
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
|
-
**
|
|
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
|
-
|
|
54
|
+
Two presentation modes control how panel responses appear inline. The session artifact (see below) always stores the full verbatim text regardless of mode — only the inline presentation differs:
|
|
55
55
|
|
|
56
|
-
|
|
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
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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: `{
|
|
45
|
-
- Decimal phase (inserted): `{
|
|
46
|
-
- Plan within phase: `{
|
|
47
|
-
- Task within plan: `{
|
|
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/")
|