gemstack-ai 1.1.2 → 1.3.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/skills/gemstack-plan/SKILL.md +2 -1
- package/.agents/skills/gemstack-qa/SKILL.md +3 -0
- package/.agents/skills/gemstack-ship/SKILL.md +5 -1
- package/.agents/skills/gemstack-spec/SKILL.md +3 -2
- package/.agents/skills/gemstack-tasks/SKILL.md +4 -3
- package/.gemstack/state.json +7 -8
- package/CHANGELOG.md +75 -0
- package/README.md +36 -0
- package/RELEASE_NOTES.md +61 -0
- package/docs/architecture-consistency.md +14 -2
- package/docs/spec-driven-development.md +26 -0
- package/{gemstack-ai-1.1.2.tgz → gemstack-ai-1.3.0.tgz} +0 -0
- package/handoff.md +30 -15
- package/package.json +2 -2
- 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/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/templates/plan.md +30 -0
- package/specs/templates/spec.md +18 -0
- package/specs/templates/tasks.md +9 -0
- package/src/cli.js +8 -0
- package/src/commands/collect.js +340 -0
- package/src/commands/context.js +95 -0
- package/src/commands/ship.js +79 -0
- package/src/commands/verify.js +182 -6
- package/src/lib/closure-context.js +453 -0
- 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/runner-adapters.js +347 -0
- package/src/lib/safety-gates.js +277 -0
- package/src/lib/test-matrix.js +187 -0
|
@@ -0,0 +1,456 @@
|
|
|
1
|
+
# Plan de Implementación: Cost & Provider Safety Gates (Upgrade C)
|
|
2
|
+
|
|
3
|
+
**Feature Branch**: `008-cost-provider-safety-gates`
|
|
4
|
+
**Feature Directory**: `specs/008-cost-provider-safety-gates/`
|
|
5
|
+
**Spec**: [`specs/008-cost-provider-safety-gates/spec.md`](file:///c:/CODES/Gemstack/specs/008-cost-provider-safety-gates/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 C establishes a deterministic, fail-closed safety and cost verification framework for external and commercial provider interactions.
|
|
14
|
+
It builds directly upon the cryptographic and mechanical guarantees of Upgrade A (Architecture Consistency Engine) and Upgrade B (Mechanical Test Matrix & Closure Evidence):
|
|
15
|
+
```text
|
|
16
|
+
SPEC (gemstack-test-matrix: canonical criteria TEST-COST-A01..H01)
|
|
17
|
+
→ PLAN (gemstack-test-bindings: physical suite mapping & gemstack-closure-gates)
|
|
18
|
+
→ PROVIDER REGISTRY & COST LEDGER (.gemstack/providers.json & cost-ledger.json)
|
|
19
|
+
→ GATES (ProviderCapabilityGate & BillableActionGate)
|
|
20
|
+
→ BOUNDARY INTERCEPTOR (Safe Provider Execution Target)
|
|
21
|
+
→ VERIFY (Stage 5/6: Read-only ledger & gate verification; zero network)
|
|
22
|
+
→ CLOSURE (closure.json: fresh mechanical evidence & gatekeeper)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Central Invariant & Non-Negotiables:
|
|
26
|
+
1. **Central Invariant**: `NO PROOF OF AUTHORIZATION = NO COMMERCIAL EXECUTION`.
|
|
27
|
+
2. **Ambient Credential Distrust**: `credentials present ≠ authorization`. Presence of API keys or environment variables in shell/CI never bypasses policy.
|
|
28
|
+
3. **Environment Safety**: Commercial provider operations are strictly **DENIED** in `test` and `ci` environments.
|
|
29
|
+
4. **Re-entrant Fallbacks**: Switching providers during fallback re-evaluates all gates independently.
|
|
30
|
+
5. **VERIFY is ALWAYS Read-Only**: `gemstack verify` inspects declarations and ledgers with **zero** network requests, zero billing API calls, and zero file mutations.
|
|
31
|
+
6. **Zero External Runtime Dependencies**: Standard Node.js library exclusively (`node:fs`, `node:path`, `node:crypto`).
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## 2. Exact Repository Change Map
|
|
36
|
+
|
|
37
|
+
```text
|
|
38
|
+
================================================================================
|
|
39
|
+
REPOSITORY CHANGE MAP
|
|
40
|
+
================================================================================
|
|
41
|
+
[NEW MODULES]
|
|
42
|
+
- src/lib/cost-ledger.js : Parser, validator, schema checker, and serializer
|
|
43
|
+
for cost-ledger.json (forbidding secrets, detecting staleness).
|
|
44
|
+
- src/lib/provider-registry.js : Provider registration, capability declarations,
|
|
45
|
+
environment tier resolution, and mock boundary validation.
|
|
46
|
+
- src/lib/safety-gates.js : Fail-closed implementation of ProviderCapabilityGate
|
|
47
|
+
and BillableActionGate, with structured decision objects.
|
|
48
|
+
- src/lib/provider-boundary.js : High-integrity execution interceptor binding authorization
|
|
49
|
+
tokens to target providers and re-evaluating fallback chains.
|
|
50
|
+
|
|
51
|
+
[NEW TEST SUITES]
|
|
52
|
+
- tests/billable-action-gate.test.js : Physical tests for TEST-COST-A01..A04, G01 (20 canonical tests).
|
|
53
|
+
- tests/provider-capability-gate.test.js : Physical tests for TEST-COST-B01..B04.
|
|
54
|
+
- tests/environment-provider-safety.test.js : Physical tests for TEST-COST-C01..C03.
|
|
55
|
+
- tests/provider-fallback.test.js : Physical tests for TEST-COST-D01..D02.
|
|
56
|
+
- tests/cost-ledger.test.js : Physical tests for TEST-COST-E01..E03.
|
|
57
|
+
- tests/verification-purity-cost.test.js : Physical tests for TEST-COST-F01..F02, H01.
|
|
58
|
+
|
|
59
|
+
[MODIFIED EXISTING MODULES]
|
|
60
|
+
- src/commands/verify.js : Integrate Stage 5/6 extension for cost ledger validation,
|
|
61
|
+
secrets prohibition in safety files, and commercial adapter gating checks.
|
|
62
|
+
- src/lib/closure-context.js : Include cost-ledger.json in RelevantClosureFiles and
|
|
63
|
+
aggregate hash computations when present.
|
|
64
|
+
|
|
65
|
+
[FROZEN / UNTOUCHED]
|
|
66
|
+
- Upgrade A Core (src/lib/contracts.js, src/lib/findings.js, src/lib/hasher.js, src/lib/state.js)
|
|
67
|
+
- Upgrade B Core (src/lib/test-matrix.js, src/lib/runner-adapters.js, src/commands/collect.js, src/commands/ship.js)
|
|
68
|
+
- Historical Test Suites (tests/contracts.test.js, tests/hasher.test.js, tests/findings.test.js,
|
|
69
|
+
tests/init.test.js, tests/verify.test.js, tests/test-matrix.test.js,
|
|
70
|
+
tests/reconciliation.test.js, tests/runner-adapter.test.js,
|
|
71
|
+
tests/traceability.test.js, tests/closure-manifest.test.js,
|
|
72
|
+
tests/closure-gates.test.js)
|
|
73
|
+
================================================================================
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## 3. Contratos Aditivos del Plan (`gemstack-contracts`)
|
|
79
|
+
|
|
80
|
+
Inherits all 9 contracts from `specs/008-cost-provider-safety-gates/spec.md`. No new contracts are required:
|
|
81
|
+
|
|
82
|
+
```gemstack-contracts
|
|
83
|
+
[
|
|
84
|
+
{
|
|
85
|
+
"id": "zero-dependency-core",
|
|
86
|
+
"type": "BOOLEAN_INVARIANT",
|
|
87
|
+
"value": true,
|
|
88
|
+
"description": "Upgrade C implementation must introduce zero external production npm dependencies, using Node.js built-ins exclusively."
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"id": "upgrade-c-cost-states",
|
|
92
|
+
"type": "ENUM_SET",
|
|
93
|
+
"values": [
|
|
94
|
+
"FREE",
|
|
95
|
+
"BILLABLE",
|
|
96
|
+
"POTENTIALLY_BILLABLE",
|
|
97
|
+
"UNKNOWN"
|
|
98
|
+
],
|
|
99
|
+
"description": "Canonical cost-state classifications for provider actions."
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"id": "upgrade-c-environment-types",
|
|
103
|
+
"type": "ENUM_SET",
|
|
104
|
+
"values": [
|
|
105
|
+
"test",
|
|
106
|
+
"ci",
|
|
107
|
+
"development",
|
|
108
|
+
"staging",
|
|
109
|
+
"production"
|
|
110
|
+
],
|
|
111
|
+
"description": "Deterministic environment tiers recognized by provider safety gates."
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"id": "unknown-cost-never-free",
|
|
115
|
+
"type": "BOOLEAN_INVARIANT",
|
|
116
|
+
"value": true,
|
|
117
|
+
"description": "Cost classification UNKNOWN must never evaluate or degrade silently to FREE."
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"id": "provider-gate-fail-closed",
|
|
121
|
+
"type": "BOOLEAN_INVARIANT",
|
|
122
|
+
"value": true,
|
|
123
|
+
"description": "Any gate evaluation error, missing declaration, or ambiguous policy must result in DENY."
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
"id": "verify-performs-zero-provider-calls",
|
|
127
|
+
"type": "BOOLEAN_INVARIANT",
|
|
128
|
+
"value": true,
|
|
129
|
+
"description": "gemstack verify must never execute network requests or invoke remote providers during verification."
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
"id": "fallback-requires-revalidation",
|
|
133
|
+
"type": "BOOLEAN_INVARIANT",
|
|
134
|
+
"value": true,
|
|
135
|
+
"description": "Provider fallback chains must independently evaluate all capability and cost gates for each candidate."
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
"id": "secrets-forbidden-in-safety-artifacts",
|
|
139
|
+
"type": "BOOLEAN_INVARIANT",
|
|
140
|
+
"value": true,
|
|
141
|
+
"description": "API keys, tokens, or credential secrets must never be stored, hashed, or checked into safety manifests or ledgers."
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
"id": "legacy-provider-compatibility",
|
|
145
|
+
"type": "BOOLEAN_INVARIANT",
|
|
146
|
+
"value": true,
|
|
147
|
+
"description": "Features without declared provider blocks or provider-free repositories operate cleanly in legacy mode."
|
|
148
|
+
}
|
|
149
|
+
]
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## 4. Provider Registry Architecture (`src/lib/provider-registry.js`)
|
|
155
|
+
|
|
156
|
+
- **Authoritative Source**: Declarations in `plan.md` (or `.gemstack/providers.json` at repository root).
|
|
157
|
+
- **Public API**:
|
|
158
|
+
- `loadProviderRegistry(rootPath, featureDir)`: Loads and validates provider declarations.
|
|
159
|
+
- `resolveEnvironmentTier(options)`: Resolves environment tier (`test`, `ci`, `development`, `staging`, `production`) using explicit flags and deterministic system indicators (`process.env.CI`). Never trusts ambient credentials.
|
|
160
|
+
- `validateMockIntegrity(providerConfig)`: Verifies mock provider declarations are strictly local.
|
|
161
|
+
- **Provider Shape**:
|
|
162
|
+
```json
|
|
163
|
+
{
|
|
164
|
+
"provider_id": "gemini-cloud",
|
|
165
|
+
"type": "COMMERCIAL",
|
|
166
|
+
"allowed_environments": ["development", "staging", "production"],
|
|
167
|
+
"capabilities": ["inference.generate_text", "inference.embeddings"]
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## 5. Cost Ledger Architecture (`src/lib/cost-ledger.js`)
|
|
174
|
+
|
|
175
|
+
- **Authoritative Artifact**: `cost-ledger.json` (feature-local or `.gemstack/cost-ledger.json`).
|
|
176
|
+
- **Public API**:
|
|
177
|
+
- `loadCostLedger(filePath)`: Reads, parses, and validates ledger schema.
|
|
178
|
+
- `validateLedgerSchema(data)`: Validates schema version 1, code units sorting, and data integrity.
|
|
179
|
+
- `auditSecretsForbidden(data)`: Strictly scans for forbidden keys (`api_key`, `token`, `secret`, `authorization`, `private_key`) and credential patterns.
|
|
180
|
+
- `checkStaleness(entry, maxAgeDays)`: Compares `freshness_date` against threshold; emits `STALE_PROVIDER_COST_ASSUMPTION` warning if expired.
|
|
181
|
+
- **Pure Serialization**: Deterministic code-unit sorted JSON serializer without formatting drift.
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## 6. Safety Gates Architecture (`src/lib/safety-gates.js`)
|
|
186
|
+
|
|
187
|
+
### 6.1 `ProviderCapabilityGate`
|
|
188
|
+
- **Inputs**: `{ providerId, capabilityId, environment, registry }`
|
|
189
|
+
- **Order of Evaluation**:
|
|
190
|
+
1. `UNKNOWN_PROVIDER_IDENTITY`: Provider must exist in registry.
|
|
191
|
+
2. `ENV_COMMERCIAL_DENIED`: Commercial provider disallowed in `test` / `ci`.
|
|
192
|
+
3. `PROVIDER_CAPABILITY_UNDECLARED`: Capability must be listed in provider declaration.
|
|
193
|
+
4. `PROVIDER_CAPABILITY_UNSUPPORTED`: Adapter must support capability.
|
|
194
|
+
- **Output**: `{ authorized: boolean, decision: 'ALLOW'|'DENY', reasonCode: string, message: string, context: object }`
|
|
195
|
+
|
|
196
|
+
### 6.2 `BillableActionGate`
|
|
197
|
+
- **Inputs**: `{ actionId, providerId, capabilityId, environment, requestedUnits, authorizationToken, ledger }`
|
|
198
|
+
- **Order of Evaluation**:
|
|
199
|
+
1. `ENV_COMMERCIAL_DENIED`: Fail-closed check on environment tier.
|
|
200
|
+
2. `UNDECLARED_BILLABLE_ACTION`: Action must be declared in specification/plan.
|
|
201
|
+
3. `UNKNOWN_COST_CLASSIFICATION`: Cost state must be resolved in ledger (`UNKNOWN` strictly fails closed).
|
|
202
|
+
4. `FREE`: If cost state is `FREE` and provider is local/mock, returns `ALLOW`.
|
|
203
|
+
5. `BILLABLE_ACTION_UNAUTHORIZED`: If cost is `BILLABLE` or `POTENTIALLY_BILLABLE`, explicit authorization token is required.
|
|
204
|
+
6. `BUDGET_THRESHOLD_EXCEEDED`: Evaluates estimated units against `max_budget_units` in authorization token.
|
|
205
|
+
- **Output**: Structured decision object identical in shape to `ProviderCapabilityGate`.
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## 7. Execution Boundary & Fallback Safety (`src/lib/provider-boundary.js`)
|
|
210
|
+
|
|
211
|
+
- **Execution Interceptor**: Wraps adapter invocations in a strict 2-stage verification barrier:
|
|
212
|
+
```text
|
|
213
|
+
executeProviderAction(actionRequest, adapter, fallbackChain)
|
|
214
|
+
1. ProviderCapabilityGate.evaluate(...) -> If DENY, halt with Error(reasonCode)
|
|
215
|
+
2. BillableActionGate.evaluate(...) -> If DENY, halt with Error(reasonCode)
|
|
216
|
+
3. Bind authorization token cryptographically to providerId & capabilityId
|
|
217
|
+
4. Invoke adapter.execute(...)
|
|
218
|
+
5. On adapter failure -> If fallbackChain exists:
|
|
219
|
+
For each candidate in fallbackChain:
|
|
220
|
+
RE-EVALUATE ProviderCapabilityGate & BillableActionGate INDEPENDENTLY!
|
|
221
|
+
If authorized -> execute candidate
|
|
222
|
+
If denied -> emit PROVIDER_FALLBACK_UNAUTHORIZED and halt
|
|
223
|
+
```
|
|
224
|
+
- **Anti-TOCTOU Guarantee**: Authorization tokens are non-transferable between provider IDs.
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
## 8. Findings & Accepted Exceptions Integration
|
|
229
|
+
|
|
230
|
+
Upgrade C findings map 1:1 into `src/lib/findings.js` via `createFinding`:
|
|
231
|
+
- **Finding Codes**:
|
|
232
|
+
- `UNDECLARED_BILLABLE_ACTION`
|
|
233
|
+
- `BILLABLE_ACTION_UNAUTHORIZED`
|
|
234
|
+
- `UNKNOWN_COST_CLASSIFICATION`
|
|
235
|
+
- `UNKNOWN_PROVIDER_IDENTITY`
|
|
236
|
+
- `PROVIDER_CAPABILITY_UNDECLARED`
|
|
237
|
+
- `PROVIDER_CAPABILITY_UNSUPPORTED`
|
|
238
|
+
- `ENV_COMMERCIAL_DENIED`
|
|
239
|
+
- `PROVIDER_FALLBACK_UNAUTHORIZED`
|
|
240
|
+
- `STALE_PROVIDER_COST_ASSUMPTION` (Severity: `WARNING`, Exception-eligible)
|
|
241
|
+
- `BUDGET_THRESHOLD_EXCEEDED`
|
|
242
|
+
- `MOCK_PROVIDER_ESCAPE_VIOLATION`
|
|
243
|
+
- `COST_LEDGER_INVALID`
|
|
244
|
+
- **Waiver Policy**:
|
|
245
|
+
- Only `STALE_PROVIDER_COST_ASSUMPTION` is eligible for human-approved exception bound to `contextHash`.
|
|
246
|
+
- All other safety and authorization blockers are **STRICTLY NON-WAIVABLE**.
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## 9. Verification Purity & Offline Proof (`gemstack verify`)
|
|
251
|
+
|
|
252
|
+
- **Audit Integration**: Extend `src/commands/verify.js` (Stage 5/6):
|
|
253
|
+
- Validates `cost-ledger.json` syntax and schema.
|
|
254
|
+
- Verifies zero secrets present in safety ledgers.
|
|
255
|
+
- Verifies that declared commercial adapters implement canonical gate calls.
|
|
256
|
+
- Verifies legacy mode passes cleanly if no providers are declared.
|
|
257
|
+
- **Network Purity Test**: `tests/verification-purity-cost.test.js` wraps Node's `net.Socket` and `http/https.request` with throwing mocks to mechanically prove that running `gemstack verify` generates zero network connections.
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## 10. Canonical Test Bindings (`gemstack-test-bindings`)
|
|
262
|
+
|
|
263
|
+
The 20 canonical acceptance tests from `specs/008-cost-provider-safety-gates/spec.md` are mapped 1:1 to 6 physical test suites:
|
|
264
|
+
|
|
265
|
+
```gemstack-test-bindings
|
|
266
|
+
[
|
|
267
|
+
{
|
|
268
|
+
"test_id": "TEST-COST-A01",
|
|
269
|
+
"runner": "node:test",
|
|
270
|
+
"file": "tests/billable-action-gate.test.js"
|
|
271
|
+
},
|
|
272
|
+
{
|
|
273
|
+
"test_id": "TEST-COST-A02",
|
|
274
|
+
"runner": "node:test",
|
|
275
|
+
"file": "tests/billable-action-gate.test.js"
|
|
276
|
+
},
|
|
277
|
+
{
|
|
278
|
+
"test_id": "TEST-COST-A03",
|
|
279
|
+
"runner": "node:test",
|
|
280
|
+
"file": "tests/billable-action-gate.test.js"
|
|
281
|
+
},
|
|
282
|
+
{
|
|
283
|
+
"test_id": "TEST-COST-A04",
|
|
284
|
+
"runner": "node:test",
|
|
285
|
+
"file": "tests/billable-action-gate.test.js"
|
|
286
|
+
},
|
|
287
|
+
{
|
|
288
|
+
"test_id": "TEST-COST-B01",
|
|
289
|
+
"runner": "node:test",
|
|
290
|
+
"file": "tests/provider-capability-gate.test.js"
|
|
291
|
+
},
|
|
292
|
+
{
|
|
293
|
+
"test_id": "TEST-COST-B02",
|
|
294
|
+
"runner": "node:test",
|
|
295
|
+
"file": "tests/provider-capability-gate.test.js"
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
"test_id": "TEST-COST-B03",
|
|
299
|
+
"runner": "node:test",
|
|
300
|
+
"file": "tests/provider-capability-gate.test.js"
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
"test_id": "TEST-COST-B04",
|
|
304
|
+
"runner": "node:test",
|
|
305
|
+
"file": "tests/provider-capability-gate.test.js"
|
|
306
|
+
},
|
|
307
|
+
{
|
|
308
|
+
"test_id": "TEST-COST-C01",
|
|
309
|
+
"runner": "node:test",
|
|
310
|
+
"file": "tests/environment-provider-safety.test.js"
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
"test_id": "TEST-COST-C02",
|
|
314
|
+
"runner": "node:test",
|
|
315
|
+
"file": "tests/environment-provider-safety.test.js"
|
|
316
|
+
},
|
|
317
|
+
{
|
|
318
|
+
"test_id": "TEST-COST-C03",
|
|
319
|
+
"runner": "node:test",
|
|
320
|
+
"file": "tests/environment-provider-safety.test.js"
|
|
321
|
+
},
|
|
322
|
+
{
|
|
323
|
+
"test_id": "TEST-COST-D01",
|
|
324
|
+
"runner": "node:test",
|
|
325
|
+
"file": "tests/provider-fallback.test.js"
|
|
326
|
+
},
|
|
327
|
+
{
|
|
328
|
+
"test_id": "TEST-COST-D02",
|
|
329
|
+
"runner": "node:test",
|
|
330
|
+
"file": "tests/provider-fallback.test.js"
|
|
331
|
+
},
|
|
332
|
+
{
|
|
333
|
+
"test_id": "TEST-COST-E01",
|
|
334
|
+
"runner": "node:test",
|
|
335
|
+
"file": "tests/cost-ledger.test.js"
|
|
336
|
+
},
|
|
337
|
+
{
|
|
338
|
+
"test_id": "TEST-COST-E02",
|
|
339
|
+
"runner": "node:test",
|
|
340
|
+
"file": "tests/cost-ledger.test.js"
|
|
341
|
+
},
|
|
342
|
+
{
|
|
343
|
+
"test_id": "TEST-COST-E03",
|
|
344
|
+
"runner": "node:test",
|
|
345
|
+
"file": "tests/cost-ledger.test.js"
|
|
346
|
+
},
|
|
347
|
+
{
|
|
348
|
+
"test_id": "TEST-COST-F01",
|
|
349
|
+
"runner": "node:test",
|
|
350
|
+
"file": "tests/verification-purity-cost.test.js"
|
|
351
|
+
},
|
|
352
|
+
{
|
|
353
|
+
"test_id": "TEST-COST-F02",
|
|
354
|
+
"runner": "node:test",
|
|
355
|
+
"file": "tests/verification-purity-cost.test.js"
|
|
356
|
+
},
|
|
357
|
+
{
|
|
358
|
+
"test_id": "TEST-COST-G01",
|
|
359
|
+
"runner": "node:test",
|
|
360
|
+
"file": "tests/billable-action-gate.test.js"
|
|
361
|
+
},
|
|
362
|
+
{
|
|
363
|
+
"test_id": "TEST-COST-H01",
|
|
364
|
+
"runner": "node:test",
|
|
365
|
+
"file": "tests/verification-purity-cost.test.js"
|
|
366
|
+
}
|
|
367
|
+
]
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
---
|
|
371
|
+
|
|
372
|
+
## 11. Project Closure Gates (`gemstack-closure-gates`)
|
|
373
|
+
|
|
374
|
+
Upgrade C preserves all established project closure gates:
|
|
375
|
+
|
|
376
|
+
```gemstack-closure-gates
|
|
377
|
+
[
|
|
378
|
+
{
|
|
379
|
+
"id": "project-tests",
|
|
380
|
+
"type": "PACKAGE_SCRIPT",
|
|
381
|
+
"script": "test",
|
|
382
|
+
"requirement": "REQUIRED",
|
|
383
|
+
"waivable": false
|
|
384
|
+
},
|
|
385
|
+
{
|
|
386
|
+
"id": "gate-ci-frontmatter",
|
|
387
|
+
"type": "PACKAGE_SCRIPT",
|
|
388
|
+
"script": "ci:frontmatter",
|
|
389
|
+
"requirement": "REQUIRED",
|
|
390
|
+
"waivable": false
|
|
391
|
+
},
|
|
392
|
+
{
|
|
393
|
+
"id": "gate-ci-mojibake",
|
|
394
|
+
"type": "PACKAGE_SCRIPT",
|
|
395
|
+
"script": "ci:mojibake",
|
|
396
|
+
"requirement": "REQUIRED",
|
|
397
|
+
"waivable": false
|
|
398
|
+
}
|
|
399
|
+
]
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
---
|
|
403
|
+
|
|
404
|
+
## 12. Implementation Phasing
|
|
405
|
+
|
|
406
|
+
```text
|
|
407
|
+
Phase 1: Schemas & Ledger Foundation
|
|
408
|
+
- Implement src/lib/cost-ledger.js (schema validation, secret prohibition, staleness checks).
|
|
409
|
+
- Test suites: tests/cost-ledger.test.js (TEST-COST-E01..E03).
|
|
410
|
+
|
|
411
|
+
Phase 2: Provider Registry & Environment Safety
|
|
412
|
+
- Implement src/lib/provider-registry.js (registry loading, environment tier resolution, mock verification).
|
|
413
|
+
- Test suites: tests/environment-provider-safety.test.js (TEST-COST-C01..C03).
|
|
414
|
+
|
|
415
|
+
Phase 3: Capability & Billable Action Safety Gates
|
|
416
|
+
- Implement src/lib/safety-gates.js (ProviderCapabilityGate and BillableActionGate).
|
|
417
|
+
- Test suites: tests/provider-capability-gate.test.js (TEST-COST-B01..B04),
|
|
418
|
+
tests/billable-action-gate.test.js (TEST-COST-A01..A04, G01).
|
|
419
|
+
|
|
420
|
+
Phase 4: Execution Boundary & Fallback Chains
|
|
421
|
+
- Implement src/lib/provider-boundary.js (re-entrant fallback validation, token binding).
|
|
422
|
+
- Test suites: tests/provider-fallback.test.js (TEST-COST-D01..D02).
|
|
423
|
+
|
|
424
|
+
Phase 5: Verify & Closure Integration
|
|
425
|
+
- Extend src/commands/verify.js and src/lib/closure-context.js.
|
|
426
|
+
- Test suites: tests/verification-purity-cost.test.js (TEST-COST-F01..F02, H01).
|
|
427
|
+
- Validate gemstack collect, gemstack verify, and closure.json generation.
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
---
|
|
431
|
+
|
|
432
|
+
## 13. Risk Register
|
|
433
|
+
|
|
434
|
+
| Implementation Risk | Impact | Mitigation Strategy | Mechanical Proof |
|
|
435
|
+
| :--- | :--- | :--- | :--- |
|
|
436
|
+
| **Accidental Network Call in Verify** | False closure via remote coupling | Throwing socket mock in verification purity tests | `TEST-COST-F01` passes with net/http disabled |
|
|
437
|
+
| **Fallback Authorization Leakage** | Expensive fallback invoked without spending permission | Re-entrant gate check required per candidate | `TEST-COST-D02` asserts denial on unapproved secondary |
|
|
438
|
+
| **Secret Leakage in Ledger** | Committed API tokens in repo | Strict key-name regex audit on ledger serialization | `TEST-COST-E03` fails closed on credential tokens |
|
|
439
|
+
| **Silent UNKNOWN Cost Degradation** | Unexpected cloud charges | Hardcoded invariant: `UNKNOWN` never evaluates to `FREE` | `TEST-COST-A04` asserts fail-closed behavior |
|
|
440
|
+
| **Legacy Project Breakage** | Regression in provider-free repos | Progressive legacy bypass notice without errors | `TEST-COST-H01` completes with exit code 0 |
|
|
441
|
+
|
|
442
|
+
---
|
|
443
|
+
|
|
444
|
+
## 14. Frozen Contract Compatibility Review
|
|
445
|
+
|
|
446
|
+
- **Upgrade A Contracts**: Zero contract conflicts. Reuses `FrozenContractRegistry`, findings, fingerprints, and atomic state writers byte-for-byte.
|
|
447
|
+
- **Upgrade B Semantics**: Zero semantic conflicts. Test matrix syntax, acceptance signature hashing, runner adapters, exact arithmetic, and read-only verification remain 100% intact.
|
|
448
|
+
- **Frozen Hashes Check**: No historical test files or previous feature artifacts are modified.
|
|
449
|
+
|
|
450
|
+
---
|
|
451
|
+
|
|
452
|
+
## 15. Explicit Deferred Items
|
|
453
|
+
|
|
454
|
+
- Dynamic real-time provider balance queries (out of scope, non-goal).
|
|
455
|
+
- Payment provider webhook handlers (out of scope, non-goal).
|
|
456
|
+
- Context compression algorithms (strictly reserved for Upgrade D).
|