gemstack-ai 1.2.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gemstack/state.json +11 -10
- package/CHANGELOG.md +97 -0
- package/README.md +89 -9
- package/RELEASE_NOTES.md +77 -0
- package/{gemstack-ai-1.2.0.tgz → gemstack-ai-1.4.0.tgz} +0 -0
- package/handoff.md +14 -12
- package/package.json +2 -2
- package/specs/008-cost-provider-safety-gates/.gemstack.json +5 -0
- package/specs/008-cost-provider-safety-gates/closure.json +59 -0
- package/specs/008-cost-provider-safety-gates/plan.md +456 -0
- package/specs/008-cost-provider-safety-gates/spec.md +633 -0
- package/specs/008-cost-provider-safety-gates/tasks.md +635 -0
- package/specs/009-context-capsule/closure.json +59 -0
- package/specs/009-context-capsule/context-capsule.json +428 -0
- package/specs/009-context-capsule/plan.md +663 -0
- package/specs/009-context-capsule/spec.md +913 -0
- package/specs/009-context-capsule/tasks.md +720 -0
- package/specs/010-agent-swarm-visual-qa/.gemstack.json +5 -0
- package/specs/010-agent-swarm-visual-qa/closure.json +59 -0
- package/specs/010-agent-swarm-visual-qa/plan.md +759 -0
- package/specs/010-agent-swarm-visual-qa/spec.md +842 -0
- package/specs/010-agent-swarm-visual-qa/swarm.json +49 -0
- package/specs/010-agent-swarm-visual-qa/tasks.md +873 -0
- package/specs/010-agent-swarm-visual-qa/visual-qa.json +41 -0
- package/src/cli.js +10 -0
- package/src/commands/context.js +95 -0
- package/src/commands/swarm.js +111 -0
- package/src/commands/verify.js +92 -0
- package/src/commands/visual.js +82 -0
- package/src/lib/closure-context.js +18 -1
- package/src/lib/context-capsule.js +594 -0
- package/src/lib/cost-ledger.js +355 -0
- package/src/lib/provider-boundary.js +186 -0
- package/src/lib/provider-registry.js +265 -0
- package/src/lib/safety-gates.js +277 -0
- package/src/lib/swarm.js +639 -0
- package/src/lib/visual-qa.js +499 -0
|
@@ -0,0 +1,663 @@
|
|
|
1
|
+
# Plan de Implementación: Context Capsule / Context Compression (Upgrade D)
|
|
2
|
+
|
|
3
|
+
**Feature Branch**: `009-context-capsule`
|
|
4
|
+
**Feature Directory**: `specs/009-context-capsule/`
|
|
5
|
+
**Spec**: [`specs/009-context-capsule/spec.md`](file:///c:/CODES/Gemstack/specs/009-context-capsule/spec.md)
|
|
6
|
+
**Lifecycle Status**: `PLAN_COMPLETE`
|
|
7
|
+
**Stop Reason**: `PLAN_COMPLETE_AWAITING_REVIEW`
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## 1. Architecture Mapping & Context
|
|
12
|
+
|
|
13
|
+
Upgrade D establishes a deterministic, auditable, and constraint-lossless architecture for generating compact continuation context (`context-capsule.json`). It solves the problem of cross-session and cross-agent context drift without chat transcripts, heuristic LLM summarization, or network calls.
|
|
14
|
+
|
|
15
|
+
It builds directly upon the cryptographic and mechanical guarantees of:
|
|
16
|
+
- **Upgrade A (Architecture Consistency Engine)**: Deterministic hashing (`src/lib/hasher.js`), canonical contracts (`src/lib/contracts.js`), findings and fingerprints (`src/lib/findings.js`), and atomic state persistence (`src/lib/state.js`).
|
|
17
|
+
- **Upgrade B (Mechanical Test Matrix & Closure Evidence)**: Test matrix validation, acceptance signatures (`src/lib/test-matrix.js`), closure context resolution (`src/lib/closure-context.js`), and strict `VERIFY = VALIDATE` read-only evaluation.
|
|
18
|
+
- **Upgrade C (Cost & Provider Safety Gates)**: Fail-closed gate evaluation, zero-network verification purity, and strict secret pattern prohibition.
|
|
19
|
+
|
|
20
|
+
### Architectural Flow:
|
|
21
|
+
```text
|
|
22
|
+
Authoritative Sources (spec.md, plan.md, tasks.md, .gemstack/state.json, closure.json)
|
|
23
|
+
│
|
|
24
|
+
▼ (Deterministic Resolution & SHA-256 Digesting)
|
|
25
|
+
Source Resolver & Provenance Engine
|
|
26
|
+
│
|
|
27
|
+
▼ (Constraint Extraction: MUST/MUST NOT, Contracts, Matrix)
|
|
28
|
+
Semantic Compression Engine (Zero Prose Scaffolding)
|
|
29
|
+
│
|
|
30
|
+
▼ (Secret Scanner & Size Budget Gate: ≤32KB / 64KB Max)
|
|
31
|
+
Safety & Privacy Enforcement Barrier
|
|
32
|
+
│
|
|
33
|
+
▼ (UTF-16 Sorted Key Serialization)
|
|
34
|
+
Canonical JSON Generator (`context-capsule.json`)
|
|
35
|
+
│
|
|
36
|
+
┌───────────────┴───────────────┐
|
|
37
|
+
▼ ▼
|
|
38
|
+
CLI Inspection & Verification Verify Engine (Read-Only Audit)
|
|
39
|
+
`gemstack context show/verify` `gemstack verify` (Stage 5.2)
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Central Invariants & Non-Negotiables:
|
|
43
|
+
1. `CONTEXT CAPSULE = DERIVED CONTINUATION CONTEXT, NOT CANONICAL PROJECT AUTHORITY`
|
|
44
|
+
2. `LESS TEXT ≠ LESS CONSTRAINT` (Semantic Constraint Losslessness: prose is stripped, but 100% of normative `MUST`/`MUST NOT` rules and frozen contracts are retained verbatim).
|
|
45
|
+
3. `AUTHORITATIVE ARTIFACT WINS` (If capsule diverges from `spec.md` or `tasks.md`, the source artifact unconditionally governs).
|
|
46
|
+
4. `chat transcript ≠ project authority` (Transcripts, conversation logs, and raw git diffs are strictly excluded).
|
|
47
|
+
5. `VERIFY = VALIDATE` (`gemstack verify` only validates schema and freshness; it **NEVER** regenerates or mutates capsules).
|
|
48
|
+
6. `Offline Purity`: 100% Node.js standard library built-ins (`node:fs`, `node:path`, `node:crypto`). Zero runtime npm dependencies, zero remote AI calls.
|
|
49
|
+
7. `Size Pressure Fail-Closed`: Exceeding hard limit (64 KB) throws `CONTEXT_CAPSULE_TOO_LARGE` rather than silently dropping constraints.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## 2. Canonical Artifact Placement & Scope
|
|
54
|
+
|
|
55
|
+
The canonical machine-readable capsule artifact is placed per active feature:
|
|
56
|
+
- **Active Feature Capsule**: `specs/<active-spec>/context-capsule.json` (e.g. `specs/009-context-capsule/context-capsule.json`).
|
|
57
|
+
- **Project Root Capsule (When No Active Feature)**: `.gemstack/context-capsule.json` is reserved strictly for fully shipped repositories to summarize completed upgrades across the entire project.
|
|
58
|
+
- **Canonical Feature Precedence**: When an active feature is present in `.gemstack/state.json` (`active_spec != null`), the feature-local capsule `specs/<active-spec>/context-capsule.json` is the sole canonical target. Dual authority is strictly forbidden.
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## 3. Context Capsule JSON Schema (v1.0.0)
|
|
63
|
+
|
|
64
|
+
Conforms to schema version 1 defined in `specs/009-context-capsule/spec.md`:
|
|
65
|
+
```json
|
|
66
|
+
{
|
|
67
|
+
"$schema": "https://gemstack.dev/schemas/context-capsule-v1.json",
|
|
68
|
+
"schema_version": 1,
|
|
69
|
+
"generated_at": "ISO8601 UTC timestamp",
|
|
70
|
+
"generator": {
|
|
71
|
+
"name": "gemstack",
|
|
72
|
+
"version": "1.2.0"
|
|
73
|
+
},
|
|
74
|
+
"provenance": {
|
|
75
|
+
"source_set_hash": "64-char lowercase hex SHA-256",
|
|
76
|
+
"sources": [
|
|
77
|
+
{
|
|
78
|
+
"path": "specs/009-context-capsule/spec.md",
|
|
79
|
+
"hash": "64-char lowercase hex SHA-256",
|
|
80
|
+
"role": "SPECIFICATION"
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"path": "specs/009-context-capsule/plan.md",
|
|
84
|
+
"hash": "64-char lowercase hex SHA-256",
|
|
85
|
+
"role": "PLAN"
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"path": "specs/009-context-capsule/tasks.md",
|
|
89
|
+
"hash": "64-char lowercase hex SHA-256",
|
|
90
|
+
"role": "TASKS"
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"path": ".gemstack/state.json",
|
|
94
|
+
"hash": "64-char lowercase hex SHA-256",
|
|
95
|
+
"role": "LIFECYCLE_STATE"
|
|
96
|
+
}
|
|
97
|
+
]
|
|
98
|
+
},
|
|
99
|
+
"project": {
|
|
100
|
+
"name": "gemstack-ai",
|
|
101
|
+
"active_feature": "specs/009-context-capsule",
|
|
102
|
+
"current_phase": "plan",
|
|
103
|
+
"lifecycle_status": "PLAN_COMPLETE",
|
|
104
|
+
"next_permitted_phase": "TASKS"
|
|
105
|
+
},
|
|
106
|
+
"historical_context": [
|
|
107
|
+
{
|
|
108
|
+
"feature": "specs/006-architecture-consistency-engine",
|
|
109
|
+
"status": "CLOSED",
|
|
110
|
+
"key_guarantees": ["Frozen contracts", "Deterministic hashing", "Anti-loop findings"]
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
"feature": "specs/007-mechanical-test-matrix-closure-evidence",
|
|
114
|
+
"status": "CLOSED",
|
|
115
|
+
"key_guarantees": ["Mechanical test matrix", "VERIFY = VALIDATE", "closure.json evidence"]
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
"feature": "specs/008-cost-provider-safety-gates",
|
|
119
|
+
"status": "CLOSED",
|
|
120
|
+
"key_guarantees": ["NO PROOF = NO EXECUTION", "Fail-closed gates", "Zero network verify"]
|
|
121
|
+
}
|
|
122
|
+
],
|
|
123
|
+
"architecture_summary": {
|
|
124
|
+
"core_purpose": "Deterministic context compression and safe continuation for AI-assisted engineering.",
|
|
125
|
+
"critical_boundaries": [
|
|
126
|
+
"Capsule is strictly derived, never authoritative",
|
|
127
|
+
"Semantic constraint losslessness: MUST/MUST NOT survive compression",
|
|
128
|
+
"Verification is read-only and never regenerates capsules"
|
|
129
|
+
]
|
|
130
|
+
},
|
|
131
|
+
"canonical_invariants": [
|
|
132
|
+
{
|
|
133
|
+
"id": "INV-001",
|
|
134
|
+
"rule": "CONTEXT CAPSULE = DERIVED CONTINUATION CONTEXT, NOT CANONICAL AUTHORITY",
|
|
135
|
+
"normative": "MUST",
|
|
136
|
+
"source_ref": "spec.md#3"
|
|
137
|
+
}
|
|
138
|
+
],
|
|
139
|
+
"frozen_contracts": [
|
|
140
|
+
{
|
|
141
|
+
"id": "zero-dependency-core",
|
|
142
|
+
"type": "BOOLEAN_INVARIANT",
|
|
143
|
+
"value": true
|
|
144
|
+
}
|
|
145
|
+
],
|
|
146
|
+
"acceptance_matrix": {
|
|
147
|
+
"total_required": 20,
|
|
148
|
+
"signature": "64-char lowercase hex SHA-256",
|
|
149
|
+
"canonical_ids": [
|
|
150
|
+
"TEST-CONTEXT-A01",
|
|
151
|
+
"TEST-CONTEXT-A02",
|
|
152
|
+
"TEST-CONTEXT-H01"
|
|
153
|
+
]
|
|
154
|
+
},
|
|
155
|
+
"tasks_state": {
|
|
156
|
+
"total": 20,
|
|
157
|
+
"completed": 0,
|
|
158
|
+
"in_progress": null,
|
|
159
|
+
"active_task_ids": ["T001", "T002"]
|
|
160
|
+
},
|
|
161
|
+
"relevant_files": [
|
|
162
|
+
"src/lib/context-capsule.js",
|
|
163
|
+
"tests/context-capsule-determinism.test.js"
|
|
164
|
+
],
|
|
165
|
+
"deferred_items": [
|
|
166
|
+
"Autonomous cross-repo capsule federations (out of scope)",
|
|
167
|
+
"LLM narrative fine-tuning (non-authoritative)"
|
|
168
|
+
],
|
|
169
|
+
"unresolved_blockers": []
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## 4. Exact Repository Change Map
|
|
176
|
+
|
|
177
|
+
```text
|
|
178
|
+
================================================================================
|
|
179
|
+
REPOSITORY CHANGE MAP
|
|
180
|
+
================================================================================
|
|
181
|
+
[NEW PRODUCTION MODULES]
|
|
182
|
+
- src/lib/context-capsule.js : Core engine: source resolution, semantic
|
|
183
|
+
compression, secret rejection, size budgeting,
|
|
184
|
+
canonical serialization, atomic generation,
|
|
185
|
+
and read-only validation.
|
|
186
|
+
- src/commands/context.js : CLI command handler for `gemstack context`
|
|
187
|
+
(subcommands: generate, show, verify).
|
|
188
|
+
|
|
189
|
+
[NEW TEST SUITES]
|
|
190
|
+
- tests/context-determinism.test.js : TEST-CONTEXT-A01..A04 (byte identity, UTF-16 sorting,
|
|
191
|
+
volatile timestamp exclusion, POSIX path normalization).
|
|
192
|
+
- tests/context-authority.test.js : TEST-CONTEXT-B01..B04 (authority conflict rejection,
|
|
193
|
+
source override, tampering detection, transcript exclusion).
|
|
194
|
+
- tests/context-freshness.test.js : TEST-CONTEXT-C01..C03 (spec/tasks mutation staleness,
|
|
195
|
+
unmodified valid state preservation).
|
|
196
|
+
- tests/context-constraints.test.js : TEST-CONTEXT-D01..D02 (100% MUST/MUST NOT extraction,
|
|
197
|
+
frozen contract & matrix signature preservation).
|
|
198
|
+
- tests/context-secrets.test.js : TEST-CONTEXT-E01..E03 (forbidden properties, regex token
|
|
199
|
+
patterns, .env exclusion fail-closed).
|
|
200
|
+
- tests/context-purity.test.js : TEST-CONTEXT-F01..F02 (verify read-only zero-mutation,
|
|
201
|
+
zero network socket execution).
|
|
202
|
+
- tests/context-size-budget.test.js : TEST-CONTEXT-G01 (hard budget overflow fail-closed,
|
|
203
|
+
target budget priority condensation).
|
|
204
|
+
- tests/context-legacy.test.js : TEST-CONTEXT-H01 (legacy repository compatibility,
|
|
205
|
+
zero blocker notice).
|
|
206
|
+
|
|
207
|
+
[MODIFIED EXISTING MODULES]
|
|
208
|
+
- src/cli.js : Register `context` command routing and help text.
|
|
209
|
+
- src/commands/verify.js : Integrate Stage 5.2: Read-only Context Capsule audit
|
|
210
|
+
(schema validation, freshness check, legacy notice).
|
|
211
|
+
- src/lib/closure-context.js : Include `context-capsule.json` in relevant closure
|
|
212
|
+
files resolution when present.
|
|
213
|
+
- package.json : Register 8 new test files in npm test script.
|
|
214
|
+
|
|
215
|
+
[FROZEN / UNTOUCHED]
|
|
216
|
+
- Upgrade A Core: src/lib/contracts.js, src/lib/hasher.js, src/lib/findings.js, src/lib/state.js
|
|
217
|
+
- Upgrade B Core: src/lib/test-matrix.js, src/lib/runner-adapters.js, src/commands/collect.js,
|
|
218
|
+
src/commands/ship.js
|
|
219
|
+
- Upgrade C Core: src/lib/cost-ledger.js, src/lib/provider-registry.js, src/lib/safety-gates.js,
|
|
220
|
+
src/lib/provider-boundary.js
|
|
221
|
+
- All 17 Historical Test Suites: tests/contracts.test.js through tests/verification-purity-cost.test.js
|
|
222
|
+
================================================================================
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## 5. Frozen & Bootstrap Contracts Mapping (`gemstack-contracts`)
|
|
228
|
+
|
|
229
|
+
Inherits all 8 bootstrap contracts declared in `specs/009-context-capsule/spec.md`. Zero existing frozen contracts from Upgrade A, B, or C are modified.
|
|
230
|
+
|
|
231
|
+
```gemstack-contracts
|
|
232
|
+
[
|
|
233
|
+
{
|
|
234
|
+
"id": "zero-dependency-core",
|
|
235
|
+
"type": "BOOLEAN_INVARIANT",
|
|
236
|
+
"value": true,
|
|
237
|
+
"description": "Upgrade D implementation must introduce zero external production npm dependencies, using Node.js built-ins exclusively."
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
"id": "capsule-is-derived-not-authority",
|
|
241
|
+
"type": "BOOLEAN_INVARIANT",
|
|
242
|
+
"value": true,
|
|
243
|
+
"description": "The context capsule is strictly a derived projection; authoritative artifacts always override capsule content in case of divergence."
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
"id": "compression-preserves-semantic-constraints",
|
|
247
|
+
"type": "BOOLEAN_INVARIANT",
|
|
248
|
+
"value": true,
|
|
249
|
+
"description": "Context compression must never drop, weaken, or generalize normative MUST/MUST NOT behavioral constraints or frozen contracts."
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
"id": "verify-never-regenerates-capsule",
|
|
253
|
+
"type": "BOOLEAN_INVARIANT",
|
|
254
|
+
"value": true,
|
|
255
|
+
"description": "gemstack verify must operate in read-only mode, validating capsule freshness without silently regenerating or mutating files on disk."
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
"id": "capsule-secrets-forbidden",
|
|
259
|
+
"type": "BOOLEAN_INVARIANT",
|
|
260
|
+
"value": true,
|
|
261
|
+
"description": "Context capsules must never contain credential tokens, private keys, API secrets, or ambient environment variable values."
|
|
262
|
+
},
|
|
263
|
+
{
|
|
264
|
+
"id": "capsule-offline-deterministic",
|
|
265
|
+
"type": "BOOLEAN_INVARIANT",
|
|
266
|
+
"value": true,
|
|
267
|
+
"description": "Canonical context capsule generation and validation must execute completely offline with deterministic output given identical inputs."
|
|
268
|
+
},
|
|
269
|
+
{
|
|
270
|
+
"id": "capsule-size-budget-fail-closed",
|
|
271
|
+
"type": "BOOLEAN_INVARIANT",
|
|
272
|
+
"value": true,
|
|
273
|
+
"description": "Exceeding the maximum capsule byte budget must fail closed with an explicit finding rather than silently dropping constraints."
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
"id": "legacy-capsule-compatibility",
|
|
277
|
+
"type": "BOOLEAN_INVARIANT",
|
|
278
|
+
"value": true,
|
|
279
|
+
"description": "Existing repositories and features lacking context capsules operate cleanly with informational notices and zero false blockers."
|
|
280
|
+
}
|
|
281
|
+
]
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
### Bootstrap Contracts Implementation & Validation Mapping:
|
|
285
|
+
| Contract ID | Implementation Surface | Validation Mechanism | Future Test File |
|
|
286
|
+
| :--- | :--- | :--- | :--- |
|
|
287
|
+
| `zero-dependency-core` | `package.json` | `check-package-contents.js` / node stdlib only | `tests/context-purity.test.js` |
|
|
288
|
+
| `capsule-is-derived-not-authority` | `src/lib/context-capsule.js` | Resolver priority check & source precedence | `tests/context-authority.test.js` |
|
|
289
|
+
| `compression-preserves-semantic-constraints` | `src/lib/context-capsule.js` | Invariant coverage & contract preservation | `tests/context-constraints.test.js` |
|
|
290
|
+
| `verify-never-regenerates-capsule` | `src/commands/verify.js` | Filesystem hash comparison before/after | `tests/context-purity.test.js` |
|
|
291
|
+
| `capsule-secrets-forbidden` | `src/lib/context-capsule.js` | Property & regex scan on payload | `tests/context-secrets.test.js` |
|
|
292
|
+
| `capsule-offline-deterministic` | `src/lib/context-capsule.js` | Multiple runs yield identical SHA-256 | `tests/context-determinism.test.js` |
|
|
293
|
+
| `capsule-size-budget-fail-closed` | `src/lib/context-capsule.js` | Serialized UTF-8 byte limit check (64KB) | `tests/context-size-budget.test.js` |
|
|
294
|
+
| `legacy-capsule-compatibility` | `src/commands/verify.js` | Graceful fallback & info notice | `tests/context-legacy.test.js` |
|
|
295
|
+
|
|
296
|
+
---
|
|
297
|
+
|
|
298
|
+
## 6. Detailed Subsystem Architecture
|
|
299
|
+
|
|
300
|
+
### 6.1 Source Resolution & Lifecycle Awareness
|
|
301
|
+
`resolveAuthoritativeSources(rootPath, featureDir, currentPhase)`:
|
|
302
|
+
- Ingests strictly:
|
|
303
|
+
1. `spec.md` (mandatory once active spec exists).
|
|
304
|
+
2. `plan.md` (mandatory in `plan`, `tasks`, `implementation`, `shipped` phases).
|
|
305
|
+
3. `tasks.md` (mandatory in `tasks`, `implementation`, `shipped` phases).
|
|
306
|
+
4. `.gemstack/state.json` (mandatory lifecycle status).
|
|
307
|
+
5. `closure.json` (ingested if present).
|
|
308
|
+
6. `cost-ledger.json` (ingested if present).
|
|
309
|
+
- Excludes completely: chat logs, `.git`, `node_modules`, `.env`, build artifacts.
|
|
310
|
+
- Computes SHA-256 for each source using `hasher.hashFile(absPath)` and repository-relative POSIX path via `hasher.normalizePath(absPath, rootPath)`.
|
|
311
|
+
- Calculates `source_set_hash` by hashing the UTF-16 sorted JSON string of normalized `{ path, hash }` objects.
|
|
312
|
+
|
|
313
|
+
### 6.2 Semantic Compression Engine
|
|
314
|
+
`extractSemanticConstraints(sourceFiles)`:
|
|
315
|
+
- Extracts structured blocks via existing parsers:
|
|
316
|
+
- Contracts via `extractContractsBlock` in `src/lib/contracts.js`.
|
|
317
|
+
- Test matrix via `extractTestMatrixBlock` and `validateTestMatrix` in `src/lib/test-matrix.js`.
|
|
318
|
+
- Task metadata via `parseTaskMetadata` in `src/lib/closure-context.js`.
|
|
319
|
+
- Extracts normative constraints (`MUST`, `MUST NOT`, `REQUIRED`, `FORBIDDEN`):
|
|
320
|
+
- Parses markdown text lines, extracts numbered rules, list items, and bullet points containing normative terms.
|
|
321
|
+
- Links each extracted rule to its section reference (`source_ref: "spec.md#3"`).
|
|
322
|
+
- Categorizes rules into `MUST` vs `MUST_NOT`.
|
|
323
|
+
- Omits background paragraphs, conversational explanations, tutorial prose, and rejected alternative approaches.
|
|
324
|
+
|
|
325
|
+
### 6.3 Canonical JSON Serialization
|
|
326
|
+
`serializeCanonicalJson(data)`:
|
|
327
|
+
- Recursively sorts all object keys by UTF-16 code units (`(a < b ? -1 : (a > b ? 1 : 0))`).
|
|
328
|
+
- Arrays with primary identifiers (`sources`, `canonical_invariants`, `frozen_contracts`, `canonical_ids`) are sorted deterministically.
|
|
329
|
+
- Serializes with 2-space indentation and standard POSIX newline (`\n`).
|
|
330
|
+
- Emits byte-identical output across OS environments.
|
|
331
|
+
|
|
332
|
+
### 6.4 Secret Defense Boundary
|
|
333
|
+
`assertSecretsForbidden(capsuleObj)`:
|
|
334
|
+
- Inspects property keys against forbidden list: `apiKey`, `api_key`, `token`, `accessToken`, `access_token`, `secret`, `clientSecret`, `password`, `credentials`.
|
|
335
|
+
- Scans all string values across the object hierarchy for pattern regexes:
|
|
336
|
+
- AWS keys: `/AKIA[0-9A-Z]{16}/`
|
|
337
|
+
- GitHub tokens: `/gh[pousr]_[A-Za-z0-9_]{36,}/`
|
|
338
|
+
- OpenAI / AI tokens: `/sk-[A-Za-z0-9]{20,}/`
|
|
339
|
+
- Google API keys: `/AIza[0-9A-Za-z-_]{35}/`
|
|
340
|
+
- Bearer tokens: `/Bearer\s+[A-Za-z0-9\-._~+/]+=*/i`
|
|
341
|
+
- Private key headers: `/-----BEGIN[ A-Z0-9_-]*PRIVATE KEY-----/`
|
|
342
|
+
- Throws `CONTEXT_CAPSULE_SECRET_DETECTED` fail-closed. Emits zero secret content in error details.
|
|
343
|
+
|
|
344
|
+
### 6.5 Size Budget & Priority Condensation
|
|
345
|
+
`enforceSizeBudget(capsuleObj)`:
|
|
346
|
+
- Target Budget: `32,768 bytes` (32 KB).
|
|
347
|
+
- Hard Upper Limit: `65,536 bytes` (64 KB).
|
|
348
|
+
- If serialized size > 32 KB:
|
|
349
|
+
- Condenses Priority 3 (historical upgrade details condensed to ID and status token).
|
|
350
|
+
- If still > 32 KB, condenses Priority 2 (condenses acceptance descriptions while retaining exact canonical IDs; condenses task descriptions while retaining status counts and active IDs).
|
|
351
|
+
- Priority 1 (Authority model, safety invariants, contracts, lifecycle state) is **NEVER** dropped or condensed.
|
|
352
|
+
- If serialized size > 64 KB after condensation, throws `CONTEXT_CAPSULE_TOO_LARGE` fail-closed.
|
|
353
|
+
|
|
354
|
+
### 6.6 Atomic Generation
|
|
355
|
+
`generateContextCapsule(rootPath, featureDir, options)`:
|
|
356
|
+
- Runs pipeline: Resolve Sources → Extract Constraints → Build Object → Scan Secrets → Enforce Budget → Canonicalize JSON.
|
|
357
|
+
- Writes atomically to temporary file `<target>.tmp.<pid>_<timestamp>` in destination directory and renames over destination using Windows-safe bounded retry (reusing `writeJsonAtomic` pattern from `src/lib/state.js`).
|
|
358
|
+
|
|
359
|
+
### 6.7 Read-Only Validation
|
|
360
|
+
`validateContextCapsule(rootPath, featureDir)`:
|
|
361
|
+
- Read-only inspection returning `{ valid: boolean, state: 'VALID'|'STALE'|'INVALID'|'MISSING', findings: [] }`.
|
|
362
|
+
- Validates:
|
|
363
|
+
1. File existence (if missing: `MISSING`).
|
|
364
|
+
2. Schema version and JSON validity (if malformed: `INVALID`).
|
|
365
|
+
3. Re-computes SHA-256 for all recorded source files on disk. If any hash differs or file is missing, marks `STALE` with `CONTEXT_CAPSULE_STALE`.
|
|
366
|
+
4. Checks for forbidden secrets (`CONTEXT_CAPSULE_SECRET_DETECTED`).
|
|
367
|
+
5. Checks hard size budget (`CONTEXT_CAPSULE_TOO_LARGE`).
|
|
368
|
+
6. Reconciles invariants against `spec.md` (`CONTEXT_CAPSULE_INVARIANT_DROPPED`).
|
|
369
|
+
7. Checks for claims contradicting source (`CONTEXT_CAPSULE_AUTHORITY_CONFLICT`).
|
|
370
|
+
- **NEVER** mutates disk or regenerates the capsule.
|
|
371
|
+
|
|
372
|
+
---
|
|
373
|
+
|
|
374
|
+
## 7. Findings & Accepted Exceptions Taxonomy
|
|
375
|
+
|
|
376
|
+
| Finding Code | Severity | Trigger | Fingerprint Inputs | Exception Eligible? |
|
|
377
|
+
| :--- | :--- | :--- | :--- | :--- |
|
|
378
|
+
| `CONTEXT_CAPSULE_MISSING` | WARNING / BLOCKER | Capsule absent in active feature at ship | code, activeSpec, phase | **NO** |
|
|
379
|
+
| `CONTEXT_CAPSULE_INVALID` | BLOCKER | Malformed JSON or invalid schema | code, activeSpec, phase | **NO** |
|
|
380
|
+
| `CONTEXT_CAPSULE_STALE` | BLOCKER | Recorded source hash mismatches live file | code, sourcePath, phase | **NO** |
|
|
381
|
+
| `CONTEXT_CAPSULE_SOURCE_MISMATCH` | BLOCKER | File listed in sources does not exist | code, missingPath, phase | **NO** |
|
|
382
|
+
| `CONTEXT_CAPSULE_SECRET_DETECTED` | BLOCKER | Credential key or token pattern detected | code, fieldName, phase | **NO** |
|
|
383
|
+
| `CONTEXT_CAPSULE_INVARIANT_DROPPED`| BLOCKER | Normative rule missing from capsule | code, ruleId, phase | **NO** |
|
|
384
|
+
| `CONTEXT_CAPSULE_TOO_LARGE` | BLOCKER | Capsule exceeds 64 KB hard budget | code, byteSize, phase | **NO** |
|
|
385
|
+
| `CONTEXT_CAPSULE_AUTHORITY_CONFLICT`| BLOCKER | Capsule claims state contrary to source | code, conflictField, phase | **NO** |
|
|
386
|
+
|
|
387
|
+
**Zero Waivable Blocker Policy**: Stale, invalid, secret-bearing, or conflicting capsules cannot be waived. Remediation requires explicit regeneration (`gemstack context generate`).
|
|
388
|
+
|
|
389
|
+
---
|
|
390
|
+
|
|
391
|
+
## 8. CLI Surface Specification
|
|
392
|
+
|
|
393
|
+
```text
|
|
394
|
+
gemstack context generate [--target <dir>] [--feature <path>]
|
|
395
|
+
--> Compiles authoritative sources into specs/<feature>/context-capsule.json atomically.
|
|
396
|
+
|
|
397
|
+
gemstack context show [--target <dir>] [--json]
|
|
398
|
+
--> Reads specs/<feature>/context-capsule.json and displays structured summary or formatted JSON.
|
|
399
|
+
|
|
400
|
+
gemstack context verify [--target <dir>]
|
|
401
|
+
--> Runs standalone read-only validation of context-capsule.json and reports status.
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
### Integration into `gemstack verify`:
|
|
405
|
+
In `src/commands/verify.js`, add Stage 5.2 (following closure evidence and cost ledger audits):
|
|
406
|
+
```javascript
|
|
407
|
+
// 5.2 Verificación de Context Capsule (Upgrade D - Read-Only)
|
|
408
|
+
logger.info('--- 5.2 Verificación de Context Capsule (Read-Only) ---');
|
|
409
|
+
// Audits active_spec context-capsule.json. Logs legacy notice if absent in legacy feature.
|
|
410
|
+
// Emits blocker findings if STALE, INVALID, TOO_LARGE, or SECRET_DETECTED.
|
|
411
|
+
// ZERO disk writes, ZERO network requests.
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
---
|
|
415
|
+
|
|
416
|
+
## 9. Canonical Acceptance Test Bindings (`gemstack-test-bindings`)
|
|
417
|
+
|
|
418
|
+
The 20 canonical acceptance tests from `specs/009-context-capsule/spec.md` are bound 1:1 to 8 physical test suites:
|
|
419
|
+
|
|
420
|
+
```gemstack-test-bindings
|
|
421
|
+
[
|
|
422
|
+
{
|
|
423
|
+
"test_id": "TEST-CONTEXT-A01",
|
|
424
|
+
"runner": "node:test",
|
|
425
|
+
"file": "tests/context-determinism.test.js"
|
|
426
|
+
},
|
|
427
|
+
{
|
|
428
|
+
"test_id": "TEST-CONTEXT-A02",
|
|
429
|
+
"runner": "node:test",
|
|
430
|
+
"file": "tests/context-determinism.test.js"
|
|
431
|
+
},
|
|
432
|
+
{
|
|
433
|
+
"test_id": "TEST-CONTEXT-A03",
|
|
434
|
+
"runner": "node:test",
|
|
435
|
+
"file": "tests/context-determinism.test.js"
|
|
436
|
+
},
|
|
437
|
+
{
|
|
438
|
+
"test_id": "TEST-CONTEXT-A04",
|
|
439
|
+
"runner": "node:test",
|
|
440
|
+
"file": "tests/context-determinism.test.js"
|
|
441
|
+
},
|
|
442
|
+
{
|
|
443
|
+
"test_id": "TEST-CONTEXT-B01",
|
|
444
|
+
"runner": "node:test",
|
|
445
|
+
"file": "tests/context-authority.test.js"
|
|
446
|
+
},
|
|
447
|
+
{
|
|
448
|
+
"test_id": "TEST-CONTEXT-B02",
|
|
449
|
+
"runner": "node:test",
|
|
450
|
+
"file": "tests/context-authority.test.js"
|
|
451
|
+
},
|
|
452
|
+
{
|
|
453
|
+
"test_id": "TEST-CONTEXT-B03",
|
|
454
|
+
"runner": "node:test",
|
|
455
|
+
"file": "tests/context-authority.test.js"
|
|
456
|
+
},
|
|
457
|
+
{
|
|
458
|
+
"test_id": "TEST-CONTEXT-B04",
|
|
459
|
+
"runner": "node:test",
|
|
460
|
+
"file": "tests/context-authority.test.js"
|
|
461
|
+
},
|
|
462
|
+
{
|
|
463
|
+
"test_id": "TEST-CONTEXT-C01",
|
|
464
|
+
"runner": "node:test",
|
|
465
|
+
"file": "tests/context-freshness.test.js"
|
|
466
|
+
},
|
|
467
|
+
{
|
|
468
|
+
"test_id": "TEST-CONTEXT-C02",
|
|
469
|
+
"runner": "node:test",
|
|
470
|
+
"file": "tests/context-freshness.test.js"
|
|
471
|
+
},
|
|
472
|
+
{
|
|
473
|
+
"test_id": "TEST-CONTEXT-C03",
|
|
474
|
+
"runner": "node:test",
|
|
475
|
+
"file": "tests/context-freshness.test.js"
|
|
476
|
+
},
|
|
477
|
+
{
|
|
478
|
+
"test_id": "TEST-CONTEXT-D01",
|
|
479
|
+
"runner": "node:test",
|
|
480
|
+
"file": "tests/context-constraints.test.js"
|
|
481
|
+
},
|
|
482
|
+
{
|
|
483
|
+
"test_id": "TEST-CONTEXT-D02",
|
|
484
|
+
"runner": "node:test",
|
|
485
|
+
"file": "tests/context-constraints.test.js"
|
|
486
|
+
},
|
|
487
|
+
{
|
|
488
|
+
"test_id": "TEST-CONTEXT-E01",
|
|
489
|
+
"runner": "node:test",
|
|
490
|
+
"file": "tests/context-secrets.test.js"
|
|
491
|
+
},
|
|
492
|
+
{
|
|
493
|
+
"test_id": "TEST-CONTEXT-E02",
|
|
494
|
+
"runner": "node:test",
|
|
495
|
+
"file": "tests/context-secrets.test.js"
|
|
496
|
+
},
|
|
497
|
+
{
|
|
498
|
+
"test_id": "TEST-CONTEXT-E03",
|
|
499
|
+
"runner": "node:test",
|
|
500
|
+
"file": "tests/context-secrets.test.js"
|
|
501
|
+
},
|
|
502
|
+
{
|
|
503
|
+
"test_id": "TEST-CONTEXT-F01",
|
|
504
|
+
"runner": "node:test",
|
|
505
|
+
"file": "tests/context-purity.test.js"
|
|
506
|
+
},
|
|
507
|
+
{
|
|
508
|
+
"test_id": "TEST-CONTEXT-F02",
|
|
509
|
+
"runner": "node:test",
|
|
510
|
+
"file": "tests/context-purity.test.js"
|
|
511
|
+
},
|
|
512
|
+
{
|
|
513
|
+
"test_id": "TEST-CONTEXT-G01",
|
|
514
|
+
"runner": "node:test",
|
|
515
|
+
"file": "tests/context-size-budget.test.js"
|
|
516
|
+
},
|
|
517
|
+
{
|
|
518
|
+
"test_id": "TEST-CONTEXT-H01",
|
|
519
|
+
"runner": "node:test",
|
|
520
|
+
"file": "tests/context-legacy.test.js"
|
|
521
|
+
}
|
|
522
|
+
]
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
---
|
|
526
|
+
|
|
527
|
+
## 10. Project Closure Gates (`gemstack-closure-gates`)
|
|
528
|
+
|
|
529
|
+
Preserves mandatory project closure gates:
|
|
530
|
+
|
|
531
|
+
```gemstack-closure-gates
|
|
532
|
+
[
|
|
533
|
+
{
|
|
534
|
+
"id": "project-tests",
|
|
535
|
+
"type": "PACKAGE_SCRIPT",
|
|
536
|
+
"script": "test",
|
|
537
|
+
"requirement": "REQUIRED",
|
|
538
|
+
"waivable": false
|
|
539
|
+
},
|
|
540
|
+
{
|
|
541
|
+
"id": "gate-ci-frontmatter",
|
|
542
|
+
"type": "PACKAGE_SCRIPT",
|
|
543
|
+
"script": "ci:frontmatter",
|
|
544
|
+
"requirement": "REQUIRED",
|
|
545
|
+
"waivable": false
|
|
546
|
+
},
|
|
547
|
+
{
|
|
548
|
+
"id": "gate-ci-mojibake",
|
|
549
|
+
"type": "PACKAGE_SCRIPT",
|
|
550
|
+
"script": "ci:mojibake",
|
|
551
|
+
"requirement": "REQUIRED",
|
|
552
|
+
"waivable": false
|
|
553
|
+
}
|
|
554
|
+
]
|
|
555
|
+
```
|
|
556
|
+
|
|
557
|
+
---
|
|
558
|
+
|
|
559
|
+
## 11. Implementation Phasing
|
|
560
|
+
|
|
561
|
+
```text
|
|
562
|
+
Phase 1: Foundation — Serialization, Schema & Secrets Guard
|
|
563
|
+
- Implement src/lib/context-capsule.js core utilities:
|
|
564
|
+
* canonical JSON serializer (UTF-16 sorted keys, array order, 2-space indentation).
|
|
565
|
+
* secret detection scanner (forbidden property names and token regex patterns).
|
|
566
|
+
* size budget counter and priority condensation.
|
|
567
|
+
- Tests: tests/context-determinism.test.js (TEST-CONTEXT-A01..A04),
|
|
568
|
+
tests/context-secrets.test.js (TEST-CONTEXT-E01..E03),
|
|
569
|
+
tests/context-size-budget.test.js (TEST-CONTEXT-G01).
|
|
570
|
+
|
|
571
|
+
Phase 2: Source Resolution, Provenance & Constraint Compression
|
|
572
|
+
- Implement source ingestion, hashing, and constraint extraction:
|
|
573
|
+
* resolveAuthoritativeSources, source_set_hash calculation.
|
|
574
|
+
* extractSemanticConstraints: normative MUST/MUST NOT extraction, contract preservation.
|
|
575
|
+
- Tests: tests/context-constraints.test.js (TEST-CONTEXT-D01..D02),
|
|
576
|
+
tests/context-authority.test.js (TEST-CONTEXT-B01..B04).
|
|
577
|
+
|
|
578
|
+
Phase 3: Generator & Validator Engines
|
|
579
|
+
- Implement generateContextCapsule and validateContextCapsule in src/lib/context-capsule.js:
|
|
580
|
+
* atomic file writing.
|
|
581
|
+
* read-only freshness evaluation and state mapping (VALID, STALE, INVALID, MISSING).
|
|
582
|
+
- Tests: tests/context-freshness.test.js (TEST-CONTEXT-C01..C03).
|
|
583
|
+
|
|
584
|
+
Phase 4: CLI Surface & Verify Read-Only Integration
|
|
585
|
+
- Implement src/commands/context.js and connect to src/cli.js router.
|
|
586
|
+
- Integrate Stage 5.2 Context Capsule audit in src/commands/verify.js.
|
|
587
|
+
- Update src/lib/closure-context.js relevant files resolution.
|
|
588
|
+
- Tests: tests/context-purity.test.js (TEST-CONTEXT-F01..F02),
|
|
589
|
+
tests/context-legacy.test.js (TEST-CONTEXT-H01).
|
|
590
|
+
|
|
591
|
+
Phase 5: Package Registration & Verification Hardening
|
|
592
|
+
- Register all 8 test files in package.json test script.
|
|
593
|
+
- Execute full test suite (`npm test`), verify passes 0 errors, run CI gates.
|
|
594
|
+
```
|
|
595
|
+
|
|
596
|
+
---
|
|
597
|
+
|
|
598
|
+
## 12. Dependency Graph
|
|
599
|
+
|
|
600
|
+
```text
|
|
601
|
+
Schema Definition & Canonical Serializer
|
|
602
|
+
│
|
|
603
|
+
▼
|
|
604
|
+
Secret Defense & Size Budget Guards
|
|
605
|
+
│
|
|
606
|
+
▼
|
|
607
|
+
Source Resolver & Provenance Hasher
|
|
608
|
+
│
|
|
609
|
+
▼
|
|
610
|
+
Semantic Constraint Extractor (Normative MUST/MUST NOT)
|
|
611
|
+
│
|
|
612
|
+
▼
|
|
613
|
+
Capsule Generator (Atomic Write)
|
|
614
|
+
│
|
|
615
|
+
▼
|
|
616
|
+
Capsule Validator (Read-Only Freshness & Schema Audit)
|
|
617
|
+
│
|
|
618
|
+
┌────────┴────────┐
|
|
619
|
+
▼ ▼
|
|
620
|
+
CLI Commands Verify Command Integration
|
|
621
|
+
(`gemstack context`) (`gemstack verify` Stage 5.2)
|
|
622
|
+
│ │
|
|
623
|
+
└────────┬────────┘
|
|
624
|
+
▼
|
|
625
|
+
Canonical Acceptance Test Suite (20 Tests / 8 Files)
|
|
626
|
+
│
|
|
627
|
+
▼
|
|
628
|
+
Closure Evidence Collection (`gemstack collect`)
|
|
629
|
+
```
|
|
630
|
+
|
|
631
|
+
---
|
|
632
|
+
|
|
633
|
+
## 13. Risk Register
|
|
634
|
+
|
|
635
|
+
| Risk | Impact | Mitigation Strategy | Mechanical Proof |
|
|
636
|
+
| :--- | :--- | :--- | :--- |
|
|
637
|
+
| **Semantic Constraint Loss** | Agent ignores safety rules | Priority 1 rules immutable; extraction tests verify 100% rule retention | `TEST-CONTEXT-D01` fails if any MUST rule omitted |
|
|
638
|
+
| **Capsule Becomes Accidental Authority** | Outdated capsule overrides source | Precedence hierarchy: Authoritative artifact always wins; verify rejects conflicts | `TEST-CONTEXT-B01` asserts authority conflict |
|
|
639
|
+
| **False Freshness / Silent Drift** | Stale capsule trusted by agent | Live SHA-256 hash comparison against disk state on every validation | `TEST-CONTEXT-C01` transitions to STALE on edit |
|
|
640
|
+
| **Nondeterministic Serialization** | Git noise / hash flapping | Strict UTF-16 code-unit key sorting and stable array ordering | `TEST-CONTEXT-A01` generates byte-identical files |
|
|
641
|
+
| **Secret Leakage in Capsule** | Exposed credentials | Strict forbidden keys list and credential regex scanner fail-closed | `TEST-CONTEXT-E01` fails closed on tokens |
|
|
642
|
+
| **Oversized Capsule** | Context window exhaustion | 32KB target / 64KB hard limit; fail-closed rejection on overflow | `TEST-CONTEXT-G01` halts with error |
|
|
643
|
+
| **Verify Accidentally Regenerating** | Violation of `VERIFY = VALIDATE` | Read-only verify implementation; socket and file mutation mocks | `TEST-CONTEXT-F01` checks 0-byte file diff |
|
|
644
|
+
| **Legacy Project Breakage** | Errors in existing repos | Progressive adoption; missing capsule logs info notice and exits 0 | `TEST-CONTEXT-H01` exits with code 0 |
|
|
645
|
+
|
|
646
|
+
---
|
|
647
|
+
|
|
648
|
+
## 14. Frozen Contract Compatibility Review
|
|
649
|
+
|
|
650
|
+
- **Upgrade A Contracts**: Zero conflicts. Reuses `hasher.js`, `contracts.js`, and `findings.js` without modifying existing behavior.
|
|
651
|
+
- **Upgrade B Semantics**: Zero conflicts. `VERIFY = VALIDATE` invariant is strictly preserved; `closure.json` evidence collection remains intact.
|
|
652
|
+
- **Upgrade C Safety**: Zero conflicts. Provider safety gates and cost ledger validation remain untouched.
|
|
653
|
+
- **Frozen Contracts Affected**: **`NONE`**.
|
|
654
|
+
|
|
655
|
+
---
|
|
656
|
+
|
|
657
|
+
## 15. Explicit Deferred Work
|
|
658
|
+
|
|
659
|
+
- Multi-repository capsule federation and aggregation (non-goal).
|
|
660
|
+
- Semantic vector embeddings or vector store integration (non-goal).
|
|
661
|
+
- Autonomous agent swarms and work-stealing queues (non-goal).
|
|
662
|
+
- Visual QA and automated browser capture (non-goal).
|
|
663
|
+
- Package version bumping or release publishing (strictly post-closure).
|