specatlas 0.1.0 → 0.1.2
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/dist/bin.js +54 -45
- package/package.json +5 -3
- package/profiles/dotnet-sqlserver.yaml +36 -0
- package/profiles/generic.yaml +19 -0
- package/profiles/node-ts.yaml +38 -0
- package/profiles/python.yaml +36 -0
- package/workflow/phases/adopt.md +51 -0
- package/workflow/phases/archive.md +43 -0
- package/workflow/phases/build.md +52 -0
- package/workflow/phases/fix.md +31 -0
- package/workflow/phases/mockup.md +54 -0
- package/workflow/phases/plan.md +48 -0
- package/workflow/phases/review.md +28 -0
- package/workflow/phases/specify.md +51 -0
- package/workflow/phases/verify.md +41 -0
- package/workflow/snippets/evidencia.md +21 -0
- package/workflow/snippets/reglas-negocio.md +10 -0
package/dist/bin.js
CHANGED
|
@@ -8768,6 +8768,30 @@ function highlightCode(code, language, enabled) {
|
|
|
8768
8768
|
function splitRow(line) {
|
|
8769
8769
|
return line.trim().replace(/^\|/, "").replace(/\|$/, "").split("|").map((cell) => cell.trim());
|
|
8770
8770
|
}
|
|
8771
|
+
function tableOfContents(markdown2, maxLevel = 2) {
|
|
8772
|
+
const entries = [];
|
|
8773
|
+
let inFence = false;
|
|
8774
|
+
for (const line of markdown2.replace(/\r\n?/g, "\n").split("\n")) {
|
|
8775
|
+
if (/^```/.test(line)) {
|
|
8776
|
+
inFence = !inFence;
|
|
8777
|
+
continue;
|
|
8778
|
+
}
|
|
8779
|
+
if (inFence) continue;
|
|
8780
|
+
const match = /^(#{1,4})\s+(.*)$/.exec(line);
|
|
8781
|
+
if (!match) continue;
|
|
8782
|
+
const level = (match[1] ?? "").length;
|
|
8783
|
+
if (level > maxLevel) continue;
|
|
8784
|
+
const text = match[2] ?? "";
|
|
8785
|
+
entries.push({ level, text, id: slugify(text) });
|
|
8786
|
+
}
|
|
8787
|
+
return entries;
|
|
8788
|
+
}
|
|
8789
|
+
function renderToc(entries, title) {
|
|
8790
|
+
if (entries.length === 0) return "";
|
|
8791
|
+
const items = entries.map((entry) => `<li class="toc-h${entry.level}"><a href="#${entry.id}">${inlineMarkdown(entry.text)}</a></li>`).join("");
|
|
8792
|
+
return `<nav class="atlas-toc"><h2>${escapeHtml(title)}</h2><ul>${items}</ul></nav>
|
|
8793
|
+
`;
|
|
8794
|
+
}
|
|
8771
8795
|
function renderMarkdown(markdown2, opts = {}) {
|
|
8772
8796
|
const highlight = opts.highlight !== false;
|
|
8773
8797
|
const mermaidMode = opts.mermaid ?? "code";
|
|
@@ -8900,7 +8924,11 @@ function renderMarkdown(markdown2, opts = {}) {
|
|
|
8900
8924
|
i += 1;
|
|
8901
8925
|
}
|
|
8902
8926
|
flush();
|
|
8903
|
-
|
|
8927
|
+
const html = out.join("\n");
|
|
8928
|
+
if (opts.toc) {
|
|
8929
|
+
return renderToc(tableOfContents(markdown2), opts.tocTitle ?? "\xCDndice") + html;
|
|
8930
|
+
}
|
|
8931
|
+
return html;
|
|
8904
8932
|
}
|
|
8905
8933
|
|
|
8906
8934
|
// ../core/dist/index.js
|
|
@@ -12753,6 +12781,7 @@ import path20 from "path";
|
|
|
12753
12781
|
|
|
12754
12782
|
// ../adapters/dist/index.js
|
|
12755
12783
|
import path18 from "path";
|
|
12784
|
+
import { stringify as stringifyYaml5 } from "yaml";
|
|
12756
12785
|
import path22 from "path";
|
|
12757
12786
|
async function loadWorkflow(workflowDir) {
|
|
12758
12787
|
const phasesDir = path18.join(workflowDir, "phases");
|
|
@@ -12806,6 +12835,15 @@ var NO_SUBSTITUTION_NOTE = "<!-- Si al invocar indicaste un slug, \xFAsalo; si n
|
|
|
12806
12835
|
function vars(language, slugToken, commandPrefix) {
|
|
12807
12836
|
return { SLUG: slugToken, LANGUAGE: language, LANGUAGE_NAME: LANGUAGE_NAMES[language], SDD_DIR: ".sdd", COMMAND_PREFIX: commandPrefix };
|
|
12808
12837
|
}
|
|
12838
|
+
function frontmatter(data, body) {
|
|
12839
|
+
const yaml2 = stringifyYaml5(data, { lineWidth: 0 }).trimEnd();
|
|
12840
|
+
return `---
|
|
12841
|
+
${yaml2}
|
|
12842
|
+
---
|
|
12843
|
+
|
|
12844
|
+
${body}
|
|
12845
|
+
`;
|
|
12846
|
+
}
|
|
12809
12847
|
function renderFor(ctx, phase, slugToken) {
|
|
12810
12848
|
return renderPhase(phase.body, ctx.sources.snippets, vars(ctx.language, slugToken, ctx.commandPrefix));
|
|
12811
12849
|
}
|
|
@@ -12834,23 +12872,12 @@ function compileOpencode(ctx) {
|
|
|
12834
12872
|
files.push({
|
|
12835
12873
|
target: "opencode",
|
|
12836
12874
|
path: `.opencode/command/satlas-${phase.id}.md`,
|
|
12837
|
-
content:
|
|
12838
|
-
description: ${phase.description}
|
|
12839
|
-
---
|
|
12840
|
-
|
|
12841
|
-
${commandBody}
|
|
12842
|
-
`
|
|
12875
|
+
content: frontmatter({ description: phase.description }, commandBody)
|
|
12843
12876
|
});
|
|
12844
12877
|
files.push({
|
|
12845
12878
|
target: "opencode",
|
|
12846
12879
|
path: `.opencode/skills/satlas-${phase.id}/SKILL.md`,
|
|
12847
|
-
content:
|
|
12848
|
-
name: satlas-${phase.id}
|
|
12849
|
-
description: ${phase.description}
|
|
12850
|
-
---
|
|
12851
|
-
|
|
12852
|
-
${skillBody}
|
|
12853
|
-
`
|
|
12880
|
+
content: frontmatter({ name: `satlas-${phase.id}`, description: phase.description }, skillBody)
|
|
12854
12881
|
});
|
|
12855
12882
|
}
|
|
12856
12883
|
return files;
|
|
@@ -12863,23 +12890,12 @@ function compileClaudeCode(ctx) {
|
|
|
12863
12890
|
files.push({
|
|
12864
12891
|
target: "claude-code",
|
|
12865
12892
|
path: `.claude/commands/satlas/${phase.id}.md`,
|
|
12866
|
-
content:
|
|
12867
|
-
description: ${phase.description}
|
|
12868
|
-
---
|
|
12869
|
-
|
|
12870
|
-
${commandBody}
|
|
12871
|
-
`
|
|
12893
|
+
content: frontmatter({ description: phase.description }, commandBody)
|
|
12872
12894
|
});
|
|
12873
12895
|
files.push({
|
|
12874
12896
|
target: "claude-code",
|
|
12875
12897
|
path: `.claude/skills/satlas-${phase.id}/SKILL.md`,
|
|
12876
|
-
content:
|
|
12877
|
-
name: satlas-${phase.id}
|
|
12878
|
-
description: ${phase.description}
|
|
12879
|
-
---
|
|
12880
|
-
|
|
12881
|
-
${skillBody}
|
|
12882
|
-
`
|
|
12898
|
+
content: frontmatter({ name: `satlas-${phase.id}`, description: phase.description }, skillBody)
|
|
12883
12899
|
});
|
|
12884
12900
|
}
|
|
12885
12901
|
return files;
|
|
@@ -12891,14 +12907,7 @@ function compileCursor(ctx) {
|
|
|
12891
12907
|
files.push({
|
|
12892
12908
|
target: "cursor",
|
|
12893
12909
|
path: `.cursor/skills/satlas-${phase.id}/SKILL.md`,
|
|
12894
|
-
content:
|
|
12895
|
-
name: satlas-${phase.id}
|
|
12896
|
-
description: ${phase.description}
|
|
12897
|
-
disable-model-invocation: true
|
|
12898
|
-
---
|
|
12899
|
-
|
|
12900
|
-
${body}
|
|
12901
|
-
`
|
|
12910
|
+
content: frontmatter({ name: `satlas-${phase.id}`, description: phase.description, "disable-model-invocation": true }, body)
|
|
12902
12911
|
});
|
|
12903
12912
|
files.push({
|
|
12904
12913
|
target: "cursor",
|
|
@@ -12918,16 +12927,9 @@ function compileCopilot(ctx) {
|
|
|
12918
12927
|
files.push({
|
|
12919
12928
|
target: "copilot",
|
|
12920
12929
|
path: `.github/prompts/satlas-${phase.id}.prompt.md`,
|
|
12921
|
-
content:
|
|
12922
|
-
description: ${phase.description}
|
|
12923
|
-
name: satlas-${phase.id}
|
|
12924
|
-
agent: agent
|
|
12925
|
-
---
|
|
12930
|
+
content: frontmatter({ description: phase.description, name: `satlas-${phase.id}`, agent: "agent" }, `${NO_SUBSTITUTION_NOTE}
|
|
12926
12931
|
|
|
12927
|
-
${
|
|
12928
|
-
|
|
12929
|
-
${body}
|
|
12930
|
-
`
|
|
12932
|
+
${body}`)
|
|
12931
12933
|
});
|
|
12932
12934
|
}
|
|
12933
12935
|
files.push({ target: "copilot", path: ".github/copilot-instructions.md", content: agentsBlock(ctx, "copilot") });
|
|
@@ -13757,7 +13759,14 @@ async function runInit(ctx) {
|
|
|
13757
13759
|
});
|
|
13758
13760
|
const compiled = [];
|
|
13759
13761
|
const workflowDir = await resolveWorkflowDir();
|
|
13760
|
-
if (workflowDir
|
|
13762
|
+
if (!workflowDir) {
|
|
13763
|
+
result.diagnostics.push({
|
|
13764
|
+
code: "ATLAS-ADAPTERS-003",
|
|
13765
|
+
severity: "error",
|
|
13766
|
+
message: "No se encontr\xF3 la carpeta workflow/phases con las fuentes de prompts: no se compilaron los adaptadores",
|
|
13767
|
+
suggestion: "Verifica la instalaci\xF3n del CLI o define SPECATLAS_WORKFLOW_DIR apuntando a la carpeta workflow del paquete"
|
|
13768
|
+
});
|
|
13769
|
+
} else if (!result.diagnostics.some((d) => d.severity === "error")) {
|
|
13761
13770
|
const loaded = await loadConfig(result.sddDir);
|
|
13762
13771
|
const agentsFlag = flagString(ctx.flags, "agents");
|
|
13763
13772
|
const requested = agentsFlag ? agentsFlag.split(",").map((t) => t.trim()).filter((t) => t.length > 0) : loaded.config.adapters.targets;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "specatlas",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "SpecAtlas: kernel determinista de Spec-Driven Development (CLI)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -10,7 +10,9 @@
|
|
|
10
10
|
},
|
|
11
11
|
"main": "dist/bin.js",
|
|
12
12
|
"files": [
|
|
13
|
-
"dist"
|
|
13
|
+
"dist",
|
|
14
|
+
"workflow",
|
|
15
|
+
"profiles"
|
|
14
16
|
],
|
|
15
17
|
"engines": {
|
|
16
18
|
"node": ">=20"
|
|
@@ -37,7 +39,7 @@
|
|
|
37
39
|
"zod": "^3.24.1"
|
|
38
40
|
},
|
|
39
41
|
"devDependencies": {
|
|
40
|
-
"@specatlas/adapters": "0.1.
|
|
42
|
+
"@specatlas/adapters": "0.1.1",
|
|
41
43
|
"@specatlas/core": "0.1.0"
|
|
42
44
|
},
|
|
43
45
|
"scripts": {
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
name: dotnet-sqlserver
|
|
2
|
+
display_name: .NET + SQL Server
|
|
3
|
+
detection:
|
|
4
|
+
files:
|
|
5
|
+
- '**/*.cs'
|
|
6
|
+
- '**/*.csproj'
|
|
7
|
+
- '**/*.sln'
|
|
8
|
+
manifests:
|
|
9
|
+
- file: '*.sln'
|
|
10
|
+
contains: []
|
|
11
|
+
- file: '*.csproj'
|
|
12
|
+
contains: []
|
|
13
|
+
priority: 20
|
|
14
|
+
domains:
|
|
15
|
+
- backend
|
|
16
|
+
- database
|
|
17
|
+
commands:
|
|
18
|
+
build: dotnet build
|
|
19
|
+
test: dotnet test
|
|
20
|
+
lint: dotnet format --verify-no-changes
|
|
21
|
+
format: dotnet format
|
|
22
|
+
verify:
|
|
23
|
+
executable:
|
|
24
|
+
- dotnet test
|
|
25
|
+
automatic:
|
|
26
|
+
- dotnet build
|
|
27
|
+
manual:
|
|
28
|
+
- Ejecución del flujo contra la base de datos de desarrollo
|
|
29
|
+
rollback: Script SQL de rollback por objeto afectado + revertir el commit.
|
|
30
|
+
antipatterns:
|
|
31
|
+
- DML directo sobre tablas históricas
|
|
32
|
+
- Endpoints sin autenticación
|
|
33
|
+
- Cambios de base de datos sin script de rollback
|
|
34
|
+
assumptions:
|
|
35
|
+
- .NET LTS
|
|
36
|
+
- SQL Server accesible en desarrollo
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
name: generic
|
|
2
|
+
display_name: Genérico (cualquier stack)
|
|
3
|
+
detection:
|
|
4
|
+
files: []
|
|
5
|
+
manifests: []
|
|
6
|
+
priority: 0
|
|
7
|
+
domains:
|
|
8
|
+
- other
|
|
9
|
+
commands: {}
|
|
10
|
+
verify:
|
|
11
|
+
executable: []
|
|
12
|
+
automatic: []
|
|
13
|
+
manual:
|
|
14
|
+
- Confirmación humana explícita del resultado observado
|
|
15
|
+
rollback: Revierte los archivos tocados al estado anterior (git revert o restaurar backup).
|
|
16
|
+
antipatterns:
|
|
17
|
+
- Inventar comandos de build/test que el proyecto no tiene
|
|
18
|
+
assumptions:
|
|
19
|
+
- El stack no está cubierto por un perfil específico
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
name: node-ts
|
|
2
|
+
display_name: Node + TypeScript
|
|
3
|
+
detection:
|
|
4
|
+
files:
|
|
5
|
+
- '**/*.ts'
|
|
6
|
+
- '**/*.tsx'
|
|
7
|
+
- package.json
|
|
8
|
+
manifests:
|
|
9
|
+
- file: package.json
|
|
10
|
+
contains:
|
|
11
|
+
- typescript
|
|
12
|
+
priority: 10
|
|
13
|
+
domains:
|
|
14
|
+
- backend
|
|
15
|
+
- frontend
|
|
16
|
+
- fullstack
|
|
17
|
+
- testing
|
|
18
|
+
commands:
|
|
19
|
+
build: npm run build
|
|
20
|
+
lint: npm run lint
|
|
21
|
+
test: npm test
|
|
22
|
+
format: npm run format
|
|
23
|
+
verify:
|
|
24
|
+
executable:
|
|
25
|
+
- npm test
|
|
26
|
+
- npm run lint
|
|
27
|
+
automatic:
|
|
28
|
+
- Búsqueda de efectos colaterales con grep
|
|
29
|
+
manual:
|
|
30
|
+
- Prueba manual del flujo principal en desarrollo
|
|
31
|
+
rollback: Revierte el commit y deshaz migraciones si el cambio las incluye.
|
|
32
|
+
antipatterns:
|
|
33
|
+
- SQL concatenado en lugar de consultas parametrizadas
|
|
34
|
+
- Secretos versionados o logueados
|
|
35
|
+
- console.log olvidados en producción
|
|
36
|
+
assumptions:
|
|
37
|
+
- Node LTS
|
|
38
|
+
- El proyecto declara sus scripts en package.json
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
name: python
|
|
2
|
+
display_name: Python
|
|
3
|
+
detection:
|
|
4
|
+
files:
|
|
5
|
+
- '**/*.py'
|
|
6
|
+
- pyproject.toml
|
|
7
|
+
- requirements.txt
|
|
8
|
+
manifests:
|
|
9
|
+
- file: pyproject.toml
|
|
10
|
+
contains: []
|
|
11
|
+
- file: requirements.txt
|
|
12
|
+
contains: []
|
|
13
|
+
priority: 10
|
|
14
|
+
domains:
|
|
15
|
+
- backend
|
|
16
|
+
- other
|
|
17
|
+
commands:
|
|
18
|
+
build: ''
|
|
19
|
+
lint: ruff check .
|
|
20
|
+
test: pytest
|
|
21
|
+
format: ruff format .
|
|
22
|
+
verify:
|
|
23
|
+
executable:
|
|
24
|
+
- pytest
|
|
25
|
+
- ruff check .
|
|
26
|
+
automatic:
|
|
27
|
+
- Revisión de imports y efectos colaterales
|
|
28
|
+
manual:
|
|
29
|
+
- Ejecución manual del flujo principal
|
|
30
|
+
rollback: Revierte el commit; si hay migraciones, aplica el downgrade correspondiente.
|
|
31
|
+
antipatterns:
|
|
32
|
+
- Excepciones silenciadas sin log
|
|
33
|
+
- Credenciales en el código
|
|
34
|
+
assumptions:
|
|
35
|
+
- Python 3.11+
|
|
36
|
+
- El proyecto declara dependencias (pyproject o requirements)
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: adopt
|
|
3
|
+
title: Adoptar (brownfield)
|
|
4
|
+
description: >-
|
|
5
|
+
Recupera las specs de un proyecto existente: lee el inventario y las anclas, entrevista al usuario y redacta requisitos AS-IS.
|
|
6
|
+
Usar cuando el usuario pide adoptar, documentar o recuperar las specs de un proyecto que ya existe.
|
|
7
|
+
requires: []
|
|
8
|
+
produces:
|
|
9
|
+
- specs/<dominio>/spec.md
|
|
10
|
+
- changes/adopt-<dominio>/spec.md
|
|
11
|
+
arguments: true
|
|
12
|
+
agent:
|
|
13
|
+
mode: primary
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# Fase: Adoptar (brownfield)
|
|
17
|
+
|
|
18
|
+
El contenido se escribe en **{{LANGUAGE_NAME}}**.
|
|
19
|
+
|
|
20
|
+
## Pasos
|
|
21
|
+
|
|
22
|
+
1. Genera el inventario y las specs baseline:
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
satlas adopt
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
2. Lee `.sdd/adopt-report.md`, las anclas de cada `specs/<dominio>/spec.md` y el código real que esas anclas señalan.
|
|
29
|
+
3. Por cada dominio, **entrevista al usuario** (máximo 5 preguntas) para confirmar el comportamiento actual antes de escribirlo. No inventes reglas: si el código no lo aclara, pregunta.
|
|
30
|
+
4. Crea el cambio de adopción y redacta el delta con el comportamiento **actual** (AS-IS):
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
satlas new adopt-<dominio> --domain <dominio>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
- Requisitos `REQ-<DOMINIO>-NNN` con actor, prosa de negocio y reglas `BR-*`.
|
|
37
|
+
- Escenarios `CUANDO/ENTONCES` que describan lo que el sistema hace hoy, incluyendo errores y límites visibles.
|
|
38
|
+
- `## Anclas de implementación` con los archivos/símbolos que respaldan cada requisito (permite detectar drift después).
|
|
39
|
+
5. Valida y pliega (la adopción documenta lo existente: no requiere tareas ni verificación):
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
satlas validate --change adopt-<dominio>
|
|
43
|
+
satlas archive adopt-<dominio> --yes
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
6. Repite por dominio y reporta la cobertura: dominios adoptados, requisitos recuperados y zonas del código sin requisito (deuda de documentación).
|
|
47
|
+
|
|
48
|
+
## Prohibido
|
|
49
|
+
|
|
50
|
+
- Escribir requisitos de comportamiento que no exista hoy (eso es un cambio: usa `satlas new`).
|
|
51
|
+
- Copiar nombres técnicos a la spec: la spec es de negocio aunque documente lo existente.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: archive
|
|
3
|
+
title: Archivar
|
|
4
|
+
description: >-
|
|
5
|
+
Cierra el cambio: pliega los deltas en la spec viva y mueve el cambio al histórico.
|
|
6
|
+
Usar cuando el usuario pide archivar, cerrar o dar por terminado un cambio.
|
|
7
|
+
requires:
|
|
8
|
+
- changes/<slug>/verify.md
|
|
9
|
+
produces:
|
|
10
|
+
- specs/<dominio>/spec.md
|
|
11
|
+
arguments: true
|
|
12
|
+
agent:
|
|
13
|
+
mode: primary
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# Fase: Archivar
|
|
17
|
+
|
|
18
|
+
## Precondición
|
|
19
|
+
|
|
20
|
+
- Sin tareas pendientes y con evidencia `pass` por escenario (`satlas trace --change {{SLUG}}`).
|
|
21
|
+
- Sin hallazgos críticos abiertos en `review.md` (si el carril lo exige).
|
|
22
|
+
|
|
23
|
+
## Pasos
|
|
24
|
+
|
|
25
|
+
1. Revisa el plan (seco) antes de tocar nada:
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
satlas archive {{SLUG}} --dry-run
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
2. Si el plegado es correcto (agregados/modificados/eliminados/renombrados esperados), archiva:
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
satlas archive {{SLUG}} --yes
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
3. Verifica el resultado: `specs/<dominio>/spec.md` versionado y `changes/archive/AAAA-MM-{{SLUG}}/` con la historia; `INDEX.md` regenerado.
|
|
38
|
+
4. Reporta: requisitos plegados, versión de la spec viva y ubicación del archivo.
|
|
39
|
+
|
|
40
|
+
## Prohibido
|
|
41
|
+
|
|
42
|
+
- Editar la spec viva a mano: el plegado lo hace el CLI de forma determinista.
|
|
43
|
+
- Archivar con evidencia fallida o tareas pendientes.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: build
|
|
3
|
+
title: Construir
|
|
4
|
+
description: >-
|
|
5
|
+
Implementa las tareas del cambio por olas paralelas, con evidencia y sin tocar los artefactos aprobados.
|
|
6
|
+
Usar cuando el usuario pide construir, implementar o codificar las tareas.
|
|
7
|
+
requires:
|
|
8
|
+
- changes/<slug>/tasks.md
|
|
9
|
+
produces:
|
|
10
|
+
- código y pruebas del cambio
|
|
11
|
+
arguments: true
|
|
12
|
+
agent:
|
|
13
|
+
mode: primary
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# Fase: Construir
|
|
17
|
+
|
|
18
|
+
## Precondición
|
|
19
|
+
|
|
20
|
+
- `satlas trace --change {{SLUG}}` sin errores y `satlas status` en "construyendo" (o "aprobado/planificado").
|
|
21
|
+
- Si hay tareas pendientes y la spec cambió sin re-aprobar, detente.
|
|
22
|
+
|
|
23
|
+
## Pasos
|
|
24
|
+
|
|
25
|
+
1. Lee `tasks.md`. Calcula olas:
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
satlas waves --change {{SLUG}}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
2. Ejecuta **bloque por bloque** y **ola por ola**:
|
|
32
|
+
- Confirma con el usuario el bloque y su mapa de olas antes de empezar.
|
|
33
|
+
- Dentro de una ola, ejecuta las tareas en paralelo solo si no comparten archivos; si comparten, secuéncialas.
|
|
34
|
+
- Cada tarea: implementa exactamente su `Archivos:`, respeta `Cubre:` y deja el código funcionando.
|
|
35
|
+
- Al cerrar cada tarea, marca `- [x]` en `tasks.md` (una sola edición por bloque).
|
|
36
|
+
3. Tras cada bloque:
|
|
37
|
+
- Ejecuta la validación del perfil (build/lint/test) y captura el resultado.
|
|
38
|
+
- Commitea solo el código (nunca `.sdd/` en commits de build).
|
|
39
|
+
4. Si una tarea falla: reintenta (máx. 3), si sigue fallando detén el bloque y reporta con el log.
|
|
40
|
+
5. Al terminar todas las tareas, cierra con:
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
satlas trace --change {{SLUG}}
|
|
44
|
+
satlas status
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Prohibido
|
|
48
|
+
|
|
49
|
+
- Modificar `spec.md`, `plan.md` o `meta.yaml` (los artefactos aprobados son inmutables).
|
|
50
|
+
- Ejecutar `git` dentro de subagentes.
|
|
51
|
+
- Marcar tareas sin haber ejecutado la validación correspondiente.
|
|
52
|
+
- Dar por terminado sin evidencia (esa es la fase de verificación).
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: fix
|
|
3
|
+
title: Fix express
|
|
4
|
+
description: >-
|
|
5
|
+
Carril express para incidentes (bug, hotfix, configuración): un solo artefacto, con causa raíz, cambio mínimo y evidencia.
|
|
6
|
+
Usar cuando el usuario pide arreglar un bug, un hotfix o un cambio pequeño sin ceremonia completa.
|
|
7
|
+
requires: []
|
|
8
|
+
produces:
|
|
9
|
+
- changes/<slug>/fix.md
|
|
10
|
+
arguments: true
|
|
11
|
+
agent:
|
|
12
|
+
mode: primary
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# Fase: Fix express (incidente)
|
|
16
|
+
|
|
17
|
+
Un solo artefacto: `.sdd/changes/{{SLUG}}/fix.md`. El contenido se escribe en **{{LANGUAGE_NAME}}**.
|
|
18
|
+
|
|
19
|
+
## Pasos
|
|
20
|
+
|
|
21
|
+
1. Reproduce el problema o reúne la evidencia de que ocurre (log, pantalla, datos).
|
|
22
|
+
2. Investiga la causa raíz en el código real; cita `archivo:línea`.
|
|
23
|
+
3. Aplica el **cambio mínimo** que corrige la causa (no aproveches para refactorizar).
|
|
24
|
+
4. Escribe `fix.md` con: `## Síntoma`, `## Causa raíz`, `## Cambio`, `## Rollback` y un bloque `evidence`.
|
|
25
|
+
5. Verifica que el síntoma ya no ocurre y que no rompiste nada alrededor (validación del perfil).
|
|
26
|
+
6. Si el arreglo revela alcance de feature (no de incidente), **promuévelo**: crea un cambio normal con `satlas new` y pásalo a especificación.
|
|
27
|
+
|
|
28
|
+
## Prohibido
|
|
29
|
+
|
|
30
|
+
- Tocar la spec viva o los artefactos de otros cambios.
|
|
31
|
+
- Mezclar en el mismo fix varios problemas no relacionados.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: mockup
|
|
3
|
+
title: Mockups
|
|
4
|
+
description: >-
|
|
5
|
+
Genera mockups profesionales (web/mobile) como contrato visual de la propuesta: alta fidelidad, estados, responsive y accesibles.
|
|
6
|
+
Usar cuando el usuario pide mockups, prototipos visuales o la propuesta visual del cambio.
|
|
7
|
+
requires:
|
|
8
|
+
- changes/<slug>/spec.md
|
|
9
|
+
produces:
|
|
10
|
+
- changes/<slug>/mockups/*.html
|
|
11
|
+
arguments: true
|
|
12
|
+
agent:
|
|
13
|
+
mode: primary
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# Fase: Mockups (contrato visual)
|
|
17
|
+
|
|
18
|
+
El contenido se escribe en **{{LANGUAGE_NAME}}**.
|
|
19
|
+
|
|
20
|
+
## Pasos
|
|
21
|
+
|
|
22
|
+
1. Prepara el plan y el manifiesto:
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
satlas mockup {{SLUG}}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
2. Lee el plan (`changes/{{SLUG}}/mockups/plan.yaml`), la spec, el glosario y, si existen, `design/tokens.json` o `DESIGN.md` (sistema de diseño del proyecto).
|
|
29
|
+
3. Genera **un HTML autocontenido por pantalla** (`changes/{{SLUG}}/mockups/<id>.html`) con calidad de producto:
|
|
30
|
+
- banner fijo visible: `MOCKUP · NO FUNCIONAL · vX · fecha`;
|
|
31
|
+
- datos reales del dominio (prohibido Lorem ipsum, "Item 1" o textos de relleno);
|
|
32
|
+
- estados completos conmutables (`data-state`): default, loading, vacío, error; en mobile también offline;
|
|
33
|
+
- responsive real (390 / 768 / 1440) y tema claro/oscuro si el proyecto lo define;
|
|
34
|
+
- accesibilidad: contraste AA, foco visible, áreas táctiles ≥ 44 px, jerarquía semántica;
|
|
35
|
+
- navegación entre pantallas con enlaces relativos entre archivos;
|
|
36
|
+
- sin recursos externos: sin CDN, sin fuentes remotas, sin `http(s)://`; embebe lo necesario.
|
|
37
|
+
4. Valida y corrige hasta que no haya errores:
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
satlas mockup {{SLUG}} --check
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
5. Opcional (si hay Playwright instalado): captura de pantallas por breakpoint.
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
satlas mockup {{SLUG}} --capture
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
6. Reporta las pantallas generadas, los escenarios que ilustra cada una y el resultado de la validación.
|
|
50
|
+
|
|
51
|
+
## Prohibido
|
|
52
|
+
|
|
53
|
+
- Aprobar mockups sin estados ni responsive, o que no sigan los tokens del proyecto cuando existen.
|
|
54
|
+
- Añadir lógica real o datos personales reales en el mockup.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: plan
|
|
3
|
+
title: Planificar
|
|
4
|
+
description: >-
|
|
5
|
+
Crea el plan técnico y las tareas trazadas de un cambio ya aprobado.
|
|
6
|
+
Usar cuando el usuario pide planificar, diseñar la solución o desglosar tareas.
|
|
7
|
+
requires:
|
|
8
|
+
- changes/<slug>/spec.md
|
|
9
|
+
produces:
|
|
10
|
+
- changes/<slug>/plan.md
|
|
11
|
+
- changes/<slug>/tasks.md
|
|
12
|
+
arguments: true
|
|
13
|
+
agent:
|
|
14
|
+
mode: primary
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
# Fase: Planificar (técnico)
|
|
18
|
+
|
|
19
|
+
El contenido se escribe en **{{LANGUAGE_NAME}}**. El plan es interno: puede (y debe) hablar de tecnología; la spec no se toca.
|
|
20
|
+
|
|
21
|
+
## Precondición
|
|
22
|
+
|
|
23
|
+
- La spec del cambio debe estar aprobada (`satlas status` no debe decir "esperando aprobación").
|
|
24
|
+
- Si no lo está, detente y pide la aprobación.
|
|
25
|
+
|
|
26
|
+
## Pasos
|
|
27
|
+
|
|
28
|
+
1. Lee `.sdd/changes/{{SLUG}}/spec.md`, `.sdd/constitution.md`, `.sdd/profiles/detected.yaml`, `.sdd/profiles/custom/*` y el código real que vayas a tocar (anclas AS-IS: existe / no existe / blast radius).
|
|
29
|
+
2. Escribe `plan.md` con las secciones canónicas:
|
|
30
|
+
1. Contexto AS-IS · 2. Enfoque técnico (con alternativas descartadas) · 3. **Diagramas** · 4. Diseño por capa/módulos · 5. Matriz de trazabilidad (REQ → tareas) · 6. Matriz de paridad AS-IS → TO-BE (solo refactors sustitutivos) · 7. Tareas (referencia) · 8. Riesgos y mitigaciones · 9. Rollback · 10. Dependencias y supuestos.
|
|
31
|
+
3. En `## 3. Diagramas` incluye los diagramas mermaid que el cambio necesite: `erDiagram` si toca datos, `sequenceDiagram` si hay integración/API/jobs, `flowchart` si hay proceso o validaciones, `stateDiagram-v2` si hay estados, `classDiagram` si el dominio no es trivial, diagrama de arquitectura si hay módulos nuevos.
|
|
32
|
+
4. Escribe `tasks.md` con la gramática canónica (separador ` · `):
|
|
33
|
+
- `## Bloque N — Título` y `- [ ] T<N>.<seq> Acción · Archivos: ruta · Cubre: REQ-…-S1 · Depende de: T<N>.<seq> · Reversión: cómo revertir`
|
|
34
|
+
- Tareas atómicas (una acción por tarea). Trabajo de infraestructura sin requisito: `· Infra`.
|
|
35
|
+
5. Valida y planifica olas:
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
satlas trace --change {{SLUG}}
|
|
39
|
+
satlas waves --change {{SLUG}}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
6. Reporta: bloques, tareas, olas, riesgos y cualquier hueco de trazabilidad (debe quedar en 0 errores).
|
|
43
|
+
|
|
44
|
+
## Prohibido
|
|
45
|
+
|
|
46
|
+
- Tareas sin archivo concreto o sin requisito (salvo `· Infra`).
|
|
47
|
+
- Modificar la spec aprobada (si falta algo, vuelve a especificar y re-aprueba).
|
|
48
|
+
- Prometer horas: estima talla y confianza, con supuestos.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: review
|
|
3
|
+
title: Revisar
|
|
4
|
+
description: >-
|
|
5
|
+
Revisión de código con lentes por tamaño del diff y verificación adversarial de hallazgos.
|
|
6
|
+
Usar cuando el usuario pide revisar el código antes del PR.
|
|
7
|
+
requires:
|
|
8
|
+
- changes/<slug>/tasks.md
|
|
9
|
+
produces:
|
|
10
|
+
- changes/<slug>/review.md
|
|
11
|
+
arguments: true
|
|
12
|
+
agent:
|
|
13
|
+
mode: primary
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# Fase: Revisar (código)
|
|
17
|
+
|
|
18
|
+
## Pasos
|
|
19
|
+
|
|
20
|
+
1. Obtén el diff completo del cambio (`git diff` contra la rama base).
|
|
21
|
+
2. Elige el nivel:
|
|
22
|
+
- Diff pequeño: una pasada con dos lentes: **corrección** (¿hace lo que dice la spec?) y **estándares** (perfil + constitución).
|
|
23
|
+
- Diff grande (> 400 líneas) o ruta sensible: tres lentes (corrección, seguridad, mantenibilidad) y un verificador adversarial.
|
|
24
|
+
3. **Verificación adversarial**: cada hallazgo se intenta refutar contra el código real. Etiquetas:
|
|
25
|
+
- `CONFIRMADO` (evidencia `archivo:línea`), `RENUNCIADO` (no se pudo refutar: mantener severidad), `REFUTADO` (con evidencia).
|
|
26
|
+
- Nunca marcar `REFUTADO` sin `archivo:línea`.
|
|
27
|
+
4. Escribe `.sdd/changes/{{SLUG}}/review.md`: hallazgos con severidad, evidencia, decisión y estado.
|
|
28
|
+
5. Crítico confirmado = bloquea el PR hasta corregirlo o registrar un override con motivo, autor y fecha.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: specify
|
|
3
|
+
title: Especificar
|
|
4
|
+
description: >-
|
|
5
|
+
Escribe o refina la especificación funcional de un cambio (delta) en lenguaje de negocio.
|
|
6
|
+
Usar cuando el usuario pide especificar, definir requisitos, redactar la spec o crear un cambio.
|
|
7
|
+
requires: []
|
|
8
|
+
produces:
|
|
9
|
+
- changes/<slug>/spec.md
|
|
10
|
+
arguments: true
|
|
11
|
+
agent:
|
|
12
|
+
mode: primary
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# Fase: Especificar (spec funcional y de negocio)
|
|
16
|
+
|
|
17
|
+
{{>reglas-negocio}}
|
|
18
|
+
|
|
19
|
+
## Objetivo
|
|
20
|
+
|
|
21
|
+
Escribir el delta de especificación del cambio `{{SLUG}}` en `.sdd/changes/{{SLUG}}/spec.md`.
|
|
22
|
+
El contenido se escribe en **{{LANGUAGE_NAME}}**.
|
|
23
|
+
|
|
24
|
+
## Pasos
|
|
25
|
+
|
|
26
|
+
1. Lee `.sdd/constitution.md`, `.sdd/glossary.md` y las specs vivas de `.sdd/specs/**/spec.md` que toquen el dominio.
|
|
27
|
+
2. Si hay código existente relacionado, inspecciónalo solo para entender el comportamiento actual (AS-IS); no lo describas con tecnología en la spec.
|
|
28
|
+
3. Si falta información de negocio, **pregunta** (máximo 5 preguntas concretas) antes de escribir. No inventes reglas.
|
|
29
|
+
4. Redacta el delta con las secciones canónicas:
|
|
30
|
+
- `## Requisitos agregados` (`ADDED`), `## Requisitos modificados` (`MODIFIED`), `## Requisitos eliminados` (`REMOVED`), `## Requisitos renombrados` (`RENAMED`).
|
|
31
|
+
- Cada requisito: `### Requisito: REQ-<DOMINIO>-NNN — Título` (ids inmutables), prosa de negocio, reglas `- Regla BR-<DOMINIO>-NNN: ...` y escenarios `#### Escenario: REQ-<DOMINIO>-NNN-S1 — Título` con `- **CUANDO** ...` / `- **ENTONCES** ...`.
|
|
32
|
+
- Incluye siempre escenarios de error, vacío, sin permiso y límites.
|
|
33
|
+
- `MODIFIED` copia el bloque **completo** del requisito tal como está en la spec viva y lo edita.
|
|
34
|
+
- `REMOVED` declara `- Motivo:` y `- Migración:`.
|
|
35
|
+
5. Verifica con el CLI y corrige hasta que no haya errores:
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
satlas validate --change {{SLUG}}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
6. Reporta: número de requisitos y escenarios, supuestos, y las preguntas que quedaron abiertas.
|
|
42
|
+
|
|
43
|
+
## Prohibido
|
|
44
|
+
|
|
45
|
+
- Nombres de tablas, campos, endpoints, clases, archivos, frameworks o librerías.
|
|
46
|
+
- Adjetivos vagos ("rápido", "fácil", "varios", "robusto") sin un valor medible.
|
|
47
|
+
- Renumerar ids existentes o reescribir un requisito aprobado sin pasar por `MODIFIED`/`REMOVED`.
|
|
48
|
+
|
|
49
|
+
## Salida
|
|
50
|
+
|
|
51
|
+
`changes/{{SLUG}}/spec.md` validado, más un resumen para el usuario y la indicación de que la spec debe aprobarse (`satlas approve`) antes de planificar.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: verify
|
|
3
|
+
title: Verificar
|
|
4
|
+
description: >-
|
|
5
|
+
Registra evidencia real por escenario (comando y resultado) en verify.md.
|
|
6
|
+
Usar cuando el usuario pide verificar, probar o demostrar que el cambio funciona.
|
|
7
|
+
requires:
|
|
8
|
+
- changes/<slug>/tasks.md
|
|
9
|
+
produces:
|
|
10
|
+
- changes/<slug>/verify.md
|
|
11
|
+
arguments: true
|
|
12
|
+
agent:
|
|
13
|
+
mode: primary
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# Fase: Verificar (evidencia por escenario)
|
|
17
|
+
|
|
18
|
+
{{>evidencia}}
|
|
19
|
+
|
|
20
|
+
## Pasos
|
|
21
|
+
|
|
22
|
+
1. Lee el delta y lista **todos** los escenarios (`### Escenario: REQ-…-S1`).
|
|
23
|
+
2. Para cada escenario elige el método más fuerte posible:
|
|
24
|
+
- `executable`: prueba automatizada, petición HTTP, script SQL, Playwright, emulador.
|
|
25
|
+
- `automatic`: comprobación mecánica (grep/inspección) sobre el resultado.
|
|
26
|
+
- `semi`: verificación asistida con revisión humana.
|
|
27
|
+
- `manual`: último recurso, con justificación.
|
|
28
|
+
3. Ejecuta realmente el comando y captura la salida. Hash de la salida:
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
satlas hash "<salida o archivo>" # (F1: satlas verify --record lo hará por ti)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
4. Escribe en `.sdd/changes/{{SLUG}}/verify.md` un bloque `evidence` por escenario con el formato exacto.
|
|
35
|
+
5. Comprueba que no queden huecos:
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
satlas trace --change {{SLUG}} --require-evidence
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
6. Reporta la tabla escenario → método → resultado y cualquier fallo encontrado (un fallo se corrige y se vuelve a verificar; no se marca como pasado).
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
## Formato de evidencia (bloques `evidence`)
|
|
2
|
+
|
|
3
|
+
Un bloque por escenario en `verify.md`, con YAML válido:
|
|
4
|
+
|
|
5
|
+
````markdown
|
|
6
|
+
### REQ-DOMINIO-001-S1 — Título del escenario
|
|
7
|
+
|
|
8
|
+
```evidence
|
|
9
|
+
method: executable # executable | automatic | semi | manual
|
|
10
|
+
command: npm test -- modulo
|
|
11
|
+
result: pass # pass | fail | skipped
|
|
12
|
+
output_hash: sha256:… # hash de la salida (satlas hash)
|
|
13
|
+
date: 2026-01-01T00:00:00Z
|
|
14
|
+
by: tu-nombre
|
|
15
|
+
notes: 12/12 casos
|
|
16
|
+
```
|
|
17
|
+
````
|
|
18
|
+
|
|
19
|
+
- `executable` exige `command` y que el comando se haya ejecutado de verdad.
|
|
20
|
+
- Un resultado `fail` bloquea el PR; se corrige y se registra de nuevo (nuevo bloque con la fecha nueva).
|
|
21
|
+
- No hay evidencia sin comando cuando el método es `executable`, ni "terminado" sin evidencia.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
## Reglas de la especificación de negocio
|
|
2
|
+
|
|
3
|
+
- Se escribe para el usuario del sistema, no para programadores.
|
|
4
|
+
- Cada requisito declara **qué** y **por qué**, nunca **cómo**.
|
|
5
|
+
- Vocabulario: el del glosario (`.sdd/glossary.md`). Si un término no existe, agrégalo al glosario o pregunta.
|
|
6
|
+
- Prohibido: nombres de tablas, campos, endpoints, clases, archivos, frameworks, librerías, SQL, diagramas técnicos y estimaciones.
|
|
7
|
+
- Prohibido: adjetivos no medibles ("rápido", "fácil", "varios", "óptimo", "robusto", "adecuado", "simple").
|
|
8
|
+
- Cada escenario tiene un resultado observable y verificable (`ENTONCES` medible).
|
|
9
|
+
- Todo requisito incluye escenarios de error, caso vacío, falta de permiso y límites.
|
|
10
|
+
- Los ids `REQ-*` y `BR-*` son inmutables: no se renumeran ni se reutilizan.
|