Engine 0782f26c (0782f26c26d57047a29fcf16506b8c489a7f7c6d) · 25 Oct 2026, 18:38 UTC

Assure decides 53 of 61 promises about itself: 51 hold, 2 disproven, 8 not established.
Premised: A1, A4 and G5.

Holds: True of this release.
Not established: Not shown either way yet.
Disproven: This release breaks it.
From the code: Checked against Assure's own source.
From a run record (premised): An outcome we measure each release, such as how setup went.

## Holds (51)

51 promises, each read from the code.

### What the live API answers

| Promise | Reading | Kind | Says | How it was read | What was read and why | Evidence |
|---|---|---|---|---|---|---|
| R1 | holds | formal | Every answer tells browsers to speak to this API over HTTPS only. | Read from the code and the live API's answers | We sent requests to api.symbolia.ai and to our own server code, and every answer read (/healthz, /, /v1/profiles) tells browsers to use HTTPS only. | serve/api.py, deploy/Caddyfile (assure/checkers/http-observed-baseline/PROFILE.json#obligations/HTTP-STS-PRESENT) @ 0782f26c |
| R2 | holds | formal | No answer states both its length and that it is sent in chunks. | Read from the code and the live API's answers | We sent requests to api.symbolia.ai and to our own server code, and every answer read (/healthz, /, /v1/profiles) states its length or says it is chunked, never both. | serve/api.py, deploy/Caddyfile (assure/checkers/http-observed-baseline/PROFILE.json#obligations/HTTP-FRAMING-CL-TE) @ 0782f26c |
| R3 | holds | formal | Answers that describe the service are never stored by anything between the server and the customer. | Read from the code and the live API's answers | We sent requests to api.symbolia.ai and to our own server code, and every answer read (/healthz, /, /v1/profiles) tells anything in between not to store it. | serve/api.py, deploy/Caddyfile (assure/checkers/http-observed-baseline/PROFILE.json#obligations/HTTP-CACHE-NO-STORE) @ 0782f26c |
| R4 | holds | formal | Browsers are told to take an answer's declared type at its word and never guess it from the bytes. | Read from the code and the live API's answers | We sent requests to api.symbolia.ai and to our own server code, and every answer read (/healthz, /, /v1/profiles) tells browsers not to guess its type. | serve/api.py, deploy/Caddyfile (assure/checkers/http-observed-baseline/PROFILE.json#obligations/HTTP-NOSNIFF-PRESENT) @ 0782f26c |
| R5 | holds | formal | The API never sets a cookie. | Read from the code and the live API's answers | We sent requests to api.symbolia.ai and to our own server code, and every answer read (/healthz, /, /v1/profiles) sets no cookie. | serve/api.py, deploy/Caddyfile (assure/checkers/http-observed-baseline/PROFILE.json#obligations/HTTP-NO-SET-COOKIE) @ 0782f26c |
| R6 | holds | formal | A key issued to one account cannot read another account's verdicts. | Read from the code | We read every route and handler of our API server (serve/) and found that every stored item is looked up under the account of the key that asks for it. | assure/checkers/identity/adapters/python_stdlib_http/fixtures/assure-self/requirements.md:50 @ 0782f26c |
| R7 | holds | formal | An API key is never written to any log line. | Read from the code | We read every route and handler of our API server (serve/) and found that no log line writes a key; the request log records the key's id, never the key. | assure/checkers/identity/adapters/python_stdlib_http/fixtures/assure-self/requirements.md:43 @ 0782f26c |

### Getting to value

| Promise | Reading | Kind | Says | How it was read | What was read and why | Evidence |
|---|---|---|---|---|---|---|
| A2 | holds | formal | Every run tells the customer something useful, including a refused one, and names one next step. | Read from the code | We read every message our API sends (serve/render.py), and each of the 31 ways a run can end, refusals included, names a next step. | serve/render.py (next_step, failure_markdown, pr_refusal_markdown, summary_markdown, pr_comment_markdown) @ 0782f26c |

### Who can reach what

| Promise | Reading | Kind | Says | How it was read | What was read and why | Evidence |
|---|---|---|---|---|---|---|
| B1 | holds | formal | Without a key, someone reaches only what is meant to be public, and each public route is reached only by the means it is meant for: a signature, a signed link, or nothing sensitive. | Read from the code | We read every route and handler of our API server (serve/) and found that without a key only /healthz and the routes meant to be public answer, each by its own means: a signature, a signed link, or nothing sensitive. | assure/checkers/identity/adapters/python_stdlib_http/fixtures/assure-self/requirements.md:5 @ 0782f26c |
| B2 | holds | formal | Every other request needs a valid API key. | Read from the code | We read every route and handler of our API server (serve/) and found that every other route needs a valid API key. | assure/checkers/identity/adapters/python_stdlib_http/fixtures/assure-self/requirements.md:5 @ 0782f26c |
| B3 | holds | formal | Once a key is revoked, the very next request made with it is turned away. | Read from the code | We read every route and handler of our API server (serve/) and found that each request reads the key's current state, so a revoked key is turned away on its next use. | assure/checkers/identity/adapters/python_stdlib_http/fixtures/assure-self/requirements.md:36 @ 0782f26c |
| B4 | holds | formal | Every key has an expiry set when it is issued; responses say when it expires and warn before it does; an expired key is turned away. | Read from the code | We read every route and handler of our API server (serve/) and found that every key is issued with an expiry, responses carry it and warn before it, and an expired key or one without an expiry is turned away. | assure/checkers/identity/adapters/python_stdlib_http/fixtures/assure-self/requirements.md:11 @ 0782f26c |
| B5 | holds | formal | Rotating a key brings the new key in and retires the old one after a stated window, and never leaves an account without a working key. | Read from the code | We read every route and handler of our API server (serve/) and found that rotation issues the new key first and retires the old one only after the stated window. | assure/checkers/identity/adapters/python_stdlib_http/fixtures/assure-self/requirements.md:47 @ 0782f26c |
| B6 | holds | formal | A paid action runs only when the plan, balance or agreed overage covers it. | Read from the code | We read every route and handler of our API server (serve/) and found that every paid route checks the plan, balance or agreed overage before doing the work. | assure/checkers/identity/adapters/python_stdlib_http/fixtures/assure-self/requirements.md:48 @ 0782f26c |
| B7 | holds | formal | A proof-tree link opens only if the server signed it, only until it expires, and never after the verdict has been deleted. | Read from the code | We read every route and handler of our API server (serve/) and found that a proof-tree link opens only when we signed it, it has not expired and the verdict is still kept. | assure/checkers/identity/adapters/python_stdlib_http/fixtures/assure-self/requirements.md:31 @ 0782f26c |
| B8 | holds | formal | A billing event is applied only when its signature verifies and the event is recent. | Read from the code | We read every route and handler of our API server (serve/) and found that a billing event is applied only when its signature checks out and it is recent. | assure/checkers/identity/adapters/python_stdlib_http/fixtures/assure-self/requirements.md:46 @ 0782f26c |
| B9 | holds | formal | Every signing or verification key comes from configuration. | Read from the code | We read every route and handler of our API server (serve/) and found that every signing and verification key is read from configuration, never written in the code. | assure/checkers/identity/adapters/python_stdlib_http/fixtures/assure-self/requirements.md:10 @ 0782f26c |
| B10 | holds | formal | Every stored item belongs to one account; no other account can read it or tell that it exists. | Read from the code | We read every route and handler of our API server (serve/) and found that every stored item is opened only under its own account, and another account gets the same answer as if it did not exist. | assure/checkers/identity/adapters/python_stdlib_http/fixtures/assure-self/requirements.md:50 @ 0782f26c |

### What a verdict is

| Promise | Reading | Kind | Says | How it was read | What was read and why | Evidence |
|---|---|---|---|---|---|---|
| C1 | holds | formal | A requirement reads holds, not established or disproven. | Read from the code | We read the verdict code (assure/checkers/identity/grade.py), and it has exactly three readings: holds, not established and disproven. | assure/checkers/identity/grade.py:51 @ 0782f26c |
| C2 | holds | formal | Nothing reads holds when there was nothing to check; it reads not established. | Read from the code | We read the verdict code (assure/checkers/identity/grade.py), and every case with nothing to check reads not established. | assure/checkers/identity/grade.py:53 @ 0782f26c |
| C3 | holds | formal | Nothing reads disproven unless the code really breaks the rule; a route whose purpose is not known reads not established. | Read from the code | We read the verdict code (assure/checkers/identity/grade.py), and only a found break reads disproven; anything not understood reads not established. | assure/checkers/identity/grade.py:53 @ 0782f26c |
| C4 | holds | formal | The engine checks that its own code matches its pin before it runs. | Read from the code | We read the server start-up (serve/api.py, serve/worker.py, serve/check.py), and it checks the engine's pin before loading the engine. | serve/api.py:3630; serve/worker.py:425; serve/check.py:753 @ 0782f26c |
| C5 | holds | formal | Every verdict names the engine version it ran on. | Read from the code | We read how verdicts are built (serve/envelope.py, serve/check.py), and every verdict carries the engine version it ran on. | serve/envelope.py:1571; serve/check.py:226; serve/worker.py:162; serve/worker.py:437; serve/api.py:1084; serve/api.py:1061 @ 0782f26c |
| C6 | holds | formal | The limits the API publishes are the limits it enforces. | Read from the code | We read the API (serve/api.py, serve/bundle.py), and the limits it publishes are the same values it enforces. | serve/api.py:610; serve/api.py:1857; serve/bundle.py:194; serve/bundle.py:606; serve/api.py:543; serve/meter.py:2219; serve/meter.py:2264 @ 0782f26c |
| C7 | holds | formal | An account cannot create a volume of requests beyond reliable limits. | Read from the code | We read the API (serve/api.py), and every request that creates work passes a rate limit first. | serve/api.py:399 @ 0782f26c |
| C8 | holds | formal | Sending the same check twice with the same idempotency key returns the first check and is not charged again. | Read from the code | We read the check route (serve/api.py, serve/store.py), and a repeated idempotency key returns the first check before any charge. | serve/api.py:2197; serve/store.py:892 @ 0782f26c |
| C10 | holds | formal | When a checker can model only the first few of something, everything past that point reads not established with the bound named. | Read from the code | We read the checker's limits (assure/checkers/identity/explore.py), and past each limit the result reads not established and names the limit. | assure/checkers/identity/explore.py:301; serve/profiles.py:1484 @ 0782f26c |

### How a job runs

| Promise | Reading | Kind | Says | How it was read | What was read and why | Evidence |
|---|---|---|---|---|---|---|
| D1 | holds | formal | A job completes at most once. | Read from the code | We explored every state our job queue can reach (hosted/MACHINE.json) and found that a job completes at most once. | hosted/MACHINE.json#invariants/completes_at_most_once @ 0782f26c |
| D2 | holds | formal | A worker whose lease has lapsed writes nothing. | Read from the code | We explored every state our job queue can reach (hosted/MACHINE.json) and found that a worker whose lease has lapsed writes nothing. | hosted/MACHINE.json#invariants/stale_lease_never_writes @ 0782f26c |
| D3 | holds | formal | Two workers never claim the same job. | Read from the code | We explored every state our job queue can reach (hosted/MACHINE.json) and found that two workers never hold the same job. | hosted/MACHINE.json#invariants/claim_exclusive @ 0782f26c |
| D4 | holds | formal | A job is attempted at most its allowed number of times. | Read from the code | We explored every state our job queue can reach (hosted/MACHINE.json) and found that a job is never attempted more than its allowed number of times. | hosted/MACHINE.json#invariants/attempts_bounded @ 0782f26c |
| D5 | holds | formal | A job is retried only when the failure was not its own; a refusal is final. | Read from the code | We explored every state our job queue can reach (hosted/MACHINE.json) and found that a refused job is never retried. | hosted/MACHINE.json#invariants/refusal_never_retried @ 0782f26c |
| D6 | holds | formal | Every way a job can end records a typed outcome. | Read from the code | We explored every state our job queue can reach (hosted/MACHINE.json) and found that every ending records a typed outcome. | hosted/MACHINE.json#invariants/exit_typed_outcome @ 0782f26c |
| D7 | holds | formal | A job moves only along the allowed path. | Read from the code | We explored every state our job queue can reach (hosted/MACHINE.json) and found that every move is one of the allowed moves. | hosted/MACHINE.json#transitions @ 0782f26c |
| D8 | holds | formal | If a worker is interrupted mid-job, nothing is written. | Read from the code | We explored every state our job queue can reach (hosted/MACHINE.json) and found that an interrupted job writes nothing. | hosted/MACHINE.json#invariants/interrupt_writes_nothing @ 0782f26c |

### What happens to a customer's data

| Promise | Reading | Kind | Says | How it was read | What was read and why | Evidence |
|---|---|---|---|---|---|---|
| E1 | holds | formal | Only what a check needs leaves the customer's runner, never raw rows, names or values. | Read from the code | We read what the runner sends (action/collect.py, serve/bundle.py), and the raw files are held back on the runner; only what the check needs leaves it. | serve/bundle.py (RUNNER_ONLY, from_directory), action/collect.py (_gather) @ 0782f26c |
| E2 | holds | formal | The facts collected for a check are deleted when the check ends; on a paid plan one sealed copy is kept, encrypted for that account alone. | Read from the code | We read the worker (serve/worker.py, serve/bundle_keep.py), and it deletes the check's files on every exit, keeping one sealed copy only on a paid plan. | serve/worker.py (run_in_child), serve/bundle_keep.py (keep, includes_premium, PREMIUM_TIERS) @ 0782f26c |
| E3 | holds | formal | What we keep is minimal and kept briefly, then deleted with everything that belongs to it. | Read from the code | We read our data-keeping rules (hosted/data_rule.py) and found that each kind of kept data has a short limit or ends with the tier or account it belongs to. | hosted/data_rule.py @ 0782f26c |
| E5 | holds | formal | Using de-identified configuration data to improve the product is on by default for the free tier and off by default for paid tiers, and one setting changes it. | Read from the code | We read our data-keeping rules (hosted/data_rule.py) and found that product use of de-identified data is on by default for free, off for paid, and one setting changes it. | hosted/data_rule.py @ 0782f26c |
| E6 | holds | formal | An enterprise account keeps none of its code or collected facts after the check ends. | Read from the code | We read our data-keeping rules (hosted/data_rule.py) and found that an enterprise account keeps none of its code or collected facts after a check. | hosted/data_rule.py @ 0782f26c |
| E8 | holds | formal | Feedback and telemetry are kept only as long as they are useful, and never a requirement's text. | Read from the code | We read our data-keeping rules (hosted/data_rule.py) and found that feedback and telemetry are kept 12 months and neither keeps a requirement's text. | hosted/data_rule.py @ 0782f26c |
| E9 | holds | formal | A customer's private model is deleted when they ask, and soon after the account closes. | Read from the code | We read our data-keeping rules (hosted/data_rule.py) and found that a private model is deleted on request and 30 days after the account closes. | hosted/data_rule.py @ 0782f26c |

### Money

| Promise | Reading | Kind | Says | How it was read | What was read and why | Evidence |
|---|---|---|---|---|---|---|
| F1 | holds | formal | An account's plan and charges change only by something it agreed to or was given, and never twice for the same event. | Read from the code | We read our billing code (serve/billing_machine.py) and found that each billing event is applied once, a repeat changes nothing, and the plan moves only by an event or a gift. | serve/billing_machine.py @ 0782f26c |
| F2 | holds | formal | When a customer leaves a paid plan, what was kept for it is deleted. | Read from the code | We read our billing code (serve/billing_machine.py) and found that leaving a paid plan deletes what was kept for it. | serve/billing_machine.py @ 0782f26c |
| F4 | holds | formal | Overage is charged at the published rate, and only within the budget the customer agreed. | Read from the code | We read our billing code (serve/billing_machine.py) and found that overage is charged at the published rate and refused past the agreed budget. | serve/billing_machine.py @ 0782f26c |
| F5 | holds | formal | Every ledger is append-only, and every total is recomputed from its entries. | Read from the code | We read our billing code (serve/billing_machine.py) and found that every ledger only ever grows, and every total is worked out again from its entries. | serve/billing_machine.py @ 0782f26c |
| F6 | holds | formal | A customer can always see their plan and what each check cost them. | Read from the code | We read the usage route and cost records (serve/api.py, serve/meter.py), and an account's plan and every check's cost come from its own ledger. | serve/api.py _usage; serve/meter.py check_costs; persisted customer ledgers @ 0782f26c |
| F7 | holds | formal | A statement shows the same figures a real bill would. | Read from the code | We produced statements (serve/billing.py) for a gifted account and a paid one, and each showed the figures a real bill would. | serve/billing.py @ 0782f26c |

### What a customer reads

| Promise | Reading | Kind | Says | How it was read | What was read and why | Evidence |
|---|---|---|---|---|---|---|
| G2 | holds | formal | No file a customer reads or commits carries an internal flag or marker. | Read from the code | We read the 45 files a customer reads or commits (docs, action, skills), and none carries an internal flag or marker. | action/build_dist.py (RECORD_RE, FLAG_LINE) @ 0782f26c |
| G3 | holds | formal | Every refusal names what was refused and the field or input that fixes it. | Read from the code | We read all 558 places our API and Action refuse (serve/, action/), and each names what was refused and why. | serve/outcomes.py (_TABLE, Refusal.__init__) @ 0782f26c |
| G4 | holds | formal | Every served profile answers in readable words on its first run, in its verdict, its summary and its pull-request comment. | Read from the code | We ran every profile we serve on its first run (serve/profiles), and each answered in readable words in its verdict, summary and pull-request comment. | serve/PROPERTIES.json; serve/profiles/*.json; tests/checkers/fixtures/http/flaskr-intent-001; tests/serving/fixtures/mysql-declared/positive; tests/serving/fixtures/run-37121027064; tests/serving/fixtures/run-37121027064; tests/checkers/fixtures/python-auth/flask-session-a @ 0782f26c |

## Not established (7)

7 promises read from the code that Assure could not decide. Each says what is missing.

| Promise | Reading | Kind | Says | How it was read | What was read and why | Evidence |
|---|---|---|---|---|---|---|
| A3 | not established | formal | The pre-flight predicts the check; it never says the code is ready when the check cannot read it. | Read from the code | We replayed unreadable code and route tables for two app types (serve/lint.py, serve/input_readers.py), and the pre-flight never said ready; those replays do not cover every kind of app we serve. | serve/lint.py; serve/input_readers.py; serve/profiles.py; tests/checkers/identity/fixtures/adapter-2-fastapi/positive @ 0782f26c |
| B11 | not established | formal | Keys and signing values are never written to logs, records or responses. | Read from the code | We read how keys are stored (serve/keys.py): issuing a key stores only a fingerprint of it, but we could not yet follow the key through rotation, so this is not yet shown. | assure/checkers/identity/adapters/python_stdlib_http/fixtures/assure-self/requirements.md:43 @ 0782f26c |
| B12 | not established | formal | POST /v1/checks and POST /v1/declaration-proposal refuse a request whose declared size exceeds the account's plan limit (Free 6 MiB, Premium 24 MiB, Pro 64 MiB) before any request content is read, and the refusal names the plan that fits. | Read from the code | Nothing in our checks reads this promise yet. | - @ 0782f26c |
| C9 | not established | formal | The API and the check process never contact anything outside the server. | Read from the code | We read the worker (serve/worker.py), but part of the code it loads is outside what this read covers, so it is not yet shown that nothing outside is contacted. | serve/worker.py:58 @ 0782f26c |
| E7 | not established | formal | Backups keep only what is needed to restore accounts and billing, briefly, and never a customer's verdicts or collected facts. | Read from the code | We looked for a backup job and found none; the backup rule is written down (hosted/data_rule.py) but nothing runs it yet. | hosted/data_rule.py (RESTORE_ONLY, declared) @ 0782f26c |
| F3 | not established | formal | No one is charged beyond what they agreed: overage starts at zero, only a person's yes turns it on, the customer is told as it nears the budget, and it is never raised for them. | Read from the code | The overage budget this promise needs is not in this release yet, so there is nothing to read. | serve/billing_machine.py @ 0782f26c |
| G1 | not established | formal | A drafted goal never claims more than its checks prove, and says what it covers. | Read from the code | The goal drafter this promise is about is not in this release yet, so there is nothing to read. | - @ 0782f26c |

## Read from a run record (3)

These 3 promises are about measured outcomes rather than code. We state them as Assure's own customer, and each release reads them from the latest record of a measured run.

A1 and A4 are disproven, read from the record of the 22 Oct setup run. They measure how setup went on sample apps, not the code: no promise read from the code is disproven. Each row below says what was found and what it means for you.

| Promise | Reading | Kind | Says | How it was read | What was read and why | Evidence |
|---|---|---|---|---|---|---|
| A1 | disproven | premised | Anyone can set Assure up from one line, and is asked only what only they can answer, each question with its tradeoff. | Read from a run record | We read the record of our v0.1.3 setup measurement on ten sample apps, which keeps the questions each setup agent asked (carried from our 17 October run); v0.1.4 was not measured again, so this reading is carried from v0.1.3. Most of the setup questions were about how the product works, not something only the customer knows, and none came with its tradeoff. Setup may ask you things it should work out itself, and you may have to answer without being told what each choice costs. Tracked as #3089. What we state: Each setup agent asked the person only what only they could answer, and gave the tradeoff of each question. Record: docs/validation/setup-qual/runs/20261022T222243Z-v0.1.3/results.jsonl, 2026-10-22 (the setup measurement at 22:22Z; the questions are the ones the setup agents asked in the run of 2026-10-17). This reading comes from a record of a run, not from reading our code, so it is only as good as that run: it tells you how setup went on ten sample apps, not how it will go on yours. | docs/validation/setup-qual/runs/20261022T222243Z-v0.1.3/results.jsonl @ 0782f26c |
| A4 | disproven | premised | A fresh agent working from the one line gets a correct result on at least 6 of 10 qualification apps, and each other app is reachable through Assure's shipped extension paths. | Read from a run record | We read the record of our v0.1.3 setup measurement on ten sample apps, each with a known flaw added, to see whether the check found it; v0.1.4 was not measured again, so this reading is carried from v0.1.3. Only 5 of 10 sample apps got a real check on the first run. All 5 found the added flaw, and none reported a broken rule that was not broken. The other 5 stopped, each naming the line it could not read. On an app like yours, setup may not reach a working check the first time, and you may need to step in. Tracked as #3679. What we state: A fresh agent following the one line got a check that found the added flaw, without false alarms, on nearly every sample app. Record: docs/validation/setup-qual/runs/20261022T222243Z-v0.1.3/results.jsonl, 2026-10-22 (setup measurement at 22:22Z against the v0.1.3 release on staging; carried to v0.1.4, not re-measured). This reading comes from a record of a run, not from reading our code, so it is only as good as that run: it tells you how setup went on ten sample apps, not how it will go on yours. | docs/validation/setup-qual/runs/20261022T222243Z-v0.1.3/results.jsonl @ 0782f26c |
| G5 | not established | premised | Every feedback note a customer files is read back over the API by Symbolia's own loop and answered or routed; none sits unread. | Read from a run record | We looked for the record of our own loop reading customer feedback back over the API, and there is none yet (docs/validation/feedback-digest/). What we state: A record of our own loop reading the feedback notes customers filed back over the API, with each one answered or routed. Record: none yet: no such record exists under docs/validation/feedback-digest/. This promise can only be shown by a record of us reading and answering your feedback notes, and no such record exists yet, so we cannot yet show that a note you file will be read and answered. | docs/validation/feedback-digest/ @ 0782f26c |

The record: /self-check/0782f26c/meta.json, /self-check/0782f26c/report.json, /self-check/0782f26c/areas.json (the section headings of Assure's requirements.md at 0782f26c26d57047a29fcf16506b8c489a7f7c6d). Every release: /assure-on-assure.