Portal
Documentation: all sections

Sable Autopilot

Autopilot watches an account's real metered usage, proposes a cheaper or faster Model Foundry configuration, and proves the swap is safe by running your eval suite against both the current and the proposed spec and showing the receipted comparison. One action adopts it. One action rolls it back.

Autopilot is built and tested. It is not on the production deployment yet, so the calls below describe a surface you cannot reach at api.buildsable.com today.

It never changes anything on its own

That is the design constraint, not a caveat. An optimizer that silently rerouted traffic would destroy the proposition the whole gateway rests on: a signed receipt is worth something only because nobody moved the thing it describes.

So Autopilot produces a proposal with evidence attached and stops. Adoption is an explicit owner action at Admin — the same bar publishing a foundry version sets, because it changes what foundry/<slug> does for every caller in the account, live. And a proposal whose evidence says regression cannot be adopted by anyone, with no override, ever.

Adoption goes through the Foundry's own handlers in process. Autopilot does not write a single row of foundry_builds itself, so version numbering under the family lock, the never-reused version rule, the at-most-one-published constraint, ownership checks on the referenced policy and rule sets, the sealed prompt and the spec digest are all still enforced by the code that owns them. Autopilot is a caller of the Foundry, exactly as a human with a browser is.

Rollback needs no machinery

The version that was published before adoption was never mutated, so publishing it again restores the previous configuration exactly. The adopt response names that call for you:

"rollback": {
  "method": "POST",
  "path": "/v1/foundry/builds/<previous build id>/publish",
  "restores_spec_sha256": "9f3a…",
  "note": "Publishing the previous version again restores the exact configuration this replaced — the row was never mutated, so nothing about it was lost."
}

The repricing guard

An optimizer that always finds a saving is a tell that it is guessing.

Before projecting any saving, Autopilot reprices the baseline's own observed token mix at catalogue prices and compares the result to what the account was actually billed. If the two disagree by more than the allowed divergence, no proposal is produced at all and the divergence is reported as repricing_disagrees with all four numbers.

This is the load-bearing honesty mechanism. Several real things make the two figures diverge — a flagship id whose engine chain served a different upstream than the id's own list price, prompt-cache passthrough discounts, a fleet node's self-report being clamped, a margin change mid-window — and in every one of those cases the arithmetic Autopilot is about to project with is not the arithmetic that billed.

If it cannot reproduce the bill you already have, it has no business predicting the bill you would have had.

The same conservatism runs through every other threshold. Each refusal is a fixed class carrying the figures that decided it:

ClassMeaning
no_trafficNothing ran against this build's base model in the window.
too_few_requestsThe token mix is still noise.
too_little_spendAny saving would be smaller than the cost of the evidence runs that would justify it.
repricing_disagreesThe guard above.
no_eligible_candidateCandidates were considered; none can carry this traffic — its largest prompt, its modality, or its confidentiality tier rules them out.
saving_below_thresholdA cheaper candidate exists, but the saving is inside the noise of a shifting token mix.

What the analysis is allowed to know

Only figures Sable actually has: real usage_events for the account in the window (request counts, prompt and completion tokens, billed cost, observed latency); real catalogue prices with the deployment's own margin applied, so a projection is in the units you are actually charged; and real observed latency, only for models this account has itself run in the same window. Autopilot never quotes a latency for a model it has not served — that would be an invention, and an invention is the one thing this feature cannot afford.

There is no quality model. Autopilot does not know, guess, or imply that one model is as good as another. That question is answered by your eval suite, on your own cases, and by nothing else. A proposal without evidence is a priced hypothesis, and the API says exactly that.

Attribution, honestly

usage_events.model records the base model, because a foundry build rewrites the request's model id to the base model before anything is metered. A build's traffic is therefore not separately attributable, and a window's figures describe every call to that base model on the account — foundry-routed or not.

Every proposal carries "attribution": "base_model" and says this in plain words. It is not a defect to be hidden; it is a bound on what the figures mean.

Evidence

Both arms execute your eval suite through the ordinary in-process chat path, under one of your own API keys. Holds, spend caps, key policy, guardrails, metering and signed receipts all apply with no new enforcement code — which is what makes the pass rates mean anything at all: they were produced by the same path a paying request takes. Each arm's receipts are chained into one run id, so GET /v1/runs/{id} folds a whole arm into a head hash a third party can verify.

VerdictMeaningAdoptable
equivalentThe candidate scored at least as well as the baseline, within tolerance.yes
improvementThe candidate scored better.yes
inconclusiveThe comparison could not be made: too few cases, or an arm where some case never produced a completion. A model we could not reach did not score zero.only with acknowledge_no_evidence
regressionThe candidate scored worse.never, by anybody

inconclusive is a real, expected outcome. It is never presented as equivalent, and it does not by itself authorise adoption — the honest statement there is nobody has checked, not it is worse, which is why an owner may override it and may never override a regression.

The default equivalence tolerance is zero basis points: any drop in pass rate is a regression. A suite too small to tell noise from signal should say so through the minimum-cases threshold, not be papered over with a tolerance.

Honesty box

Proven: that on these declared cases, at this time, the candidate scored this much against the baseline, with both arms run through the ordinary metered, receipted path and every receipt chained into a verifiable run.

Not proven: that the candidate is better in general, that it will hold on traffic the suite does not cover, or that the projected saving will be realised on a token mix that changes — a cheaper model that needs more output tokens to say the same thing will not save what is projected. A proposal is a priced hypothesis, never an instruction.

Evidence is opt-in and costs money

Passing an eval_suite_id runs your suite twice — once per arm, per case — through the real billed path. That is the point, and it is also a bill, so it never happens implicitly and never happens on the background pass. One analyze call gathers evidence for at most four proposals; the rest are reported in evidence_skipped with the call that would cover them.

Evidence runs are capped at 50 cases and 512 completion tokens per case.

Quickstart

# Priced hypotheses only: no eval_suite_id, so nothing extra is billed.
curl -s https://api.buildsable.com/v1/autopilot/analyze \
-H "Authorization: Bearer $SESSION" \
-H "Content-Type: application/json" \
-d '{"window_days": 7}'

# {
#   "window_days": 7,
#   "targets": [{"target":"triage","observed":{…},"analysis":{…},"minted":["…"]}],
#   "proposals": [ … ],
#   "evidence_gathered": false,
#   "note": "No evidence was gathered. Each proposal is a priced hypothesis; pass an
#            `eval_suite_id` to run your own suite against both configurations before adopting.",
#   "trust_model": "An Autopilot proposal is a PRICED HYPOTHESIS, never an instruction…"
# }

What adoption refuses

ClassMeaningOverridable
not_openAlready decided. Decisions are not re-run.no
spec_movedThe published spec is no longer the one this proposal reasoned about, so its figures describe a configuration that is not there any more.no
spec_corruptThe stored candidate spec does not hash to its recorded digest.no
spec_driftThe version drafted from the proposal hashes to something other than what was promised. The draft is left unpublished and named, and the model id still serves what it served before.no
evidence_regressionThe candidate passed fewer basis points of your own suite than the baseline.never
no_evidenceNobody has checked.acknowledge_no_evidence
evidence_inconclusiveEvidence exists but could not establish equivalence.acknowledge_no_evidence

The spec_drift check runs between drafting and publishing: if a catalogue move or a revoked policy changed the digest, publishing anyway would make the whole audit trail decorative. Adoption also refuses if the published build's system prompt is not the one the proposal was built from — Autopilot swaps the base model and carries the prompt across verbatim, so a fingerprint that does not match means the two have drifted.

Adopting supersedes every other open proposal for the same target, because they all reasoned about the spec that was just replaced.

reject is refused on a proposal that was adopted: an adoption is a published foundry version, and pretending it had been rejected would make the record disagree with what the model id actually serves.

Verify a proposal without trusting the API

Configuration

VariableDefaultMeaning
SABLE_AUTOPILOT_WINDOW_DAYS7Observation window.
SABLE_AUTOPILOT_MIN_REQUESTS50Below this the token mix is noise.
SABLE_AUTOPILOT_MIN_SPEND_MICRO_USD100000Below this a saving cannot pay for the evidence.
SABLE_AUTOPILOT_MIN_SAVING_BPS1000Smallest saving worth proposing (10%).
SABLE_AUTOPILOT_MAX_REPRICE_DIVERGENCE_BPS1000How far the repricing may miss the real bill before Autopilot refuses to project.
SABLE_AUTOPILOT_MIN_LATENCY_SAMPLES20Observed requests needed before a latency claim.
SABLE_AUTOPILOT_MIN_LATENCY_GAIN_BPS2000Smallest latency gain worth proposing (20%).
SABLE_AUTOPILOT_MIN_EVIDENCE_CASES5Below this a suite cannot establish equivalence.
SABLE_AUTOPILOT_EQUIVALENCE_TOLERANCE_BPS0Pass-rate drop tolerated before it is a regression.
SABLE_AUTOPILOT_PROPOSAL_TTL_DAYS14An open proposal older than this goes stale.
SABLE_AUTOPILOT_TICK_MAX_ACCOUNTS50Accounts refreshed per background pass.

Endpoints

MethodPathRoleNotes
POST/v1/autopilot/analyzeMemberLook at real usage now and propose. Body: {targets?, window_days?, eval_suite_id?, api_key_id?}. Spends credit when a suite is attached.
GET/v1/autopilot/proposalsViewerOpen and decided proposals.
GET/v1/autopilot/proposals/{id}ViewerOne proposal with all of its evidence, plus applies_to_current_spec.
POST/v1/autopilot/proposals/{id}/adoptAdminPublish the proposed configuration as a new foundry version. Body {acknowledge_no_evidence?, name?}.
POST/v1/autopilot/proposals/{id}/rejectMemberClose without adopting. Idempotent; refused on an adopted proposal.

Privacy posture

Proposals and evidence are metadata: model ids, catalogue prices, token counts, pass rates in basis points, receipt request ids, spec hashes, run ids. No prompt, completion, eval case input or model output ever enters these tables — and that explicitly includes reason, which is a fixed class, and figures, which holds numbers.

Eval cases are read in-frame to build a request and are never copied here; each arm's output is scored and dropped, exactly as chat drops it. The candidate spec is a foundry canonical spec, which is content-free by construction: the system prompt appears in it only as its sha256. See the privacy contract.