gemstack-ai 1.0.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/.agents/rules/01-gemstack-core.md +15 -0
  2. package/.agents/rules/02-gemstack-constitution.md +12 -1
  3. package/.agents/skills/gemstack-handoff/SKILL.md +2 -1
  4. package/.agents/skills/gemstack-plan/SKILL.md +3 -1
  5. package/.agents/skills/gemstack-qa/SKILL.md +3 -0
  6. package/.agents/skills/gemstack-review/SKILL.md +7 -5
  7. package/.agents/skills/gemstack-ship/SKILL.md +10 -1
  8. package/.agents/skills/gemstack-spec/SKILL.md +4 -2
  9. package/.agents/skills/gemstack-tasks/SKILL.md +5 -3
  10. package/.gemstack/state.json +18 -2
  11. package/CHANGELOG.md +84 -0
  12. package/MANUAL.md +4 -4
  13. package/README.md +49 -8
  14. package/RELEASE_NOTES.md +129 -0
  15. package/assets/logo.jpg +0 -0
  16. package/docs/architecture-consistency.md +156 -0
  17. package/docs/spec-driven-development.md +26 -0
  18. package/gemstack-ai-1.2.0.tgz +0 -0
  19. package/handoff.md +40 -40
  20. package/package.json +3 -2
  21. package/scripts/ci/smoke-cli.js +1 -0
  22. package/specs/006-architecture-consistency-engine/.gemstack.json +9 -0
  23. package/specs/006-architecture-consistency-engine/plan.md +319 -0
  24. package/specs/006-architecture-consistency-engine/spec.md +179 -0
  25. package/specs/006-architecture-consistency-engine/tasks.md +532 -0
  26. package/specs/007-mechanical-test-matrix-closure-evidence/.gemstack.json +5 -0
  27. package/specs/007-mechanical-test-matrix-closure-evidence/closure.json +59 -0
  28. package/specs/007-mechanical-test-matrix-closure-evidence/plan.md +484 -0
  29. package/specs/007-mechanical-test-matrix-closure-evidence/spec.md +597 -0
  30. package/specs/007-mechanical-test-matrix-closure-evidence/tasks.md +536 -0
  31. package/specs/templates/plan.md +41 -0
  32. package/specs/templates/spec.md +35 -0
  33. package/specs/templates/tasks.md +10 -0
  34. package/src/cli.js +15 -4
  35. package/src/commands/collect.js +340 -0
  36. package/src/commands/ship.js +79 -0
  37. package/src/commands/verify.js +433 -0
  38. package/src/lib/closure-context.js +444 -0
  39. package/src/lib/contracts.js +388 -0
  40. package/src/lib/findings.js +227 -0
  41. package/src/lib/hasher.js +103 -0
  42. package/src/lib/runner-adapters.js +347 -0
  43. package/src/lib/state.js +143 -0
  44. package/src/lib/test-matrix.js +187 -0
  45. package/src/mcp-server.js +1 -1
  46. package/template/.agents/rules/01-gemstack-core.md +15 -0
  47. package/template/.agents/rules/02-gemstack-constitution.md +12 -1
  48. package/template/.agents/skills/gemstack-handoff/SKILL.md +2 -1
  49. package/template/.agents/skills/gemstack-plan/SKILL.md +2 -1
  50. package/template/.agents/skills/gemstack-review/SKILL.md +7 -5
  51. package/template/.agents/skills/gemstack-ship/SKILL.md +5 -0
  52. package/template/.agents/skills/gemstack-spec/SKILL.md +3 -2
  53. package/template/.agents/skills/gemstack-tasks/SKILL.md +4 -3
  54. package/template/docs/architecture-consistency.md +144 -0
  55. package/template/specs/templates/plan.md +11 -0
  56. package/template/specs/templates/spec.md +17 -0
  57. package/template/specs/templates/tasks.md +1 -0
  58. package/gemstack-ai-1.0.1.tgz +0 -0
@@ -0,0 +1,187 @@
1
+ const crypto = require('node:crypto');
2
+ const { normalizeContent } = require('./hasher');
3
+
4
+ const CANONICAL_LAYERS = ['UNIT', 'INTEGRATION', 'E2E', 'CLI'];
5
+ const CANONICAL_GATES = ['REQUIRED', 'SUPPLEMENTAL'];
6
+ const CANONICAL_ID_REGEX = /^TEST-[A-Z0-9]+-[A-Z0-9]+$/;
7
+ const REQUIRED_FIELDS = ['id', 'category', 'layer', 'description', 'pass_criteria', 'gate'];
8
+
9
+ /**
10
+ * Extracts the single column-0 gemstack-test-matrix block from markdown.
11
+ *
12
+ * @param {string} markdownContent
13
+ * @returns {{ matrix: Array<object>|null, isLegacy: boolean }}
14
+ */
15
+ function extractTestMatrixBlock(markdownContent) {
16
+ const normalized = normalizeContent(markdownContent);
17
+ const lines = normalized.split('\n');
18
+ const fence = '```';
19
+ const header = '```gemstack-test-matrix';
20
+
21
+ const blocks = [];
22
+ let inBlock = false;
23
+ let blockLines = [];
24
+
25
+ for (const line of lines) {
26
+ if (!inBlock) {
27
+ if (line.trimEnd() === header) {
28
+ inBlock = true;
29
+ blockLines = [];
30
+ }
31
+ } else {
32
+ if (line.trimEnd() === fence) {
33
+ inBlock = false;
34
+ blocks.push(blockLines.join('\n'));
35
+ } else {
36
+ blockLines.push(line);
37
+ }
38
+ }
39
+ }
40
+
41
+ if (blocks.length === 0) {
42
+ return { matrix: null, isLegacy: true };
43
+ }
44
+
45
+ if (blocks.length > 1) {
46
+ const err = new Error(`Multiple gemstack-test-matrix blocks detected (${blocks.length}). Exactly one is permitted.`);
47
+ err.code = 'TEST_MATRIX_PARSE_ERROR';
48
+ throw err;
49
+ }
50
+
51
+ const jsonRaw = blocks[0].trim();
52
+ let parsed;
53
+ try {
54
+ parsed = JSON.parse(jsonRaw);
55
+ } catch (parseErr) {
56
+ const err = new Error(`Failed to parse gemstack-test-matrix JSON: ${parseErr.message}`);
57
+ err.code = 'TEST_MATRIX_PARSE_ERROR';
58
+ throw err;
59
+ }
60
+
61
+ return { matrix: parsed, isLegacy: false };
62
+ }
63
+
64
+ /**
65
+ * Validates a canonical test matrix array.
66
+ *
67
+ * @param {any} matrix
68
+ * @returns {Array<object>} Sanitized array of canonical test objects
69
+ */
70
+ function validateTestMatrix(matrix) {
71
+ if (!Array.isArray(matrix)) {
72
+ const err = new Error('gemstack-test-matrix must be a JSON array of test objects');
73
+ err.code = 'TEST_MATRIX_INVALID_SHAPE';
74
+ throw err;
75
+ }
76
+
77
+ const seenIds = new Set();
78
+ const validated = [];
79
+
80
+ for (let i = 0; i < matrix.length; i++) {
81
+ const item = matrix[i];
82
+ if (!item || typeof item !== 'object' || Array.isArray(item)) {
83
+ const err = new Error(`Item at index ${i} in gemstack-test-matrix must be a non-null object`);
84
+ err.code = 'TEST_MATRIX_INVALID_SHAPE';
85
+ throw err;
86
+ }
87
+
88
+ // Check unknown fields
89
+ const keys = Object.keys(item);
90
+ for (const k of keys) {
91
+ if (!REQUIRED_FIELDS.includes(k)) {
92
+ const err = new Error(`Item at index ${i} contains unknown field: "${k}"`);
93
+ err.code = 'TEST_MATRIX_INVALID_SHAPE';
94
+ throw err;
95
+ }
96
+ }
97
+
98
+ // Check required fields and empty values
99
+ for (const rf of REQUIRED_FIELDS) {
100
+ if (!(rf in item)) {
101
+ const err = new Error(`Item at index ${i} missing required field: "${rf}"`);
102
+ err.code = 'TEST_MATRIX_INVALID_SHAPE';
103
+ throw err;
104
+ }
105
+ if (typeof item[rf] !== 'string' || item[rf].trim().length === 0) {
106
+ const err = new Error(`Item at index ${i} field "${rf}" must be a non-empty string`);
107
+ err.code = 'TEST_MATRIX_INVALID_SHAPE';
108
+ throw err;
109
+ }
110
+ }
111
+
112
+ // Validate ID regex
113
+ if (!CANONICAL_ID_REGEX.test(item.id)) {
114
+ const err = new Error(`Item at index ${i} has invalid ID "${item.id}". Must match ^TEST-[A-Z0-9]+-[A-Z0-9]+$`);
115
+ err.code = 'TEST_MATRIX_INVALID_SHAPE';
116
+ throw err;
117
+ }
118
+
119
+ // Validate duplicate ID
120
+ if (seenIds.has(item.id)) {
121
+ const err = new Error(`Duplicate test ID detected in gemstack-test-matrix: "${item.id}"`);
122
+ err.code = 'TEST_MATRIX_DUPLICATE_ID';
123
+ throw err;
124
+ }
125
+ seenIds.add(item.id);
126
+
127
+ // Validate enum fields
128
+ if (!CANONICAL_LAYERS.includes(item.layer)) {
129
+ const err = new Error(`Item "${item.id}" has invalid layer "${item.layer}". Must be one of: ${CANONICAL_LAYERS.join(', ')}`);
130
+ err.code = 'TEST_MATRIX_INVALID_SHAPE';
131
+ throw err;
132
+ }
133
+
134
+ if (!CANONICAL_GATES.includes(item.gate)) {
135
+ const err = new Error(`Item "${item.id}" has invalid gate "${item.gate}". Must be one of: ${CANONICAL_GATES.join(', ')}`);
136
+ err.code = 'TEST_MATRIX_INVALID_SHAPE';
137
+ throw err;
138
+ }
139
+
140
+ validated.push({
141
+ id: item.id,
142
+ category: item.category,
143
+ layer: item.layer,
144
+ description: item.description,
145
+ pass_criteria: item.pass_criteria,
146
+ gate: item.gate
147
+ });
148
+ }
149
+
150
+ return validated;
151
+ }
152
+
153
+ /**
154
+ * Computes deterministic SHA-256 acceptanceSignature digest over canonical test matrix.
155
+ *
156
+ * @param {Array<object>} matrix
157
+ * @returns {string} 64-character lowercase hexadecimal digest
158
+ */
159
+ function computeAcceptanceSignature(matrix) {
160
+ const validated = validateTestMatrix(matrix);
161
+
162
+ // Sort canonical records by id using deterministic code-unit ordering
163
+ const sorted = [...validated].sort((a, b) => (a.id < b.id ? -1 : (a.id > b.id ? 1 : 0)));
164
+
165
+ // Normalize each record with ASCII-sorted keys: category, description, gate, id, layer, pass_criteria
166
+ const normalizedRecords = sorted.map(rec => ({
167
+ category: rec.category,
168
+ description: rec.description,
169
+ gate: rec.gate,
170
+ id: rec.id,
171
+ layer: rec.layer,
172
+ pass_criteria: rec.pass_criteria
173
+ }));
174
+
175
+ const canonicalJson = JSON.stringify(normalizedRecords);
176
+ return crypto.createHash('sha256').update(canonicalJson, 'utf8').digest('hex');
177
+ }
178
+
179
+ module.exports = {
180
+ CANONICAL_LAYERS,
181
+ CANONICAL_GATES,
182
+ CANONICAL_ID_REGEX,
183
+ REQUIRED_FIELDS,
184
+ extractTestMatrixBlock,
185
+ validateTestMatrix,
186
+ computeAcceptanceSignature
187
+ };
package/src/mcp-server.js CHANGED
@@ -7,7 +7,7 @@
7
7
  const fs = require('fs');
8
8
  const path = require('path');
9
9
  const readline = require('readline');
10
- const manifest = require('../lib/manifest');
10
+ const manifest = require('./lib/manifest');
11
11
 
12
12
  // MCP Protocol structures
13
13
  function sendResponse(id, result, error = null) {
@@ -13,6 +13,7 @@ Eres Antigravity operando bajo el framework **Gemstack**, una metodología local
13
13
  2. **Aprobación para Deploy/Push:** Nunca hagas `git push`, merge o deploy sin aprobación explícita.
14
14
  3. **Handoff Inmutable:** NUNCA borres la sección "Intentos fallidos" de `handoff.md`. Si crece demasiado, mueve de forma segura el contenido antiguo a `handoff_archive.md`.
15
15
  4. **Dependencias y Auth:** Cambios a la arquitectura de autenticación, migraciones de base de datos o instalación de dependencias globales requieren generación de plan técnico y aprobación humana.
16
+ 5. **Consistencia de Arquitectura y Congelamiento de Fases (Upgrade A):** Las decisiones arquitectónicas congeladas en `gemstack-contracts` no pueden ser contradichas silenciosamente por fases posteriores. Toda enmienda requiere aprobación humana explícita.
16
17
 
17
18
  ## Pseudo-Comandos (Ruteo Obligatorio)
18
19
  Si el usuario empieza su mensaje con uno de estos comandos, **NO improvises. DEBES cargar o seguir el skill correspondiente**:
@@ -49,3 +50,17 @@ Si el usuario empieza su mensaje con uno de estos comandos, **NO improvises. DEB
49
50
  - `/guard` -> Invoca `gemstack-guard`
50
51
  - `/unfreeze` -> Invoca `gemstack-guard`
51
52
 
53
+ ## Ruteo Semántico por Intención (Intent-Based Routing)
54
+ Si el usuario interactúa en lenguaje natural sin usar un `/comando` explícito, DEBES detectar la intención subyacente y activar el protocolo correspondiente:
55
+ 1. **Nueva funcionalidad o módulo mayor sin spec activa:**
56
+ - Si pide crear o agregar una feature sustancial (ej. "pon una parte para editar paquetes", "vamos a agregar cobro bimoneda"), **NO saltes directo al código**. Activa `gemstack-spec` para definir requisitos y criterios de éxito antes de implementar.
57
+ 2. **Solicitud de pruebas o validación:**
58
+ - Si el usuario dice "haz pruebas", "valida lo hecho", "comprueba que funcione" o "verifica los cambios", activa `gemstack-qa`.
59
+ 3. **Reporte de error o bug:**
60
+ - Si el usuario reporta que algo falló o no funciona como se esperaba, activa `gemstack-investigate` (principio: *No fixes before investigation*).
61
+ 4. **Cierre o pausa de sesión:**
62
+ - Si el usuario indica "terminamos por hoy", "voy a pausar", "dejo esto listo" o "prepara el resumen", activa `gemstack-handoff`.
63
+ 5. **Auditoría de seguridad:**
64
+ - Si pide revisar seguridad, permisos, tokens o vulnerabilidades, activa `gemstack-cso`.
65
+ 6. **Entrega o preparación de release:**
66
+ - Si pide preparar el merge, PR o entrega formal de la feature terminada, activa `gemstack-ship`.
@@ -14,11 +14,16 @@ Toda nueva funcionalidad DEBE nacer y estar estructurada preferentemente como un
14
14
  ## Article II: CLI / Interface Mandate
15
15
  Cada módulo o librería clave debe tener una forma de probarse e interactuar textualmente (CLI, scripts independientes, peticiones directas de texto o JSON). Evita componentes opacos que solo puedan probarse levantando interfaces gráficas complejas.
16
16
 
17
- ## Article III: Test-First Imperative (NON-NEGOTIABLE)
17
+ ## Article III: Test-First Imperative & Zero Silent Failures (NON-NEGOTIABLE)
18
18
  NUNCA escribas el código de implementación antes que los tests (TDD).
19
19
  1. Escribe los tests (unitarios, de integración o contratos) basándote en la especificación.
20
20
  2. Si es posible, demuestra que fallan.
21
21
  3. Solo entonces, escribe la implementación real.
22
+ 4. **Zero Silent Failures (Multiplataforma Windows / Linux / macOS):**
23
+ - PROHIBIDO el uso de operadores de supresión de shell que enmascaren fallos en scripts de `test` de `package.json` (ej. `2>nul`, `2>/dev/null || true`).
24
+ - El script de test DEBE terminar con exit code distinto de cero si ocurre cualquier falla.
25
+ - En monorepos TypeScript, usa runners multiplataforma estandarizados (ej. `tsx --test src/**/*.test.ts tests/**/*.test.ts`, `node --test`, `vitest` o `jest`).
26
+ - El test runner debe validar que la suite ejecutó efectivamente pruebas (`tests > 0`). Un reporte de 0 tests ejecutados finalizando con exit code 0 es considerado un falso positivo inaceptable.
22
27
 
23
28
  ## Article IV: Zero Assumptions (No Hallucinations)
24
29
  Si un requerimiento del humano es vago, la IA NO debe adivinar.
@@ -42,3 +47,9 @@ Usa las funciones del framework y librerías estándar nativamente en lugar de c
42
47
 
43
48
  ## Article IX: Integration-First Testing
44
49
  Prioriza el testing realista. Si puedes probar el contrato real o la base de datos local real (con un entorno temporal) por encima de mocks complejos, hazlo. El código generado debe funcionar en la práctica.
50
+
51
+ ## Article X: Architecture Consistency & Immutability Gate (Upgrade A)
52
+ Las decisiones arquitectónicas congeladas no pueden ser contradichas silenciosamente por fases posteriores.
53
+ - Antes de avanzar de fase, el hash del artefacto aguas arriba debe ser válido, los contratos compatibles y la cantidad de bloqueadores deterministas abiertos debe ser exactamente 0.
54
+ - Los artefactos de fases aprobadas quedan sellados criptográficamente (SHA-256) y no pueden mutar sin enmienda explícita aprobada por humanos.
55
+ - Proyectos preexistentes sin bloques de contratos operan en modo LEGACY transparente sin fallas.
@@ -17,5 +17,6 @@ Esta habilidad se ejecuta cuando el usuario pide terminar la sesión, invoca `/h
17
17
  5. **ARCHIVADO SEGURO:** Si "Intentos fallidos" en `handoff.md` tiene demasiados puntos (más de 10-15), CORTA los elementos más antiguos y pégalos en `handoff_archive.md` bajo su lista, conservando solo los 3-5 intentos recientes en `handoff.md`.
18
18
  6. Define los "5. Próximos pasos" exactos para la próxima sesión.
19
19
  7. Guarda los cambios en `handoff.md` (y `handoff_archive.md` si fue necesario).
20
- 8. Despídete del usuario indicando que el handoff está listo.
20
+ 8. **Sincronización de Estado:** Verifica `.gemstack/state.json` asegurando que `current_phase` refleje con precisión si hay una spec activa o en espera, y actualiza `last_update` con la marca temporal actual.
21
+ 9. Despídete del usuario indicando que el handoff está listo.
21
22
 
@@ -16,5 +16,6 @@ Invocado mediante `/plan`.
16
16
  4. Genera `specs/[nombre-feature]/plan.md` usando `specs/templates/plan.md`.
17
17
  5. Detalla el stack y llena la tabla "Complexity Tracking" SÓLO si rompiste alguna regla de la constitución y necesitas justificarlo.
18
18
  6. Opcionalmente, genera los entregables satélites: `data-model.md`, `contracts/` (para APIs/Interfaces), y `quickstart.md`.
19
- 7. Pide aprobación al usuario antes de permitir la ejecución de `/tasks`.
19
+ 7. **Herencia y Contratos Aditivos (Upgrade A)**: PLAN hereda automáticamente los contratos declarados en `spec.md`. No contradigas ni alteres los contratos congelados heredados; si requieres contratos técnicos adicionales, decláralos de forma compatible y aditiva en el bloque ````gemstack-contracts ```` de `plan.md`.
20
+ 8. Pide aprobación al usuario antes de permitir la ejecución de `/tasks`.
20
21
 
@@ -11,8 +11,10 @@ Invocado mediante `/review`.
11
11
 
12
12
  ## Proceso:
13
13
  1. Analiza el código modificado (git diff, o archivos editados).
14
- 2. Verifica que las convenciones arquitectónicas del proyecto se respeten.
15
- 3. VERIFICACIÓN DE SEGURIDAD: Revisa obligatoriamente `.agents/rules/03-gemstack-security.md` para garantizar que el código propuesto no introduzca brechas de seguridad (IDOR, XSS, tokens expuestos).
16
- 4. Verifica que los tests cubran adecuadamente los cambios.
17
- 5. Emite sugerencias o aplica correcciones automáticas si son triviales.
18
- 6. Si el código está listo, sugiere `/qa` o `/ship`.
14
+ 2. **Validación Determinista Primero (Upgrade A)**: Ejecuta `node src/cli.js verify` o comprueba contratos congelados, hashes de fase y bloqueadores antes de proceder a la revisión semántica.
15
+ 3. Proporciona al revisor la lista de contratos efectivos, hashes de fase y hallazgos deterministas para no forzarlo a redescubrir desviaciones mecánicas.
16
+ 4. Verifica que las convenciones arquitectónicas del proyecto se respeten.
17
+ 5. VERIFICACIÓN DE SEGURIDAD: Revisa obligatoriamente `.agents/rules/03-gemstack-security.md` para garantizar que el código propuesto no introduzca brechas de seguridad (IDOR, XSS, tokens expuestos).
18
+ 6. Verifica que los tests cubran adecuadamente los cambios.
19
+ 7. Emite sugerencias o aplica correcciones automáticas si son triviales.
20
+ 8. Si el código está listo, sugiere `/qa` o `/ship`.
@@ -16,4 +16,9 @@ Invocado mediante `/ship`.
16
16
  4. Genera un PR summary si se pide.
17
17
  5. NO hagas push, merge o deploy sin aprobación explícita.
18
18
  6. Sugiere ejecutar `/handoff` para documentar la entrega en la memoria del proyecto.
19
+ 7. **Sincronización de Estado:** Actualiza `.gemstack/state.json`:
20
+ - Establece `"active_spec": null`
21
+ - Registra `"last_completed_feature": "specs/[nombre-feature]/"`
22
+ - Establece `"current_phase": "shipped"`
23
+ - Actualiza `"last_update"` con el timestamp ISO actual.
19
24
 
@@ -19,6 +19,7 @@ Eres un Product Manager técnico. Tu objetivo es convertir ideas vagas en requis
19
19
  4. El documento DEBE incluir: Historias de usuario priorizadas (P1, P2) que sean independientemente testeables, Criterios de Éxito medibles, y Casos Extremos.
20
20
  5. **CERO SUPOSICIONES**: Si el usuario omitió detalles, NO adivines. Usa el marcador `[NEEDS CLARIFICATION: tu duda]` en el documento.
21
21
  6. No describas implementación técnica (nada de stacks, bases de datos o APIs). Concéntrate estrictamente en el "Qué" y "Por qué".
22
- 7. Actualiza el archivo `.gemstack/state.json` para reflejar la rama activa: `{"active_spec": "specs/[nombre-feature]/"}` y el timestamp.
23
- 8. Una vez finalizado, indica al usuario que puede revisar la especificación y, tras resolver las dudas, ejecutar `/plan`.
22
+ 7. **Contratos Arquitectónicos Congelados (Upgrade A)**: Si la funcionalidad implica decisiones estructurales críticas (estados enum, tuplas de identidad, reglas de procedencia, invariantes booleanas, límites de roadmap o límites boundary), decláralos explícitamente en el bloque canónico ````gemstack-contracts ````. Congela solo decisiones materiales, no texto arbitrario.
23
+ 8. Actualiza el archivo `.gemstack/state.json` para reflejar la rama activa y fase: `{"active_spec": "specs/[nombre-feature]/", "current_phase": "spec", "last_update": "<timestamp>"}`.
24
+ 9. Una vez finalizado, indica al usuario que puede revisar la especificación y, tras resolver las dudas, ejecutar `/plan`.
24
25
 
@@ -12,7 +12,8 @@ Invocado mediante `/tasks`.
12
12
  ## Proceso:
13
13
  1. Lee `specs/[nombre-feature]/plan.md` y, si existen, `data-model.md` y la carpeta `contracts/`.
14
14
  2. Convierte los contratos, entidades y el plan en una lista estricta de ejecución en `specs/[nombre-feature]/tasks.md` usando la plantilla `specs/templates/tasks.md`.
15
- 3. Aplica Test-First: Las tareas de escribir pruebas (y validarlas) deben ir ANTES que la implementación de código.
16
- 4. Usa el marcador `[P]` para tareas independientes que se puedan paralelizar.
17
- 5. Ofrece al usuario comenzar automáticamente con la primera tarea o delegar a subagentes paralelos si hay múltiples `[P]`.
15
+ 3. **Herencia de Contratos (Upgrade A)**: TASKS hereda automáticamente los contratos consolidados de SPEC y PLAN. No se requiere declarar un bloque de contratos propio salvo que se agreguen contratos operacionales específicos de tareas.
16
+ 4. Aplica Test-First: Las tareas de escribir pruebas (y validarlas) deben ir ANTES que la implementación de código.
17
+ 5. Usa el marcador `[P]` para tareas independientes que se puedan paralelizar.
18
+ 6. Ofrece al usuario comenzar automáticamente con la primera tarea o delegar a subagentes paralelos si hay múltiples `[P]`.
18
19
 
@@ -0,0 +1,144 @@
1
+ # Architecture Consistency & Phase Freezing
2
+
3
+ Gemstack includes a native, deterministic **Architecture Consistency Engine** and **Phase Freezing** protocol. It prevents AI agents from silently introducing contradictions, architectural drift, or unauthorized mutations across the Spec-Driven Development lifecycle.
4
+
5
+ ---
6
+
7
+ ## 1. The Architecture Consistency Problem
8
+
9
+ In complex AI coding projects, language models often agree to constraints in a specification (such as "zero external dependencies" or "single tenant isolation"), but later quietly contradict them in implementation or tasks (e.g. installing unauthorized packages).
10
+
11
+ Gemstack solves this mechanically at the framework layer:
12
+ 1. Architectural decisions are declared as formal, machine-verifiable **contracts**.
13
+ 2. Upstream phases (`SPEC`, `PLAN`, `TASKS`) are cryptographically **frozen**.
14
+ 3. Downstream phases inherit contracts and are mechanically compared for contradictions.
15
+ 4. Any contradiction or mutation immediately halts execution as a deterministic blocker.
16
+
17
+ ---
18
+
19
+ ## 2. Canonical Contract Block Format
20
+
21
+ Contracts are declared inside phase markdown files (`spec.md`, `plan.md`, `tasks.md`) within a column-0 fenced code block:
22
+
23
+ ```gemstack-contracts
24
+ [
25
+ {
26
+ "id": "zero-dependency-core",
27
+ "type": "BOOLEAN_INVARIANT",
28
+ "value": true
29
+ },
30
+ {
31
+ "id": "database-engine",
32
+ "type": "ENUM_SET",
33
+ "values": ["sqlite", "postgres"]
34
+ },
35
+ {
36
+ "id": "external-sync",
37
+ "type": "BOUNDARY",
38
+ "value": "FORBIDDEN"
39
+ }
40
+ ]
41
+ ```
42
+
43
+ ### Block Parsing Rules
44
+ - **Exactly One Block**: Each phase document may contain at most one `gemstack-contracts` block. Multiple blocks trigger a `CONTRACT_PARSE_ERROR`.
45
+ - **Legacy Mode**: Phase documents with 0 contract blocks operate in **LEGACY** mode without errors or blocking.
46
+ - **Strict Encoding**: UTF-8 without BOM is required; CRLF and LF line endings are canonically normalized to LF.
47
+
48
+ ---
49
+
50
+ ## 3. The Six Canonical Contract Types
51
+
52
+ Gemstack enforces six deterministic contract types:
53
+
54
+ | Contract Type | Value Shape | Description / Evaluation |
55
+ |---|---|---|
56
+ | `ENUM_SET` | `values: string[]` | Closed set of allowed identifiers. Order-insensitive. Downstream cannot add unapproved values. |
57
+ | `IDENTITY_TUPLE` | `tuple: string[]` | Immutable composite tuple. Order-insensitive, duplicate-sensitive, exact-member matching. |
58
+ | `PROVENANCE_RULE` | `source: string, rule: string` | Origin and lineage constraints. Downstream cannot omit or alter provenance. |
59
+ | `BOOLEAN_INVARIANT` | `value: boolean` | Strict binary invariant (e.g. `true` for zero-dependency). Downstream contradiction is blocked. |
60
+ | `BOUNDARY` | `value: "FORBIDDEN" | "REQUIRED"` | Hard system boundary. Only `FORBIDDEN` and `REQUIRED` are valid. |
61
+ | `ROADMAP_LIMIT` | `value: string | number` | Milestone or scope bound (e.g. max task count). Downstream cannot expand beyond the limit. |
62
+
63
+ ---
64
+
65
+ ## 4. Cross-Phase Contract Inheritance
66
+
67
+ Contracts follow a strict unidirectional inheritance hierarchy:
68
+
69
+ ```
70
+ SPEC (declares base contracts)
71
+
72
+
73
+ PLAN (inherits SPEC contracts + may add technical contracts)
74
+
75
+
76
+ TASKS (inherits consolidated SPEC + PLAN contracts)
77
+ ```
78
+
79
+ - **Inheritance**: Downstream phases automatically inherit all upstream contracts. An inherited contract does not need to be re-declared downstream unless adding specific attributes.
80
+ - **Equivalence**: Redeclaring an inherited contract with identical semantics passes validation.
81
+ - **Contradiction**: Redeclaring an inherited contract with contradictory values triggers `FROZEN_CONTRACT_VIOLATION` and blocks execution.
82
+ - **Additive Extension**: Downstream phases may introduce new contract IDs as long as they do not conflict with existing contracts.
83
+
84
+ ---
85
+
86
+ ## 5. Phase Freezing & Mutation Detection
87
+
88
+ When a phase is completed and approved by the human supervisor, its artifact is cryptographically sealed:
89
+ - **Canonical Hash**: Normalized SHA-256 (64 lowercase hexadecimal characters).
90
+ - **CRLF Normalization**: All line breaks are normalized to LF (`\n`) prior to hashing, ensuring identical digests across Windows, macOS, and Linux.
91
+ - **UTF-8 BOM Forbidden**: Leading Byte Order Marks trigger `CONTRACT_PARSE_ERROR`.
92
+ - **Mutation Detection**: If an upstream artifact (`spec.md` or `plan.md`) is modified after approval, `gemstack verify` detects the hash mismatch and halts with `FROZEN_ARTIFACT_CHANGED`.
93
+
94
+ > **VERIFY != FREEZE**: `gemstack verify`, `gemstack doctor`, and agent reviews are strictly read-only and **never** overwrite or mutate accepted phase hashes.
95
+
96
+ ---
97
+
98
+ ## 6. Findings & Anti-Loop Lifecycle
99
+
100
+ When a consistency rule is violated, Gemstack generates a structured **Finding**:
101
+ - **Canonical Fingerprint**: Full 64-character lowercase SHA-256 digest computed over `{ code, contractId, phase, location }`.
102
+ - **Display Token**: First 12 characters of the fingerprint for human-readable CLI display.
103
+ - **Finding Lifecycle**:
104
+ - `OPEN`: Active blocker preventing shipping.
105
+ - `RESOLVED`: Violation was corrected in artifacts.
106
+ - `ACCEPTED_EXCEPTION`: Formally approved human exception.
107
+ - `SUPERSEDED`: Replaced by a subsequent finding.
108
+ - **Anti-Loop Protection**: If a previously `RESOLVED` defect re-appears in subsequent runs, it is immediately re-opened to `OPEN`.
109
+
110
+ ---
111
+
112
+ ## 7. Accepted Exceptions & Context Hash
113
+
114
+ When an architectural deviation is intentionally approved by a human supervisor, it is recorded in the feature sidecar with a cryptographic `contextHash`:
115
+
116
+ `contextHash = SHA-256(upstreamAcceptedHash + currentComparedHash + normalizedContract)`
117
+
118
+ If the upstream phase artifact, compared phase artifact, or contract representation changes, the suppression is automatically invalidated and the violation re-opens as a blocking finding.
119
+
120
+ ---
121
+
122
+ ## 8. State & Persistence Boundary
123
+
124
+ Gemstack strictly separates operational state from historical audit trails:
125
+ - **`.gemstack/state.json`**: Lightweight operational state only (active feature, completed phases, guard mode, verification summary). Historical finding arrays are forbidden in this file.
126
+ - **`specs/<feature>/.gemstack.json`**: Per-feature sidecar hosting the complete audit log, phase hash history, finding fingerprints, and accepted exceptions.
127
+ - **Atomic Operations**: All state writes use temporary file creation and atomic file renaming to prevent corruption during unexpected shutdowns or process kills.
128
+
129
+ ---
130
+
131
+ ## 9. Verification Integration (`gemstack verify`)
132
+
133
+ Architectural consistency is embedded as **Step 4/5** in the unified `gemstack verify` command:
134
+
135
+ ```text
136
+ [INFO] --- 4/5 Verificación de Consistencia de Arquitectura y Hashes de Fase ---
137
+ [OK] [STRUCTURED] 5 contrato(s) base declarados en spec.md.
138
+ [OK] Hash congelado de spec.md verificado: f5d423eaf508...
139
+ [OK] Hash congelado de plan.md verificado: 1ce0e5886342...
140
+ [OK] Hash congelado de tasks.md verificado: dfad2484ad11...
141
+ [OK] Verificación de consistencia arquitectónica aprobada (0 bloqueadores).
142
+ ```
143
+
144
+ If any contracts contradict, artifacts mutate, or unapproved blockers exist, `gemstack verify` exits with code 1, halting CI/CD pipelines.
@@ -36,3 +36,14 @@ ruta/archivo: [Razón]
36
36
  | Violación de Regla | Por qué es necesario | Alternativa simple rechazada por |
37
37
  |--------------------|----------------------|-----------------------------------|
38
38
  | [Ej. Wrapper] | [Razón] | [Razón] |
39
+
40
+ ## 6. Contratos Aditivos del Plan (Opcional - Upgrade A)
41
+ <!--
42
+ Hereda automáticamente los contratos de spec.md.
43
+ Si se requieren contratos técnicos adicionales compatibles, declararlos aquí en un bloque canónico.
44
+ No modifiques contratos de spec sin aprobación explícita de enmienda.
45
+ -->
46
+ ```gemstack-contracts
47
+ [
48
+ ]
49
+ ```
@@ -33,3 +33,20 @@
33
33
  ## 5. Entidades Clave (Data / Models)
34
34
  - **[Entidad 1]**: [Representación abstracta]
35
35
  - **[Entidad 2]**: [Relación]
36
+
37
+ ## 6. Contratos Arquitectónicos Congelados (Opcional - Upgrade A)
38
+ <!--
39
+ Declara decisiones arquitectónicas congeladas usando el bloque canónico.
40
+ Tipos soportados: ENUM_SET, IDENTITY_TUPLE, PROVENANCE_RULE, BOOLEAN_INVARIANT, BOUNDARY, ROADMAP_LIMIT.
41
+ Si no se incluye este bloque, la feature operará en modo LEGACY.
42
+ -->
43
+ ```gemstack-contracts
44
+ [
45
+ {
46
+ "id": "feature-invariants",
47
+ "type": "BOOLEAN_INVARIANT",
48
+ "value": true,
49
+ "description": "Invariante principal congelada para este feature"
50
+ }
51
+ ]
52
+ ```
@@ -4,6 +4,7 @@
4
4
  Instrucciones:
5
5
  - Marca con `[P]` las tareas que sean seguras de paralelizar (por ej. si usas múltiples subagentes).
6
6
  - Incluye la redacción y validación de TESTS ANTES de la implementación real.
7
+ - Hereda los contratos congelados de SPEC y PLAN por defecto (no se requiere bloque de contratos).
7
8
  -->
8
9
 
9
10
  ## Fase 1: Tests (Test-First Imperative)
Binary file