CI Integration — Concepts
Concepts
Section titled “Concepts”Five-minute orientation for the CI integration guides. If you’ve used wt locally, you can skip this page.
What’s a twin
Section titled “What’s a twin”A twin is a self-hosted binary that simulates a SaaS API surface (Stripe, Twilio, GitHub, etc.) with high fidelity. You run it on the same machine as your tests; your tests hit the twin instead of the real vendor. WonderTwin maintains ten community twins (MIT-licensed) and additional pro twins (commercial).
A twin’s behavior is intentionally close to the real vendor’s: same endpoints, same response shapes, same error codes, same idempotency semantics. The differences that matter for CI are:
- Faster — no network latency to the vendor
- Free or flat-rate — no per-call vendor sandbox costs
- Deterministic — given the same seed and input, identical output
- Resettable —
wt runs startwipes state for a clean run - Observable — every request and response is captured for replay
What’s a run
Section titled “What’s a run”A run is the boundary between two CI invocations. A run starts with a clean twin state (or with BYO fixtures), captures every request the twin handles, and ends with a manifest you can download as a build artifact.
The lifecycle:
wt runs start— resets state, optionally applies a seed, optionally loads fixtures, binds arun_id, begins replay capture- your test suite runs — every request to the twin during this window is captured
wt runs finish --export <path>— writes the JSONL bundle (manifest + every entry) to disk
A run_id should uniquely identify the CI invocation — typically ${CI_RUN_ID}-${CI_RUN_ATTEMPT} or equivalent. The id surfaces in telemetry, in the manifest, and in the artifact filename.
What’s in a replay artifact
Section titled “What’s in a replay artifact”A replay.jsonl.gz artifact is a gzipped JSON Lines file:
- Line 1: a manifest —
{twin_name, run_id, started_at, finished_at, entry_count, schema_version} - Lines 2..N: one entry per request to the twin. Each entry has timestamp, method, path, request headers (scrubbed), request body (scrubbed and capped), response status, response headers, response body, duration, and the active quirks list (pro only)
Default scrubbers redact Authorization, X-Api-Key, Stripe-Account, Cookie, Set-Cookie, and JSON fields named password, client_secret, cvc, card[number], etc. Customers shouldn’t see secrets in their replay artifacts; if you do, the scrubber list needs an addition (open an issue).
Replay is captured for free runs and licensed runs alike. The license affects telemetry attribution and (eventually) feature gating, not capture fidelity.
What does a license unlock
Section titled “What does a license unlock”The soft-gate model: everything works without a license. A licensed CI run differs from an unlicensed one in two ways today:
- The startup banner reports
WonderTwin license activeinstead of warning about no license - Telemetry events include
license_idandlicense_ok=true, surfacing in your org’s WonderTwin dashboard for visibility and follow-up
Future licensed-only features may include: production-grade rate-limit enforcement (vs. test-mode), advanced quirks for pinned versions, longer retention of replay artifacts on hosted infrastructure. The CI v2 launch set is the same for both tiers.
License files are signed JSON. Sales issues them. Customers store them as a CI secret and pass the contents to wt license install.
What’s BYO synthetic data
Section titled “What’s BYO synthetic data”wt runs start --fixtures <file> accepts a JSON snapshot blob that conforms to the twin’s existing snapshot schema. The blob populates the twin’s state after reset, before the run begins. Customers who already have synthetic-data generators can pipe their output into a fixtures file and seed the twin with realistic-looking data per run.
This is the integration hook for the future WonderTwin Synthetic Data product. For now, it’s an open contract — you bring the data, we apply it. See product/synthetic-data/synthetic-data-product-integration.md for the full scope.
What’s wt runs wrap
Section titled “What’s wt runs wrap”A convenience wrapper that does the start → user-command → finish-and-export sequence in one shell invocation:
wt runs wrap --seed 42 --export replay.jsonl.gz -- ./run-tests.shUseful for laptop development and shell-script CIs. Less useful for declarative pipelines (GitHub Actions, GitLab CI) where customers want their test step to be its own first-class step. Both patterns are documented in the per-platform guides.
Glossary
Section titled “Glossary”| Term | Meaning |
|---|---|
| Twin | The self-hosted simulator binary |
| Run | The boundary unit; one CI invocation |
| Manifest | First line of a replay JSONL — metadata about the run |
| Entry | One captured request/response in the replay |
| Scrubber | The redaction layer applied to entries before storage |
| Quirk | A toggle for selective behavior adoption (pro only) |
| Soft gate | Everything works unlicensed; license affects telemetry only (current behavior) |
| Fixtures | A snapshot blob loaded into the twin at run start (BYO synthetic data) |
wt | The CLI customers install in CI to drive twins |
Reference
Section titled “Reference”wt runs --helpfor the full CLI surface- strategy.md for the docs strategy and skill plan
- index.md for the platform picker