@hanzlaa/rcode 4.10.2 → 4.10.4

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.2",
3
+ "version": "4.10.4",
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": {
@@ -24,9 +24,9 @@ rcode sprint planner. Create executable SPRINT.md files with story breakdown, de
24
24
 
25
25
  **CRITICAL:** Over-splitting ticket-sized work is a bug. Only split when stories exceed 8 AND have independent work streams.
26
26
 
27
- **Hierarchical IDs:** Every story must have a hierarchical ID in its heading: `### Story {sprint-id}.{NN}{name}`. The orchestrator passes you the `sprint-id` — use it verbatim in all story headings. Format: `NN.S.TT` (Phase.Sprint.Story).
27
+ **Hierarchical IDs:** Every story must have a hierarchical ID on its `<task id="...">` attribute — NOT a markdown heading. `### Story N — Title` headings are a legacy pre-`<task>` format scanner.js only tolerates as a last-resort fallback; writing them as primary output breaks `execute-sprint.md`'s per-task dashboard-state-sync step, which parses `<task id=...>` and the frontmatter block, not headings (confirmed live issue class #1034-#1036). The orchestrator passes you the `sprint-id` — use it verbatim as `<task id="{sprint-id}.{NN}">`. Format: `NN.S.TT` (Phase.Sprint.Story).
28
28
 
29
- **Output:** Write SPRINT.md (not PLAN.md) using the template at `rcode/templates/sprint.md`. Register the sprint in state via `rcode-tools.cjs state sprint add`.
29
+ **Output:** Write SPRINT.md (not PLAN.md) using the template at `rcode/templates/sprint.md` EXACTLY — YAML frontmatter block (`phase:`/`sprint:`/`owner:`/etc.) followed by `<task>` XML blocks. This is not a style suggestion; downstream tooling parses this file with `grep`/regex against that exact shape, and any deviation (headings instead of `<task>` blocks, bold-label metadata instead of YAML frontmatter) silently breaks dashboard sync while the sprint still executes and commits real code — the failure is invisible until someone checks the dashboard. Register the sprint in state via `rcode-tools.cjs state sprint add`.
30
30
 
31
31
  Core: Parse user decisions from CONTEXT.md, decompose into sprints with stories, build dependency graphs, derive acceptance criteria per story.
32
32
  </role>
@@ -64,24 +64,7 @@ Read ONLY when current task needs them. Don't preemptively load.
64
64
 
65
65
  ## SPRINT.md Frontmatter Template
66
66
 
67
- ```yaml
68
- ---
69
- phase: XX-name
70
- sprint: NN.S
71
- type: execute | tdd
72
- wave: N # Auto-derived from depends_on
73
- depends_on: [sprint-id, ...]
74
- files_modified: [paths...]
75
- autonomous: true | false # false if has checkpoints
76
- requirements: [REQ-01, REQ-02] # MUST NOT be empty
77
- owner: yousef # OPTIONAL — see below
78
-
79
- must_haves:
80
- truths: [...] # Observable outcomes from user perspective
81
- artifacts: [...] # Files/models that must exist
82
- key_links: [...] # Critical connections, breakage points
83
- ---
84
- ```
67
+ **`rcode/templates/sprint.md` is the single canonical template — read it now, don't improvise a different structure.** It is not optional/decorative; it is what `execute-sprint.md`'s `owner_agent_resolution` step and its per-task dashboard-state-sync step parse via `grep '^owner:'`/`^phase:'`/`^sprint:'`. A SPRINT.md that free-styles a different structure (bold-label metadata, `### Story N — Title` headings, or any shape without the exact `phase:`/`sprint:`/`owner:` YAML frontmatter block) silently breaks that parsing — the sprint still executes and commits real code, but the dashboard never learns it happened (confirmed live, issue class closed by #1034-#1036's fixes — do not reintroduce it by drifting from the template).
85
68
 
86
69
  **`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
70
 
@@ -1,19 +1,43 @@
1
- # Sprint {sprint_id} — {sprint_goal}
1
+ ---
2
+ phase: {phase_dir}
3
+ sprint: {sprint_id}
4
+ type: execute | tdd
5
+ wave: {N}
6
+ depends_on: [{sprint_id}, ...]
7
+ files_modified: [{paths...}]
8
+ autonomous: true | false
9
+ requirements: [{REQ-01, REQ-02}]
10
+ owner: {haitham|hanzla|omar|waleed|yousef} # OPTIONAL — omit if no council session grounds this plan or the domain split is ambiguous; see planner-playbook.md's "owner: field" section
2
11
 
3
- <!-- P2: Omit Dependencies and Risks sections if empty. Omit Retrospective until sprint is complete. -->
12
+ must_haves:
13
+ truths: [{observable outcomes from the user's perspective}]
14
+ artifacts: [{files/models that must exist}]
15
+ key_links: [{critical connections, breakage points}]
16
+ ---
4
17
 
5
- **Phase:** {phase_number} {phase_name}
6
- **Status:** {status}
7
- **Velocity target:** {velocity_target} points
8
- **Started:** {started_at}
18
+ ## Sprint {sprint_id}: {one-line sprint goal, plain English, no jargon}
9
19
 
10
- ## Sprint Goal
20
+ {2-4 sentence plain-English recap: what this sprint builds and why, written for someone who will never open the XML tags below}
11
21
 
12
- {sprint_goal}
22
+ **Tasks:**
23
+ 1. {task 1 title — copy the <title> attribute text verbatim}
24
+ 2. {task 2 title}
25
+ 3. {task N title}
13
26
 
14
- ## Stories
27
+ _Below this line is the execution prompt the agent reads — task bodies, read-first file lists, verification commands. Not meant for skimming._
15
28
 
16
- <!-- One <task> block per story. id= and <title> are REQUIRED (scanner.js's primary parse path) -->
29
+ ---
30
+
31
+ <objective>{what this sprint delivers and why, grounded in the council session or codebase scan}</objective>
32
+
33
+ <execution_context>
34
+ @.rcode/workflows/execute-sprint.md
35
+ @.rcode/templates/summary.md
36
+ </execution_context>
37
+
38
+ <context>{council session reference if one grounds this plan, else key codebase facts verified by Read}</context>
39
+
40
+ <!-- One <task> block per story. id= and title= are REQUIRED (scanner.js's primary parse path — do not use nested <title> tags or "### Story N — name" headings, those are legacy formats scanner.js only supports as a fallback). -->
17
41
  <tasks>
18
42
  <task id="{sprint_id}.{NN}" type="auto">
19
43
  <title>{story title}</title>
@@ -28,53 +52,6 @@
28
52
  </task>
29
53
  </tasks>
30
54
 
31
- ## Capacity
32
-
33
- - **Velocity target:** {velocity_target} points
34
- - **Total committed:** {total_points} points
35
- - **Buffer:** {buffer_points} points ({buffer_pct}%)
36
-
37
- <!-- Omit if no cross-story dependencies exist -->
38
- ## Dependencies
39
-
40
- | Story | Depends on | Status |
41
- |-------|-----------|--------|
42
-
43
- <!-- Omit if no risks identified -->
44
- ## Risks
45
-
46
- | Risk | Impact | Mitigation |
47
- |------|--------|------------|
48
-
49
- ## Files Touched
50
-
51
- <!-- Planner must populate before handoff to executor. Used by wave-overlap checker and merge reviewers. -->
52
-
53
- **Creates:**
54
- <!-- - `exact/path/new-file.ts` — one-line responsibility -->
55
-
56
- **Modifies:**
57
- <!-- - `exact/path/existing.ts` — what changes -->
58
-
59
- **Tests:**
60
- <!-- - `tests/exact/path/test.ts` — tests for -->
61
-
62
- **Aggregator files (append-only — never replace):**
63
- <!-- - `packages/shared/src/index.ts` — adds export for X -->
64
-
65
- ## Sprint Review
66
-
67
- <!-- Fill at sprint completion only — omit this section until then -->
68
- - Stories completed: {done_count}/{total_count}
69
- - Velocity actual: {velocity_actual} points
70
- - Carryover: {carryover}
71
-
72
- ## Retrospective
73
-
74
- <!-- Fill at sprint completion only — omit this section until then -->
75
- ### What went well
76
- -
77
- ### What didn't
78
- -
79
- ### Action items
80
- -
55
+ <verification>{how to confirm the whole sprint, not just individual tasks, actually works}</verification>
56
+ <success_criteria>{bullet list — what must be true for this sprint to count as done}</success_criteria>
57
+ <output>Create `.planning/phases/{phase-dir}/{phase}-{plan}-SUMMARY.md`</output>
@@ -602,6 +602,14 @@ node .rcode/bin/rcode-tools.cjs state record-council \
602
602
  node .rcode/bin/rcode-tools.cjs state record-session
603
603
  ```
604
604
 
605
+ **Also record the decision itself (closes #1036-adjacent gap — dashboard "Decisions (ADRs)" reads `state.json`'s `decisions[]`, which `record-council` above does NOT populate; only `state add-decision` does).** Write one concise line per DISTINCT consensus decision the council reached — not the full synthesis prose, not one line per panelist. A council session that reached one architectural consensus gets one `add-decision` call; a session with 2-3 genuinely separate decisions gets that many calls. `add-decision` takes the summary as a plain positional argument (no `--summary-file` flag exists on this subcommand — verified against `rcode-tools.cjs`'s actual implementation, don't invent flags), so keep each summary to one shell-safe line:
606
+
607
+ ```bash
608
+ node .rcode/bin/rcode-tools.cjs state add-decision "{one-line consensus decision, e.g. 'Password reset: opaque crypto token, sha256-hashed on existing user record, 15-30min single-use expiry, console-stub email'}"
609
+ ```
610
+
611
+ If the council reached no real consensus (pure disagreement, or panelists only asked clarifying questions), skip this call — don't manufacture a decision that wasn't made.
612
+
605
613
  > **Note:** If `rcode-tools.cjs` state commands fail (e.g. state.json missing or not yet initialized), continue without error — state tracking is optional, the session artifact saved in Step 5 is mandatory.
606
614
 
607
615
  ## Success Criteria
@@ -31,7 +31,11 @@ else
31
31
  fi
32
32
  ```
33
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.
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.
35
+
36
+ **Fall back to `rcode-executor` and note the fallback in SUMMARY.md's Deviations section (do not fail the sprint) when:**
37
+ - `$EXEC_AGENT` is a persona and that persona's agent file is not installed in this project, OR
38
+ - The persona agent **declines/refuses the role** — a persona's own scope-discipline and anti-injection instincts may correctly distrust a spawn prompt that merely *asserts* "you are the sprint executor" without provenance from a real `/rcode-execute` dispatch (confirmed live: this happens; a hand-authored trigger reads exactly like a prompt-injection attempt to the persona, and refusing that is the correct default). Detect this by the spawn returning zero commits / zero file changes with a refusal-shaped response (no tool calls, explanation citing lack of authorization or wrong capability lane) rather than a normal execution report. Retry once with `rcode-executor`; do not retry the same persona a second time.
35
39
  </step>
36
40
 
37
41
  <process>