refacil-sdd-ai 4.3.0 → 4.4.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/auditor.md CHANGED
@@ -157,10 +157,17 @@ Next step: [/refacil:archive | /refacil:verify]
157
157
  "summary": "<1-line summary>",
158
158
  "failCount": <integer count of FAILs in NEW code>,
159
159
  "preexistingCount": <integer count of pre-existing FAILs found>,
160
- "blockers": <true|false — new code only>
160
+ "blockers": <true|false — new code only>,
161
+ "failedFiles": ["path/to/file-1.ts", "path/to/file-2.ts"]
161
162
  }
162
163
  ```
163
164
 
165
+ **`failedFiles` rules**:
166
+ - On `REQUIERE CORRECCIONES`: list the relative paths (from repo root) of every file in the **blocking scope** (`changedFiles`) that had at least one CRITICAL or HIGH FAIL.
167
+ - On `APROBADO` or `APROBADO CON OBSERVACIONES`: emit `"failedFiles": []`.
168
+ - Files with only MEDIUM/LOW findings do NOT appear in `failedFiles`.
169
+ - Pre-existing context files do NOT appear in `failedFiles` — only blocking scope.
170
+
164
171
  **IMPORTANT about the JSON block**:
165
172
  - Use the literal fence ` ```refacil-review-result ` (not ` ```json `).
166
173
  - Emit it ALWAYS, even if the verdict is `REQUIERE CORRECCIONES`.
@@ -2,7 +2,7 @@
2
2
  name: refacil-proposer
3
3
  description: Generates SDD-AI planning artifacts (proposal, specs, design, tasks) for any codebase. Delegated by /refacil:propose — do not invoke directly.
4
4
  tools: Read, Grep, Glob, Bash, Edit, Write
5
- model: opusplan
5
+ model: sonnet
6
6
  ---
7
7
 
8
8
  # refacil-proposer — Planning Artifact Generator
@@ -3,7 +3,21 @@
3
3
  const fs = require('fs');
4
4
  const path = require('path');
5
5
 
6
- const projectRoot = process.cwd();
6
+ function findProjectRoot() {
7
+ let dir = process.cwd();
8
+ const { root } = path.parse(dir);
9
+ while (dir !== root) {
10
+ if (fs.existsSync(path.join(dir, 'refacil-sdd')) || fs.existsSync(path.join(dir, '.git'))) {
11
+ return dir;
12
+ }
13
+ const parent = path.dirname(dir);
14
+ if (parent === dir) break;
15
+ dir = parent;
16
+ }
17
+ return process.cwd();
18
+ }
19
+
20
+ const projectRoot = findProjectRoot();
7
21
 
8
22
  // --- Helpers ---
9
23
 
package/lib/installer.js CHANGED
@@ -71,10 +71,12 @@ function installSkills(packageRoot, projectRoot) {
71
71
  // Claude Code: tools allowlist granular, model: sonnet|opus|haiku
72
72
  // Cursor: readonly: true|false (booleano), model: inherit (default)
73
73
  function transformFrontmatterForCursor(content) {
74
- const match = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
74
+ const normalized = content.replace(/\r\n/g, '\n');
75
+ const match = normalized.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
75
76
  if (!match) return content;
76
77
 
77
78
  const [, frontmatterRaw, body] = match;
79
+ // work with normalized content from here on
78
80
  const lines = frontmatterRaw.split('\n');
79
81
  const out = [];
80
82
  let toolsLine = null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "refacil-sdd-ai",
3
- "version": "4.3.0",
3
+ "version": "4.4.0",
4
4
  "description": "SDD-AI: Specification-Driven Development with AI — development methodology using AI with Claude Code and Cursor",
5
5
  "bin": {
6
6
  "refacil-sdd-ai": "./bin/cli.js"
@@ -99,6 +99,23 @@ The sub-agent will use the briefing as the primary guide and will only read the
99
99
 
100
100
  Returns ONE single message with the report + JSON block fenced as ` ```refacil-apply-result `.
101
101
 
102
+ ### Step 2.5: Write memory.yaml (CA-16 — cross-skill state)
103
+
104
+ After parsing the `refacil-apply-result` block:
105
+ - Extract `touchedFiles` from the result (list of files actually created/modified by the implementer).
106
+ - Write or update `refacil-sdd/changes/<changeName>/memory.yaml` preserving any existing fields:
107
+
108
+ ```yaml
109
+ lastStep: apply
110
+ touchedFiles:
111
+ - path/file-1.ts
112
+ - path/file-2.ts
113
+ ```
114
+
115
+ If the file already exists, merge: update `lastStep` and `touchedFiles`; do not remove fields set by other steps (e.g. `commandsRun` from test).
116
+
117
+ If `result` is `"FAILED"`, skip the write and wait for user instructions.
118
+
102
119
  ### Step 3: Present result and next step
103
120
 
104
121
  Show the user the **report** (everything before the `refacil-apply-result` block). Do not show the JSON block — it is internal metadata.
@@ -65,6 +65,8 @@ Depending on the type, follow the corresponding step:
65
65
 
66
66
  Bug fixes only contain `summary.md` (and optionally `.review-passed`); they are not full proposal/spec/design/task trees. Archive them with **git mv** / **mv** per the steps below — **do not** use `refacil-sdd-ai sdd archive` for these folders.
67
67
 
68
+ 0. **Delete memory.yaml if present** (CA-18): run `rm -f "refacil-sdd/changes/[fix-name]/memory.yaml"` before moving the folder.
69
+
68
70
  1. **Move to archive (move operation, not copy)**: transfer the full fix folder from `refacil-sdd/changes/[fix-name]/` to `refacil-sdd/changes/archive/[ISO-date]-[fix-name]/`. The source folder **must be eliminated** when done.
69
71
 
70
72
  Recommended execution order (deterministic and cross-platform):
@@ -140,10 +142,12 @@ The spec and review evidence are written **before** running the CLI archive comm
140
142
  ```
141
143
  - If `review.yaml` already exists, update only the fields that changed without removing others.
142
144
 
143
- 3. **Run the CLI archive**: `refacil-sdd-ai sdd archive <changeName>`this moves the change to `refacil-sdd/changes/archive/<date>-<changeName>/`.
144
- 4. Verify the command completed successfully (exit 0) and the original folder no longer exists.
145
+ 3. **Delete memory.yaml if present** (CA-18): before running the CLI archive, delete `refacil-sdd/changes/<changeName>/memory.yaml` if it existsrun `rm -f "refacil-sdd/changes/<changeName>/memory.yaml"`. This is part of the archive cleanup.
146
+
147
+ 4. **Run the CLI archive**: `refacil-sdd-ai sdd archive <changeName>` — this moves the change to `refacil-sdd/changes/archive/<date>-<changeName>/`.
148
+ 5. Verify the command completed successfully (exit 0) and the original folder no longer exists.
145
149
 
146
- 5. Continue to **Step 3**.
150
+ 6. Continue to **Step 3**.
147
151
 
148
152
  The goal is for `refacil-sdd/specs/` to document how the system works TODAY.
149
153
 
@@ -17,6 +17,18 @@ This skill is a **thin wrapper** that delegates the investigation to the `refaci
17
17
  - If `$ARGUMENTS` is empty, ask the user for the question or topic to explore BEFORE invoking the sub-agent.
18
18
  - If there is a question, continue.
19
19
 
20
+ ### Step 0.1: Duplicate exploration guard (CA-11)
21
+
22
+ Before delegating, check the current session conversation context for a prior complete exploration report with overlapping scope (same modules, files, or question topic):
23
+
24
+ - **If a prior complete exploration exists for the same or highly overlapping topic**: summarize the already-known context in 2-3 sentences and ask:
25
+ ```
26
+ I already explored [topic] earlier in this session. The key findings were: [summary].
27
+ Do you want me to run a targeted follow-up on a specific aspect, or proceed with a new full exploration?
28
+ ```
29
+ Wait for the user's answer before proceeding.
30
+ - **If there is no prior exploration** (or it is on a clearly different topic): continue to Step 1 without interruption.
31
+
20
32
  ### Step 1: Delegate to the refacil-investigator sub-agent
21
33
 
22
34
  Invoke the `refacil-investigator` sub-agent passing it:
@@ -12,6 +12,18 @@ This skill is a **wrapper** that prepares the scope, delegates SDD artifact gene
12
12
 
13
13
  ## Flow
14
14
 
15
+ ### Step 0.5: Duplicate exploration guard (CA-11)
16
+
17
+ Before gathering context or delegating, check the current session conversation for a prior complete exploration report with overlapping scope (same modules, files, or described topic):
18
+
19
+ - **If a prior complete exploration exists for the same or highly overlapping topic**: summarize the already-known context in 2-3 sentences and ask:
20
+ ```
21
+ I already explored [topic] earlier in this session. The key findings were: [summary].
22
+ Do you want me to run a targeted follow-up, or proceed with the full exploration for this proposal?
23
+ ```
24
+ Wait for the user's answer. If they confirm "proceed", continue to Step 1 — do not re-invoke a full exploration automatically.
25
+ - **If there is no prior exploration** for this topic: continue to Step 1 without interruption.
26
+
15
27
  ### Step 1: Understand the change
16
28
 
17
29
  If the user did NOT provide sufficient context in `$ARGUMENTS`, ask:
@@ -43,11 +43,21 @@ If you already have a `changeName`, run `refacil-sdd-ai sdd status <changeName>
43
43
  The change [name] already has an approved review ([verdict] — [date]) and there are no subsequent changes.
44
44
  ```
45
45
 
46
+ ### Step 0.4: Incremental scope (CA-07 — only if re-running after REQUIERE CORRECCIONES)
47
+
48
+ If `changeName` is not null, check whether `refacil-sdd/changes/<changeName>/.review-last-fails.json` exists (read by explicit path — it is NOT a dotfile but may be hidden in listings):
49
+
50
+ - **If the file EXISTS**: read `failedFiles` from it. Compute:
51
+ `incrementalScope = failedFiles ∪ changedFilesUnion`
52
+ - If `incrementalScope` is empty (CR-02): fall back to `changedFilesUnion` and add a comment in the briefing: `"# warning: incremental scope was empty — using full changedFilesUnion"`.
53
+ - Use `incrementalScope` as `changedFiles` in the briefing (Step 0.5), instead of the full `changedFilesUnion`.
54
+ - **If the file does NOT exist**: use `changedFilesUnion` as `changedFiles` normally.
55
+
46
56
  ### Step 0.5: Build briefing for the sub-agent (reduces auditor tool calls)
47
57
 
48
58
  Before invoking the sub-agent, extract the context that the auditor would otherwise calculate on its own:
49
59
 
50
- 1. **Changed files** — use **`changedFilesUnion` from Step 0.3** as the blocking scope. Do not run `git diff` or `git status` again.
60
+ 1. **Changed files** — use the scope resolved in Step 0.4 (`incrementalScope` if available, otherwise `changedFilesUnion`). Do not run `git diff` or `git status` again.
51
61
 
52
62
  2. **Project type** — read `package.json` (if it exists) and inspect the dependencies:
53
63
  - Backend indicators: `@nestjs/*`, `express`, `fastify`, `koa`, `typeorm`, `prisma`, `pg`, `mongoose`, `bullmq`, `amqplib`
@@ -56,6 +66,10 @@ Before invoking the sub-agent, extract the context that the auditor would otherw
56
66
 
57
67
  3. **Change objective** (only if there is an active change in `refacil-sdd/changes/`) — read the first section of `proposal.md`. Extract the objective in 1-2 sentences. If the scope is `git-diff` without an active change → `null`.
58
68
 
69
+ 4. **Cross-skill memory** — if `changeName` is not null and `refacil-sdd/changes/<changeName>/memory.yaml` exists, read it and extract `stackDetected`, `touchedFiles`. Include them in the briefing so the auditor skips re-discovery. If the file does not exist, omit — do not block (CR-04).
70
+
71
+ 5. **Mode** — default `concise`. If re-running after a prior `REQUIERE CORRECCIONES` (i.e., `.review-last-fails.json` was found with non-empty `failedFiles` in Step 0.4): set `mode: focused` — the auditor re-evaluates only the failing checklist items on the `failedFiles` (CR-05: focused mode still reads those files). Otherwise keep `concise`.
72
+
59
73
  Build the BRIEFING block:
60
74
 
61
75
  ```
@@ -64,7 +78,9 @@ scope: <changeName | "git-diff">
64
78
  changedFiles: [path/file-1.ts, path/file-2.ts, ...]
65
79
  projectType: backend | frontend | fullstack | library
66
80
  changeObjective: <objective in 1-2 sentences, or null>
67
- mode: concise | detailed
81
+ mode: concise | detailed | focused
82
+ stackDetected: <from memory.yaml, or omit>
83
+ touchedFiles: [...] # from memory.yaml — omit if not present
68
84
  ```
69
85
 
70
86
  ### Step 1: Delegate to the refacil-auditor sub-agent
@@ -85,6 +101,18 @@ Show the user the **concise report** (everything before the `refacil-review-resu
85
101
 
86
102
  **If the sub-agent returned `SCOPE_ERROR: <reason>`**: propagate the error to the user and ask for clarification. Do not write a marker.
87
103
 
104
+ ### Step 2.5: Persist or clean incremental-scope state (CA-06/CA-08/CA-09/CR-01)
105
+
106
+ Parse the `refacil-review-result` block from the sub-agent.
107
+
108
+ **If `verdict` is `REQUIERE CORRECCIONES`**:
109
+ - Only if `changeName` is not null (CR-01) AND the block includes a `failedFiles` field (CA-09 backward compat):
110
+ - Write `refacil-sdd/changes/<changeName>/.review-last-fails.json` with content: `{ "failedFiles": [...] }` using the `failedFiles` array from the JSON block.
111
+ - If `changeName` is null or `failedFiles` is absent: skip silently — existing behavior unchanged.
112
+
113
+ **If `verdict` is `APROBADO` or `APROBADO CON OBSERVACIONES`**:
114
+ - If `refacil-sdd/changes/<changeName>/.review-last-fails.json` exists: delete it (CA-08) — run `rm -f "refacil-sdd/changes/<changeName>/.review-last-fails.json"`.
115
+
88
116
  ### Step 3: Create `.review-passed` marker (if applicable)
89
117
 
90
118
  Parse the ` ```refacil-review-result ` block from the sub-agent. If `verdict` is **APROBADO** or **APROBADO CON OBSERVACIONES** and `changeName` is not null:
@@ -69,6 +69,24 @@ Parse the `refacil-test-result` block from the sub-agent:
69
69
  - **If `passed: false`** (tests failed): present the `issues` from the JSON and ask the user how to proceed. **Do not continue to Step 4** until the tests pass.
70
70
  - **If `passed: true`**: continue to Step 4.
71
71
 
72
+ ### Step 3.5: Write memory.yaml (CA-16 — cross-skill state)
73
+
74
+ After parsing the `refacil-test-result` block and only if `passed: true`:
75
+ - Extract from the result or from the briefing: `commandsRun` (list of test commands executed), `criteriaRun` (list of CA-XX/CR-XX covered by tests), `stackDetected` (if the tester identified the stack).
76
+ - Write or update `refacil-sdd/changes/<changeName>/memory.yaml` preserving any existing fields:
77
+
78
+ ```yaml
79
+ lastStep: test
80
+ stackDetected: <detected stack or omit>
81
+ commandsRun:
82
+ - <test command used>
83
+ criteriaRun:
84
+ - CA-01
85
+ - CR-01
86
+ ```
87
+
88
+ If the file already exists, merge: update `lastStep`, `stackDetected`, `commandsRun`, `criteriaRun`; preserve fields from other steps (e.g. `touchedFiles` from apply).
89
+
72
90
  ### Step 4: Flow continuity (only if tests passed)
73
91
 
74
92
  Add:
@@ -27,6 +27,16 @@ If you already have a `changeName`, run `refacil-sdd-ai sdd status <changeName>
27
27
 
28
28
  If **this session** inspects the change directory before or after delegating, apply **`refacil-prereqs/METHODOLOGY-CONTRACT.md` §8**.
29
29
 
30
+ ### Step 0.6: Verify validator agent is installed (blocking — CA-12)
31
+
32
+ Before doing anything else, check that `.claude/agents/refacil-validator.md` exists (read by explicit path or `ls -la .claude/agents/refacil-validator.md`).
33
+
34
+ **If the file does NOT exist**, stop immediately:
35
+ ```
36
+ El agente `refacil-validator` no está instalado. Ejecuta `/refacil:update` y reinicia la sesión antes de volver a correr `/refacil:verify`.
37
+ ```
38
+ Do not continue and do not escalate to any other agent.
39
+
30
40
  ### Step 1: Build briefing for the sub-agent (reduces validator tool calls)
31
41
 
32
42
  Before invoking the sub-agent, extract the context that the validator would otherwise calculate on its own:
@@ -40,6 +50,11 @@ Before invoking the sub-agent, extract the context that the validator would othe
40
50
 
41
51
  3. **Scope files** — run `git diff --name-only HEAD` to get the files modified in this change.
42
52
 
53
+ 4. **Cross-skill memory** — if `changeName` is not null and `refacil-sdd/changes/<changeName>/memory.yaml` exists, read it and extract:
54
+ - `commandsRun` — the test command(s) already executed by the tester. Include in the briefing so the validator uses the same command without re-discovering it.
55
+ - `criteriaRun` — the CA-XX/CR-XX already tested. Include in the briefing so the validator can skip re-reading specs for those criteria.
56
+ If the file does not exist, omit these fields — do not block (CR-04).
57
+
43
58
  Build the BRIEFING block:
44
59
 
45
60
  ```
@@ -54,6 +69,8 @@ criteria:
54
69
  - CR-01: <description>
55
70
  changedFiles: [path/file-1.ts, ...]
56
71
  mode: concise | detailed
72
+ commandsRun: [<command>, ...] # from memory.yaml — omit if not present
73
+ criteriaRun: [CA-01, CR-01, ...] # from memory.yaml — omit if not present
57
74
  ```
58
75
 
59
76
  ### Step 2: Delegate to the refacil-validator sub-agent
@@ -73,7 +90,18 @@ The sub-agent:
73
90
 
74
91
  Show the user the **combined report** (everything before the `refacil-verify-result` block). Do not show the JSON block — it is internal metadata.
75
92
 
76
- **If the sub-agent returned a scope error** (without JSON block): propagate to the user and ask for clarification.
93
+ **If the sub-agent failed to load** (tool error, agent type not found, or no response at all): stop immediately and do NOT escalate to any other agent:
94
+ ```
95
+ The validator sub-agent could not be loaded — retry or run `/refacil:verify` again.
96
+ ```
97
+
98
+ **If the sub-agent responded but without a `refacil-verify-result` block** (unstructured output): show the raw report and stop:
99
+ ```
100
+ The validator returned an unstructured report — continue manually.
101
+ ```
102
+ Do not re-invoke a different agent.
103
+
104
+ **If the sub-agent returned a scope error** (`SCOPE_ERROR: <reason>`, without JSON block): propagate to the user and ask for clarification. This is NOT the CA-01 failsafe — the agent loaded correctly but found an ambiguous scope.
77
105
 
78
106
  ### Step 4: Process the result
79
107
 
@@ -124,5 +152,8 @@ Do you want me to apply these corrections? (yes/no)
124
152
  - **Corrections are ONLY applied by this wrapper** (Step 5), after explicit approval.
125
153
  - **Corrections must be surgical**: only what is necessary to resolve the reported issues.
126
154
  - Maximum 2 rounds of automatic correction before escalating to manual.
127
- - If the sub-agent returned something out of format, inform: "The validator returned an unstructured reportcontinue manually."
155
+ - **Sub-agent failsafe (CA-01)**: if the validator fails to load (tool error) or returns no responsestop and inform the user. Do NOT escalate to any other agent.
156
+ - **Unstructured output (CA-02)**: if the validator responds but without a `refacil-verify-result` block — show the raw report and stop. Do NOT re-invoke another agent.
157
+ - **SCOPE_ERROR (CR-03)**: if the validator returns `SCOPE_ERROR: <reason>` — propagate and ask for clarification. CA-01 does NOT apply here.
158
+ - **Agent missing (CA-12)**: checked in Step 0.6 — stop before delegating if `.claude/agents/refacil-validator.md` is absent.
128
159
  - **Flow continuity**: if the result is APPROVED and the user confirms affirmatively, immediately invoke the **Skill tool** with `skill: "refacil:review"`. (See `METHODOLOGY-CONTRACT.md §5`.)