gemstack-ai 1.4.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/.agents/rules/03-gemstack-security.md +2 -2
  2. package/.gemstack/state.json +10 -11
  3. package/CHANGELOG.md +33 -0
  4. package/CONTRIBUTING.md +1 -1
  5. package/README.md +47 -13
  6. package/RELEASE_NOTES.md +40 -1
  7. package/handoff.md +33 -19
  8. package/package.json +4 -3
  9. package/scripts/ci/check-package-contents.js +1 -1
  10. package/scripts/ci/check-secrets.js +84 -0
  11. package/specs/011-gemstack-2.0-hardening/.gemstack.json +5 -0
  12. package/specs/011-gemstack-2.0-hardening/closure.json +58 -0
  13. package/specs/011-gemstack-2.0-hardening/plan.md +210 -0
  14. package/specs/011-gemstack-2.0-hardening/spec.md +277 -0
  15. package/specs/011-gemstack-2.0-hardening/tasks.md +59 -0
  16. package/specs/012-gemstack-2.0-honest-evidence/.gemstack.json +5 -0
  17. package/specs/012-gemstack-2.0-honest-evidence/closure.json +58 -0
  18. package/specs/012-gemstack-2.0-honest-evidence/plan.md +202 -0
  19. package/specs/012-gemstack-2.0-honest-evidence/spec.md +222 -0
  20. package/specs/012-gemstack-2.0-honest-evidence/tasks.md +99 -0
  21. package/specs/013-gemstack-2.0-adaptable-sdd/.gemstack.json +9 -0
  22. package/specs/013-gemstack-2.0-adaptable-sdd/closure.json +58 -0
  23. package/specs/013-gemstack-2.0-adaptable-sdd/context-capsule.json +227 -0
  24. package/specs/013-gemstack-2.0-adaptable-sdd/plan.md +179 -0
  25. package/specs/013-gemstack-2.0-adaptable-sdd/spec.md +212 -0
  26. package/specs/013-gemstack-2.0-adaptable-sdd/tasks.md +90 -0
  27. package/specs/014-gemstack-2.0-context-memory/.gemstack.json +9 -0
  28. package/specs/014-gemstack-2.0-context-memory/closure.json +58 -0
  29. package/specs/014-gemstack-2.0-context-memory/plan.md +161 -0
  30. package/specs/014-gemstack-2.0-context-memory/spec.md +163 -0
  31. package/specs/014-gemstack-2.0-context-memory/tasks.md +79 -0
  32. package/src/cli.js +3 -0
  33. package/src/commands/doctor.js +18 -0
  34. package/src/commands/hooks.js +98 -14
  35. package/src/commands/init.js +1 -1
  36. package/src/commands/install.js +174 -49
  37. package/src/commands/spec.js +105 -0
  38. package/src/commands/update.js +1 -1
  39. package/src/commands/verify.js +10 -0
  40. package/src/lib/backup.js +3 -3
  41. package/src/lib/context-fatigue.js +165 -0
  42. package/src/lib/contract-amendments.js +109 -0
  43. package/src/lib/dependency-audit.js +202 -0
  44. package/src/lib/filesystem-safe.js +85 -15
  45. package/src/lib/memory-audit.js +121 -0
  46. package/src/lib/provider-boundary.js +5 -1
  47. package/src/lib/provider-registry.js +6 -4
  48. package/src/lib/safety-gates.js +176 -8
  49. package/src/lib/sdd-rigor.js +181 -0
  50. package/src/lib/spec-delta.js +194 -0
  51. package/src/lib/spec-merge.js +168 -0
  52. package/src/lib/swarm.js +2 -2
  53. package/src/lib/visual-qa.js +162 -9
  54. package/template/.agents/rules/03-gemstack-security.md +2 -2
  55. package/.github/workflows/main-ci.yml +0 -32
  56. package/.github/workflows/pr-ci.yml +0 -31
  57. package/.github/workflows/publish.yml +0 -52
  58. package/.github/workflows/release-readiness.yml +0 -43
  59. package/gemstack-ai-1.4.0.tgz +0 -0
@@ -0,0 +1,202 @@
1
+ # Implementation Plan: Gemstack 2.0 Sprint B — Honest Evidence & Reliable Metrics
2
+
3
+ **Feature ID:** `012-gemstack-2.0-honest-evidence`
4
+ **Phase:** `plan`
5
+ **Parent Release:** `gemstack-ai@2.0.0-alpha`
6
+
7
+ ---
8
+
9
+ ## 1. Inherited Architecture Contracts
10
+
11
+ ```gemstack-inherited-contracts
12
+ [
13
+ {
14
+ "id": "gate-token-trusted-boundary",
15
+ "type": "ENUM_SET",
16
+ "values": [
17
+ "signed-token",
18
+ "positive-units",
19
+ "cumulative-budget",
20
+ "scope-binding",
21
+ "expiration-check"
22
+ ]
23
+ },
24
+ {
25
+ "id": "vqa-computed-evidence",
26
+ "type": "ENUM_SET",
27
+ "values": [
28
+ "disk-recomputed-hash",
29
+ "real-image-adapter",
30
+ "unverified-fallback",
31
+ "immutable-baseline"
32
+ ]
33
+ },
34
+ {
35
+ "id": "vqa-pre-persistence-masking",
36
+ "type": "BOOLEAN_INVARIANT",
37
+ "value": true
38
+ },
39
+ {
40
+ "id": "truthful-documentation-table",
41
+ "type": "ENUM_SET",
42
+ "values": [
43
+ "control",
44
+ "scope",
45
+ "test",
46
+ "limit"
47
+ ]
48
+ },
49
+ {
50
+ "id": "workflow-least-privilege",
51
+ "type": "ENUM_SET",
52
+ "values": [
53
+ "sha-pinned-actions",
54
+ "permissions-least-privilege",
55
+ "npm-ci"
56
+ ]
57
+ }
58
+ ]
59
+ ```
60
+
61
+ ---
62
+
63
+ ## 2. Technical Architecture & Component Changes
64
+
65
+ ### Component 1: `src/lib/safety-gates.js`
66
+ - Export `issueSpendingToken({ secret, provider_id, action_id, max_budget_units, ttl_seconds })`: Generates a verifiable token containing `token_id`, `provider_id`, `action_id`, `max_budget_units`, `expires_at`, and HMAC-SHA256 signature using a boundary secret.
67
+ - Export `verifySpendingToken(token, secret)`: Validates format, signature, and expiration.
68
+ - Add in-memory cumulative spending tracking (`tokenSpendingLedger` or token tracking object) to record cumulative units spent per `token_id`.
69
+ - Update `evaluateBillableAction(request, ledger, options)`:
70
+ 1. Validate `requested_units`: must be finite positive number (`> 0`). Reject with `INVALID_REQUESTED_UNITS` otherwise.
71
+ 2. Validate `authorization_token`: must be present and verified by trusted boundary (`verifySpendingToken` or trusted authority). Reject unsigned/self-declared tokens with `BILLABLE_ACTION_UNAUTHORIZED`.
72
+ 3. Validate token scope: `token.provider_id` must match `request.provider_id` (or `'*'`), and `token.action_id` must match `request.action_id` (or `'*'`). Reject mismatches with `TOKEN_SCOPE_MISMATCH`.
73
+ 4. Validate expiration: `Date.now() <= Date.parse(token.expires_at)`. Reject expired tokens with `TOKEN_EXPIRED`.
74
+ 5. Validate cumulative budget: `(current_spent + estimatedTotalCost) <= token.max_budget_units`. Reject overages with `BUDGET_THRESHOLD_EXCEEDED`. On allow, update cumulative spent units.
75
+
76
+ ### Component 2: `src/lib/visual-qa.js`
77
+ - Update `compareVisualEvidence(scenario, evidence, targetDir, options)`:
78
+ 1. Recompute `baseline` hash from `scenario.baseline.image_path` on disk using `resolveSafeStrict`. If file is missing or tampered, fail with `VQA_BASELINE_TAMPERED`.
79
+ 2. Locate `evidence.live_screenshot_path` on disk using `resolveSafeStrict`. If missing, return `VQA_IMAGE_NOT_FOUND`.
80
+ 3. Recompute live screenshot hash from disk. If `evidence.image_sha256` is provided and does not match disk hash, reject with `VQA_EVIDENCE_HASH_MISMATCH`.
81
+ 4. Compare disk hashes: If live hash === baseline hash, observed diff is `0.0%` (status `PASS`).
82
+ 5. If hashes differ: check if an image diff adapter (`options.diffAdapter`) is provided. If so, execute adapter to calculate mathematical diff. If no adapter is provided, return status `UNVERIFIED` with `passed: false` and finding `VQA_DIFF_ENGINE_UNAVAILABLE`.
83
+ - Add `maskSensitiveFieldsBeforeCapture(domTreeOrSelectors)`: sanitizes credential and sensitive fields prior to screenshot persistence.
84
+
85
+ ### Component 3: Documentation & Rules Truthfulness
86
+ - `README.md`:
87
+ - Replace "military-grade" badge and text with "Architecture Consistency & Security Gates".
88
+ - Replace "physically prevented" with "Mechanically verified".
89
+ - Add public table: `Control | Scope | Test Verification | Boundary Limit`.
90
+ - `.agents/rules/03-gemstack-security.md` & `template/.agents/rules/03-gemstack-security.md`:
91
+ - Replace "mitigar el 99% de las vulnerabilidades comunes (OWASP)" with "Diseño sistemático de controles arquitectónicos y de seguridad verificables".
92
+ - `CONTRIBUTING.md`: Remove "military-grade".
93
+
94
+ ### Component 4: GitHub Actions Hardening (`.github/workflows/*`)
95
+ - Pin all actions to 40-character commit SHAs:
96
+ - `actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2`
97
+ - `actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0`
98
+ - `actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1`
99
+ - Add top-level `permissions: contents: read` across all workflows; only `publish.yml` gets `contents: write` on the release job.
100
+ - Standardize on `npm ci` where `package-lock.json` is present.
101
+
102
+ ---
103
+
104
+ ## 3. Canonical Test Bindings
105
+
106
+ ```gemstack-test-bindings
107
+ [
108
+ {
109
+ "id": "TEST-EVID-A01",
110
+ "file": "tests/honest-evidence-p1.test.js",
111
+ "symbol": "TEST-EVID-A01"
112
+ },
113
+ {
114
+ "id": "TEST-EVID-A02",
115
+ "file": "tests/honest-evidence-p1.test.js",
116
+ "symbol": "TEST-EVID-A02"
117
+ },
118
+ {
119
+ "id": "TEST-EVID-A03",
120
+ "file": "tests/honest-evidence-p1.test.js",
121
+ "symbol": "TEST-EVID-A03"
122
+ },
123
+ {
124
+ "id": "TEST-EVID-A04",
125
+ "file": "tests/honest-evidence-p1.test.js",
126
+ "symbol": "TEST-EVID-A04"
127
+ },
128
+ {
129
+ "id": "TEST-EVID-B01",
130
+ "file": "tests/honest-evidence-p1.test.js",
131
+ "symbol": "TEST-EVID-B01"
132
+ },
133
+ {
134
+ "id": "TEST-EVID-B02",
135
+ "file": "tests/honest-evidence-p1.test.js",
136
+ "symbol": "TEST-EVID-B02"
137
+ },
138
+ {
139
+ "id": "TEST-EVID-B03",
140
+ "file": "tests/honest-evidence-p1.test.js",
141
+ "symbol": "TEST-EVID-B03"
142
+ },
143
+ {
144
+ "id": "TEST-EVID-B04",
145
+ "file": "tests/honest-evidence-p1.test.js",
146
+ "symbol": "TEST-EVID-B04"
147
+ },
148
+ {
149
+ "id": "TEST-EVID-C01",
150
+ "file": "tests/honest-evidence-p1.test.js",
151
+ "symbol": "TEST-EVID-C01"
152
+ },
153
+ {
154
+ "id": "TEST-EVID-C02",
155
+ "file": "tests/honest-evidence-p1.test.js",
156
+ "symbol": "TEST-EVID-C02"
157
+ },
158
+ {
159
+ "id": "TEST-EVID-C03",
160
+ "file": "tests/honest-evidence-p1.test.js",
161
+ "symbol": "TEST-EVID-C03"
162
+ },
163
+ {
164
+ "id": "TEST-EVID-D01",
165
+ "file": "tests/honest-evidence-p1.test.js",
166
+ "symbol": "TEST-EVID-D01"
167
+ },
168
+ {
169
+ "id": "TEST-EVID-D02",
170
+ "file": "tests/honest-evidence-p1.test.js",
171
+ "symbol": "TEST-EVID-D02"
172
+ },
173
+ {
174
+ "id": "TEST-EVID-D03",
175
+ "file": "tests/honest-evidence-p1.test.js",
176
+ "symbol": "TEST-EVID-D03"
177
+ }
178
+ ]
179
+ ```
180
+
181
+ ---
182
+
183
+ ## 4. Mechanical Closure Gates
184
+
185
+ ```gemstack-closure-gates
186
+ [
187
+ {
188
+ "id": "gate-test",
189
+ "type": "PACKAGE_SCRIPT",
190
+ "script": "test",
191
+ "requirement": "REQUIRED",
192
+ "waivable": false
193
+ },
194
+ {
195
+ "id": "gate-ci-all",
196
+ "type": "PACKAGE_SCRIPT",
197
+ "script": "ci:all",
198
+ "requirement": "REQUIRED",
199
+ "waivable": false
200
+ }
201
+ ]
202
+ ```
@@ -0,0 +1,222 @@
1
+ # Feature Specification: Gemstack 2.0 Sprint B — Honest Evidence & Reliable Metrics
2
+
3
+ **Feature ID:** `012-gemstack-2.0-honest-evidence`
4
+ **Phase:** `spec`
5
+ **Parent Release:** `gemstack-ai@2.0.0-alpha`
6
+ **Sprint:** Sprint B (P1 — Honest Gates, Real Visual Diff, Release Hygiene & Docs Truthfulness)
7
+
8
+ ---
9
+
10
+ ## 1. Context & Business Intent
11
+
12
+ Gemstack 1.4.0 introduced spending safety gates (`safety-gates.js`), visual QA validation (`visual-qa.js`), and pre-commit hooks. However, an architectural audit revealed trust boundary weaknesses:
13
+ 1. `safety-gates.js`: Caller-supplied authorization tokens with `max_budget_units` or `source: CLI_FLAG` passed validation without trusted boundary verification; negative unit requests (`requested_units = -1`) could bypass cost ceilings; spending was not tracked cumulatively across calls; tokens lacked cryptographic scope and expiration checks.
14
+ 2. `visual-qa.js`: Visual comparison blindly accepted caller-supplied `image_sha256` and `diff_percentage` without recomputing hashes from disk or running a real image diff engine. If no diff engine was present, callers could falsely declare `0.0%` diff and achieve `PASS`.
15
+ 3. Documentation: Unmeasured marketing claims ("military-grade", "physically prevented", "99% OWASP mitigation") did not reflect mechanical reality or acknowledge boundaries between agent guidance, CLI verification, CI enforcement, and human review.
16
+ 4. GitHub Actions: Actions were referenced via mutable version tags (`@v4`) and workflows lacked explicit least-privilege permission isolation.
17
+
18
+ Sprint B replaces self-declarations with verifiable, independent evidence, enforces cryptographic and cumulative token authorization, mandates real disk-computed visual evidence with `UNVERIFIED` fallback, establishes a truthful public `Control / Scope / Test / Limit` specification table, and hardens CI/CD workflows to pinned commit SHAs.
19
+
20
+ ---
21
+
22
+ ## 2. User Stories & Acceptance Criteria
23
+
24
+ ### User Story 1: Cryptographic & Cumulative Spending Gate Authorization
25
+ **As a** repository administrator or team lead,
26
+ **I want** cost and spending gates to reject self-declared tokens, validate token scope and expiration, check positive unit bounds, and enforce cumulative budget accounting,
27
+ **So that** rogue or buggy agents cannot bypass billable action controls by forging tokens or passing negative units.
28
+
29
+ ### User Story 2: Honest Disk-Computed Visual QA Evidence
30
+ **As a** frontend engineer or QA lead,
31
+ **I want** visual comparison to compute image hashes directly from files on disk, calculate real diffs via an adapter, and return `UNVERIFIED` if no diff engine is available,
32
+ **So that** automated visual test suites cannot be fooled by synthetic evidence objects claiming false zero diffs.
33
+
34
+ ### User Story 3: Pre-Persistence Sensitive Data Protection
35
+ **As a** Chief Security Officer (CSO),
36
+ **I want** visual capture workflows to sanitize and mask sensitive input fields before writing screenshots to disk,
37
+ **So that** credentials, tokens, and personal data are never persisted in the test evidence directory.
38
+
39
+ ### User Story 4: Truthful Documentation & Control Scope Table
40
+ **As an** open-source user or auditor,
41
+ **I want** Gemstack documentation to replace ungrounded marketing claims with an honest `Control / Scope / Test / Limit` matrix,
42
+ **So that** engineering teams understand exactly what Gemstack mechanically enforces versus what requires CI or human review.
43
+
44
+ ### User Story 5: Hardened Least-Privilege GitHub Actions
45
+ **As a** DevSecOps engineer,
46
+ **I want** GitHub Actions workflows to pin actions to immutable commit SHAs and specify explicit least-privilege job permissions,
47
+ **So that** the supply chain is protected against tag poisoning and unauthorized token escalation.
48
+
49
+ ---
50
+
51
+ ## 3. Architecture Consistency Contracts
52
+
53
+ ```gemstack-contracts
54
+ [
55
+ {
56
+ "id": "gate-token-trusted-boundary",
57
+ "type": "ENUM_SET",
58
+ "values": [
59
+ "signed-token",
60
+ "positive-units",
61
+ "cumulative-budget",
62
+ "scope-binding",
63
+ "expiration-check"
64
+ ]
65
+ },
66
+ {
67
+ "id": "vqa-computed-evidence",
68
+ "type": "ENUM_SET",
69
+ "values": [
70
+ "disk-recomputed-hash",
71
+ "real-image-adapter",
72
+ "unverified-fallback",
73
+ "immutable-baseline"
74
+ ]
75
+ },
76
+ {
77
+ "id": "vqa-pre-persistence-masking",
78
+ "type": "BOOLEAN_INVARIANT",
79
+ "value": true
80
+ },
81
+ {
82
+ "id": "truthful-documentation-table",
83
+ "type": "ENUM_SET",
84
+ "values": [
85
+ "control",
86
+ "scope",
87
+ "test",
88
+ "limit"
89
+ ]
90
+ },
91
+ {
92
+ "id": "workflow-least-privilege",
93
+ "type": "ENUM_SET",
94
+ "values": [
95
+ "sha-pinned-actions",
96
+ "permissions-least-privilege",
97
+ "npm-ci"
98
+ ]
99
+ }
100
+ ]
101
+ ```
102
+
103
+ ---
104
+
105
+ ## 4. Canonical Acceptance Test Matrix
106
+
107
+ ```gemstack-test-matrix
108
+ [
109
+ {
110
+ "id": "TEST-EVID-A01",
111
+ "category": "SAFETY_GATES",
112
+ "layer": "UNIT",
113
+ "description": "Rejects self-declared or unsigned authorization tokens with BILLABLE_ACTION_UNAUTHORIZED",
114
+ "pass_criteria": "evaluateBillableAction returns DENY with reasonCode BILLABLE_ACTION_UNAUTHORIZED when token is unsigned or self-declared",
115
+ "gate": "REQUIRED"
116
+ },
117
+ {
118
+ "id": "TEST-EVID-A02",
119
+ "category": "SAFETY_GATES",
120
+ "layer": "UNIT",
121
+ "description": "Rejects non-positive or negative requested units (requested_units <= 0)",
122
+ "pass_criteria": "evaluateBillableAction returns DENY with reasonCode INVALID_REQUESTED_UNITS when requested_units is <= 0 or non-numeric",
123
+ "gate": "REQUIRED"
124
+ },
125
+ {
126
+ "id": "TEST-EVID-A03",
127
+ "category": "SAFETY_GATES",
128
+ "layer": "UNIT",
129
+ "description": "Rejects token when provider or action does not match token scope",
130
+ "pass_criteria": "evaluateBillableAction returns DENY with reasonCode TOKEN_SCOPE_MISMATCH when token scope does not match action or provider",
131
+ "gate": "REQUIRED"
132
+ },
133
+ {
134
+ "id": "TEST-EVID-A04",
135
+ "category": "SAFETY_GATES",
136
+ "layer": "UNIT",
137
+ "description": "Rejects expired tokens and tracks cumulative spending against budget limits",
138
+ "pass_criteria": "evaluateBillableAction returns DENY with TOKEN_EXPIRED if past expires_at, and cumulative requests exceeding budget return BUDGET_THRESHOLD_EXCEEDED",
139
+ "gate": "REQUIRED"
140
+ },
141
+ {
142
+ "id": "TEST-EVID-B01",
143
+ "category": "VISUAL_QA",
144
+ "layer": "INTEGRATION",
145
+ "description": "Recomputes image SHA-256 directly from disk and rejects falsified caller-supplied hashes",
146
+ "pass_criteria": "compareVisualEvidence computes disk hash and rejects spoofed evidence.image_sha256 with VQA_EVIDENCE_HASH_MISMATCH",
147
+ "gate": "REQUIRED"
148
+ },
149
+ {
150
+ "id": "TEST-EVID-B02",
151
+ "category": "VISUAL_QA",
152
+ "layer": "INTEGRATION",
153
+ "description": "Rejects falsified zero diff percentages and returns UNVERIFIED when no visual diff adapter engine is present",
154
+ "pass_criteria": "When baseline and live hashes differ and no adapter is configured, compareVisualEvidence returns status UNVERIFIED with passed=false",
155
+ "gate": "REQUIRED"
156
+ },
157
+ {
158
+ "id": "TEST-EVID-B03",
159
+ "category": "VISUAL_QA",
160
+ "layer": "INTEGRATION",
161
+ "description": "Computes real pixel diff via pluggable image adapter and evaluates against scenario threshold",
162
+ "pass_criteria": "With a configured diff adapter, compareVisualEvidence calculates exact mathematical diff and applies tolerance thresholds",
163
+ "gate": "REQUIRED"
164
+ },
165
+ {
166
+ "id": "TEST-EVID-B04",
167
+ "category": "VISUAL_QA",
168
+ "layer": "UNIT",
169
+ "description": "Enforces pre-persistence masking on credential and sensitive fields before writing capture to disk",
170
+ "pass_criteria": "maskSensitiveFieldsBeforeCapture sanitizes password, secret, and token input nodes in visual capture workflow",
171
+ "gate": "REQUIRED"
172
+ },
173
+ {
174
+ "id": "TEST-EVID-C01",
175
+ "category": "DOCS_TRUTHFULNESS",
176
+ "layer": "E2E",
177
+ "description": "README.md and documentation contain public Control / Scope / Test / Limit matrix with zero claims of military-grade or physically prevented",
178
+ "pass_criteria": "README.md contains the 4-column matrix and 0 occurrences of military-grade or physically prevented",
179
+ "gate": "REQUIRED"
180
+ },
181
+ {
182
+ "id": "TEST-EVID-C02",
183
+ "category": "DOCS_TRUTHFULNESS",
184
+ "layer": "E2E",
185
+ "description": "Rule 03 and template Rule 03 contain zero unmeasured 99% OWASP claims and define explicit verification boundaries",
186
+ "pass_criteria": "Both 03-gemstack-security.md files contain zero occurrences of 99% and document verification boundaries",
187
+ "gate": "REQUIRED"
188
+ },
189
+ {
190
+ "id": "TEST-EVID-C03",
191
+ "category": "DOCS_TRUTHFULNESS",
192
+ "layer": "E2E",
193
+ "description": "Package tarball contents verify clean documentation without unsubstantiated claims",
194
+ "pass_criteria": "npm run ci:all and check-package-contents.js pass with 100% clean documentation",
195
+ "gate": "REQUIRED"
196
+ },
197
+ {
198
+ "id": "TEST-EVID-D01",
199
+ "category": "CI_HARDENING",
200
+ "layer": "E2E",
201
+ "description": "GitHub Actions workflows pin external actions to immutable commit SHAs",
202
+ "pass_criteria": "actions/checkout, actions/setup-node, and actions/upload-artifact are pinned to 40-character commit SHAs across all workflow YAML files",
203
+ "gate": "REQUIRED"
204
+ },
205
+ {
206
+ "id": "TEST-EVID-D02",
207
+ "category": "CI_HARDENING",
208
+ "layer": "E2E",
209
+ "description": "GitHub Actions workflows enforce explicit least-privilege job permissions",
210
+ "pass_criteria": "Workflows specify top-level permissions: contents: read, restricting contents: write strictly to release publish job",
211
+ "gate": "REQUIRED"
212
+ },
213
+ {
214
+ "id": "TEST-EVID-D03",
215
+ "category": "CI_HARDENING",
216
+ "layer": "E2E",
217
+ "description": "Workflows utilize clean lockfile installation without redundant runs",
218
+ "pass_criteria": "Workflows use npm ci where package-lock.json exists, maintaining zero installation divergence",
219
+ "gate": "REQUIRED"
220
+ }
221
+ ]
222
+ ```
@@ -0,0 +1,99 @@
1
+ # Tasks Breakdown: Gemstack 2.0 Sprint B — Honest Evidence & Reliable Metrics
2
+
3
+ **Feature ID:** `012-gemstack-2.0-honest-evidence`
4
+ **Phase:** `tasks`
5
+ **Parent Release:** `gemstack-ai@2.0.0-alpha`
6
+
7
+ ---
8
+
9
+ ## 1. Inherited Architecture Contracts
10
+
11
+ ```gemstack-contracts
12
+ [
13
+ {
14
+ "id": "gate-token-trusted-boundary",
15
+ "type": "ENUM_SET",
16
+ "values": [
17
+ "signed-token",
18
+ "positive-units",
19
+ "cumulative-budget",
20
+ "scope-binding",
21
+ "expiration-check"
22
+ ]
23
+ },
24
+ {
25
+ "id": "vqa-computed-evidence",
26
+ "type": "ENUM_SET",
27
+ "values": [
28
+ "disk-recomputed-hash",
29
+ "real-image-adapter",
30
+ "unverified-fallback",
31
+ "immutable-baseline"
32
+ ]
33
+ },
34
+ {
35
+ "id": "vqa-pre-persistence-masking",
36
+ "type": "BOOLEAN_INVARIANT",
37
+ "value": true
38
+ },
39
+ {
40
+ "id": "truthful-documentation-table",
41
+ "type": "ENUM_SET",
42
+ "values": [
43
+ "control",
44
+ "scope",
45
+ "test",
46
+ "limit"
47
+ ]
48
+ },
49
+ {
50
+ "id": "workflow-least-privilege",
51
+ "type": "ENUM_SET",
52
+ "values": [
53
+ "sha-pinned-actions",
54
+ "permissions-least-privilege",
55
+ "npm-ci"
56
+ ]
57
+ }
58
+ ]
59
+ ```
60
+
61
+ ---
62
+
63
+ ## 2. Task Inventory
64
+
65
+ - [x] **TASK-001: Author adversarial test suite reproducing 1.4.0 vulnerabilities**
66
+ <!-- gemstack:validation_required=true -->
67
+ <!-- gemstack:tests=TEST-EVID-A01, TEST-EVID-A02, TEST-EVID-A03, TEST-EVID-A04, TEST-EVID-B01, TEST-EVID-B02, TEST-EVID-B03, TEST-EVID-B04, TEST-EVID-C01, TEST-EVID-C02, TEST-EVID-C03, TEST-EVID-D01, TEST-EVID-D02, TEST-EVID-D03 -->
68
+ <!-- gemstack:files=tests/honest-evidence-p1.test.js -->
69
+ <!-- gemstack:depends= -->
70
+
71
+ - [x] **TASK-002: Harden BillableActionGate with trusted boundary tokens and cumulative tracking**
72
+ <!-- gemstack:validation_required=true -->
73
+ <!-- gemstack:tests=TEST-EVID-A01, TEST-EVID-A02, TEST-EVID-A03, TEST-EVID-A04 -->
74
+ <!-- gemstack:files=src/lib/safety-gates.js, src/lib/provider-boundary.js -->
75
+ <!-- gemstack:depends=TASK-001 -->
76
+
77
+ - [x] **TASK-003: Harden Visual QA with disk-recomputed evidence, adapter diffing, and masking**
78
+ <!-- gemstack:validation_required=true -->
79
+ <!-- gemstack:tests=TEST-EVID-B01, TEST-EVID-B02, TEST-EVID-B03, TEST-EVID-B04 -->
80
+ <!-- gemstack:files=src/lib/visual-qa.js -->
81
+ <!-- gemstack:depends=TASK-001 -->
82
+
83
+ - [x] **TASK-004: Truthfulness audit: Control matrix and superlative removal in docs & rules**
84
+ <!-- gemstack:validation_required=true -->
85
+ <!-- gemstack:tests=TEST-EVID-C01, TEST-EVID-C02, TEST-EVID-C03 -->
86
+ <!-- gemstack:files=README.md, CONTRIBUTING.md, .agents/rules/03-gemstack-security.md, template/.agents/rules/03-gemstack-security.md -->
87
+ <!-- gemstack:depends=TASK-001 -->
88
+
89
+ - [x] **TASK-005: Harden GitHub Actions workflows with pinned commit SHAs and least privilege**
90
+ <!-- gemstack:validation_required=true -->
91
+ <!-- gemstack:tests=TEST-EVID-D01, TEST-EVID-D02, TEST-EVID-D03 -->
92
+ <!-- gemstack:files=.github/workflows/main-ci.yml, .github/workflows/pr-ci.yml, .github/workflows/publish.yml, .github/workflows/release-readiness.yml -->
93
+ <!-- gemstack:depends=TASK-001 -->
94
+
95
+ - [x] **TASK-006: Verify test suite, execute full CI suite, and collect closure evidence**
96
+ <!-- gemstack:validation_required=true -->
97
+ <!-- gemstack:tests=TEST-EVID-A01, TEST-EVID-A02, TEST-EVID-A03, TEST-EVID-A04, TEST-EVID-B01, TEST-EVID-B02, TEST-EVID-B03, TEST-EVID-B04, TEST-EVID-C01, TEST-EVID-C02, TEST-EVID-C03, TEST-EVID-D01, TEST-EVID-D02, TEST-EVID-D03 -->
98
+ <!-- gemstack:files=tests/honest-evidence-p1.test.js, src/commands/collect.js -->
99
+ <!-- gemstack:depends=TASK-002, TASK-003, TASK-004, TASK-005 -->
@@ -0,0 +1,9 @@
1
+ {
2
+ "phase_hashes": {
3
+ "spec": "32f326f279a7083e67bd3b386597718c203abbcca99f71d8426b50ca3616d93d",
4
+ "plan": "8be9cb72e649dbdc53819c8fac9029fc73241d7c267e3ff596e0104927a1b5c1",
5
+ "tasks": "843f2d12bf20c0ba844f0b7979aeb9b829faba32b2bcc04aa67f254126ceb9c4"
6
+ },
7
+ "historical_findings": [],
8
+ "accepted_exceptions": []
9
+ }
@@ -0,0 +1,58 @@
1
+ {
2
+ "schema": "gemstack-closure",
3
+ "version": 1,
4
+ "feature": "specs/013-gemstack-2.0-adaptable-sdd",
5
+ "generated_at": "2026-09-23T02:03:25.332Z",
6
+ "status": "VERIFIED",
7
+ "closure_context": {
8
+ "closure_context_hash": "b52fe3acce82fe7d2d102ad0227438ebb60c8ff47bcb9652cbaadf1c17cbcc8a",
9
+ "repository_type": "git",
10
+ "git_commit": "dd57930a56e02e7aba59ce929112f8327d125541",
11
+ "working_tree_clean": false,
12
+ "relevant_files_digest": "ff07ec45a69e0fb973d7dfc9e06216833f804f232f3a61e8718a1c247bbddf2a"
13
+ },
14
+ "acceptance_signature": "6ae546034e43677a9ce51b451415db890d27b57e36df3163286897fcd6720e07",
15
+ "canonical_summary": {
16
+ "required_total": 13,
17
+ "required_passed": 13,
18
+ "supplemental_total": 0,
19
+ "supplemental_passed": 0
20
+ },
21
+ "physical_summary": {
22
+ "supporting_total": 0,
23
+ "supporting_passed": 0,
24
+ "total_executed": 13,
25
+ "total_passed": 13,
26
+ "total_failed": 0,
27
+ "total_skipped": 0
28
+ },
29
+ "reconciliation": {
30
+ "math_valid": true,
31
+ "phantoms_detected": 0,
32
+ "orphans_detected": 0,
33
+ "missing_canonical_ids": []
34
+ },
35
+ "task_traceability_summary": {
36
+ "tasks_total": 6,
37
+ "tasks_with_validation": 6,
38
+ "tasks_documentation_only": 0,
39
+ "unmapped_canonical_tests": []
40
+ },
41
+ "required_gates": {
42
+ "gate-test": "PASS",
43
+ "gate-ci-all": "PASS"
44
+ },
45
+ "supplemental_gates": {},
46
+ "exceptions": [],
47
+ "evidence_sources": [
48
+ {
49
+ "type": "PACKAGE_SCRIPT",
50
+ "script": "test",
51
+ "runner": "node:test",
52
+ "exit_code": 0,
53
+ "duration_ms": 390
54
+ }
55
+ ],
56
+ "blockers": [],
57
+ "warnings": []
58
+ }