@variantlab/core 0.1.4 → 0.1.6

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.
@@ -0,0 +1,306 @@
1
+ # Phase 4 — Advanced (v0.4)
2
+
3
+ **Status**: Not started
4
+ **Goal**: Ship the features that differentiate variantlab from every free tool and most paid ones.
5
+ **Target version**: `0.4.0`
6
+
7
+ ## Table of contents
8
+
9
+ - [Exit criteria](#exit-criteria)
10
+ - [HMAC-signed configs](#hmac-signed-configs)
11
+ - [Crash rollback persistence](#crash-rollback-persistence)
12
+ - [Time-travel replay](#time-travel-replay)
13
+ - [Statistical tools](#statistical-tools)
14
+ - [Remote config improvements](#remote-config-improvements)
15
+ - [Security hardening](#security-hardening)
16
+ - [Milestones](#milestones)
17
+
18
+ ---
19
+
20
+ ## Exit criteria
21
+
22
+ Phase 4 is done when:
23
+
24
+ 1. `variantlab sign` CLI command ships with tests
25
+ 2. Engine verifies signatures via Web Crypto API on all runtimes
26
+ 3. Crash rollback is persistent across sessions when configured
27
+ 4. Time travel "replay" mode works (read-only variant history replay)
28
+ 5. `variantlab distribution` grows into a proper stats tool
29
+ 6. SSE / WebSocket config push is GA (if phase 2 was experimental)
30
+ 7. A third-party security audit is initiated
31
+ 8. The devtools extension goes from beta to stable
32
+ 9. All phase 4 features are documented with examples
33
+
34
+ ---
35
+
36
+ ## HMAC-signed configs
37
+
38
+ See [`hmac-signing.md`](../features/hmac-signing.md) for the full spec. Phase 4 ships:
39
+
40
+ ### Core
41
+
42
+ - [ ] `verifySignature(config, key)` using Web Crypto API
43
+ - [ ] Canonical JSON form per RFC 8785
44
+ - [ ] Key rotation support (multiple keys, key ID prefix)
45
+ - [ ] `onSignatureFailure: "reject" | "warn"` modes
46
+ - [ ] Constant-time verification (from Web Crypto, not hand-rolled)
47
+ - [ ] Tests covering: valid sig, invalid sig, missing sig, tampered body, wrong key
48
+
49
+ ### CLI
50
+
51
+ - [ ] `variantlab sign <file> [--out <file>] [--key <env>]`
52
+ - [ ] `variantlab verify <file> [--key <env>]`
53
+ - [ ] `variantlab rotate-key` helper
54
+ - [ ] Exit codes per docs
55
+
56
+ ### Integration
57
+
58
+ - [ ] Example GitHub Actions workflow that signs on merge
59
+ - [ ] Example S3 + CloudFront deployment guide
60
+ - [ ] Example Cloudflare Workers deployment with KV key storage
61
+ - [ ] Documentation of the threat model
62
+
63
+ ---
64
+
65
+ ## Crash rollback persistence
66
+
67
+ See [`crash-rollback.md`](../features/crash-rollback.md). Phase 4 finalizes:
68
+
69
+ ### Core
70
+
71
+ - [ ] Rollback state persisted to Storage
72
+ - [ ] Rollback state cleared on config version bump
73
+ - [ ] Rollback state cleared on manual reset
74
+ - [ ] `persistent: "forever"` option (never auto-clear)
75
+ - [ ] Engine emits `rollback` events with full context
76
+ - [ ] `engine.getRollbacks()` returns all active rollbacks
77
+ - [ ] `engine.clearRollback(id)` clears one
78
+
79
+ ### Adapters
80
+
81
+ - [ ] `<VariantErrorBoundary>` refined with custom fallback
82
+ - [ ] Automatic crash reporting forward to Telemetry
83
+ - [ ] Native iOS crash hook (via NSException → JS)
84
+ - [ ] Native Android crash hook (via UncaughtExceptionHandler → JS)
85
+ - [ ] Integration with `sentry-expo` (user-supplied adapter)
86
+
87
+ ### Debug overlay
88
+
89
+ - [ ] History tab shows rollback events prominently
90
+ - [ ] "Clear rollback" button per experiment
91
+ - [ ] Simulate rollback button (dev only) for testing
92
+
93
+ ---
94
+
95
+ ## Time-travel replay
96
+
97
+ See [`time-travel.md`](../features/time-travel.md). Phase 4 ships the replay mode:
98
+
99
+ ### Core
100
+
101
+ - [ ] `replaySession(history, newConfig)` pure function
102
+ - [ ] Diff output: which experiments change assignment under new config
103
+ - [ ] Export session as JSON
104
+ - [ ] Import session from JSON
105
+ - [ ] Persistent history (optional)
106
+
107
+ ### Debug overlay
108
+
109
+ - [ ] Replay tab in the overlay
110
+ - [ ] "Import session" file picker
111
+ - [ ] Scrubber for time-based navigation
112
+ - [ ] "Apply this state" button
113
+
114
+ ### Use cases
115
+
116
+ - Regression testing configs before shipping
117
+ - Reproducing user bug reports
118
+ - Migration validation
119
+
120
+ ---
121
+
122
+ ## Statistical tools
123
+
124
+ ### `variantlab distribution` improvements
125
+
126
+ - [ ] Bootstrap simulation (10,000 users by default)
127
+ - [ ] Bucket deviation analysis
128
+ - [ ] Chi-square test for assignment uniformity
129
+ - [ ] JSON output for CI integration
130
+
131
+ ### `variantlab sample-size` — NEW
132
+
133
+ Compute the sample size needed to detect a given effect size:
134
+
135
+ ```bash
136
+ variantlab sample-size --baseline 0.10 --effect 0.02 --power 0.8
137
+ ```
138
+
139
+ Output: minimum users per arm.
140
+
141
+ ### `variantlab power` — NEW
142
+
143
+ Compute statistical power given observed sample size:
144
+
145
+ ```bash
146
+ variantlab power --baseline 0.10 --variant 0.12 --users 1000
147
+ ```
148
+
149
+ ### Not shipping
150
+
151
+ - [ ] ❌ No t-tests / z-tests on actual user data (we don't collect data)
152
+ - [ ] ❌ No dashboard for "how is my experiment doing" (we have no data to show)
153
+ - [ ] ❌ No auto-decision logic (that's a telemetry tool's job)
154
+
155
+ We ship **pre-launch planning tools**, not runtime stats.
156
+
157
+ ---
158
+
159
+ ## Remote config improvements
160
+
161
+ ### SSE GA
162
+
163
+ - [ ] Production-ready `createEventSourceFetcher`
164
+ - [ ] Automatic reconnection with exponential backoff
165
+ - [ ] Connection state in debug overlay
166
+ - [ ] Tests against a test SSE server
167
+
168
+ ### Partial config updates
169
+
170
+ - [ ] Support delta updates: server sends only changed experiments
171
+ - [ ] Merge logic in the engine
172
+ - [ ] Reduces bandwidth for frequent pushes
173
+
174
+ ### Config versioning
175
+
176
+ - [ ] Engine tracks the config version hash
177
+ - [ ] `If-None-Match` + ETag support in `createHttpFetcher`
178
+ - [ ] 304 responses don't reload
179
+
180
+ ### Config caching
181
+
182
+ - [ ] Pluggable cache backends (LRU in-memory, LocalStorage, AsyncStorage)
183
+ - [ ] Cache TTL per config
184
+ - [ ] Manual cache invalidation
185
+
186
+ ---
187
+
188
+ ## Security hardening
189
+
190
+ ### Third-party audit
191
+
192
+ - [ ] Engage a security firm for an audit of the core engine
193
+ - [ ] Focus areas: prototype pollution, HMAC verification, config parsing, DoS vectors
194
+ - [ ] Publish the audit report
195
+
196
+ ### Fuzz testing
197
+
198
+ - [ ] Integrate with OSS-Fuzz or a custom fuzzer
199
+ - [ ] Fuzz the config parser, targeting evaluator, and HMAC verifier
200
+ - [ ] Run fuzz tests in CI nightly
201
+
202
+ ### Supply chain
203
+
204
+ - [ ] All releases signed with Sigstore
205
+ - [ ] SBOMs published per release
206
+ - [ ] Provenance attestation via GitHub Actions OIDC
207
+ - [ ] SLSA level 3 compliance
208
+
209
+ ### CSP strict mode
210
+
211
+ - [ ] Verify variantlab works in CSP-strict environments
212
+ - [ ] Document CSP headers users should set
213
+ - [ ] Tests that exercise CSP violations
214
+
215
+ ---
216
+
217
+ ## Milestones
218
+
219
+ ### M1: HMAC signing end-to-end
220
+
221
+ - Signer
222
+ - Verifier
223
+ - CLI commands
224
+ - Canonicalization
225
+ - Tests
226
+ - Deployment guide
227
+
228
+ Gate: a signed config fetched from a CDN is verified on mobile and rejected if tampered.
229
+
230
+ ### M2: Crash rollback persistence
231
+
232
+ - Storage integration
233
+ - Error boundary refinement
234
+ - Native crash hooks
235
+ - Debug overlay integration
236
+ - Tests
237
+
238
+ Gate: a crashing variant auto-rolls back within 3 crashes; rollback survives app restart; a config update clears it.
239
+
240
+ ### M3: Time travel replay
241
+
242
+ - Replay pure function
243
+ - Diff output
244
+ - Debug overlay UI
245
+ - Tests
246
+
247
+ Gate: a recorded session can be replayed against a different config and the diffs are accurate.
248
+
249
+ ### M4: Statistical tools
250
+
251
+ - Distribution bootstrap
252
+ - Sample size calculator
253
+ - Power analysis
254
+ - Tests
255
+
256
+ Gate: sample-size output matches published statistical tables for common inputs.
257
+
258
+ ### M5: Security audit + hardening
259
+
260
+ - Engage auditor
261
+ - Address findings
262
+ - Publish report
263
+ - Fuzz integration
264
+
265
+ Gate: audit finds no high/critical issues (or they're fixed before release).
266
+
267
+ ### M6: v0.4.0 release
268
+
269
+ - All features shipped
270
+ - Docs updated
271
+ - Migration guide
272
+ - Blog post
273
+
274
+ ---
275
+
276
+ ## Risks
277
+
278
+ ### Risk: HMAC canonicalization bugs
279
+
280
+ Mitigation: use RFC 8785 and test against the published test vectors. Don't hand-roll canonicalization rules.
281
+
282
+ ### Risk: Persistent rollback never clears
283
+
284
+ Mitigation: hard cap on persistent rollback duration (e.g., 7 days) unless explicitly opted in. Clear on config version bump.
285
+
286
+ ### Risk: Security audit surfaces architectural issues
287
+
288
+ Mitigation: the earlier we audit, the cheaper it is to fix. Phase 4 is the right time because the API is stable but not yet v1.
289
+
290
+ ### Risk: Time travel replay doesn't match real behavior
291
+
292
+ Mitigation: replay is read-only and runs the same evaluation code as the engine. If it diverges, that's a bug we fix.
293
+
294
+ ---
295
+
296
+ ## Transition to phase 5
297
+
298
+ Phase 4 exits when:
299
+
300
+ - All advanced features GA
301
+ - Security audit complete
302
+ - Devtools extension stable
303
+ - v0.4.0 published
304
+ - Community is using advanced features in production
305
+
306
+ Phase 5 is the v1.0 stable release: API freeze, long-term support commitment, and polish. See [`phase-5-v1-stable.md`](./phase-5-v1-stable.md).
@@ -0,0 +1,350 @@
1
+ # Phase 5 — v1.0 Stable
2
+
3
+ **Status**: Not started
4
+ **Goal**: Freeze the public API, commit to long-term support, and polish for a stable release.
5
+ **Target version**: `1.0.0`
6
+
7
+ ## Table of contents
8
+
9
+ - [Exit criteria](#exit-criteria)
10
+ - [API freeze](#api-freeze)
11
+ - [LTS commitment](#lts-commitment)
12
+ - [Polish](#polish)
13
+ - [Marketing / launch](#marketing--launch)
14
+ - [Governance](#governance)
15
+ - [Milestones](#milestones)
16
+ - [Post-1.0 roadmap](#post-10-roadmap)
17
+
18
+ ---
19
+
20
+ ## Exit criteria
21
+
22
+ Phase 5 is done when:
23
+
24
+ 1. Every public API is documented with examples
25
+ 2. Every public API is type-safe and has test coverage > 95%
26
+ 3. Every adapter has a working example app in `examples/`
27
+ 4. All known bugs with labels `bug` and severity `high` are fixed
28
+ 5. The npm package metadata is complete (keywords, repository, homepage, author, license)
29
+ 6. Public docs site is live (optional — README is enough)
30
+ 7. Security audit findings are all resolved
31
+ 8. v1.0.0 tag is published
32
+ 9. A public announcement is made (blog post, HN, Reddit, Twitter)
33
+ 10. At least one case study from a non-Drishtikon user is documented
34
+
35
+ ---
36
+
37
+ ## API freeze
38
+
39
+ The public API becomes stable at v1.0. Breaking changes require a major version bump and a formal RFC.
40
+
41
+ ### What "stable" means
42
+
43
+ - **Types**: adding new fields to interfaces is fine. Removing or changing existing fields is breaking.
44
+ - **Hooks**: the signature cannot change. New overloads can be added.
45
+ - **Components**: the prop names cannot change. New props can be added.
46
+ - **Config**: `version: 1` remains supported forever.
47
+ - **Core engine**: the `VariantEngine` interface cannot change.
48
+
49
+ ### Deprecation policy
50
+
51
+ - Deprecated APIs emit a console warning in dev builds
52
+ - Deprecated APIs remain functional for at least one major version
53
+ - Deprecations are documented in the changelog
54
+ - Replacement APIs are documented in the deprecation notice
55
+
56
+ ### What's NOT stable
57
+
58
+ - Internal APIs (modules under `@variantlab/core/internal`)
59
+ - Debug overlay UI (can change look/feel in minor releases)
60
+ - CLI output format (can improve in minor releases)
61
+ - Error message text (but not error types)
62
+
63
+ ---
64
+
65
+ ## LTS commitment
66
+
67
+ v1.0 comes with a Long-Term Support commitment:
68
+
69
+ - **Security patches**: for the latest 2 major versions
70
+ - **Bug fixes**: for the latest major version
71
+ - **Performance improvements**: for the latest major version
72
+ - **New features**: only in the latest major version
73
+
74
+ ### v1.x line
75
+
76
+ - Minor versions (`1.1`, `1.2`, ...) — new features, backward-compatible
77
+ - Patch versions (`1.0.1`, `1.0.2`, ...) — bug fixes only
78
+ - Security patches for v1.x continue until v3.0 ships
79
+
80
+ ### Migration assurance
81
+
82
+ Users on v1.x will never be forced to upgrade to v2.x. When v2 ships, we'll:
83
+
84
+ 1. Document the breaking changes
85
+ 2. Ship a `variantlab migrate` command
86
+ 3. Support v1.x for at least 12 months after v2 ships
87
+
88
+ ---
89
+
90
+ ## Polish
91
+
92
+ ### Documentation
93
+
94
+ - [ ] Every exported function has a JSDoc comment with an example
95
+ - [ ] Every type has a comment explaining its purpose
96
+ - [ ] The `docs/` tree is navigable with a table of contents
97
+ - [ ] `CHANGELOG.md` is up to date and formatted cleanly
98
+ - [ ] `README.md` screenshots/GIFs are updated
99
+ - [ ] Typos are fixed (we'll run a pass with a spell-checker)
100
+
101
+ ### Error messages
102
+
103
+ - [ ] Every error message includes a docs link
104
+ - [ ] Every error has a unique code (e.g., `E_CONFIG_INVALID`)
105
+ - [ ] Error codes are documented in `docs/errors.md`
106
+ - [ ] Errors suggest fixes when possible
107
+
108
+ ### Performance
109
+
110
+ - [ ] Run benchmarks across all hot paths
111
+ - [ ] Publish benchmark results in `docs/performance.md`
112
+ - [ ] Compare against LaunchDarkly, Firebase, GrowthBook (where possible)
113
+ - [ ] Target: core evaluation < 10 µs per experiment
114
+
115
+ ### Bundle size
116
+
117
+ - [ ] Final size audit
118
+ - [ ] Publish bundle size analysis for every package
119
+ - [ ] Compare against competitors
120
+ - [ ] Target: core < 3 KB gzipped
121
+
122
+ ### DX
123
+
124
+ - [ ] IDE autocomplete works smoothly with codegen
125
+ - [ ] TypeScript error messages are helpful, not cryptic
126
+ - [ ] `variantlab init` produces a working project
127
+ - [ ] Example apps are deployable with one command
128
+
129
+ ---
130
+
131
+ ## Marketing / launch
132
+
133
+ ### Pre-launch
134
+
135
+ - [ ] Beta release (1.0.0-beta.1) shared with a small group
136
+ - [ ] Collect feedback for 2-4 weeks
137
+ - [ ] Fix issues
138
+ - [ ] Release candidate (1.0.0-rc.1)
139
+
140
+ ### Launch
141
+
142
+ - [ ] Blog post: "Introducing variantlab"
143
+ - [ ] Hacker News post
144
+ - [ ] Reddit: r/reactnative, r/webdev, r/javascript, r/typescript
145
+ - [ ] Twitter/X thread
146
+ - [ ] Product Hunt launch
147
+ - [ ] Dev.to cross-post
148
+ - [ ] Mailing list announcement (if we have one)
149
+
150
+ ### Materials
151
+
152
+ - [ ] Logo (simple, recognizable)
153
+ - [ ] Social card images
154
+ - [ ] Demo video (< 2 minutes, shows the debug overlay in action)
155
+ - [ ] Example gallery
156
+
157
+ ### Press targets (stretch)
158
+
159
+ - [ ] React Newsletter
160
+ - [ ] JavaScript Weekly
161
+ - [ ] Bytes.dev
162
+ - [ ] This Week in React
163
+
164
+ ### Anti-marketing
165
+
166
+ Things we **won't** do:
167
+
168
+ - ❌ Launch a mailing list to nag users
169
+ - ❌ Buy ads
170
+ - ❌ Sponsor influencers
171
+ - ❌ Gate features behind "contact sales"
172
+ - ❌ Claim unverified benchmarks
173
+
174
+ ---
175
+
176
+ ## Governance
177
+
178
+ ### Maintainers
179
+
180
+ At v1.0, we formalize the maintainer list:
181
+
182
+ - [ ] At least 2 maintainers with publish access (avoid bus factor of 1)
183
+ - [ ] Maintainer responsibilities documented in `GOVERNANCE.md`
184
+ - [ ] Code review policy: 1 approval for minor changes, 2 for breaking
185
+
186
+ ### Decision-making
187
+
188
+ - Minor changes: maintainer discretion
189
+ - Major changes: RFC process
190
+ - Breaking changes: RFC + 2 maintainer approvals + community discussion
191
+
192
+ ### RFC process
193
+
194
+ - RFCs filed as GitHub issues with the `rfc` label
195
+ - Minimum 1 week open for comment
196
+ - Final decision recorded in the issue
197
+ - Implementation PR links back to the RFC
198
+
199
+ ### Code of conduct
200
+
201
+ - [ ] Adopt the Contributor Covenant v2.1
202
+ - [ ] Publish enforcement guidelines
203
+ - [ ] Designate a CoC response team
204
+
205
+ ### Security policy
206
+
207
+ - [ ] `SECURITY.md` specifies the reporting flow
208
+ - [ ] Dedicated security contact (email or form)
209
+ - [ ] 90-day disclosure window
210
+ - [ ] CVE assignment for critical issues
211
+
212
+ ---
213
+
214
+ ## Milestones
215
+
216
+ ### M1: API freeze audit
217
+
218
+ - Review every exported API
219
+ - Remove internal APIs from the public surface
220
+ - Document every public API
221
+ - Tag release candidate
222
+
223
+ ### M2: Polish pass
224
+
225
+ - Fix every `bug`-labeled issue
226
+ - Improve error messages
227
+ - Update docs
228
+
229
+ ### M3: Beta → RC
230
+
231
+ - Ship beta to small group
232
+ - Collect feedback
233
+ - Fix issues
234
+ - Ship RC
235
+
236
+ ### M4: Security audit wrap-up
237
+
238
+ - Resolve any remaining audit findings
239
+ - Publish audit report
240
+
241
+ ### M5: Launch
242
+
243
+ - Publish v1.0.0
244
+ - Blog post
245
+ - Social posts
246
+ - HN + Reddit
247
+ - PH launch
248
+
249
+ ### M6: Post-launch
250
+
251
+ - Monitor issues
252
+ - Address launch-day bugs
253
+ - Write retrospective
254
+
255
+ ---
256
+
257
+ ## Post-1.0 roadmap
258
+
259
+ Ideas for v1.x and beyond, not committed:
260
+
261
+ ### v1.1: Quality of life
262
+
263
+ - Better error messages
264
+ - More example apps
265
+ - More documentation
266
+ - Community-contributed adapters
267
+
268
+ ### v1.2: Advanced targeting
269
+
270
+ - Time-based interpolation (rollout curves)
271
+ - Geolocation via adapter
272
+ - Device capability targeting (GPU tier, RAM)
273
+
274
+ ### v1.3: Analytics integration
275
+
276
+ - First-class adapters for PostHog, Mixpanel, Amplitude, Segment
277
+ - Exposure deduplication
278
+ - Funnel-aware targeting
279
+
280
+ ### v1.4: Collaborative sessions
281
+
282
+ - Real-time multi-device sync (self-hosted)
283
+ - Session sharing for design review
284
+ - Multi-user debug overlay
285
+
286
+ ### v1.5: Cohort targeting
287
+
288
+ - User cohorts defined as saved queries
289
+ - Cross-experiment cohort reuse
290
+
291
+ ### v2.0 (speculative)
292
+
293
+ - Schema v2 with breaking improvements informed by v1 usage
294
+ - Formal migration tooling
295
+ - Possible rename of some types if v1 names turned out to be wrong
296
+ - Released only when v1 has clear limitations, not on a calendar
297
+
298
+ ### Things we'll never add
299
+
300
+ - ❌ A hosted SaaS dashboard
301
+ - ❌ Default telemetry
302
+ - ❌ A full expression language in JSON
303
+ - ❌ Proprietary features
304
+ - ❌ Paid tiers
305
+
306
+ ---
307
+
308
+ ## The v1.0 contract
309
+
310
+ At v1.0, we commit to our users:
311
+
312
+ 1. **The public API is stable.** Breaking changes require a major version.
313
+ 2. **Security patches continue for the latest 2 majors.**
314
+ 3. **No telemetry will ever be added without explicit opt-in.**
315
+ 4. **No paid tier will ever gate existing functionality.**
316
+ 5. **The license stays MIT.** Always.
317
+ 6. **The repo stays open source.** Always.
318
+ 7. **The code stays hand-reviewed.** No auto-merge bots touching source.
319
+ 8. **The size budgets stay.** If a feature can't fit, it doesn't ship.
320
+ 9. **The framework list keeps growing.** We accept reasonable framework adapter contributions.
321
+ 10. **Docs remain first-class.** Every feature ships with its spec.
322
+
323
+ ---
324
+
325
+ ## Definition of done
326
+
327
+ Phase 5 is done when:
328
+
329
+ - v1.0.0 is published on npm
330
+ - The README, docs, and examples match reality
331
+ - A user can go from `npm install @variantlab/react` to a working experiment in under 5 minutes
332
+ - The project has survived its first launch-day traffic without breaking
333
+ - The maintainer team is comfortable with ongoing stewardship
334
+
335
+ When all 5 are true, variantlab is a mature, stable open source project. We shift to maintenance + incremental improvement mode.
336
+
337
+ ---
338
+
339
+ ## Anti-goals for phase 5
340
+
341
+ Things we deliberately avoid at v1.0:
342
+
343
+ - ❌ Shipping "just one more feature" that isn't in the phase plan
344
+ - ❌ Rushing the release to hit an arbitrary date
345
+ - ❌ Skipping the security audit
346
+ - ❌ Over-promising on post-1.0 features
347
+ - ❌ Hiring a community manager
348
+ - ❌ Setting up a Discord (we use GitHub discussions)
349
+
350
+ Quality > velocity at v1.0.