What Auxon owns, and what you own
| Auxon | You |
|---|---|
| Guarantees every variant is on-brand before it can go live | Hypothesize, and author the variants |
| Assigns traffic and collects conversions | Choose the goal and the sample target |
| Computes the statistics honestly, and says when they aren’t decision-grade | Read the numbers and call it |
| Splices the winner in with a containment proof | Decide which variant won |
promote. That promotion is the first byte to change on the live page, and it’s unshippable unless it can be proven contained.
1. Create the experiment
draft record at experiments/hero-cta.json and nothing live.
| Flag | Meaning |
|---|---|
--page <slug> | The control page, slug without .html. Required. |
--section <id> | Optional — restrict the test to one data-section rather than the whole page. |
--goal <spec> | Required. The conversion event. |
--target-n <n> | Sample target per arm. Without it, status always reports underpowered: true. |
--split <spec> | e.g. control=50,b=50. Must sum to 100. Defaults to an even split as you add variants. |
--provider <name> | The experiment provider. Defaults to native. |
Declaring the goal
A goal is structural and declared up front — never inferred after the fact. Four forms:| Spec | Fires when |
|---|---|
click:<id> | A click on [data-sk-goal="<id>"] |
route:/path | The visitor reaches that path |
submit:<formId> | That form is submitted |
checkout | A checkout completes |
2. Author the variants
Variants can only be added while the record is adraft.
- Vary one section
- Ingest a whole page
reconcile --section uses, spliced into a copy of the control. It is conformant by construction and contained by construction — a fragment that reaches outside its own section is E_EDIT_OVERREACH and writes nothing.pages/_experiments/<id>/<key>.html, which is excluded from the page walk — they are not site pages. Every variant is conformance-checked the moment it’s recorded.
3. Go live
- The fail-closed conformance gate runs the full verify pipeline over every variant before any side effect. One error-severity failure refuses the start, names the variant and the failing check, and leaves the record
draft. - The provider activates — for
native, the Cloudflare Pages Functions splitter plus its KV config.
4. Read the evidence
native, this is a two-proportion z-test over the counters your edge collected. Per arm it reports exposures, conversions, and rate; per variant against control it reports relative lift, p-value, and a confidence interval on the difference — plus targetReached and underpowered.
Reading it honestly
underpowered: true means not decision-grade yet. It’s set when any arm is below targetN, or when no targetN was declared at all.
Auxon deliberately does not stop you looking. Anti-peeking here is by labeling, not gating: check as often as you like, and the honest flag tells you whether the number is worth acting on. You decide to wait, extend, or end.
The --json envelope is zod-validated and stable, so a dashboard can consume it. It still has no winner in it.
5. Decide
- Promote the winner
- Abort safely
E_EDIT_OVERREACH — the control is untouched and nothing is written. For a whole-page experiment the body is replaced under the same discipline.Then the control marker is restamped clean: provenance recomputed, the experiment block removed, and a wonExperiment: <id> audit note added. Teardown is record-driven and orphan-proof — the splitter surface and the variant directory are removed.Always run --diff first. It builds the exact projection and writes nothing.A live experiment locks its page
Re-authoring a page mid-flight would invalidate the running test, so Auxon prevents it.reconcile --page/--sectionon a locked page →E_RECONCILE_PAGE_UNDER_EXPERIMENT. Nothing is written.- Site-wide reconcile flavors (
--restyle,--messaging,--upgrade-packs) skip the locked page with a warning and process the rest. sitekit inspectsurfaces the lock per page asunderExperiment: <id>.
Self-optimizing sections
The flow above settles once. To make a section keep regenerating against a conversion goal — a living region whose arms rotate as data arrives — add--loop.
Auxon is the guardrail and the gauge; your loop is the hand and the brain. There is no scheduler, no decision, and no model call in Auxon here. It gates each arm for brand conformance, splices it contained, records lineage, and refreshes the splitter. Which arm to spawn, which to kill, and how to weight them is entirely your loop’s call — and your loop authors each fragment with its own model.
Experiments on a site Auxon didn’t build
The same loop runs on WordPress, Squarespace, Next.js, or bespoke — decoupled from Auxon’s hosting and HTML.start prints a script tag you drop onto the page. Assignment and collection happen client-side.
Situational awareness
experiment.integrity flags a live experiment whose variant file is missing, whose data-sk-goal marker is absent, or whose split doesn’t sum to 100. Every subcommand accepts --json.
What’s next
The lifecycle
The other three loops: build, maintain, evolve.
Dynamic HTML generation
Generate a page or a single section per request, at runtime.