gemstack-ai 1.3.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 (71) hide show
  1. package/.agents/rules/03-gemstack-security.md +2 -2
  2. package/.gemstack/state.json +7 -8
  3. package/CHANGELOG.md +87 -0
  4. package/CONTRIBUTING.md +1 -1
  5. package/README.md +113 -22
  6. package/RELEASE_NOTES.md +80 -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/009-context-capsule/context-capsule.json +4 -4
  12. package/specs/010-agent-swarm-visual-qa/.gemstack.json +5 -0
  13. package/specs/010-agent-swarm-visual-qa/closure.json +59 -0
  14. package/specs/010-agent-swarm-visual-qa/plan.md +759 -0
  15. package/specs/010-agent-swarm-visual-qa/spec.md +842 -0
  16. package/specs/010-agent-swarm-visual-qa/swarm.json +49 -0
  17. package/specs/010-agent-swarm-visual-qa/tasks.md +873 -0
  18. package/specs/010-agent-swarm-visual-qa/visual-qa.json +41 -0
  19. package/specs/011-gemstack-2.0-hardening/.gemstack.json +5 -0
  20. package/specs/011-gemstack-2.0-hardening/closure.json +58 -0
  21. package/specs/011-gemstack-2.0-hardening/plan.md +210 -0
  22. package/specs/011-gemstack-2.0-hardening/spec.md +277 -0
  23. package/specs/011-gemstack-2.0-hardening/tasks.md +59 -0
  24. package/specs/012-gemstack-2.0-honest-evidence/.gemstack.json +5 -0
  25. package/specs/012-gemstack-2.0-honest-evidence/closure.json +58 -0
  26. package/specs/012-gemstack-2.0-honest-evidence/plan.md +202 -0
  27. package/specs/012-gemstack-2.0-honest-evidence/spec.md +222 -0
  28. package/specs/012-gemstack-2.0-honest-evidence/tasks.md +99 -0
  29. package/specs/013-gemstack-2.0-adaptable-sdd/.gemstack.json +9 -0
  30. package/specs/013-gemstack-2.0-adaptable-sdd/closure.json +58 -0
  31. package/specs/013-gemstack-2.0-adaptable-sdd/context-capsule.json +227 -0
  32. package/specs/013-gemstack-2.0-adaptable-sdd/plan.md +179 -0
  33. package/specs/013-gemstack-2.0-adaptable-sdd/spec.md +212 -0
  34. package/specs/013-gemstack-2.0-adaptable-sdd/tasks.md +90 -0
  35. package/specs/014-gemstack-2.0-context-memory/.gemstack.json +9 -0
  36. package/specs/014-gemstack-2.0-context-memory/closure.json +58 -0
  37. package/specs/014-gemstack-2.0-context-memory/plan.md +161 -0
  38. package/specs/014-gemstack-2.0-context-memory/spec.md +163 -0
  39. package/specs/014-gemstack-2.0-context-memory/tasks.md +79 -0
  40. package/src/cli.js +11 -0
  41. package/src/commands/context.js +1 -1
  42. package/src/commands/doctor.js +18 -0
  43. package/src/commands/hooks.js +98 -14
  44. package/src/commands/init.js +1 -1
  45. package/src/commands/install.js +174 -49
  46. package/src/commands/spec.js +105 -0
  47. package/src/commands/swarm.js +111 -0
  48. package/src/commands/update.js +1 -1
  49. package/src/commands/verify.js +48 -0
  50. package/src/commands/visual.js +82 -0
  51. package/src/lib/backup.js +3 -3
  52. package/src/lib/closure-context.js +9 -1
  53. package/src/lib/context-fatigue.js +165 -0
  54. package/src/lib/contract-amendments.js +109 -0
  55. package/src/lib/dependency-audit.js +202 -0
  56. package/src/lib/filesystem-safe.js +85 -15
  57. package/src/lib/memory-audit.js +121 -0
  58. package/src/lib/provider-boundary.js +5 -1
  59. package/src/lib/provider-registry.js +6 -4
  60. package/src/lib/safety-gates.js +176 -8
  61. package/src/lib/sdd-rigor.js +181 -0
  62. package/src/lib/spec-delta.js +194 -0
  63. package/src/lib/spec-merge.js +168 -0
  64. package/src/lib/swarm.js +639 -0
  65. package/src/lib/visual-qa.js +652 -0
  66. package/template/.agents/rules/03-gemstack-security.md +2 -2
  67. package/.github/workflows/main-ci.yml +0 -32
  68. package/.github/workflows/pr-ci.yml +0 -31
  69. package/.github/workflows/publish.yml +0 -52
  70. package/.github/workflows/release-readiness.yml +0 -43
  71. package/gemstack-ai-1.3.0.tgz +0 -0
@@ -0,0 +1,873 @@
1
+ # Tareas de Implementación: Agent Swarm & Visual QA (Upgrade E)
2
+
3
+ **Feature Branch**: `010-agent-swarm-visual-qa`
4
+ **Feature Directory**: `specs/010-agent-swarm-visual-qa/`
5
+ **Spec**: [`specs/010-agent-swarm-visual-qa/spec.md`](file:///c:/CODES/Gemstack/specs/010-agent-swarm-visual-qa/spec.md)
6
+ **Plan**: [`specs/010-agent-swarm-visual-qa/plan.md`](file:///c:/CODES/Gemstack/specs/010-agent-swarm-visual-qa/plan.md)
7
+ **Lifecycle Status**: `TASKS_COMPLETE`
8
+ **Stop Reason**: `TASKS_COMPLETE_AWAITING_REVIEW`
9
+
10
+ ---
11
+
12
+ ## Contratos Congelados Heredados & Bootstrap (`gemstack-contracts`)
13
+
14
+ ```gemstack-contracts
15
+ [
16
+ {
17
+ "id": "swarm-authority-subordinate",
18
+ "type": "BOOLEAN_INVARIANT",
19
+ "value": true,
20
+ "description": "Agent swarm orchestrators and workers are strictly subordinate to repository specifications, plans, tasks, and frozen contracts."
21
+ },
22
+ {
23
+ "id": "author-not-reviewer",
24
+ "type": "BOOLEAN_INVARIANT",
25
+ "value": true,
26
+ "description": "Separation of duties requires that the author of a code or task change cannot review or approve their own work."
27
+ },
28
+ {
29
+ "id": "exclusive-task-write-ownership",
30
+ "type": "BOOLEAN_INVARIANT",
31
+ "value": true,
32
+ "description": "Concurrent swarm tasks must declare disjoint, non-overlapping file write sets to prevent write collisions."
33
+ },
34
+ {
35
+ "id": "swarm-provider-safety-gated",
36
+ "type": "BOOLEAN_INVARIANT",
37
+ "value": true,
38
+ "description": "All worker operations must pass Upgrade C capability and billable action gates."
39
+ },
40
+ {
41
+ "id": "swarm-context-projected",
42
+ "type": "BOOLEAN_INVARIANT",
43
+ "value": true,
44
+ "description": "Worker contexts must be deterministically projected from Upgrade D context capsule without chat history leakage."
45
+ },
46
+ {
47
+ "id": "visual-evidence-subordinate",
48
+ "type": "BOOLEAN_INVARIANT",
49
+ "value": true,
50
+ "description": "Visual artifacts and screenshots are verification evidence only and cannot alter specifications or override gates."
51
+ },
52
+ {
53
+ "id": "deterministic-viewports",
54
+ "type": "BOOLEAN_INVARIANT",
55
+ "value": true,
56
+ "description": "All visual QA scenarios must specify explicit width, height, and device scale factor."
57
+ },
58
+ {
59
+ "id": "baseline-explicit-update-only",
60
+ "type": "BOOLEAN_INVARIANT",
61
+ "value": true,
62
+ "description": "Visual reference baselines may only be modified through explicit, recorded update operations."
63
+ },
64
+ {
65
+ "id": "verify-swarm-visual-offline",
66
+ "type": "BOOLEAN_INVARIANT",
67
+ "value": true,
68
+ "description": "gemstack verify validates swarm manifests and visual evidence offline with zero network and zero browser spawns."
69
+ },
70
+ {
71
+ "id": "legacy-swarm-visual-compatibility",
72
+ "type": "BOOLEAN_INVARIANT",
73
+ "value": true,
74
+ "description": "Repositories lacking swarm schedules or visual QA manifests operate cleanly without error."
75
+ }
76
+ ]
77
+ ```
78
+
79
+ ---
80
+
81
+ ## Task Execution Rules & Safety Invariants
82
+
83
+ 1. **Central Authority Invariant**: `SPEC / PLAN / TASKS / FROZEN CONTRACTS = SOLE AUTHORITY`. Agent outputs are proposed work; visual screenshots are verification evidence; neither can alter specifications or waive frozen contracts.
84
+ 2. **Separation of Duties (`AUTHOR != REVIEWER`)**: The entity/worker ID that implements code or changes cannot act as the reviewer, security auditor, or closure approver for that task.
85
+ 3. **Exclusive Task Write Ownership**: Concurrent tasks in the same wave must have strictly disjoint write sets (`write_set(T1) ∩ write_set(T2) = ∅`). Overlaps produce fail-closed rejection.
86
+ 4. **Offline Purity & Zero Runtime Dependencies**: Gemstack core maintains runtime dependency delta = 0. Swarm coordination and visual QA verification rely strictly on Node.js built-ins.
87
+ 5. **Verify Purity (`VERIFY = VALIDATE`)**: `gemstack verify` operates strictly in read-only mode, with zero worker execution, zero browser spawns, and zero file mutations.
88
+ 6. **Explicit Baseline Lifecycle**: Baselines are NEVER auto-updated or healed during verification. Updates require explicit promotion (`gemstack vqa promote`).
89
+ 7. **Deterministic Projections**: Swarm worker context derives strictly from Upgrade D `context-capsule.json` with chat logs and environment secrets excluded.
90
+ 8. **Provider & Cost Safety**: Swarm model invocations are intercepted by Upgrade C `ProviderCapabilityGate` and `BillableActionGate`.
91
+
92
+ ---
93
+
94
+ ## Dependency Graph (5 Phased Waves)
95
+
96
+ ```mermaid
97
+ graph TD
98
+ subgraph "Phase 1: Swarm Core Contracts & Partition Planner"
99
+ UE_T001["UE-T001: Zero-Dependency Core & Bootstrap Registration"] --> UE_T002["UE-T002: Swarm Manifest Schema & Parser (src/lib/swarm.js)"]
100
+ UE_T002 --> UE_T003["UE-T003: Worker Identity, Mechanical Roles & Authority Hierarchy"]
101
+ UE_T003 --> UE_T004["UE-T004: Task Ownership & Dependency Graph Resolver"]
102
+ UE_T004 --> UE_T005["UE-T005: Exclusive Write Partition Planner & Collision Detector"]
103
+ end
104
+
105
+ subgraph "Phase 2: Review Independence, Safety Gates & Context Projection"
106
+ UE_T005 --> UE_T006["UE-T006: Review Independence Gate (AUTHOR != REVIEWER)"]
107
+ UE_T006 --> UE_T007["UE-T007: Reviewer & Visual QA Read-Only Write Scope Policies"]
108
+ UE_T006 --> UE_T008["UE-T008: Context Capsule Projection Engine & Freshness"]
109
+ UE_T008 --> UE_T009["UE-T009: Worker Output Evidence & Completion Proof Reconciler"]
110
+ UE_T009 --> UE_T010["UE-T010: Worker Limit & Anti-Recursive Spawning Guard"]
111
+ UE_T010 --> UE_T011["UE-T011: Upgrade C Provider Capability & Cost Budget Interceptor"]
112
+ end
113
+
114
+ subgraph "Phase 3: Visual QA Contracts & Offline Evidence Validation"
115
+ UE_T001 --> UE_T012["UE-T012: Visual QA Manifest Schema & Scenario Registry (src/lib/visual-qa.js)"]
116
+ UE_T012 --> UE_T013["UE-T013: Deterministic Viewport Matrix & Resolution Resolver"]
117
+ UE_T013 --> UE_T014["UE-T014: Capture Environment Identity & Metadata Validator"]
118
+ UE_T014 --> UE_T015["UE-T015: Dynamic Region Masking & Secret Auto-Masking Engine"]
119
+ UE_T015 --> UE_T016["UE-T016: Cryptographic Baseline Safety & Tamper Detector"]
120
+ UE_T016 --> UE_T017["UE-T017: Offline Diffing & Failure Classification Engine"]
121
+ end
122
+
123
+ subgraph "Phase 4: CLI Ergonomics, Verify Purity & Closure Integration"
124
+ UE_T005 --> UE_T018["UE-T018: Swarm CLI Commands (src/commands/swarm.js)"]
125
+ UE_T017 --> UE_T019["UE-T019: Visual QA CLI Commands (src/commands/visual.js)"]
126
+ UE_T018 & UE_T019 --> UE_T020["UE-T020: CLI Router Registration (src/cli.js)"]
127
+ UE_T020 --> UE_T021["UE-T021: Verify Integration Stages 5.3 & 5.4 (src/commands/verify.js)"]
128
+ UE_T021 --> UE_T022["UE-T022: Closure Context Tracking (src/lib/closure-context.js)"]
129
+ UE_T022 --> UE_T023["UE-T023: Test Suite Registration & Zero Dependency Proof (package.json)"]
130
+ end
131
+
132
+ subgraph "Phase 5: Acceptance, Adversarial & Regression Closure"
133
+ UE_T023 --> UE_T024["UE-T024: Swarm Partitioning Acceptance Suite (tests/swarm-partitioning.test.js)"]
134
+ UE_T024 --> UE_T025["UE-T025: Swarm Review & Gate Safety Suite (tests/swarm-review.test.js)"]
135
+ UE_T025 --> UE_T026["UE-T026: Visual Manifest & Baseline Safety Suite (tests/visual-manifest.test.js)"]
136
+ UE_T026 --> UE_T027["UE-T027: Visual Regression & Masking Suite (tests/visual-diff.test.js)"]
137
+ UE_T027 --> UE_T028["UE-T028: Offline Purity & Legacy Compatibility Suite (tests/swarm-visual-purity.test.js)"]
138
+ UE_T028 --> UE_T029["UE-T029: Full CI, Frozen Contract & Closure Readiness Audit"]
139
+ end
140
+ ```
141
+
142
+ ---
143
+
144
+ ## Detailed Task Inventory (29 Tasks)
145
+
146
+ ### Phase 1: Swarm Core Contracts & Partition Planner
147
+
148
+ - [x] **UE-T001: Zero-Dependency Core & Bootstrap Registration**
149
+ <!-- gemstack:validation_required=true -->
150
+ <!-- gemstack:tests=TEST-SWARM-A01,TEST-VISUAL-A01 -->
151
+ <!-- gemstack:files=src/lib/contracts.js -->
152
+ <!-- gemstack:depends= -->
153
+ - **Phase**: Phase 1 — Swarm Core Contracts & Partition Planner
154
+ - **Objective**: Register Upgrade E bootstrap contracts in `src/lib/contracts.js` and ensure runtime dependency delta = 0.
155
+ - **Files**: `src/lib/contracts.js`
156
+ - **Prerequisites**: None
157
+ - **Implementation Requirements**:
158
+ - Add 10 bootstrap contracts: `swarm-authority-subordinate`, `author-not-reviewer`, `exclusive-task-write-ownership`, `swarm-provider-safety-gated`, `swarm-context-projected`, `visual-evidence-subordinate`, `deterministic-viewports`, `baseline-explicit-update-only`, `verify-swarm-visual-offline`, `legacy-swarm-visual-compatibility`.
159
+ - Validate all values are `BOOLEAN_INVARIANT: true`.
160
+ - **Must NOT**: Add external npm packages or modify frozen contracts from Upgrades A, B, C, D.
161
+ - **Tests**: `tests/contracts.test.js`
162
+ - **Acceptance IDs**: `TEST-SWARM-A01`, `TEST-VISUAL-A01`
163
+ - **Bootstrap Contracts**: All 10 contracts
164
+ - **Adversarial Cases**: Attempting to alter invariant values or inject external dependencies.
165
+ - **Completion Criteria**: Contracts extract cleanly without affecting legacy tests.
166
+ - **Evidence**: Unit test pass in `tests/contracts.test.js`.
167
+
168
+ - [x] **UE-T002: Swarm Manifest Schema & Parser (`src/lib/swarm.js`)**
169
+ <!-- gemstack:validation_required=true -->
170
+ <!-- gemstack:tests=TEST-SWARM-A01 -->
171
+ <!-- gemstack:files=src/lib/swarm.js -->
172
+ <!-- gemstack:depends=UE-T001 -->
173
+ - **Phase**: Phase 1
174
+ - **Objective**: Implement canonical JSON schema parsing and structural validation for `swarm.json`.
175
+ - **Files**: `src/lib/swarm.js` [NEW]
176
+ - **Prerequisites**: UE-T001
177
+ - **Implementation Requirements**:
178
+ - Implement `parseSwarmManifest(manifestJson)` and `validateSwarmSchema(manifest)`.
179
+ - Validate schema version `1.0.0`, required top-level fields: `feature_id`, `source_capsule_hash`, `waves`.
180
+ - Implement deterministic key sorting using UTF-16 code units.
181
+ - **Must NOT**: Execute worker agents or spawn child processes.
182
+ - **Tests**: `tests/swarm-partitioning.test.js`
183
+ - **Acceptance IDs**: `TEST-SWARM-A01`
184
+ - **Bootstrap Contracts**: `swarm-authority-subordinate`
185
+ - **Adversarial Cases**: Missing schema version, malformed JSON, missing wave blocks.
186
+ - **Completion Criteria**: Rejects invalid schemas fail-closed; parses valid schemas deterministically.
187
+ - **Evidence**: Unit test assertions on schema validation.
188
+
189
+ - [x] **UE-T003: Worker Identity, Mechanical Roles & Authority Hierarchy**
190
+ <!-- gemstack:validation_required=true -->
191
+ <!-- gemstack:tests=TEST-SWARM-A01 -->
192
+ <!-- gemstack:files=src/lib/swarm.js -->
193
+ <!-- gemstack:depends=UE-T002 -->
194
+ - **Phase**: Phase 1
195
+ - **Objective**: Implement worker ID validation, mechanical role enforcement, and authority subordination.
196
+ - **Files**: `src/lib/swarm.js`
197
+ - **Prerequisites**: UE-T002
198
+ - **Implementation Requirements**:
199
+ - Validate worker IDs are non-empty strings matching explicit naming format (no random UUIDs/PIDs).
200
+ - Enforce mechanical roles: `implementer`, `reviewer`, `security-auditor`, `coordinator`.
201
+ - Implement `validateSwarmAuthority(manifest, authoritativeSources)` ensuring swarm manifests cannot alter specifications or bypass tasks.
202
+ - **Must NOT**: Introduce fuzzy role personas or allow worker consensus to override spec.
203
+ - **Tests**: `tests/swarm-partitioning.test.js`
204
+ - **Acceptance IDs**: `TEST-SWARM-A01`
205
+ - **Bootstrap Contracts**: `swarm-authority-subordinate`
206
+ - **Adversarial Cases**: Dynamic UUID worker identity, undeclared role string, worker attempting to override `spec.md`.
207
+ - **Completion Criteria**: Emits `SWARM_AUTHORITY_CONFLICT` on override attempts.
208
+ - **Evidence**: Unit tests in `tests/swarm-partitioning.test.js`.
209
+
210
+ - [x] **UE-T004: Task Ownership & Dependency Graph Resolver**
211
+ <!-- gemstack:validation_required=true -->
212
+ <!-- gemstack:tests=TEST-SWARM-A01 -->
213
+ <!-- gemstack:files=src/lib/swarm.js -->
214
+ <!-- gemstack:depends=UE-T003 -->
215
+ - **Phase**: Phase 1
216
+ - **Objective**: Reconcile swarm task assignments against `tasks.md` and enforce dependency wave ordering.
217
+ - **Files**: `src/lib/swarm.js`
218
+ - **Prerequisites**: UE-T003
219
+ - **Implementation Requirements**:
220
+ - Implement `resolveTaskOwnership(tasksContent, manifest)`.
221
+ - Ensure every task in `swarm.json` maps to an accepted `task_id` in `tasks.md`.
222
+ - Detect circular dependencies and ensure prerequisite tasks reside in strictly earlier waves.
223
+ - **Must NOT**: Allow orphan tasks or tasks outside the active feature.
224
+ - **Tests**: `tests/swarm-partitioning.test.js`
225
+ - **Acceptance IDs**: `TEST-SWARM-A01`
226
+ - **Bootstrap Contracts**: `swarm-authority-subordinate`
227
+ - **Adversarial Cases**: Assigning unlisted task ID, circular task prerequisites (`A -> B -> A`).
228
+ - **Completion Criteria**: Emits `SWARM_TASK_ORPHANED` or `SWARM_DEPENDENCY_CYCLE`.
229
+ - **Evidence**: Unit tests asserting dependency ordering and orphan detection.
230
+
231
+ - [x] **UE-T005: Exclusive Write Partition Planner & Collision Detector**
232
+ <!-- gemstack:validation_required=true -->
233
+ <!-- gemstack:tests=TEST-SWARM-A01,TEST-SWARM-A02 -->
234
+ <!-- gemstack:files=src/lib/swarm.js -->
235
+ <!-- gemstack:depends=UE-T004 -->
236
+ - **Phase**: Phase 1
237
+ - **Objective**: Implement disjoint write-set partition planning and collision detection for concurrent waves.
238
+ - **Files**: `src/lib/swarm.js`
239
+ - **Prerequisites**: UE-T004
240
+ - **Implementation Requirements**:
241
+ - Implement `planSwarmWaves(tasksList)` and `validateWritePartitions(wave)`.
242
+ - Enforce that for concurrent tasks ( T_1, T_2 in W ), `write_set(T1) ∩ write_set(T2) = ∅`.
243
+ - If overlapping paths exist, serialize conflicting tasks into wave ( W+1 ) with warning `SWARM_WRITE_COLLISION_PREVENTED`.
244
+ - In manifest audit, fail closed with `SWARM_WRITE_COLLISION` if concurrent tasks share write paths.
245
+ - **Must NOT**: Allow silent last-writer-wins or concurrent writes to identical files.
246
+ - **Tests**: `tests/swarm-partitioning.test.js`
247
+ - **Acceptance IDs**: `TEST-SWARM-A01`, `TEST-SWARM-A02`
248
+ - **Bootstrap Contracts**: `exclusive-task-write-ownership`
249
+ - **Adversarial Cases**: Two workers in wave 1 declaring write lease on `src/foo.js`.
250
+ - **Completion Criteria**: Emits `SWARM_WRITE_COLLISION` and blocks concurrent execution.
251
+ - **Evidence**: Passing tests for `TEST-SWARM-A01` and `TEST-SWARM-A02`.
252
+
253
+ ---
254
+
255
+ ### Phase 2: Review Independence, Safety Gates & Context Projection
256
+
257
+ - [x] **UE-T006: Review Independence Gate (`AUTHOR != REVIEWER`)**
258
+ <!-- gemstack:validation_required=true -->
259
+ <!-- gemstack:tests=TEST-SWARM-B01,TEST-SWARM-B02 -->
260
+ <!-- gemstack:files=src/lib/swarm.js -->
261
+ <!-- gemstack:depends=UE-T005 -->
262
+ - **Phase**: Phase 2 — Review Independence, Safety Gates & Context Projection
263
+ - **Objective**: Implement non-waivable separation of duties checking worker IDs on review attestations.
264
+ - **Files**: `src/lib/swarm.js`
265
+ - **Prerequisites**: UE-T005
266
+ - **Implementation Requirements**:
267
+ - Implement `validateReviewSeparation(taskAssignment)`.
268
+ - Compare `worker_id` of implementer with `reviewer_id` of reviewer.
269
+ - Fail closed with `SWARM_SELF_REVIEW_DETECTED` if `implementer == reviewer`.
270
+ - **Must NOT**: Allow role-switching bypass within the same session/identity.
271
+ - **Tests**: `tests/swarm-review.test.js` [NEW]
272
+ - **Acceptance IDs**: `TEST-SWARM-B01`, `TEST-SWARM-B02`
273
+ - **Bootstrap Contracts**: `author-not-reviewer`
274
+ - **Adversarial Cases**: Worker implements task then changes role to `reviewer` to approve own work.
275
+ - **Completion Criteria**: Self-review attempts halt fail-closed with error.
276
+ - **Evidence**: Passing `TEST-SWARM-B01` and `TEST-SWARM-B02`.
277
+
278
+ - [x] **UE-T007: Reviewer & Visual QA Read-Only Write Scope Policies**
279
+ <!-- gemstack:validation_required=true -->
280
+ <!-- gemstack:tests=TEST-SWARM-B01 -->
281
+ <!-- gemstack:files=src/lib/swarm.js -->
282
+ <!-- gemstack:depends=UE-T006 -->
283
+ - **Phase**: Phase 2
284
+ - **Objective**: Enforce architectural read-only restrictions for reviewer and visual QA roles.
285
+ - **Files**: `src/lib/swarm.js`
286
+ - **Prerequisites**: UE-T006
287
+ - **Implementation Requirements**:
288
+ - Implement `validateRoleWriteScope(workerRole, modifiedFiles)`.
289
+ - For `reviewer` and `security-auditor`: `modifiedFiles` must be empty.
290
+ - For `visual-qa`: `modifiedFiles` must be strictly confined to `specs/<feature>/evidence/`.
291
+ - **Must NOT**: Allow reviewers to "fix code while reviewing".
292
+ - **Tests**: `tests/swarm-review.test.js`
293
+ - **Acceptance IDs**: `TEST-SWARM-B01`
294
+ - **Bootstrap Contracts**: `author-not-reviewer`, `exclusive-task-write-ownership`
295
+ - **Adversarial Cases**: Reviewer commits bugfix directly to implementation file under review.
296
+ - **Completion Criteria**: Emits `SWARM_WRITE_SET_VIOLATION` if reviewer modifies code.
297
+ - **Evidence**: Unit test assertions verifying write boundary violations.
298
+
299
+ - [x] **UE-T008: Context Capsule Projection Engine & Freshness**
300
+ <!-- gemstack:validation_required=true -->
301
+ <!-- gemstack:tests=TEST-SWARM-D01,TEST-SWARM-D02 -->
302
+ <!-- gemstack:files=src/lib/swarm.js -->
303
+ <!-- gemstack:depends=UE-T006 -->
304
+ - **Phase**: Phase 2
305
+ - **Objective**: Implement task-scoped context projection derived from `context-capsule.json` with cryptographic freshness checking.
306
+ - **Files**: `src/lib/swarm.js`
307
+ - **Prerequisites**: UE-T006
308
+ - **Implementation Requirements**:
309
+ - Implement `projectWorkerContext(capsule, taskId)`.
310
+ - Extract only relevant task description, write scope, frozen contracts, and acceptance IDs.
311
+ - Embed `source_capsule_hash`; check live hash against disk state during validation.
312
+ - Fail closed with `SWARM_CONTEXT_STALE` if capsule on disk has drifted.
313
+ - Exclude conversational chat transcripts and raw developer logs.
314
+ - **Must NOT**: Build a new memory store; reuse Upgrade D `context-capsule.json`.
315
+ - **Tests**: `tests/swarm-review.test.js`
316
+ - **Acceptance IDs**: `TEST-SWARM-D01`, `TEST-SWARM-D02`
317
+ - **Bootstrap Contracts**: `swarm-context-projected`
318
+ - **Adversarial Cases**: Modifying `spec.md` causing capsule hash drift; injecting chat history.
319
+ - **Completion Criteria**: Validates provenance hash; detects stale projection immediately.
320
+ - **Evidence**: Passing `TEST-SWARM-D01` and `TEST-SWARM-D02`.
321
+
322
+ - [x] **UE-T009: Worker Output Evidence & Completion Proof Reconciler**
323
+ <!-- gemstack:validation_required=true -->
324
+ <!-- gemstack:tests=TEST-SWARM-B02 -->
325
+ <!-- gemstack:files=src/lib/swarm.js -->
326
+ <!-- gemstack:depends=UE-T008 -->
327
+ - **Phase**: Phase 2
328
+ - **Objective**: Enforce that task completion requires structured evidence and independent review proof.
329
+ - **Files**: `src/lib/swarm.js`
330
+ - **Prerequisites**: UE-T008
331
+ - **Implementation Requirements**:
332
+ - Implement `validateTaskCompletionProof(taskAssignment)`.
333
+ - Require structured fields: `files_modified`, `tests_executed`, `review` block.
334
+ - Validate that `review.status == "APPROVED"` and `review.reviewer_role == "reviewer"`.
335
+ - **Must NOT**: Accept agent prose claims ("I'm done") as authoritative completion.
336
+ - **Tests**: `tests/swarm-review.test.js`
337
+ - **Acceptance IDs**: `TEST-SWARM-B02`
338
+ - **Bootstrap Contracts**: `swarm-authority-subordinate`, `author-not-reviewer`
339
+ - **Adversarial Cases**: Worker marks status `COMPLETED` with no review attestation.
340
+ - **Completion Criteria**: Emits `SWARM_MISSING_REVIEW` and rejects closure.
341
+ - **Evidence**: Unit tests proving unreviewed claims fail validation.
342
+
343
+ - [x] **UE-T010: Worker Limit & Anti-Recursive Spawning Guard**
344
+ <!-- gemstack:validation_required=true -->
345
+ <!-- gemstack:tests=TEST-SWARM-A01 -->
346
+ <!-- gemstack:files=src/lib/swarm.js -->
347
+ <!-- gemstack:depends=UE-T009 -->
348
+ - **Phase**: Phase 2
349
+ - **Objective**: Enforce declared worker count limits and prohibit undeclared recursive child worker spawning.
350
+ - **Files**: `src/lib/swarm.js`
351
+ - **Prerequisites**: UE-T009
352
+ - **Implementation Requirements**:
353
+ - Implement `validateWorkerLimits(manifest)`.
354
+ - Enforce `workers.length <= max_workers` (default: 4, hard cap: 8).
355
+ - Reject undeclared child worker claims or subagent hierarchy blocks with `SWARM_RECURSIVE_SPAWN_DENIED`.
356
+ - **Must NOT**: Allow dynamic unbounded agent spawning.
357
+ - **Tests**: `tests/swarm-review.test.js`
358
+ - **Acceptance IDs**: `TEST-SWARM-A01`
359
+ - **Bootstrap Contracts**: `swarm-authority-subordinate`
360
+ - **Adversarial Cases**: Manifest declaring 12 parallel workers or worker claiming spawned child.
361
+ - **Completion Criteria**: Fail-closed rejection on limit breach.
362
+ - **Evidence**: Unit test assertions on worker limits.
363
+
364
+ - [x] **UE-T011: Upgrade C Provider Capability & Cost Budget Interceptor**
365
+ <!-- gemstack:validation_required=true -->
366
+ <!-- gemstack:tests=TEST-SWARM-C01,TEST-SWARM-C02 -->
367
+ <!-- gemstack:files=src/lib/swarm.js -->
368
+ <!-- gemstack:depends=UE-T010 -->
369
+ - **Phase**: Phase 2
370
+ - **Objective**: Intercept worker external actions through Upgrade C `ProviderCapabilityGate` and `BillableActionGate`.
371
+ - **Files**: `src/lib/swarm.js`
372
+ - **Prerequisites**: UE-T010
373
+ - **Implementation Requirements**:
374
+ - Implement `validateSwarmProviderSafety(workerAction, featureDir)`.
375
+ - Invoke `evaluateCapabilityGate` from `src/lib/provider/capability-gate.js`.
376
+ - Track wave token limits; halt with `SWARM_COST_LIMIT_EXCEEDED` if cumulative tokens exceed budget.
377
+ - **Must NOT**: Make live network calls or incur commercial API spend in core tests.
378
+ - **Tests**: `tests/swarm-review.test.js`
379
+ - **Acceptance IDs**: `TEST-SWARM-C01`, `TEST-SWARM-C02`
380
+ - **Bootstrap Contracts**: `swarm-provider-safety-gated`
381
+ - **Adversarial Cases**: Undeclared provider invocation; wave token sum exceeding limit.
382
+ - **Completion Criteria**: Emits `SWARM_PROVIDER_UNAUTHORIZED` or `SWARM_COST_LIMIT_EXCEEDED`.
383
+ - **Evidence**: Passing `TEST-SWARM-C01` and `TEST-SWARM-C02`.
384
+
385
+ ---
386
+
387
+ ### Phase 3: Visual QA Contracts & Offline Evidence Validation
388
+
389
+ - [x] **UE-T012: Visual QA Manifest Schema & Scenario Registry (`src/lib/visual-qa.js`)**
390
+ <!-- gemstack:validation_required=true -->
391
+ <!-- gemstack:tests=TEST-VISUAL-A01 -->
392
+ <!-- gemstack:files=src/lib/visual-qa.js -->
393
+ <!-- gemstack:depends=UE-T001 -->
394
+ - **Phase**: Phase 3 — Visual QA Contracts & Offline Evidence Validation
395
+ - **Objective**: Implement canonical JSON schema validation for `visual-qa.json` and scenario registry.
396
+ - **Files**: `src/lib/visual-qa.js` [NEW]
397
+ - **Prerequisites**: UE-T001
398
+ - **Implementation Requirements**:
399
+ - Implement `parseVisualManifest(manifestJson)` and `validateVisualSchema(manifest)`.
400
+ - Validate schema version `1.0.0`, `target_base_url`, and `scenarios` array.
401
+ - Require unique `scenario_id` and non-empty `acceptance_ids` per scenario.
402
+ - **Must NOT**: Spawn headless browsers or require Puppeteer/Playwright packages.
403
+ - **Tests**: `tests/visual-manifest.test.js` [NEW]
404
+ - **Acceptance IDs**: `TEST-VISUAL-A01`
405
+ - **Bootstrap Contracts**: `visual-evidence-subordinate`
406
+ - **Adversarial Cases**: Duplicate scenario IDs, missing acceptance IDs, invalid JSON syntax.
407
+ - **Completion Criteria**: Rejects invalid manifests fail-closed with `VQA_INVALID_MANIFEST`.
408
+ - **Evidence**: Unit tests in `tests/visual-manifest.test.js`.
409
+
410
+ - [x] **UE-T013: Deterministic Viewport Matrix & Resolution Resolver**
411
+ <!-- gemstack:validation_required=true -->
412
+ <!-- gemstack:tests=TEST-VISUAL-A02 -->
413
+ <!-- gemstack:files=src/lib/visual-qa.js -->
414
+ <!-- gemstack:depends=UE-T012 -->
415
+ - **Phase**: Phase 3
416
+ - **Objective**: Enforce deterministic viewport dimensions and validate canonical profile configurations.
417
+ - **Files**: `src/lib/visual-qa.js`
418
+ - **Prerequisites**: UE-T012
419
+ - **Implementation Requirements**:
420
+ - Implement `validateViewport(viewport)`.
421
+ - Support canonical profiles: `desktop-standard` (1920x1080), `desktop-compact` (1280x800), `tablet-portrait` (768x1024), `mobile-portrait` (375x667).
422
+ - Enforce positive integers for `width`, `height`, and `device_scale_factor`.
423
+ - **Must NOT**: Allow unquantified display labels or zero/negative dimensions.
424
+ - **Tests**: `tests/visual-manifest.test.js`
425
+ - **Acceptance IDs**: `TEST-VISUAL-A02`
426
+ - **Bootstrap Contracts**: `deterministic-viewports`
427
+ - **Adversarial Cases**: Negative height, non-integer scale factor, missing viewport object.
428
+ - **Completion Criteria**: Emits `VQA_INVALID_VIEWPORT` on non-conforming configurations.
429
+ - **Evidence**: Passing `TEST-VISUAL-A02`.
430
+
431
+ - [x] **UE-T014: Capture Environment Identity & Metadata Validator**
432
+ <!-- gemstack:validation_required=true -->
433
+ <!-- gemstack:tests=TEST-VISUAL-A01 -->
434
+ <!-- gemstack:files=src/lib/visual-qa.js -->
435
+ <!-- gemstack:depends=UE-T013 -->
436
+ - **Phase**: Phase 3
437
+ - **Objective**: Validate capture environment descriptors in submitted visual evidence.
438
+ - **Files**: `src/lib/visual-qa.js`
439
+ - **Prerequisites**: UE-T013
440
+ - **Implementation Requirements**:
441
+ - Implement `validateEnvironmentMetadata(scenario, evidenceMetadata)`.
442
+ - Check browser engine family, OS profile, and color scheme match scenario declarations.
443
+ - **Must NOT**: Overfit to a specific developer workstation hostname or OS kernel patch.
444
+ - **Tests**: `tests/visual-manifest.test.js`
445
+ - **Acceptance IDs**: `TEST-VISUAL-A01`
446
+ - **Bootstrap Contracts**: `deterministic-viewports`
447
+ - **Adversarial Cases**: Evidence captured in `dark` mode when scenario requires `light`.
448
+ - **Completion Criteria**: Flags environment mismatch fail-closed.
449
+ - **Evidence**: Unit test assertions on metadata compatibility.
450
+
451
+ - [x] **UE-T015: Dynamic Region Masking & Secret Auto-Masking Engine**
452
+ <!-- gemstack:validation_required=true -->
453
+ <!-- gemstack:tests=TEST-VISUAL-D01,TEST-VISUAL-D02 -->
454
+ <!-- gemstack:files=src/lib/visual-qa.js -->
455
+ <!-- gemstack:depends=UE-T014 -->
456
+ - **Phase**: Phase 3
457
+ - **Objective**: Implement deterministic solid masking rules for dynamic elements and sensitive input fields.
458
+ - **Files**: `src/lib/visual-qa.js`
459
+ - **Prerequisites**: UE-T014
460
+ - **Implementation Requirements**:
461
+ - Implement `applySelectorMasks(domTree, maskSelectors)`.
462
+ - Replace content of declared mask elements with neutral solid fill (`#808080`).
463
+ - Automatically mask password inputs (`type="password"`) and `data-sensitive="true"` elements.
464
+ - **Must NOT**: Allow credentials or auth tokens to appear in visual evidence digests.
465
+ - **Tests**: `tests/visual-diff.test.js` [NEW]
466
+ - **Acceptance IDs**: `TEST-VISUAL-D01`, `TEST-VISUAL-D02`
467
+ - **Bootstrap Contracts**: `visual-evidence-subordinate`
468
+ - **Adversarial Cases**: Password input unmasked; live timestamp causing diff noise.
469
+ - **Completion Criteria**: Neutral mask eliminates dynamic noise; password inputs masked 100%.
470
+ - **Evidence**: Passing `TEST-VISUAL-D01` and `TEST-VISUAL-D02`.
471
+
472
+ - [x] **UE-T016: Cryptographic Baseline Safety & Tamper Detector**
473
+ <!-- gemstack:validation_required=true -->
474
+ <!-- gemstack:tests=TEST-VISUAL-B01,TEST-VISUAL-B02 -->
475
+ <!-- gemstack:files=src/lib/visual-qa.js -->
476
+ <!-- gemstack:depends=UE-T015 -->
477
+ - **Phase**: Phase 3
478
+ - **Objective**: Verify baseline image files against pinned SHA-256 hashes and enforce explicit promotion semantics.
479
+ - **Files**: `src/lib/visual-qa.js`
480
+ - **Prerequisites**: UE-T015
481
+ - **Implementation Requirements**:
482
+ - Implement `validateBaselineIntegrity(scenario, baseDir)`.
483
+ - Hash baseline image file on disk using SHA-256; compare against `baseline.image_sha256`.
484
+ - Fail closed with `VQA_BASELINE_TAMPERED` if image was modified without explicit promotion.
485
+ - Enforce that verification never overwrites or mutates baseline files.
486
+ - **Must NOT**: Auto-heal or silently overwrite baselines on test failure.
487
+ - **Tests**: `tests/visual-manifest.test.js`
488
+ - **Acceptance IDs**: `TEST-VISUAL-B01`, `TEST-VISUAL-B02`
489
+ - **Bootstrap Contracts**: `baseline-explicit-update-only`
490
+ - **Adversarial Cases**: Manually editing PNG on disk; verify attempting to update baseline.
491
+ - **Completion Criteria**: Emits `VQA_BASELINE_TAMPERED` upon hash mismatch.
492
+ - **Evidence**: Passing `TEST-VISUAL-B01` and `TEST-VISUAL-B02`.
493
+
494
+ - [x] **UE-T017: Offline Diffing & Failure Classification Engine**
495
+ <!-- gemstack:validation_required=true -->
496
+ <!-- gemstack:tests=TEST-VISUAL-C01,TEST-VISUAL-C02 -->
497
+ <!-- gemstack:files=src/lib/visual-qa.js -->
498
+ <!-- gemstack:depends=UE-T016 -->
499
+ - **Phase**: Phase 3
500
+ - **Objective**: Implement fast-path hash matching, tolerance evaluation, and deterministic failure classification.
501
+ - **Files**: `src/lib/visual-qa.js`
502
+ - **Prerequisites**: UE-T016
503
+ - **Implementation Requirements**:
504
+ - Implement `compareVisualEvidence(evidence, baseline, tolerances)`.
505
+ - Fast path: if live screenshot SHA-256 matches baseline `image_sha256`, pass immediately.
506
+ - Classify failures: `VISUAL_REGRESSION`, `BASELINE_MISSING`, `BASELINE_TAMPERED`, `EVIDENCE_MISSING`.
507
+ - **Must NOT**: Require bundled native C++ image processing addons; use Node.js built-ins and digests.
508
+ - **Tests**: `tests/visual-diff.test.js`
509
+ - **Acceptance IDs**: `TEST-VISUAL-C01`, `TEST-VISUAL-C02`
510
+ - **Bootstrap Contracts**: `visual-evidence-subordinate`
511
+ - **Adversarial Cases**: Live image deviating beyond allowed `max_diff_percentage`.
512
+ - **Completion Criteria**: Emits `VQA_VISUAL_REGRESSION_DETECTED` on mismatch; fast passes on identical hash.
513
+ - **Evidence**: Passing `TEST-VISUAL-C01` and `TEST-VISUAL-C02`.
514
+
515
+ ---
516
+
517
+ ### Phase 4: CLI Ergonomics, Verify Purity & Closure Integration
518
+
519
+ - [x] **UE-T018: Swarm CLI Commands (`src/commands/swarm.js`)**
520
+ <!-- gemstack:validation_required=true -->
521
+ <!-- gemstack:tests=TEST-SWARM-A01,TEST-SWARM-E01 -->
522
+ <!-- gemstack:files=src/commands/swarm.js -->
523
+ <!-- gemstack:depends=UE-T005, UE-T011 -->
524
+ - **Phase**: Phase 4 — CLI Ergonomics, Verify Purity & Closure Integration
525
+ - **Objective**: Implement `gemstack swarm plan` and `gemstack swarm validate` subcommands.
526
+ - **Files**: `src/commands/swarm.js` [NEW]
527
+ - **Prerequisites**: UE-T005, UE-T011
528
+ - **Implementation Requirements**:
529
+ - `gemstack swarm plan`: Reads `tasks.md`, computes waves and disjoint write sets, writes `swarm.json`.
530
+ - `gemstack swarm validate`: Strictly read-only; checks write partitions, review attestations, context freshness.
531
+ - Support `--json` flag for structured machine output.
532
+ - **Must NOT**: Implement a live worker execution daemon (`swarm run`).
533
+ - **Tests**: `tests/swarm-review.test.js`
534
+ - **Acceptance IDs**: `TEST-SWARM-A01`, `TEST-SWARM-E01`
535
+ - **Bootstrap Contracts**: `swarm-authority-subordinate`
536
+ - **Adversarial Cases**: Invoking validate with invalid manifest or overlapping writes.
537
+ - **Completion Criteria**: CLI commands execute cleanly; validate operates in read-only mode.
538
+ - **Evidence**: CLI functional tests in `tests/swarm-review.test.js`.
539
+
540
+ - [x] **UE-T019: Visual QA CLI Commands (`src/commands/visual.js`)**
541
+ <!-- gemstack:validation_required=true -->
542
+ <!-- gemstack:tests=TEST-VISUAL-B01,TEST-VISUAL-E01 -->
543
+ <!-- gemstack:files=src/commands/visual.js -->
544
+ <!-- gemstack:depends=UE-T017 -->
545
+ - **Phase**: Phase 4
546
+ - **Objective**: Implement `gemstack vqa validate` and `gemstack vqa promote` subcommands.
547
+ - **Files**: `src/commands/visual.js` [NEW]
548
+ - **Prerequisites**: UE-T017
549
+ - **Implementation Requirements**:
550
+ - `gemstack vqa validate`: Strictly read-only offline audit of `visual-qa.json`, baselines, and evidence.
551
+ - `gemstack vqa promote <scenario-id>`: Explicitly promotes live evidence to canonical baseline with updated SHA-256 and audit metadata.
552
+ - **Must NOT**: Launch browser processes or perform automated capture.
553
+ - **Tests**: `tests/visual-manifest.test.js`, `tests/swarm-visual-purity.test.js` [NEW]
554
+ - **Acceptance IDs**: `TEST-VISUAL-B01`, `TEST-VISUAL-E01`
555
+ - **Bootstrap Contracts**: `baseline-explicit-update-only`
556
+ - **Adversarial Cases**: Promoting without live evidence; validate mutating baseline image.
557
+ - **Completion Criteria**: Explicit promotion succeeds; validate never mutates files.
558
+ - **Evidence**: Passing tests verifying promote updates manifest and validate remains read-only.
559
+
560
+ - [x] **UE-T020: CLI Router Registration (`src/cli.js`)**
561
+ <!-- gemstack:validation_required=true -->
562
+ <!-- gemstack:tests=TEST-SWARM-E01,TEST-VISUAL-E01 -->
563
+ <!-- gemstack:files=src/cli.js -->
564
+ <!-- gemstack:depends=UE-T018, UE-T019 -->
565
+ - **Phase**: Phase 4
566
+ - **Objective**: Register `swarm` and `vqa` commands in the main Gemstack CLI router.
567
+ - **Files**: `src/cli.js` [MODIFY]
568
+ - **Prerequisites**: UE-T018, UE-T019
569
+ - **Implementation Requirements**:
570
+ - Add `swarm` and `vqa` command routes in `src/cli.js`.
571
+ - Update CLI help text displaying usage for `gemstack swarm` and `gemstack vqa`.
572
+ - **Must NOT**: Break existing command routing or alter flags for other commands.
573
+ - **Tests**: `tests/runner-adapter.test.js`, `scripts/ci/smoke-cli.js`
574
+ - **Acceptance IDs**: `TEST-SWARM-E01`, `TEST-VISUAL-E01`
575
+ - **Bootstrap Contracts**: `verify-swarm-visual-offline`
576
+ - **Adversarial Cases**: Unrecognized subcommand arguments under `swarm` and `vqa`.
577
+ - **Completion Criteria**: Commands invoke corresponding handlers; help text renders accurately.
578
+ - **Evidence**: Smoke test verification via `node scripts/ci/smoke-cli.js`.
579
+
580
+ - [x] **UE-T021: Verify Integration Stages 5.3 & 5.4 (`src/commands/verify.js`)**
581
+ <!-- gemstack:validation_required=true -->
582
+ <!-- gemstack:tests=TEST-SWARM-E01,TEST-SWARM-E02,TEST-VISUAL-E01,TEST-VISUAL-E02 -->
583
+ <!-- gemstack:files=src/commands/verify.js -->
584
+ <!-- gemstack:depends=UE-T020 -->
585
+ - **Phase**: Phase 4
586
+ - **Objective**: Add Stage 5.3 (Swarm Audit) and Stage 5.4 (Visual QA Audit) to `gemstack verify` in pure read-only mode.
587
+ - **Files**: `src/commands/verify.js` [MODIFY]
588
+ - **Prerequisites**: UE-T020
589
+ - **Implementation Requirements**:
590
+ - **Stage 5.3**: Validates `swarm.json` write partitions, `author != reviewer`, and context freshness.
591
+ - **Stage 5.4**: Validates `visual-qa.json` viewports, baseline SHA-256 integrity, and evidence completeness.
592
+ - Preserves legacy mode: if `swarm.json` or `visual-qa.json` is absent, logs informational notice and exits 0.
593
+ - Enforces `VERIFY = VALIDATE`: 0 file writes, 0 process launches, 0 network calls.
594
+ - **Must NOT**: Mutate files, update baselines, or spawn browsers during verify.
595
+ - **Tests**: `tests/swarm-visual-purity.test.js`
596
+ - **Acceptance IDs**: `TEST-SWARM-E01`, `TEST-SWARM-E02`, `TEST-VISUAL-E01`, `TEST-VISUAL-E02`
597
+ - **Bootstrap Contracts**: `verify-swarm-visual-offline`, `legacy-swarm-visual-compatibility`
598
+ - **Adversarial Cases**: Running verify on legacy project; running verify with mocked throwing sockets.
599
+ - **Completion Criteria**: Verify passes offline with 0 errors; legacy projects exit 0.
600
+ - **Evidence**: Passing `TEST-SWARM-E01..E02` and `TEST-VISUAL-E01..E02`.
601
+
602
+ - [x] **UE-T022: Closure Context Tracking (`src/lib/closure-context.js`)**
603
+ <!-- gemstack:validation_required=true -->
604
+ <!-- gemstack:tests=TEST-SWARM-E01,TEST-VISUAL-E01 -->
605
+ <!-- gemstack:files=src/lib/closure-context.js -->
606
+ <!-- gemstack:depends=UE-T021 -->
607
+ - **Phase**: Phase 4
608
+ - **Objective**: Incorporate `swarm.json` and `visual-qa.json` into mechanical closure context when present.
609
+ - **Files**: `src/lib/closure-context.js` [MODIFY]
610
+ - **Prerequisites**: UE-T021
611
+ - **Implementation Requirements**:
612
+ - Include `swarm.json` and `visual-qa.json` in implementation context file list when resolving closure state.
613
+ - Preserve Upgrade B closure context hashing and acceptance signature reconciliation.
614
+ - **Must NOT**: Alter closure manifest semantics or create new closure authorities.
615
+ - **Tests**: `tests/closure-manifest.test.js`, `tests/closure-gates.test.js`
616
+ - **Acceptance IDs**: `TEST-SWARM-E01`, `TEST-VISUAL-E01`
617
+ - **Bootstrap Contracts**: `swarm-authority-subordinate`, `visual-evidence-subordinate`
618
+ - **Adversarial Cases**: Modifying `swarm.json` after collect triggers stale closure evidence.
619
+ - **Completion Criteria**: Closure context digest accurately incorporates active manifests.
620
+ - **Evidence**: Unit test assertions in closure test suite.
621
+
622
+ - [x] **UE-T023: Test Suite Registration & Zero Dependency Proof (`package.json`)**
623
+ <!-- gemstack:validation_required=true -->
624
+ <!-- gemstack:tests=TEST-SWARM-A01,TEST-SWARM-A02,TEST-SWARM-B01,TEST-SWARM-B02,TEST-SWARM-C01,TEST-SWARM-C02,TEST-SWARM-D01,TEST-SWARM-D02,TEST-SWARM-E01,TEST-SWARM-E02,TEST-VISUAL-A01,TEST-VISUAL-A02,TEST-VISUAL-B01,TEST-VISUAL-B02,TEST-VISUAL-C01,TEST-VISUAL-C02,TEST-VISUAL-D01,TEST-VISUAL-D02,TEST-VISUAL-E01,TEST-VISUAL-E02 -->
625
+ <!-- gemstack:files=package.json -->
626
+ <!-- gemstack:depends=UE-T022 -->
627
+ - **Phase**: Phase 4
628
+ - **Objective**: Register the 5 new test suites into `package.json` test script and verify zero dependency delta.
629
+ - **Files**: `package.json` [MODIFY]
630
+ - **Prerequisites**: UE-T022
631
+ - **Implementation Requirements**:
632
+ - Add `tests/swarm-partitioning.test.js`, `tests/swarm-review.test.js`, `tests/visual-manifest.test.js`, `tests/visual-diff.test.js`, `tests/swarm-visual-purity.test.js` to `npm test` script.
633
+ - Verify `dependencies` and `devDependencies` remain completely empty (0 added).
634
+ - **Must NOT**: Add any runtime or development npm dependencies.
635
+ - **Tests**: `scripts/ci/check-package-contents.js`
636
+ - **Acceptance IDs**: All 20 acceptance criteria
637
+ - **Bootstrap Contracts**: All 10 contracts
638
+ - **Adversarial Cases**: Injecting an external npm package; omitting test files from runner.
639
+ - **Completion Criteria**: `package.json` scripts execute clean test runner; package contents check passes.
640
+ - **Evidence**: Clean output from `npm run ci:package`.
641
+
642
+ ---
643
+
644
+ ### Phase 5: Acceptance, Adversarial & Regression Closure
645
+
646
+ - [x] **UE-T024: Swarm Partitioning Acceptance Suite (`tests/swarm-partitioning.test.js`)**
647
+ <!-- gemstack:validation_required=true -->
648
+ <!-- gemstack:tests=TEST-SWARM-A01,TEST-SWARM-A02 -->
649
+ <!-- gemstack:files=tests/swarm-partitioning.test.js -->
650
+ <!-- gemstack:depends=UE-T023 -->
651
+ - **Phase**: Phase 5 — Acceptance, Adversarial & Regression Closure
652
+ - **Objective**: Implement mechanical unit tests for swarm partitioning, wave planning, and write collisions.
653
+ - **Files**: `tests/swarm-partitioning.test.js` [NEW]
654
+ - **Prerequisites**: UE-T023
655
+ - **Implementation Requirements**:
656
+ - Implement `TEST-SWARM-A01`: Proves parallel tasks with disjoint write sets schedule concurrently.
657
+ - Implement `TEST-SWARM-A02`: Proves overlapping write sets serialize and trigger collision prevention.
658
+ - **Must NOT**: Spawn actual parallel worker processes.
659
+ - **Tests**: `tests/swarm-partitioning.test.js`
660
+ - **Acceptance IDs**: `TEST-SWARM-A01`, `TEST-SWARM-A02`
661
+ - **Bootstrap Contracts**: `exclusive-task-write-ownership`
662
+ - **Adversarial Cases**: Concurrent tasks declaring identical files; circular prerequisite chains.
663
+ - **Completion Criteria**: Both tests pass 100% with exit code 0.
664
+ - **Evidence**: Passing test execution output.
665
+
666
+ - [x] **UE-T025: Swarm Review & Gate Safety Suite (`tests/swarm-review.test.js`)**
667
+ <!-- gemstack:validation_required=true -->
668
+ <!-- gemstack:tests=TEST-SWARM-B01,TEST-SWARM-B02,TEST-SWARM-C01,TEST-SWARM-C02,TEST-SWARM-D01,TEST-SWARM-D02 -->
669
+ <!-- gemstack:files=tests/swarm-review.test.js -->
670
+ <!-- gemstack:depends=UE-T024 -->
671
+ - **Phase**: Phase 5
672
+ - **Objective**: Implement mechanical unit tests for separation of duties, provider gates, and context projection.
673
+ - **Files**: `tests/swarm-review.test.js` [NEW]
674
+ - **Prerequisites**: UE-T024
675
+ - **Implementation Requirements**:
676
+ - Implement `TEST-SWARM-B01`: Proves author == reviewer fails closed with self-review error.
677
+ - Implement `TEST-SWARM-B02`: Proves distinct reviewer role validates review attestation.
678
+ - Implement `TEST-SWARM-C01`: Proves model invocation intercepted by ProviderCapabilityGate.
679
+ - Implement `TEST-SWARM-C02`: Proves token limit budget enforcement across wave tasks.
680
+ - Implement `TEST-SWARM-D01`: Proves context projection matches capsule hash.
681
+ - Implement `TEST-SWARM-D02`: Proves raw chat history excluded from worker context.
682
+ - **Must NOT**: Call live external model APIs; use local gate fixtures.
683
+ - **Tests**: `tests/swarm-review.test.js`
684
+ - **Acceptance IDs**: `TEST-SWARM-B01`, `TEST-SWARM-B02`, `TEST-SWARM-C01`, `TEST-SWARM-C02`, `TEST-SWARM-D01`, `TEST-SWARM-D02`
685
+ - **Bootstrap Contracts**: `author-not-reviewer`, `swarm-provider-safety-gated`, `swarm-context-projected`
686
+ - **Adversarial Cases**: Role-switching bypass; budget breach; stale context hash drift.
687
+ - **Completion Criteria**: All 6 tests pass 100% with exit code 0.
688
+ - **Evidence**: Passing test execution output.
689
+
690
+ - [x] **UE-T026: Visual Manifest & Baseline Safety Suite (`tests/visual-manifest.test.js`)**
691
+ <!-- gemstack:validation_required=true -->
692
+ <!-- gemstack:tests=TEST-VISUAL-A01,TEST-VISUAL-A02,TEST-VISUAL-B01,TEST-VISUAL-B02 -->
693
+ <!-- gemstack:files=tests/visual-manifest.test.js -->
694
+ <!-- gemstack:depends=UE-T025 -->
695
+ - **Phase**: Phase 5
696
+ - **Objective**: Implement mechanical unit tests for visual-qa.json schema, viewports, and baseline safety.
697
+ - **Files**: `tests/visual-manifest.test.js` [NEW]
698
+ - **Prerequisites**: UE-T025
699
+ - **Implementation Requirements**:
700
+ - Implement `TEST-VISUAL-A01`: Proves schema validation rejects missing route, viewport, or baseline.
701
+ - Implement `TEST-VISUAL-A02`: Proves deterministic viewport specifications across profiles.
702
+ - Implement `TEST-VISUAL-B01`: Proves baseline image file hash mismatch triggers tampered error.
703
+ - Implement `TEST-VISUAL-B02`: Proves baseline files are never silently modified during test run.
704
+ - **Must NOT**: Spawn browser binaries.
705
+ - **Tests**: `tests/visual-manifest.test.js`
706
+ - **Acceptance IDs**: `TEST-VISUAL-A01`, `TEST-VISUAL-A02`, `TEST-VISUAL-B01`, `TEST-VISUAL-B02`
707
+ - **Bootstrap Contracts**: `visual-evidence-subordinate`, `deterministic-viewports`, `baseline-explicit-update-only`
708
+ - **Adversarial Cases**: Negative viewport height; tampered PNG on disk; silent baseline rewrite.
709
+ - **Completion Criteria**: All 4 tests pass 100% with exit code 0.
710
+ - **Evidence**: Passing test execution output.
711
+
712
+ - [x] **UE-T027: Visual Regression & Masking Suite (`tests/visual-diff.test.js`)**
713
+ <!-- gemstack:validation_required=true -->
714
+ <!-- gemstack:tests=TEST-VISUAL-C01,TEST-VISUAL-C02,TEST-VISUAL-D01,TEST-VISUAL-D02 -->
715
+ <!-- gemstack:files=tests/visual-diff.test.js -->
716
+ <!-- gemstack:depends=UE-T026 -->
717
+ - **Phase**: Phase 5
718
+ - **Objective**: Implement mechanical tests for visual regression detection and dynamic region masking.
719
+ - **Files**: `tests/visual-diff.test.js` [NEW]
720
+ - **Prerequisites**: UE-T026
721
+ - **Implementation Requirements**:
722
+ - Implement `TEST-VISUAL-C01`: Proves screenshot deviating beyond threshold triggers regression.
723
+ - Implement `TEST-VISUAL-C02`: Proves identical SHA-256 hashes pass comparison immediately.
724
+ - Implement `TEST-VISUAL-D01`: Proves dynamic text variation in masked selector does not fail.
725
+ - Implement `TEST-VISUAL-D02`: Proves automatic masking of password and sensitive credential fields.
726
+ - **Must NOT**: Rely on live browser rendering; use deterministic image and DOM fixtures.
727
+ - **Tests**: `tests/visual-diff.test.js`
728
+ - **Acceptance IDs**: `TEST-VISUAL-C01`, `TEST-VISUAL-C02`, `TEST-VISUAL-D01`, `TEST-VISUAL-D02`
729
+ - **Bootstrap Contracts**: `visual-evidence-subordinate`
730
+ - **Adversarial Cases**: Unmasked password leak; live clock causing diff failure.
731
+ - **Completion Criteria**: All 4 tests pass 100% with exit code 0.
732
+ - **Evidence**: Passing test execution output.
733
+
734
+ - [x] **UE-T028: Offline Purity & Legacy Compatibility Suite (`tests/swarm-visual-purity.test.js`)**
735
+ <!-- gemstack:validation_required=true -->
736
+ <!-- gemstack:tests=TEST-SWARM-E01,TEST-SWARM-E02,TEST-VISUAL-E01,TEST-VISUAL-E02 -->
737
+ <!-- gemstack:files=tests/swarm-visual-purity.test.js -->
738
+ <!-- gemstack:depends=UE-T027 -->
739
+ - **Phase**: Phase 5
740
+ - **Objective**: Implement integration tests proving verify purity and backward compatibility.
741
+ - **Files**: `tests/swarm-visual-purity.test.js` [NEW]
742
+ - **Prerequisites**: UE-T027
743
+ - **Implementation Requirements**:
744
+ - Implement `TEST-SWARM-E01` & `TEST-VISUAL-E01`: Proves `gemstack verify` runs offline with 0 process spawns, 0 file mutations, and sockets mocked to throw.
745
+ - Implement `TEST-SWARM-E02` & `TEST-VISUAL-E02`: Proves legacy projects lacking `swarm.json` or `visual-qa.json` pass with exit code 0.
746
+ - **Must NOT**: Open live network connections or mutate disk files.
747
+ - **Tests**: `tests/swarm-visual-purity.test.js`
748
+ - **Acceptance IDs**: `TEST-SWARM-E01`, `TEST-SWARM-E02`, `TEST-VISUAL-E01`, `TEST-VISUAL-E02`
749
+ - **Bootstrap Contracts**: `verify-swarm-visual-offline`, `legacy-swarm-visual-compatibility`
750
+ - **Adversarial Cases**: Verify attempting network connection or mutating baseline file.
751
+ - **Completion Criteria**: All purity and legacy tests pass 100% with exit code 0.
752
+ - **Evidence**: Passing test execution output.
753
+
754
+ - [x] **UE-T029: Full CI, Frozen Contract & Closure Readiness Audit**
755
+ <!-- gemstack:validation_required=true -->
756
+ <!-- gemstack:tests=TEST-SWARM-A01,TEST-SWARM-A02,TEST-SWARM-B01,TEST-SWARM-B02,TEST-SWARM-C01,TEST-SWARM-C02,TEST-SWARM-D01,TEST-SWARM-D02,TEST-SWARM-E01,TEST-SWARM-E02,TEST-VISUAL-A01,TEST-VISUAL-A02,TEST-VISUAL-B01,TEST-VISUAL-B02,TEST-VISUAL-C01,TEST-VISUAL-C02,TEST-VISUAL-D01,TEST-VISUAL-D02,TEST-VISUAL-E01,TEST-VISUAL-E02 -->
757
+ <!-- gemstack:files=All repository files -->
758
+ <!-- gemstack:depends=UE-T024 through UE-T028 -->
759
+ - **Phase**: Phase 5
760
+ - **Objective**: Run full test regression, CI gate scripts, and prove frozen contracts remain 100% intact.
761
+ - **Files**: All repository files
762
+ - **Prerequisites**: UE-T024 through UE-T028
763
+ - **Implementation Requirements**:
764
+ - Execute `npm test` proving all legacy (100) + Upgrade E (20+) tests pass with 0 failures.
765
+ - Execute `npm run ci:all` proving all frontmatter, template, mojibake, package, and demo checks pass.
766
+ - Execute `node src/cli.js verify` confirming 0 errors and 0 blockers.
767
+ - Verify frozen contracts from Upgrades A, B, C, D are untouched.
768
+ - **Must NOT**: Bump package version, publish to npm, or declare closure prematurely.
769
+ - **Tests**: Full CI pipeline (`npm run ci:all`)
770
+ - **Acceptance IDs**: All 20 acceptance criteria
771
+ - **Bootstrap Contracts**: All 10 contracts
772
+ - **Adversarial Cases**: Regressions in Upgrades A/B/C/D; package content leaks.
773
+ - **Completion Criteria**: 100% clean CI run; zero regressions; ready for closure review.
774
+ - **Evidence**: Full terminal logs from `npm run ci:all` and `gemstack verify`.
775
+
776
+ ---
777
+
778
+ ## Bootstrap Contract Traceability (10 / 10 Mapped)
779
+
780
+ | Bootstrap Contract | Task ID(s) | Test File | Mechanical Proof |
781
+ | :--- | :--- | :--- | :--- |
782
+ | **`swarm-authority-subordinate`** | UE-T001, UE-T002, UE-T003 | `tests/swarm-partitioning.test.js` | Rejects manifest attempting to override spec or bypass tasks |
783
+ | **`author-not-reviewer`** | UE-T006, UE-T007, UE-T009 | `tests/swarm-review.test.js` | Fails closed with self-review error when author == reviewer |
784
+ | **`exclusive-task-write-ownership`**| UE-T005, UE-T007, UE-T024 | `tests/swarm-partitioning.test.js` | Rejects concurrent tasks with overlapping write sets |
785
+ | **`swarm-provider-safety-gated`** | UE-T011, UE-T025 | `tests/swarm-review.test.js` | Intercepts model calls via ProviderCapabilityGate |
786
+ | **`swarm-context-projected`** | UE-T008, UE-T025 | `tests/swarm-review.test.js` | Rejects stale projections and chat transcript ingestion |
787
+ | **`visual-evidence-subordinate`** | UE-T012, UE-T015, UE-T017 | `tests/visual-diff.test.js` | Screenshot evidence cannot alter spec or waive gates |
788
+ | **`deterministic-viewports`** | UE-T013, UE-T014, UE-T026 | `tests/visual-manifest.test.js` | Rejects negative or unquantified viewport dimensions |
789
+ | **`baseline-explicit-update-only`**| UE-T016, UE-T019, UE-T026 | `tests/visual-manifest.test.js` | Rejects silent baseline mutation; requires explicit promote |
790
+ | **`verify-swarm-visual-offline`** | UE-T021, UE-T028 | `tests/swarm-visual-purity.test.js` | Verify passes offline with mocked network and 0 spawns |
791
+ | **`legacy-swarm-visual-compatibility`**| UE-T021, UE-T028 | `tests/swarm-visual-purity.test.js` | Legacy projects without manifests pass verify exit 0 |
792
+
793
+ ---
794
+
795
+ ## Canonical Acceptance Traceability (20 / 20 Mapped)
796
+
797
+ | Acceptance ID | Task ID(s) | Test File | Mechanical Proof |
798
+ | :--- | :--- | :--- | :--- |
799
+ | **`TEST-SWARM-A01`** | UE-T001..T005, UE-T024 | `tests/swarm-partitioning.test.js` | Disjoint write sets schedule cleanly in concurrent waves |
800
+ | **`TEST-SWARM-A02`** | UE-T005, UE-T024 | `tests/swarm-partitioning.test.js` | Overlapping write sets serialize into sequential waves |
801
+ | **`TEST-SWARM-B01`** | UE-T006, UE-T007, UE-T025 | `tests/swarm-review.test.js` | Self-review by author triggers fail-closed rejection |
802
+ | **`TEST-SWARM-B02`** | UE-T006, UE-T009, UE-T025 | `tests/swarm-review.test.js` | Review attestation by distinct reviewer passes validation |
803
+ | **`TEST-SWARM-C01`** | UE-T011, UE-T025 | `tests/swarm-review.test.js` | Intercepts undeclared provider invocation fail-closed |
804
+ | **`TEST-SWARM-C02`** | UE-T011, UE-T025 | `tests/swarm-review.test.js` | Halts execution when wave tokens exceed allocated budget |
805
+ | **`TEST-SWARM-D01`** | UE-T008, UE-T025 | `tests/swarm-review.test.js` | Projection hash matches active context-capsule digest |
806
+ | **`TEST-SWARM-D02`** | UE-T008, UE-T025 | `tests/swarm-review.test.js` | Chat transcripts are strictly excluded from worker payloads |
807
+ | **`TEST-SWARM-E01`** | UE-T018, UE-T021, UE-T028 | `tests/swarm-visual-purity.test.js` | Verify audits swarm manifest with 0 writes and 0 spawns |
808
+ | **`TEST-SWARM-E02`** | UE-T021, UE-T028 | `tests/swarm-visual-purity.test.js` | Absent swarm manifest passes verify in legacy mode (exit 0) |
809
+ | **`TEST-VISUAL-A01`** | UE-T012, UE-T026 | `tests/visual-manifest.test.js` | Rejects manifest missing route, viewport, or baseline |
810
+ | **`TEST-VISUAL-A02`** | UE-T013, UE-T026 | `tests/visual-manifest.test.js` | Validates deterministic viewport dimensions across profiles |
811
+ | **`TEST-VISUAL-B01`** | UE-T016, UE-T019, UE-T026 | `tests/visual-manifest.test.js` | Tampered baseline image on disk triggers hash error |
812
+ | **`TEST-VISUAL-B02`** | UE-T016, UE-T026 | `tests/visual-manifest.test.js` | Baseline image hashes remain unchanged after test run |
813
+ | **`TEST-VISUAL-C01`** | UE-T017, UE-T027 | `tests/visual-diff.test.js` | Live screenshot deviating beyond tolerance triggers regression |
814
+ | **`TEST-VISUAL-C02`** | UE-T017, UE-T027 | `tests/visual-diff.test.js` | Identical SHA-256 image hashes pass immediately |
815
+ | **`TEST-VISUAL-D01`** | UE-T015, UE-T027 | `tests/visual-diff.test.js` | Dynamic variations inside masked selector do not fail |
816
+ | **`TEST-VISUAL-D02`** | UE-T015, UE-T027 | `tests/visual-diff.test.js` | Password inputs are automatically masked with solid fill |
817
+ | **`TEST-VISUAL-E01`** | UE-T019, UE-T021, UE-T028 | `tests/swarm-visual-purity.test.js` | Verify audits visual evidence offline with 0 browser spawns |
818
+ | **`TEST-VISUAL-E02`** | UE-T021, UE-T028 | `tests/swarm-visual-purity.test.js` | Absent visual manifest passes verify in legacy mode (exit 0) |
819
+
820
+ ---
821
+
822
+ ## Adversarial Matrix (26 Scenarios)
823
+
824
+ | Adversarial Attack / Vector | Task ID | Test File | Expected Finding / Result |
825
+ | :--- | :--- | :--- | :--- |
826
+ | 1. Worker attempts out-of-scope file edit | UE-T007 | `tests/swarm-review.test.js` | `SWARM_WRITE_SET_VIOLATION` |
827
+ | 2. Worker uses stale context projection | UE-T008 | `tests/swarm-review.test.js` | `SWARM_CONTEXT_STALE` |
828
+ | 3. Two workers claim identical write path | UE-T005 | `tests/swarm-partitioning.test.js` | `SWARM_WRITE_COLLISION` |
829
+ | 4. Worker claims complete without test proof | UE-T009 | `tests/swarm-review.test.js` | `SWARM_MISSING_REVIEW` |
830
+ | 5. Author self-approves implementation task | UE-T006 | `tests/swarm-review.test.js` | `SWARM_SELF_REVIEW_DETECTED` |
831
+ | 6. Author changes role string to review own work | UE-T006 | `tests/swarm-review.test.js` | `SWARM_SELF_REVIEW_DETECTED` |
832
+ | 7. Worker claims spawned undeclared subagent | UE-T010 | `tests/swarm-review.test.js` | `SWARM_RECURSIVE_SPAWN_DENIED` |
833
+ | 8. Declared worker count exceeds limit | UE-T010 | `tests/swarm-review.test.js` | `SWARM_WORKER_LIMIT_EXCEEDED` |
834
+ | 9. Model invocation without provider gate | UE-T011 | `tests/swarm-review.test.js` | `SWARM_PROVIDER_UNAUTHORIZED` |
835
+ | 10. Wave token usage exceeds allocated budget | UE-T011 | `tests/swarm-review.test.js` | `SWARM_COST_LIMIT_EXCEEDED` |
836
+ | 11. Swarm manifest attempts to modify spec.md | UE-T003 | `tests/swarm-partitioning.test.js` | `SWARM_AUTHORITY_CONFLICT` |
837
+ | 12. Worker attempts to modify closure.json | UE-T007 | `tests/swarm-review.test.js` | `SWARM_WRITE_SET_VIOLATION` |
838
+ | 13. Visual worker modifies application code | UE-T007 | `tests/swarm-review.test.js` | `SWARM_WRITE_SET_VIOLATION` |
839
+ | 14. Screenshot evidence claims architecture change| UE-T012 | `tests/visual-manifest.test.js` | `VQA_AUTHORITY_CONFLICT` |
840
+ | 15. Missing visual evidence marked as pass | UE-T017 | `tests/visual-diff.test.js` | `VQA_EVIDENCE_MISSING` |
841
+ | 16. Stale screenshot from earlier commit used | UE-T017 | `tests/visual-diff.test.js` | `VQA_EVIDENCE_STALE` |
842
+ | 17. Unquantified or negative viewport used | UE-T013 | `tests/visual-manifest.test.js` | `VQA_INVALID_VIEWPORT` |
843
+ | 18. Evidence captured in dark mode for light spec| UE-T014 | `tests/visual-manifest.test.js` | `VQA_ENVIRONMENT_MISMATCH` |
844
+ | 19. Tool attempts silent baseline auto-update | UE-T016 | `tests/visual-manifest.test.js` | `VQA_BASELINE_TAMPERED` |
845
+ | 20. Baseline image bytes forged / modified on disk| UE-T016 | `tests/visual-manifest.test.js` | `VQA_BASELINE_TAMPERED` |
846
+ | 21. Live screenshot hash forged in manifest | UE-T017 | `tests/visual-diff.test.js` | `VQA_VISUAL_REGRESSION_DETECTED`|
847
+ | 22. Unmasked password input captured in screenshot| UE-T015 | `tests/visual-diff.test.js` | Auto-masked with solid fill |
848
+ | 23. Verify command attempts worker process spawn | UE-T021 | `tests/swarm-visual-purity.test.js`| 0 spawns (mocked to throw) |
849
+ | 24. Verify command attempts browser launch | UE-T021 | `tests/swarm-visual-purity.test.js`| 0 browser calls |
850
+ | 25. Verify command mutates baseline or manifest | UE-T021 | `tests/swarm-visual-purity.test.js`| 0 file mutations (hash check) |
851
+ | 26. Legacy project without manifests run in verify | UE-T021 | `tests/swarm-visual-purity.test.js`| Exits code 0 (Legacy Notice) |
852
+
853
+ ---
854
+
855
+ ## Test File Mapping
856
+
857
+ | Test File | Total Tests | Acceptance IDs Covered | Key Responsibilities |
858
+ | :--- | :--- | :--- | :--- |
859
+ | **`tests/swarm-partitioning.test.js`** | 5 | `TEST-SWARM-A01`, `TEST-SWARM-A02` | Manifest schema, wave scheduling, disjoint write sets, authority check |
860
+ | **`tests/swarm-review.test.js`** | 8 | `TEST-SWARM-B01..B02`, `C01..C02`, `D01..D02` | Separation of duties, provider interceptor, budget cap, context projection |
861
+ | **`tests/visual-manifest.test.js`** | 5 | `TEST-VISUAL-A01..A02`, `B01..B02` | Schema, viewport matrix, environment descriptor, baseline hash integrity |
862
+ | **`tests/visual-diff.test.js`** | 5 | `TEST-VISUAL-C01..C02`, `D01..D02` | Regression diffing, identical hash bypass, dynamic masking, credential mask |
863
+ | **`tests/swarm-visual-purity.test.js`**| 5 | `TEST-SWARM-E01..E02`, `TEST-VISUAL-E01..E02` | Verify read-only purity, offline socket mocking, legacy compatibility |
864
+
865
+ ---
866
+
867
+ ## Explicit Deferred Items
868
+
869
+ 1. **Live Multi-Process Worker Daemon**: Background process supervisors or IPC servers (non-goal).
870
+ 2. **Bundled Headless Browser Binaries**: Heavy Chromium/Playwright binaries inside npm package dependencies (non-goal).
871
+ 3. **Fuzzy AI Aesthetic Grading**: Subjective LLM opinions on UI beauty or styling quality (non-goal).
872
+ 4. **Distributed Swarm Consensus**: Multi-node network consensus protocols (out of scope).
873
+ 5. **Package Version Bump / Release**: Version bumping and npm publishing (strictly post-closure).