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.
- package/.agents/rules/01-gemstack-core.md +15 -0
- package/.agents/rules/02-gemstack-constitution.md +12 -1
- package/.agents/skills/gemstack-handoff/SKILL.md +2 -1
- package/.agents/skills/gemstack-plan/SKILL.md +3 -1
- package/.agents/skills/gemstack-qa/SKILL.md +3 -0
- package/.agents/skills/gemstack-review/SKILL.md +7 -5
- package/.agents/skills/gemstack-ship/SKILL.md +10 -1
- package/.agents/skills/gemstack-spec/SKILL.md +4 -2
- package/.agents/skills/gemstack-tasks/SKILL.md +5 -3
- package/.gemstack/state.json +18 -2
- package/CHANGELOG.md +84 -0
- package/MANUAL.md +4 -4
- package/README.md +49 -8
- package/RELEASE_NOTES.md +129 -0
- package/assets/logo.jpg +0 -0
- package/docs/architecture-consistency.md +156 -0
- package/docs/spec-driven-development.md +26 -0
- package/gemstack-ai-1.2.0.tgz +0 -0
- package/handoff.md +40 -40
- package/package.json +3 -2
- package/scripts/ci/smoke-cli.js +1 -0
- package/specs/006-architecture-consistency-engine/.gemstack.json +9 -0
- package/specs/006-architecture-consistency-engine/plan.md +319 -0
- package/specs/006-architecture-consistency-engine/spec.md +179 -0
- package/specs/006-architecture-consistency-engine/tasks.md +532 -0
- package/specs/007-mechanical-test-matrix-closure-evidence/.gemstack.json +5 -0
- package/specs/007-mechanical-test-matrix-closure-evidence/closure.json +59 -0
- package/specs/007-mechanical-test-matrix-closure-evidence/plan.md +484 -0
- package/specs/007-mechanical-test-matrix-closure-evidence/spec.md +597 -0
- package/specs/007-mechanical-test-matrix-closure-evidence/tasks.md +536 -0
- package/specs/templates/plan.md +41 -0
- package/specs/templates/spec.md +35 -0
- package/specs/templates/tasks.md +10 -0
- package/src/cli.js +15 -4
- package/src/commands/collect.js +340 -0
- package/src/commands/ship.js +79 -0
- package/src/commands/verify.js +433 -0
- package/src/lib/closure-context.js +444 -0
- package/src/lib/contracts.js +388 -0
- package/src/lib/findings.js +227 -0
- package/src/lib/hasher.js +103 -0
- package/src/lib/runner-adapters.js +347 -0
- package/src/lib/state.js +143 -0
- package/src/lib/test-matrix.js +187 -0
- package/src/mcp-server.js +1 -1
- package/template/.agents/rules/01-gemstack-core.md +15 -0
- package/template/.agents/rules/02-gemstack-constitution.md +12 -1
- package/template/.agents/skills/gemstack-handoff/SKILL.md +2 -1
- package/template/.agents/skills/gemstack-plan/SKILL.md +2 -1
- package/template/.agents/skills/gemstack-review/SKILL.md +7 -5
- package/template/.agents/skills/gemstack-ship/SKILL.md +5 -0
- package/template/.agents/skills/gemstack-spec/SKILL.md +3 -2
- package/template/.agents/skills/gemstack-tasks/SKILL.md +4 -3
- package/template/docs/architecture-consistency.md +144 -0
- package/template/specs/templates/plan.md +11 -0
- package/template/specs/templates/spec.md +17 -0
- package/template/specs/templates/tasks.md +1 -0
- package/gemstack-ai-1.0.1.tgz +0 -0
|
@@ -0,0 +1,156 @@
|
|
|
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/6** in the unified `gemstack verify` command:
|
|
134
|
+
|
|
135
|
+
```text
|
|
136
|
+
[INFO] --- 4/6 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.
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## 10. Mechanical Test Matrix & Closure Evidence (Upgrade B)
|
|
149
|
+
|
|
150
|
+
Beyond static contract consistency across phase files, Gemstack Upgrade B validates execution evidence against declared requirements:
|
|
151
|
+
|
|
152
|
+
- **`acceptanceSignature`**: Full semantic record SHA-256 digest of the canonical test matrix in `spec.md`.
|
|
153
|
+
- **Authoritative Execution**: Native test runners (such as `node:test`) execute bound tests without shell intermediaries. TAP output is parsed to extract executed canonical test tokens.
|
|
154
|
+
- **Reconciliation & Set Equality**: Proves that all declared required canonical tests were physically executed and passed (`PASS + FAIL + SKIP + TODO + CANCELLED == TOTAL_PHYSICAL`). Detects `PHANTOM_TEST` (claimed but unexecuted) and `ORPHAN_TEST` (executed with unregistered canonical ID).
|
|
155
|
+
- **`closureContextHash`**: Deterministic SHA-256 fingerprint binding repository state, phase hashes, test files, implementation files, and gate definitions. Prevents whole-repository scanning while detecting stale evidence.
|
|
156
|
+
- **Progressive Legacy Compatibility**: Specifications lacking a test matrix operate seamlessly in legacy mode with an informational notice, preserving 100% backward compatibility.
|
|
@@ -8,3 +8,29 @@ Inspirado en Spec Kit, Gemstack obliga a pensar antes de teclear.
|
|
|
8
8
|
|
|
9
9
|
Usa `/specify` para comenzar este ciclo.
|
|
10
10
|
Una vez que el spec esté aprobado por el usuario, usa `/plan` y luego `/tasks`.
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Mechanical Test Matrix & Closure Evidence (Upgrade B)
|
|
16
|
+
|
|
17
|
+
Gemstack complements Architecture Consistency with mechanical closure verification:
|
|
18
|
+
|
|
19
|
+
1. **Test Matrix in Spec (`spec.md`)**:
|
|
20
|
+
Declared in a ```gemstack-test-matrix``` block. Defines canonical acceptance tests with unique IDs (`TEST-[FEATURE]-[CAT][NUM]`), verification layers (`UNIT`, `INTEGRATION`, `E2E`, `CLI`), and enforcement gates (`REQUIRED`, `SUPPLEMENTAL`). Produces an immutable `acceptanceSignature`.
|
|
21
|
+
|
|
22
|
+
2. **Physical Test Bindings in Plan (`plan.md`)**:
|
|
23
|
+
Declared in ```gemstack-test-bindings``` block mapping each canonical test ID 1:1 to a physical runner file (e.g. `tests/example.test.js` with runner `node:test`).
|
|
24
|
+
Also declares mandatory package script gates in ```gemstack-closure-gates```.
|
|
25
|
+
|
|
26
|
+
3. **Task Traceability in Tasks (`tasks.md`)**:
|
|
27
|
+
Implementation tasks declare metadata:
|
|
28
|
+
`<!-- gemstack:validation_required=true|false -->`
|
|
29
|
+
`<!-- gemstack:tests=TEST-001,TEST-002 -->`
|
|
30
|
+
`<!-- gemstack:files=src/module.js,tests/module.test.js -->`
|
|
31
|
+
Ensures that every required canonical test is bound to at least one implementation task.
|
|
32
|
+
|
|
33
|
+
4. **Lifecycle: COLLECT vs VERIFY vs SHIP**:
|
|
34
|
+
- `gemstack collect`: Mutating evidence collector. Executes test runners, evaluates package script gates, reconciles counts, computes `closureContextHash`, and generates feature-local `closure.json`.
|
|
35
|
+
- `gemstack verify`: Strictly read-only validator (6 stages). Evaluates existing `closure.json` against in-memory fresh `closureContextHash`. Never writes to disk.
|
|
36
|
+
- `gemstack ship`: Lifecycle gatekeeper. Enforces that `closure.json` is fresh and marked `VERIFIED` (or policy-waived `VERIFIED_WITH_EXCEPTIONS`) before transitioning state to `SHIPPED`.
|
|
Binary file
|
package/handoff.md
CHANGED
|
@@ -1,45 +1,45 @@
|
|
|
1
|
-
# Gemstack Handoff
|
|
1
|
+
# Gemstack Handoff
|
|
2
2
|
|
|
3
|
-
##
|
|
4
|
-
Gemstack
|
|
3
|
+
## 1. Objetivo
|
|
4
|
+
Evolucionar Gemstack incorporando el feedback de producción real de proyectos activos:
|
|
5
|
+
1. Eliminar falsos positivos silenciosos en test runners en Windows/monorepos (Zero Silent Failures).
|
|
6
|
+
2. Ruteo semántico por intención (Intent-Based Routing) para interacción natural sin requerir `/comando`.
|
|
7
|
+
3. Sincronización automática del ciclo de vida en `.gemstack/state.json` al entregar (`/ship`) o documentar (`/handoff`).
|
|
8
|
+
4. Comando unificado `gemstack verify` (alias `audit`) para auditoría integral en un solo paso.
|
|
5
9
|
|
|
6
|
-
## Estado
|
|
7
|
-
|
|
8
|
-
|
|
10
|
+
## 2. Estado actual
|
|
11
|
+
- **Upgrade A (Consistency Core & Phase Freezing)**: CERRADO Y PUBLICADO OFICIALMENTE como `gemstack-ai@1.1.2` en npm y GitHub Release.
|
|
12
|
+
- **Upgrade B (Mechanical Test Matrix & Closure Evidence)**: CERRADO Y PREPARADO PARA RELEASE como `gemstack-ai@1.2.0`.
|
|
13
|
+
- 20/20 pruebas canónicas P1 de Upgrade B pasando al 100% en 6 nuevas suites.
|
|
14
|
+
- 25/25 pruebas canónicas P1 de Upgrade A preservadas con 0 regresiones.
|
|
15
|
+
- 53/53 pruebas físicas totales ejecutadas y pasando con 0 errores en CI/CD local (`npm test`, `npm run ci:all`).
|
|
16
|
+
- Comando mutador `gemstack collect` implementado y probado en Feature 007, generando `closure.json` atómicamente.
|
|
17
|
+
- Comando `gemstack verify` ampliado a 6 etapas estrictamente read-only con validación de frescura contra `closureContextHash`.
|
|
18
|
+
- Compuerta de cierre `gemstack ship` ejecutada exitosamente con estado `VERIFIED` y transición de ciclo de vida formal.
|
|
19
|
+
- Zero dependencias externas añadidas en producción.
|
|
20
|
+
- Excluidos completamente Upgrade C y Upgrade D.
|
|
9
21
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
- El archivo `package.json` fue ascendido a `v1.0.0`.
|
|
22
|
+
## 3. Archivos y cambios
|
|
23
|
+
- `src/lib/test-matrix.js`: Parser de `gemstack-test-matrix`, validación de esquema de 20 tests canónicos y cálculo de `acceptanceSignature` canónico SHA-256.
|
|
24
|
+
- `src/lib/closure-context.js`: Parser de bindings y gates de `plan.md`, metadatos de `tasks.md`, trazabilidad bidireccional, resolución de `RelevantClosureFiles`, `computeContentAggregateHash` y cálculo de `closureContextHash`.
|
|
25
|
+
- `src/lib/runner-adapters.js`: Adaptador nativo seguro de runner `node:test`, parser TAP de resultados, motor de reconciliación aritmética canónica, ejecutor seguro de compuertas `PACKAGE_SCRIPT` y serializador atómico de `closure.json`.
|
|
26
|
+
- `src/commands/collect.js`: Comando mutador dedicado que ejecuta tests y gates para generar `specs/<feature>/closure.json`.
|
|
27
|
+
- `src/commands/ship.js`: Compuerta de transición a `SHIPPED` que exige evidencia de cierre fresca y verificada.
|
|
28
|
+
- `src/commands/verify.js`: Etapa 5/6 agregada de verificación de evidencia mecánica de cierre en modo estrictamente de solo lectura (0 mutaciones en disco).
|
|
29
|
+
- `src/cli.js`: Registro de comandos `collect` y `ship`.
|
|
30
|
+
- `specs/007-mechanical-test-matrix-closure-evidence/`: Artefactos congelados `spec.md`, `plan.md`, `tasks.md` y evidencia de cierre generada `closure.json`.
|
|
31
|
+
- `tests/`: 6 nuevas suites de prueba (`test-matrix.test.js`, `reconciliation.test.js`, `runner-adapter.test.js`, `traceability.test.js`, `closure-manifest.test.js`, `closure-gates.test.js`).
|
|
32
|
+
- `specs/templates/`: Actualizadas plantillas de `spec.md`, `plan.md` y `tasks.md` con bloques canónicos de Upgrade B.
|
|
33
|
+
- `.agents/skills/`: Actualizados skills (`gemstack-spec`, `gemstack-plan`, `gemstack-tasks`, `gemstack-qa`, `gemstack-ship`).
|
|
34
|
+
- `docs/`, `README.md`, `package.json`: Documentación técnica y script de test con enumeración explícita de las 11 suites físicas.
|
|
24
35
|
|
|
25
|
-
##
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
-
|
|
31
|
-
- Creación del Skill `gemstack-dashboard` y actualización de `.agents/rules/01-gemstack-core.md`.
|
|
32
|
-
- Nuevo servidor `src/mcp-server.js` y vinculación CLI.
|
|
33
|
-
- Todos los archivos `.agents/` nuevos fueron replicados en la carpeta `template/`.
|
|
34
|
-
- Actualización mayor de `README.md` documentando todas las capacidades "v1.0".
|
|
36
|
+
## 4. Intentos fallidos
|
|
37
|
+
- Se confirmó en proyectos reales que scripts de prueba con sintaxis `2>nul` en `package.json` provocan que PowerShell/Bash enmascaren errores y retornen código de salida 0 con 0 tests ejecutados. Ahora esto es detectado como error por `gemstack verify` y prohibido en la Constitución.
|
|
38
|
+
- **2026-09-11**: En el reporte de Upgrade A, se produjo un drift en la nomenclatura y categorización de la matriz P1 canónica. Se restauró la correlación canónica estricta de 25 tests P1 aprobados y la regla estricta de parser de 2+ bloques -> CONTRACT_PARSE_ERROR.
|
|
39
|
+
- **Node 20+ Subprocess Recursion**: Al ejecutar `node --test` como subproceso desde un proceso de test runner, `process.env.NODE_TEST_CONTEXT` suprimía la ejecución de archivos hijos con warning de recursión. Se resolvió sanitizando las variables `NODE_TEST_CONTEXT` y `NODE_TEST_WORKER_ID` en el entorno del proceso hijo.
|
|
40
|
+
- **Windows spawn 'npm.cmd' EINVAL**: Node 22+ en Windows genera `EINVAL` al invocar `spawn('npm.cmd', ..., { shell: false })`. Se resolvió ejecutando directamente el binario `npm-cli.js` vía `process.execPath` cuando se detecta en Windows, respetando la regla constitucional de `shell: false`.
|
|
41
|
+
- **Closure Manifest Self-Reference**: Al incluir `specs/<feature>/closure.json` en los archivos de implementación de `tasks.md`, `closureContextHash` cambiaba cada vez que `closure.json` era escrito, provocando que la evidencia se marcara como `STALE` inmediatamente después de recolectarse. Se resolvió excluyendo explícitamente `closure.json` de la agregación de hashes de contexto de implementación (`implementationContextHash`).
|
|
35
42
|
|
|
36
|
-
##
|
|
37
|
-
1.
|
|
38
|
-
2.
|
|
39
|
-
3. **Mantenimiento del Servidor MCP:** Actualmente el servidor MCP expone 2 herramientas (`get_current_tasks`, `get_security_rules`). En futuras iteraciones se podrían agregar herramientas de mutación (escribir specs a través de MCP).
|
|
40
|
-
|
|
41
|
-
## Archivos Críticos a Tener en Cuenta
|
|
42
|
-
- `src/cli.js`: El cerebro del enrutador de comandos.
|
|
43
|
-
- `src/commands/*.js`: Cada comando de la CLI está encapsulado de forma nativa.
|
|
44
|
-
- `template/`: Esta carpeta *debe* contener un espejo exacto de `.agents/`, `.gemstack/`, `docs/` y `specs/`. ¡Nunca modifiques reglas locales sin actualizarlas en el `template/`!
|
|
45
|
-
- `scripts/ci/*.js`: Toda la validación CI depende de scripts cero-dependencias escritos en Node.
|
|
43
|
+
## 5. Próximos pasos
|
|
44
|
+
1. Completar la publicación de la versión minor v1.2.0 en GitHub Release y npm.
|
|
45
|
+
2. Iniciar la fase de arquitectura de Upgrade C (Cost & Provider Safety Gates) en su ciclo correspondiente.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gemstack-ai",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Agentic Spec-Driven Development framework for Gemini/Antigravity",
|
|
5
5
|
"main": "src/cli.js",
|
|
6
6
|
"bin": {
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
"node": ">=18.18.0"
|
|
11
11
|
},
|
|
12
12
|
"scripts": {
|
|
13
|
-
"test": "node --test tests/init.test.js",
|
|
13
|
+
"test": "node --test tests/contracts.test.js tests/hasher.test.js tests/findings.test.js tests/init.test.js tests/verify.test.js tests/test-matrix.test.js tests/reconciliation.test.js tests/runner-adapter.test.js tests/traceability.test.js tests/closure-manifest.test.js tests/closure-gates.test.js",
|
|
14
|
+
"gemstack:verify": "node src/cli.js verify",
|
|
14
15
|
"pack:dry": "npm pack --dry-run",
|
|
15
16
|
"ci:frontmatter": "node scripts/ci/check-frontmatter.js",
|
|
16
17
|
"ci:template": "node scripts/ci/check-template-clean.js",
|
package/scripts/ci/smoke-cli.js
CHANGED
|
@@ -24,6 +24,7 @@ runSafe(`node "${path.join(rootDir, 'src/cli.js')}" show gemstack-handoff`, root
|
|
|
24
24
|
runSafe(`node "${path.join(rootDir, 'src/cli.js')}" init --dry-run --target "${tmpDir}"`, tmpDir);
|
|
25
25
|
runSafe(`node "${path.join(rootDir, 'src/cli.js')}" init --yes --target "${tmpDir}"`, tmpDir);
|
|
26
26
|
runSafe(`node "${path.join(rootDir, 'src/cli.js')}" doctor --target "${tmpDir}"`, tmpDir);
|
|
27
|
+
runSafe(`node "${path.join(rootDir, 'src/cli.js')}" verify --target "${tmpDir}"`, tmpDir);
|
|
27
28
|
runSafe(`node "${path.join(rootDir, 'src/cli.js')}" update --dry-run --target "${tmpDir}"`, tmpDir);
|
|
28
29
|
|
|
29
30
|
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
{
|
|
2
|
+
"phase_hashes": {
|
|
3
|
+
"spec": "f5d423eaf508b06b663b39f467fba1d9ceff6db21f01e427500ad739a90c5be8",
|
|
4
|
+
"plan": "1ce0e58863427905022a6294f8683b9f508d72b171379c78807db19862c75004",
|
|
5
|
+
"tasks": "dfad2484ad112e26ef906ea851b12cf6ea090d6faf244a6fbd2650baee8e0d98"
|
|
6
|
+
},
|
|
7
|
+
"historical_findings": [],
|
|
8
|
+
"accepted_exceptions": []
|
|
9
|
+
}
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
# Plan de Implementación: Architecture Consistency Engine & Phase Freezing (Upgrade A)
|
|
2
|
+
|
|
3
|
+
**Feature Branch**: `006-architecture-consistency-engine`
|
|
4
|
+
**Spec**: [`specs/006-architecture-consistency-engine/spec.md`](file:///c:/CODES/Gemstack/specs/006-architecture-consistency-engine/spec.md)
|
|
5
|
+
**Lifecycle Status**: `PLAN_COMPLETE`
|
|
6
|
+
**Stop Reason**: `PLAN_COMPLETE_AWAITING_REVIEW`
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## 1. Resumen y Contexto Técnico
|
|
11
|
+
|
|
12
|
+
El objetivo de este plan es diseñar la arquitectura técnica para **Upgrade A**, transformando la especificación congelada en módulos de Node.js nativos sin dependencias externas (*Zero-Dependency Core*).
|
|
13
|
+
|
|
14
|
+
### Restricciones Arquitectónicas Inmutables
|
|
15
|
+
- **Runtime**: Node.js >= 18.18.0 nativo.
|
|
16
|
+
- **Dependencias**: Cero paquetes npm de terceros (uso exclusivo de `crypto`, `fs`, `path`, `assert`, `node:test`).
|
|
17
|
+
- **Compatibilidad**: Modo `LEGACY` transparente para specs previas (001 a 005) y retrocompatibilidad binaria de `.gemstack/state.json`.
|
|
18
|
+
- **Multiplataforma**: Soporte idéntico en Windows (CRLF, backslashes), Linux y macOS.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## 2. Constitution Check (Phase -1 Gates)
|
|
23
|
+
|
|
24
|
+
### Simplicity Gate (Article VII)
|
|
25
|
+
- [x] **¿Se usan el mínimo número de carpetas/archivos posibles?** Sí: 4 librerías modulares en `src/lib/` (`hasher.js`, `contracts.js`, `findings.js`, `state.js`) y extensión quirúrgica de `src/commands/verify.js`.
|
|
26
|
+
- [x] **¿No hay abstracciones prematuras?** Sí: No se crea un framework de AST ni compiladores genéricos; parsing directo de bloques JSON delimitados.
|
|
27
|
+
|
|
28
|
+
### Anti-Abstraction Gate (Article VIII)
|
|
29
|
+
- [x] **¿Se usan las APIs nativas del framework sin wrappers innecesarios?** Sí: `crypto.createHash('sha256')`, `fs.writeFileSync`, `path.relative`.
|
|
30
|
+
|
|
31
|
+
### Test-First Imperative & Zero Silent Failures (Article III)
|
|
32
|
+
- [x] **¿El plan incluye la creación de tests antes que el código fuente?** Sí: Matriz P1 de 25 tests estructurados en `tests/contracts.test.js`, `tests/hasher.test.js`, `tests/findings.test.js` y regresión en `tests/verify.test.js`.
|
|
33
|
+
- [x] **¿Cero falsos positivos silenciosos?** Sí: Pruebas unitarias nativas sin `2>nul`.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 3. Diseño Detallado de Arquitectura y Módulos
|
|
38
|
+
|
|
39
|
+
```text
|
|
40
|
+
c:\CODES\Gemstack\
|
|
41
|
+
├── src\
|
|
42
|
+
│ ├── lib\
|
|
43
|
+
│ │ ├── hasher.js <-- [NUEVO] Normalización LF, detección BOM y SHA-256
|
|
44
|
+
│ │ ├── contracts.js <-- [NUEVO] Parser ```gemstack-contracts, normalizador, comparador
|
|
45
|
+
│ │ ├── findings.js <-- [NUEVO] Fingerprints, deltas consolidados y anti-loop
|
|
46
|
+
│ │ └── state.js <-- [NUEVO] Lector/escritor atómico (tmp + rename) para state.json
|
|
47
|
+
│ └── commands\
|
|
48
|
+
│ └── verify.js <-- [MODIFICAR] Incorporar paso 4: Consistencia y Hashes de Fase
|
|
49
|
+
├── tests\
|
|
50
|
+
│ ├── contracts.test.js <-- [NUEVO] Tests categorías A y B (Parsing, Enums, Identity, Boundary, Herencia)
|
|
51
|
+
│ ├── hasher.test.js <-- [NUEVO] Tests categoría C (Freeze, CRLF/LF, Detección de mutación)
|
|
52
|
+
│ └── findings.test.js <-- [NUEVO] Tests categorías D, E, F y G (Fingerprints, Anti-loop, Legacy, Windows)
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
### 3.1 Módulo `src/lib/hasher.js`
|
|
58
|
+
|
|
59
|
+
#### Responsabilidad
|
|
60
|
+
Calcular hashes deterministas de artefactos markdown garantizando invariancia de plataforma (Windows vs POSIX).
|
|
61
|
+
|
|
62
|
+
#### Algoritmo de Hashing
|
|
63
|
+
1. Leer buffer o string UTF-8.
|
|
64
|
+
2. Comprobar presencia de UTF-8 BOM (`0xEF, 0xBB, 0xBF` o `\uFEFF`). Si existe, rechazar con error `CONTRACT_PARSE_ERROR: BOM detected in phase artifact`.
|
|
65
|
+
3. Normalizar saltos de línea: reemplazar `\r\n` por `\n` y cualquier `\r` suelto por `\n`.
|
|
66
|
+
4. Calcular SHA-256 sobre los bytes UTF-8 resultantes.
|
|
67
|
+
5. Retornar digest hexadecimal en minúsculas (64 caracteres).
|
|
68
|
+
|
|
69
|
+
#### Funciones Exportadas
|
|
70
|
+
- `normalizeContent(content: string): string`
|
|
71
|
+
- `hashArtifact(content: string): string`
|
|
72
|
+
- `hashFile(filePath: string): string`
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
### 3.2 Módulo `src/lib/contracts.js`
|
|
77
|
+
|
|
78
|
+
#### Responsabilidad
|
|
79
|
+
Localizar, extraer, validar, normalizar y comparar contratos declarados en artefactos de fase.
|
|
80
|
+
|
|
81
|
+
#### Delimitador Canónico y Reglas de Parsing
|
|
82
|
+
- **Delimitador**:
|
|
83
|
+
````markdown
|
|
84
|
+
```gemstack-contracts
|
|
85
|
+
[
|
|
86
|
+
...
|
|
87
|
+
]
|
|
88
|
+
```
|
|
89
|
+
````
|
|
90
|
+
- **Regla de Bloque Único**: Se permite **exactamente un bloque** `gemstack-contracts` por artefacto. Si se detectan dos o más bloques, emite `CONTRACT_PARSE_ERROR: Multiple gemstack-contracts blocks detected`.
|
|
91
|
+
- **Bloque Vacío**: `[]` es válido y representa 0 contratos declarados.
|
|
92
|
+
- **Sin Bloque**: Retorna `null` (activa modo `LEGACY`).
|
|
93
|
+
|
|
94
|
+
#### Esquemas Exactos de Contratos
|
|
95
|
+
|
|
96
|
+
1. **`ENUM_SET`**:
|
|
97
|
+
```json
|
|
98
|
+
{
|
|
99
|
+
"id": "job-status",
|
|
100
|
+
"type": "ENUM_SET",
|
|
101
|
+
"values": ["QUEUED", "PROCESSING", "COMPLETED", "FAILED"],
|
|
102
|
+
"description": "Opcional"
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
*Normalización:* Trim a cada string; rechazar miembros vacíos o duplicados. Comparación insensible al orden (`values.slice().sort()`).
|
|
106
|
+
|
|
107
|
+
2. **`IDENTITY_TUPLE`**:
|
|
108
|
+
```json
|
|
109
|
+
{
|
|
110
|
+
"id": "publication-identity",
|
|
111
|
+
"type": "IDENTITY_TUPLE",
|
|
112
|
+
"values": ["workspaceId", "recordingId", "languageTag", "kind"]
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
*Normalización:* Trim a cada string; rechazar duplicados. Comparación es un conjunto semántico de miembros exactos (`order-insensitive`, `duplicate-sensitive`, `exact-member-sensitive`).
|
|
116
|
+
|
|
117
|
+
3. **`PROVENANCE_RULE`**:
|
|
118
|
+
```json
|
|
119
|
+
{
|
|
120
|
+
"id": "caption-provenance",
|
|
121
|
+
"type": "PROVENANCE_RULE",
|
|
122
|
+
"entity": "CaptionAsset",
|
|
123
|
+
"values": ["parentRecordingAssetId", "sourceMediaAssetType", "sourceRecordingExportAssetId"]
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
*Normalización:* Requiere `entity` (string no vacío) y lista de campos requeridos exactos.
|
|
127
|
+
|
|
128
|
+
4. **`BOOLEAN_INVARIANT`**:
|
|
129
|
+
```json
|
|
130
|
+
{
|
|
131
|
+
"id": "zero-dependency-core",
|
|
132
|
+
"type": "BOOLEAN_INVARIANT",
|
|
133
|
+
"value": true
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
*Normalización:* `value` debe ser estrictamente tipo booleano (`typeof value === 'boolean'`). Se rechazan `"true"` o `"false"` como strings.
|
|
137
|
+
|
|
138
|
+
5. **`BOUNDARY`**:
|
|
139
|
+
```json
|
|
140
|
+
{
|
|
141
|
+
"id": "eventalus-sync-dependency",
|
|
142
|
+
"type": "BOUNDARY",
|
|
143
|
+
"value": "FORBIDDEN"
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
*Valores permitidos:* Exclusivamente `"FORBIDDEN"` y `"REQUIRED"`. Comparación estricta de string (`FORBIDDEN` vs `FORBIDDEN` ➔ `PASS`; `REQUIRED` vs `REQUIRED` ➔ `PASS`; `FORBIDDEN` vs `REQUIRED` o viceversa ➔ `FROZEN_CONTRACT_VIOLATION`).
|
|
147
|
+
|
|
148
|
+
6. **`ROADMAP_LIMIT`**:
|
|
149
|
+
```json
|
|
150
|
+
{
|
|
151
|
+
"id": "final-planned-mvp",
|
|
152
|
+
"type": "ROADMAP_LIMIT",
|
|
153
|
+
"value": 18
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
*Normalización:* Escalar JSON (`number` o `string`). No hay coerción de tipo.
|
|
157
|
+
|
|
158
|
+
#### Algoritmo de Herencia y Comparación
|
|
159
|
+
```text
|
|
160
|
+
effectiveSpecRegistry = spec contracts
|
|
161
|
+
effectivePlanRegistry = effectiveSpecRegistry + additive plan contracts
|
|
162
|
+
effectiveTasksRegistry = effectivePlanRegistry + additive tasks contracts
|
|
163
|
+
```
|
|
164
|
+
- Si un contrato de `spec.md` no se repite en `plan.md` ➔ `PASS` (heredado implícitamente, no requiere duplicación).
|
|
165
|
+
- Si se re-declara con valor normalizado idéntico ➔ `PASS`.
|
|
166
|
+
- Si se re-declara con valor diferente ➔ emite `FROZEN_CONTRACT_VIOLATION` (`BLOCKER`).
|
|
167
|
+
- Si `plan.md` introduce un ID nuevo ➔ clasificado como aditivo ➔ `PASS`.
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
### 3.3 Módulo `src/lib/findings.js`
|
|
172
|
+
|
|
173
|
+
#### Responsabilidad
|
|
174
|
+
Gestión determinista de hallazgos, generación de huellas digitales (*fingerprints*), cálculo de deltas consolidados y supresión anti-loop.
|
|
175
|
+
|
|
176
|
+
#### Granularidad de Hallazgos
|
|
177
|
+
Para cada comparación de contrato, se genera **un único hallazgo consolidado** por `(contractId, phase, violationType)`.
|
|
178
|
+
El payload del hallazgo incluye:
|
|
179
|
+
```json
|
|
180
|
+
{
|
|
181
|
+
"fingerprint": "c1f...",
|
|
182
|
+
"code": "FROZEN_CONTRACT_VIOLATION",
|
|
183
|
+
"severity": "BLOCKER",
|
|
184
|
+
"contractId": "transcription-job-status",
|
|
185
|
+
"phase": "plan",
|
|
186
|
+
"location": "specs/006-architecture-consistency-engine/plan.md",
|
|
187
|
+
"delta": {
|
|
188
|
+
"expected": ["COMPLETED", "FAILED", "PROCESSING", "QUEUED"],
|
|
189
|
+
"observed": ["CANCELLED", "COMPLETED", "FAILED", "PROCESSING", "QUEUED"],
|
|
190
|
+
"missing": [],
|
|
191
|
+
"added": ["CANCELLED"]
|
|
192
|
+
},
|
|
193
|
+
"status": "OPEN"
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
#### Huella Digital (*Fingerprint*) Canónica vs Display
|
|
198
|
+
```javascript
|
|
199
|
+
function createFingerprint(finding) {
|
|
200
|
+
const raw = JSON.stringify({
|
|
201
|
+
code: finding.code,
|
|
202
|
+
contractId: finding.contractId ?? null,
|
|
203
|
+
phase: finding.phase,
|
|
204
|
+
location: finding.location ? finding.location.replace(/\\/g, '/') : null
|
|
205
|
+
});
|
|
206
|
+
return crypto.createHash('sha256').update(raw, 'utf8').digest('hex');
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
- **Fingerprint Canónico (Identidad)**: Digest SHA-256 completo en hexadecimal en minúsculas de **64 caracteres**. Es la clave inmutable utilizada para persistencia, seguimiento de excepciones y motor anti-loop. **Nunca se trunca** en el almacenamiento.
|
|
210
|
+
- **Display Fingerprint (Cosmético)**: Si se requiere para legibilidad en salida CLI, se puede derivar una representación corta visual (`displayFingerprint = fingerprint.slice(0, 12)`), pero jamás se usa como identidad ni como clave en `.gemstack.json`.
|
|
211
|
+
|
|
212
|
+
#### Context Hash y Anti-Loop
|
|
213
|
+
```javascript
|
|
214
|
+
function computeContextHash(upstreamHash, currentHash, contractNormalized) {
|
|
215
|
+
return crypto.createHash('sha256')
|
|
216
|
+
.update(`${upstreamHash || ''}:${currentHash || ''}:${JSON.stringify(contractNormalized || {})}`)
|
|
217
|
+
.digest('hex');
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
- **`RESOLVED`**: Significa que el defecto fue corregido en el código/artefacto. Si el validador vuelve a correr y la violación persiste, el hallazgo se reactiva automáticamente.
|
|
221
|
+
- **`ACCEPTED_EXCEPTION`**: Requiere `approvedByHuman = true`. Suprime el bloqueo si `contextHash` permanece idéntico. Si el artefacto involucrado cambia, la excepción vuelve a requerir revisión.
|
|
222
|
+
- **`SUPERSEDED`**: Ocurre cuando una enmienda oficial a la especificación vuelve obsoleto un hallazgo previo.
|
|
223
|
+
|
|
224
|
+
#### Almacenamiento Persistente
|
|
225
|
+
Para evitar sobrecargar `state.json` con listas ilimitadas de hallazgos, se almacenan en un sidecar por feature:
|
|
226
|
+
`specs/<feature>/.gemstack.json`
|
|
227
|
+
Contiene:
|
|
228
|
+
```json
|
|
229
|
+
{
|
|
230
|
+
"feature": "006-architecture-consistency-engine",
|
|
231
|
+
"phase_hashes": { "spec": "...", "plan": "...", "tasks": "..." },
|
|
232
|
+
"accepted_exceptions": [],
|
|
233
|
+
"resolved_findings": []
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
### 3.4 Módulo `src/lib/state.js`
|
|
240
|
+
|
|
241
|
+
#### Responsabilidad
|
|
242
|
+
Operaciones de lectura y escritura atómica sobre `.gemstack/state.json`.
|
|
243
|
+
|
|
244
|
+
#### Algoritmo de Escritura Atómica (Planificado para `src/lib/state.js`)
|
|
245
|
+
1. Resolver ruta absoluta con `fssafe.resolveSafe(targetDir, '.gemstack/state.json')`.
|
|
246
|
+
2. Escribir primero en archivo temporal adyacente: `.gemstack/state.json.tmp.<pid>.<timestamp>`.
|
|
247
|
+
3. Renombrar atómicamente (`fs.renameSync`) sobre `.gemstack/state.json`.
|
|
248
|
+
4. En Windows, si existe bloqueo temporal transitorio, realizar reintento controlado (3 intentos con backoff de 50ms).
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
## 4. Integración en `src/commands/verify.js`
|
|
253
|
+
|
|
254
|
+
El verificador actual de 4 pasos se expande a 5 pasos limpios:
|
|
255
|
+
|
|
256
|
+
```text
|
|
257
|
+
[INFO] --- 1/5 Verificación Estructural (Archivos Base) ---
|
|
258
|
+
[INFO] --- 2/5 Verificación de Memoria e Integridad de Handoff ---
|
|
259
|
+
[INFO] --- 3/5 Verificación de Estado Local (.gemstack/state.json) ---
|
|
260
|
+
[INFO] --- 4/5 Consistencia Arquitectónica y Hashes de Fase (Upgrade A) ---
|
|
261
|
+
[INFO] --- 5/5 Verificación de Seguridad y Test Runners ---
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
### Lógica del Paso 4 en `verify.js`
|
|
265
|
+
1. Leer `.gemstack/state.json`. Obtener `active_spec`.
|
|
266
|
+
2. Si `active_spec` es nulo o no existe: reportar `[OK] Sin spec activa (verificación de contratos omitida)` y continuar.
|
|
267
|
+
3. Si `specs/<active_spec>/spec.md` existe:
|
|
268
|
+
- Extraer bloques `gemstack-contracts`. Si no tiene bloques, marcar `[INFO] Modo LEGACY (sin contratos estructurados)` y continuar.
|
|
269
|
+
- Si tiene `phase_hashes.spec` en `state.json` o sidecar:
|
|
270
|
+
- Calcular hash actual de `spec.md`.
|
|
271
|
+
- Si difiere del hash congelado: emitir error crítico `FROZEN_ARTIFACT_CHANGED`.
|
|
272
|
+
4. Si existe `plan.md`:
|
|
273
|
+
- Validar herencia de contratos de `spec.md` contra `plan.md`.
|
|
274
|
+
- Reportar hallazgos de contradicciones (`ENUM_SET`, `IDENTITY_TUPLE`, `PROVENANCE_RULE`, `BOUNDARY`, `BOOLEAN_INVARIANT`, `ROADMAP_LIMIT`).
|
|
275
|
+
- Aplicar supresión anti-loop sobre hallazgos con `ACCEPTED_EXCEPTION` válidos.
|
|
276
|
+
5. Si hay bloqueadores abiertos (`open_blockers > 0`): incrementar `totalErrors`.
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
## 5. Mapeo de Trazabilidad de Pruebas P1 (Exact Mechanical Total = 25)
|
|
281
|
+
|
|
282
|
+
| ID | Categoría | Módulo Responsable | Aserción Técnica |
|
|
283
|
+
|---|---|---|---|
|
|
284
|
+
| `TEST-CONSISTENCY-A01` | Parsing | `src/lib/contracts.js` | Extracción correcta de array JSON dentro de ````gemstack-contracts. |
|
|
285
|
+
| `TEST-CONSISTENCY-A02` | Parsing | `src/lib/contracts.js` | Emisión de `CONTRACT_PARSE_ERROR` ante JSON malformado o múltiples bloques. |
|
|
286
|
+
| `TEST-CONSISTENCY-A03` | Parsing | `src/lib/contracts.js` | Emisión de `CONTRACT_DUPLICATE_ID` si dos contratos repiten `id`. |
|
|
287
|
+
| `TEST-CONSISTENCY-B01` | Cross-Phase | `src/lib/contracts.js` | `ENUM_SET`: detecta miembro extra no aprobado (ej. `PURGED`) ➔ `BLOCKED`. |
|
|
288
|
+
| `TEST-CONSISTENCY-B02` | Cross-Phase | `src/lib/contracts.js` | `ENUM_SET`: valida ordenación normalizada (`[A,B,C]` == `[C,B,A]`) ➔ `PASS`. |
|
|
289
|
+
| `TEST-CONSISTENCY-B03` | Cross-Phase | `src/lib/contracts.js` | `IDENTITY_TUPLE`: detecta dimensión faltante (omite `kind`) ➔ `BLOCKED`. |
|
|
290
|
+
| `TEST-CONSISTENCY-B04` | Cross-Phase | `src/lib/contracts.js` | `IDENTITY_TUPLE`: valida permutación de dimensiones idénticas ➔ `PASS`. |
|
|
291
|
+
| `TEST-CONSISTENCY-B05` | Cross-Phase | `src/lib/contracts.js` | `PROVENANCE_RULE`: bloquea si entidad pierde campo de procedencia ➔ `BLOCKED`. |
|
|
292
|
+
| `TEST-CONSISTENCY-B06` | Cross-Phase | `src/lib/contracts.js` | `BOOLEAN_INVARIANT` & `ROADMAP_LIMIT`: contradicciones directas ➔ `BLOCKED`. |
|
|
293
|
+
| `TEST-CONSISTENCY-B07` | Cross-Phase | `src/lib/contracts.js` | `BOUNDARY`: valores estrictos `FORBIDDEN` y `REQUIRED`; detecta contradicción explícita (`FORBIDDEN` vs `REQUIRED` ➔ `BLOCKED`) y valida equivalencia como `PASS`. |
|
|
294
|
+
| `TEST-CONSISTENCY-B08` | Cross-Phase | `src/lib/contracts.js` | Herencia: PLAN hereda SPEC y agrega compatibles sin duplicación ➔ `PASS`. |
|
|
295
|
+
| `TEST-CONSISTENCY-C01` | Hashes | `src/lib/hasher.js` | Genera SHA-256 de 64 caracteres de `spec.md`. |
|
|
296
|
+
| `TEST-CONSISTENCY-C02` | Hashes | `src/lib/hasher.js` | Detecta mutación no autorizada de artefacto congelado ➔ `FROZEN_ARTIFACT_CHANGED`. |
|
|
297
|
+
| `TEST-CONSISTENCY-C03` | Hashes | `src/commands/verify.js`| Comprueba que `verify` valida contra hashes guardados sin mutarlos. |
|
|
298
|
+
| `TEST-CONSISTENCY-C04` | Hashes | `src/lib/hasher.js` | Normalización CRLF a LF produce idéntico hash en Windows y POSIX. |
|
|
299
|
+
| `TEST-CONSISTENCY-D01` | Fingerprints | `src/lib/findings.js` | Genera fingerprint determinista canónico de 64 caracteres hex SHA-256 con location relativa (/) inmune a colisiones; valida formato de display separado. |
|
|
300
|
+
| `TEST-CONSISTENCY-D02` | Anti-Loop | `src/lib/findings.js` | Si el defecto persiste, no se suprime como RESOLVED; si se arregla, queda limpio. |
|
|
301
|
+
| `TEST-CONSISTENCY-E01` | Excepciones | `src/lib/findings.js` | `ACCEPTED_EXCEPTION` suprime el bloqueo en `verify` si contextHash coincide. |
|
|
302
|
+
| `TEST-CONSISTENCY-E02` | Excepciones | `src/lib/findings.js` | Mutación de artefacto relevante reactiva la excepción para re-evaluación. |
|
|
303
|
+
| `TEST-CONSISTENCY-F01` | Legacy | `src/commands/verify.js`| Feature sin bloques de contratos opera en modo `LEGACY` sin errores. |
|
|
304
|
+
| `TEST-CONSISTENCY-F02` | Legacy | `src/lib/state.js` | `state.json` versión 0.1 sin campos de Upgrade A se lee sin fallas. |
|
|
305
|
+
| `TEST-CONSISTENCY-G01` | Windows | `src/lib/hasher.js` | Resuelve rutas con separadores `\` y normaliza internamente a `/`. |
|
|
306
|
+
| `TEST-CONSISTENCY-G02` | Windows | `src/lib/state.js` | Escritura atómica previene corrupción de archivos en Windows. |
|
|
307
|
+
| `TEST-CONSISTENCY-H01` | Regresión | Integration | `npm run gemstack:verify` mantiene todas las validaciones de salud intactas. |
|
|
308
|
+
| `TEST-CONSISTENCY-H02` | Regresión | Integration | Las suites previas (`tests/init.test.js`, `tests/verify.test.js`) pasan al 100%. |
|
|
309
|
+
|
|
310
|
+
**Total Mecánico de Tests P1**: **25**
|
|
311
|
+
|
|
312
|
+
---
|
|
313
|
+
|
|
314
|
+
## 6. Procedimiento de Dogfooding y Bootstrap
|
|
315
|
+
|
|
316
|
+
Dado que la especificación `specs/006-architecture-consistency-engine/spec.md` ya declaró formalmente sus 5 contratos congelados (`zero-dependency-core`, `upgrade-a-contract-types`, etc.), el procedimiento de validación interna se ejecutará en 3 etapas:
|
|
317
|
+
1. **Fase Bootstrap**: Los nuevos módulos `contracts.js`, `hasher.js`, `findings.js` se implementan y prueban con `node --test`.
|
|
318
|
+
2. **Auto-Freeze de Feature 006**: Se congela el hash formal de `specs/006-architecture-consistency-engine/spec.md` en `.gemstack/state.json`.
|
|
319
|
+
3. **Auto-Verificación**: Se ejecuta `node src/cli.js verify` contra el propio repositorio de Gemstack para certificar que el motor parsea y valida sus propios contratos con `PASS`.
|