The build loop settles a page. The experiment loop asks whether it should have.
new + variant  →  start  →  status  →  promote | end
Auxon never picks a winner. experiment status reports exposures, conversions, rates, lift, p-value, confidence interval, and sample sizes. It has no winner field and no recommendation field, by design. You read the evidence and decide.It also never authors a variant. You write them; Auxon guarantees they’re on-brand and contained.

What Auxon owns, and what you own

AuxonYou
Guarantees every variant is on-brand before it can go liveHypothesize, and author the variants
Assigns traffic and collects conversionsChoose the goal and the sample target
Computes the statistics honestly, and says when they aren’t decision-gradeRead the numbers and call it
Splices the winner in with a containment proofDecide which variant won
The control page is never touched until a deliberate 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

sitekit experiment new hero-cta \
  --page index \
  --section hero \
  --goal click:signup \
  --target-n 2000 \
  --split control=50,b=50
This writes a draft record at experiments/hero-cta.json and nothing live.
FlagMeaning
--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:
SpecFires when
click:<id>A click on [data-sk-goal="<id>"]
route:/pathThe visitor reaches that path
submit:<formId>That form is submitted
checkoutA checkout completes
A click goal derives the selector [data-sk-goal="<id>"] — so add that attribute to the CTA you author, or nothing will ever be counted. verify --maintenance flags a live experiment whose goal marker is missing.

2. Author the variants

Variants can only be added while the record is a draft.
sitekit experiment variant hero-cta b --section hero
Your agent authors a new section through the same surgical-edit core that 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.
Variant files land in 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

sitekit experiment start hero-cta
sitekit deploy
Two steps happen in order, gate first, so nothing off-brand can ship:
  1. 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.
  2. The provider activates — for native, the Cloudflare Pages Functions splitter plus its KV config.
start writes the splitter; the deploy ships it. An experiment is not actually running until you sitekit deploy. start prints the one-time setup notes, including the wrangler kv namespace create SK_EXP step.

4. Read the evidence

sitekit experiment status hero-cta
sitekit experiment status hero-cta --json
For 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

sitekit experiment promote hero-cta b --diff   # preview; writes zero bytes
sitekit experiment promote hero-cta b          # apply
For a section experiment, the winner’s section is spliced into the control through the containment proof. An out-of-region byte move is 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 / --section on 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 inspect surfaces the lock per page as underExperiment: <id>.
Resolve the experiment first, then reconcile — and reconcile will correctly report any drift that accrued during the run. A continuous experiment locks only its section, not the page.

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.
sitekit experiment new form-cta --page index --section cta \
  --goal submit:contact --loop --max-arms 6 --may-vary "headline + CTA copy only"

sitekit experiment arm add form-cta b --fragment ./gen/b.html
sitekit experiment start form-cta && sitekit deploy

# each cycle, driven by your loop — not by Auxon:
sitekit experiment status form-cta --json
sitekit experiment arm add form-cta d --fragment ./gen/d.html
sitekit experiment arm retire form-cta b
sitekit experiment arm rebalance form-cta
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.
Retired arms are kept rather than deleted, so lineage survives.

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.
sitekit experiment new pricing-hero \
  --region "#hero" \
  --target-url https://example.com/pricing \
  --collector-endpoint https://collect.example.com

sitekit experiment variant pricing-hero b --region "#hero" --from ./drafts/hero-b.html
sitekit experiment start pricing-hero
# then embed the printed <script> tag on the target page
sitekit experiment status pricing-hero
You target a CSS selector rather than a section id, and start prints a script tag you drop onto the page. Assignment and collection happen client-side.
On a foreign site promote is report-only — Auxon can’t write to a page it doesn’t own. It tells you exactly what won and what to change; applying it is yours.

Situational awareness

sitekit experiment list           # every record + status
sitekit inspect --json            # site-wide, including per-page underExperiment
sitekit verify --maintenance      # surfaces the experiment.integrity check
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.