{
 "counts": {
  "decided": 53,
  "formal": 51,
  "formal_disproven": 0,
  "formal_holds": 51,
  "premised": 2,
  "total": 61
 },
 "errors": [],
 "promises": {
  "A1": {
   "check": "promise_readers.setup_qual",
   "defect": "#3089",
   "evidence": "docs/validation/setup-qual/runs/20261021T201515Z-v0.1.1/results.jsonl",
   "kind": "premised",
   "plain": {
    "evidence": "docs/validation/setup-qual/runs/20261021T201515Z-v0.1.1/results.jsonl @ 8a819c21",
    "for_you": "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.",
    "meaning": "We found a case where this release does not keep the promise.",
    "premise": "Each setup agent asked the person only what only they could answer, and gave the tradeoff of each question.",
    "premised_means": "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.",
    "promise": "Anyone can set Assure up from one line, and is asked only what only they can answer, each question with its tradeoff.",
    "reason": "We read the record of our v0.1.1 setup run on ten sample apps, which keeps the questions each setup agent asked.",
    "record": "docs/validation/setup-qual/runs/20261021T201515Z-v0.1.1/results.jsonl",
    "record_date": "2026-10-21 (the setup run at 19:58Z; the questions are the ones the setup agents asked in the run of 2026-10-17)",
    "why": "Most of the setup questions were about how the product works, not something only the customer knows, and none came with its tradeoff."
   },
   "reading": "disproven",
   "reason": "14 of 19 questions outside the customer-only list (microblog: product; microblog: product; flasky: product; flasky: unclassified; flask-base: unclassified; realworld: product); no tradeoff recorded for each question of microblog, flasky, flask-base, realworld, flask-user-starter, cookiecutter-demo, jwt-restful, rest-tutorial, flaskr, flask-bones"
  },
  "A2": {
   "check": "promise_readers.surfaces",
   "evidence": "serve/render.py (next_step, failure_markdown, pr_refusal_markdown, summary_markdown, pr_comment_markdown)",
   "kind": "formal",
   "plain": {
    "evidence": "serve/render.py (next_step, failure_markdown, pr_refusal_markdown, summary_markdown, pr_comment_markdown) @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "Every run tells the customer something useful, including a refused one, and names one next step.",
    "reason": "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."
   },
   "reading": "holds",
   "reason": "a refused run: failure_markdown and pr_refusal_markdown each reach next_step, whose fallback is the envelope's action, and each of the 31 outcomes has a non-empty action; a verdict run: summary_markdown reaches not_established_lines and pr_comment_markdown reaches _pr_closing"
  },
  "A3": {
   "check": "promise_readers.preflight",
   "evidence": "serve/lint.py; serve/input_readers.py; serve/profiles.py; tests/checkers/identity/fixtures/adapter-2-fastapi/positive",
   "kind": "formal",
   "plain": {
    "evidence": "serve/lint.py; serve/input_readers.py; serve/profiles.py; tests/checkers/identity/fixtures/adapter-2-fastapi/positive @ 8a819c21",
    "meaning": "Not shown either way: we could not read enough to say it holds, and we found nothing that breaks it.",
    "promise": "The pre-flight predicts the check; it never says the code is ready when the check cannot read it.",
    "reason": "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."
   },
   "reading": "not established",
   "reason": "the FastAPI and stdlib unreadable-source and route-table replays found no false readiness; complete equivalence of every readability guard across every served profile is not established by these finite replays"
  },
  "A4": {
   "check": "promise_readers.setup_qual",
   "defect": "#3679",
   "evidence": "docs/validation/setup-qual/runs/20261021T201515Z-v0.1.1/results.jsonl",
   "kind": "premised",
   "plain": {
    "evidence": "docs/validation/setup-qual/runs/20261021T201515Z-v0.1.1/results.jsonl @ 8a819c21",
    "for_you": "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.",
    "meaning": "We found a case where this release does not keep the promise.",
    "premise": "A fresh agent following the one line got a check that found the added flaw, without false alarms, on nearly every sample app.",
    "premised_means": "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.",
    "promise": "A fresh agent working from the one line gets a correct result on nearly every qualification app.",
    "reason": "We read the record of our v0.1.1 setup run on ten sample apps, each with a known flaw added, to see whether the check found it.",
    "record": "docs/validation/setup-qual/runs/20261021T201515Z-v0.1.1/results.jsonl",
    "record_date": "2026-10-21 (setup run at 19:58Z against production v0.1.1)",
    "why": "Only 4 of 10 sample apps got a real check, only 3 found the added flaw, and one reported a broken rule that was not broken."
   },
   "reading": "disproven",
   "reason": "4 of 10 real checks, 3 of 10 name the flaw, 1 false broken; failed: cookiecutter-demo, flask-base, flask-bones, flask-user-starter, flasky, realworld"
  },
  "B1": {
   "check": "identity:python/stdlib-http (assure-self)",
   "evidence": "assure/checkers/identity/adapters/python_stdlib_http/fixtures/assure-self/requirements.md:5",
   "kind": "formal",
   "plain": {
    "evidence": "assure/checkers/identity/adapters/python_stdlib_http/fixtures/assure-self/requirements.md:5 @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "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.",
    "reason": "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."
   },
   "read": {
    "R1": "holds",
    "R2": "holds",
    "R27": "holds",
    "R28": "holds",
    "R38": "holds",
    "premise:webhook-signature-before-body": "holds"
   },
   "reading": "holds",
   "reason": "every route outside /healthz is protected from the anonymous principal (IDENT-1); /healthz answers before the key guard from the server's own status (R38); the tree page opens only for a link whose signature matches under the configured signing value, before any record is read, until its expiry (R27); the GitHub sign-in mints a key only after the proof's signature, issuer, audience and expiry verify (R28); the billing webhook checks its signature before the body (premise)"
  },
  "B10": {
   "check": "identity:python/stdlib-http (assure-self)",
   "evidence": "assure/checkers/identity/adapters/python_stdlib_http/fixtures/assure-self/requirements.md:50",
   "kind": "formal",
   "plain": {
    "evidence": "assure/checkers/identity/adapters/python_stdlib_http/fixtures/assure-self/requirements.md:50 @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "Every stored item belongs to one account; no other account can read it or tell that it exists.",
    "reason": "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."
   },
   "read": {
    "R46": "holds"
   },
   "reading": "holds",
   "reason": "every store call in the handler class passes the principal; every account-keyed Store method opens that account's directory; Store._get refuses the same not_found for a malformed id and an absent or foreign record"
  },
  "B11": {
   "check": "identity:python/stdlib-http (assure-self)",
   "evidence": "assure/checkers/identity/adapters/python_stdlib_http/fixtures/assure-self/requirements.md:43",
   "kind": "formal",
   "plain": {
    "evidence": "assure/checkers/identity/adapters/python_stdlib_http/fixtures/assure-self/requirements.md:43 @ 8a819c21",
    "meaning": "Not shown either way: we could not read enough to say it holds, and we found nothing that breaks it.",
    "promise": "Keys and signing values are never written to logs, records or responses.",
    "reason": "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."
   },
   "read": {
    "R39": "holds",
    "R40": "holds",
    "premise:key-digest-stored": "not established"
   },
   "reading": "not established",
   "reason": "not established through premise:key-digest-stored: serve.keys.Keys.issue: holds: serve.keys.Keys.issue stores only _digest(…) = sha256 of the key (line 579); the key itself is returned once and never stored; serve.keys.Keys.issue_oidc: holds: serve.keys.Keys.issue_oidc stores only _digest(…) = sha256 of the key (line 639); the key itself is returned once and never stored; serve.keys.Keys.rotate: not_established: serve.keys.Keys.rotate digests a compound argument at line 706 whose returned-key provenance this read does not establish"
  },
  "B12": {
   "check": "-",
   "evidence": "-",
   "kind": "formal",
   "plain": {
    "evidence": "- @ 8a819c21",
    "meaning": "Not shown either way: we could not read enough to say it holds, and we found nothing that breaks it.",
    "promise": "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.",
    "reason": "Nothing in our checks reads this promise yet."
   },
   "reading": "not established",
   "reason": "no reader decides it yet"
  },
  "B2": {
   "check": "identity:python/stdlib-http (assure-self)",
   "evidence": "assure/checkers/identity/adapters/python_stdlib_http/fixtures/assure-self/requirements.md:5",
   "kind": "formal",
   "plain": {
    "evidence": "assure/checkers/identity/adapters/python_stdlib_http/fixtures/assure-self/requirements.md:5 @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "Every other request needs a valid API key.",
    "reason": "We read every route and handler of our API server (serve/) and found that every other route needs a valid API key."
   },
   "read": {
    "R1": "holds",
    "R10": "holds",
    "R11": "holds",
    "R12": "holds",
    "R13": "holds",
    "R14": "holds",
    "R15": "holds",
    "R16": "holds",
    "R17": "holds",
    "R18": "holds",
    "R19": "holds",
    "R20": "holds",
    "R21": "holds",
    "R22": "holds",
    "R23": "holds",
    "R24": "holds",
    "R25": "holds",
    "R26": "holds",
    "R3": "holds",
    "R4": "holds",
    "R5": "holds",
    "R8": "holds",
    "R9": "holds",
    "premise:key-compare-constant-time": "holds"
   },
   "reading": "holds",
   "reason": "every route outside the declared public routes is protected by the API key guard (IDENT-1), each key-guarded method-route pair reads protected, and the key is compared by digest in constant time"
  },
  "B3": {
   "check": "identity:python/stdlib-http (assure-self)",
   "evidence": "assure/checkers/identity/adapters/python_stdlib_http/fixtures/assure-self/requirements.md:36",
   "kind": "formal",
   "plain": {
    "evidence": "assure/checkers/identity/adapters/python_stdlib_http/fixtures/assure-self/requirements.md:36 @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "Once a key is revoked, the very next request made with it is turned away.",
    "reason": "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."
   },
   "read": {
    "R32": "holds"
   },
   "reading": "holds",
   "reason": "Keys.revoke marks the key row revoked and authenticate_key reads the rows on each request and refuses a revoked key"
  },
  "B4": {
   "check": "identity:python/stdlib-http (assure-self)",
   "evidence": "assure/checkers/identity/adapters/python_stdlib_http/fixtures/assure-self/requirements.md:11",
   "kind": "formal",
   "plain": {
    "evidence": "assure/checkers/identity/adapters/python_stdlib_http/fixtures/assure-self/requirements.md:11 @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "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.",
    "reason": "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."
   },
   "read": {
    "R41": "holds",
    "R7": "holds"
   },
   "reading": "holds",
   "reason": "the issued expiry and its check (IDENT-7: a key row with no `expires` is refused too, #4202) and the expiry header with its warning from KEY_WARNING_DAYS before (R41)"
  },
  "B5": {
   "check": "identity:python/stdlib-http (assure-self)",
   "evidence": "assure/checkers/identity/adapters/python_stdlib_http/fixtures/assure-self/requirements.md:47",
   "kind": "formal",
   "plain": {
    "evidence": "assure/checkers/identity/adapters/python_stdlib_http/fixtures/assure-self/requirements.md:47 @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "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.",
    "reason": "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."
   },
   "read": {
    "R43": "holds"
   },
   "reading": "holds",
   "reason": "Keys.rotate refuses before the window opens, mints a successor expiring at the clock plus a bounded duration, and writes neither `expires` nor `revoked` on the presented row: the old key works until its own expiry"
  },
  "B6": {
   "check": "identity:python/stdlib-http (assure-self)",
   "evidence": "assure/checkers/identity/adapters/python_stdlib_http/fixtures/assure-self/requirements.md:48",
   "kind": "formal",
   "plain": {
    "evidence": "assure/checkers/identity/adapters/python_stdlib_http/fixtures/assure-self/requirements.md:48 @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "A paid action runs only when the plan, balance or agreed overage covers it.",
    "reason": "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."
   },
   "read": {
    "R44": "holds"
   },
   "reading": "holds",
   "reason": "every PAID_ROUTES handler reaches a meter admission or hold with the principal before the work it pays for; the meter refuses a once-only balance past what is left and a post-paid part past the budget"
  },
  "B7": {
   "check": "identity:python/stdlib-http (assure-self)",
   "evidence": "assure/checkers/identity/adapters/python_stdlib_http/fixtures/assure-self/requirements.md:31",
   "kind": "formal",
   "plain": {
    "evidence": "assure/checkers/identity/adapters/python_stdlib_http/fixtures/assure-self/requirements.md:31 @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "A proof-tree link opens only if the server signed it, only until it expires, and never after the verdict has been deleted.",
    "reason": "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."
   },
   "read": {
    "R27": "holds",
    "R45": "holds"
   },
   "reading": "holds",
   "reason": "the tree page opens only for a signed, unexpired link (R27), refuses when no account holds the check or the verdict's retention has ended, and never serves a link longer than the retention (R45)"
  },
  "B8": {
   "check": "identity:python/stdlib-http (assure-self)",
   "evidence": "assure/checkers/identity/adapters/python_stdlib_http/fixtures/assure-self/requirements.md:46",
   "kind": "formal",
   "plain": {
    "evidence": "assure/checkers/identity/adapters/python_stdlib_http/fixtures/assure-self/requirements.md:46 @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "A billing event is applied only when its signature verifies and the event is recent.",
    "reason": "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."
   },
   "read": {
    "R42": "holds"
   },
   "reading": "holds",
   "reason": "the webhook applies an event only when its signature verifies under the configured signing value and its timestamp lies within TOLERANCE_S of the clock"
  },
  "B9": {
   "check": "identity:python/stdlib-http (assure-self)",
   "evidence": "assure/checkers/identity/adapters/python_stdlib_http/fixtures/assure-self/requirements.md:10",
   "kind": "formal",
   "plain": {
    "evidence": "assure/checkers/identity/adapters/python_stdlib_http/fixtures/assure-self/requirements.md:10 @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "Every signing or verification key comes from configuration.",
    "reason": "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."
   },
   "read": {
    "R6": "holds"
   },
   "reading": "holds",
   "reason": "every declared signing or verification key (api_key, stripe_signature, tree_link, github_oidc) resolves to a configuration surface (IDENT-8); a literal default on the environment read reads literal"
  },
  "C1": {
   "check": "properties:python/stdlib-http (assure/checkers/identity/adapters/python_stdlib_http/properties.py)",
   "evidence": "assure/checkers/identity/grade.py:51",
   "kind": "formal",
   "plain": {
    "evidence": "assure/checkers/identity/grade.py:51 @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "A requirement reads holds, not established or disproven.",
    "reason": "We read the verdict code (assure/checkers/identity/grade.py), and it has exactly three readings: holds, not established and disproven."
   },
   "reading": "holds",
   "reason": "verdict-three-readings: STATES is exactly holds, not_established, disproven (assure/checkers/identity/grade.py:51); MAP_001's 10 result types map onto them (assure/checkers/identity/grade.py:53); map_result returns only those states; _row takes its state from map_result (assure/checkers/identity/grade.py:318)"
  },
  "C10": {
   "check": "properties:python/stdlib-http (assure/checkers/identity/adapters/python_stdlib_http/properties.py)",
   "evidence": "assure/checkers/identity/explore.py:301; serve/profiles.py:1484",
   "kind": "formal",
   "plain": {
    "evidence": "assure/checkers/identity/explore.py:301; serve/profiles.py:1484 @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "When a checker can model only the first few of something, everything past that point reads not established with the bound named.",
    "reason": "We read the checker's limits (assure/checkers/identity/explore.py), and past each limit the result reads not established and names the limit."
   },
   "reading": "holds",
   "reason": "identity-bound-refused-and-named: BOUNDS caps states, routes, principals (assure/checkers/identity/explore.py:59); each is raised as Overbound (states at assure/checkers/identity/explore.py:273, routes at assure/checkers/identity/explore.py:257, principals at assure/checkers/identity/explore.py:255); explore refuses representation/bound naming the dimension and the cap (assure/checkers/identity/explore.py:301); MAP_001 maps representation to not_established (assure/checkers/identity/grade.py:53); postgresql-rows-past-the-first-table: bounded_machines refuses M5 when _distinct(tables) > 1 (serve/profiles.py:1483) with a reason naming the bound (one protected table per declaration) and the count (serve/profiles.py:1484); _derive_evaluate reads each machine bounded_machines names as representation with that reason, never evaluated (serve/profiles.py:2067)"
  },
  "C2": {
   "check": "properties:python/stdlib-http (assure/checkers/identity/adapters/python_stdlib_http/properties.py)",
   "evidence": "assure/checkers/identity/grade.py:53",
   "kind": "formal",
   "plain": {
    "evidence": "assure/checkers/identity/grade.py:53 @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "Nothing reads holds when there was nothing to check; it reads not established.",
    "reason": "We read the verdict code (assure/checkers/identity/grade.py), and every case with nothing to check reads not established."
   },
   "reading": "holds",
   "reason": "verdict-nothing-holds-on-nothing: 11 holds rows each name their domain; 8 empty-domain branches read vacuous; vacuous maps to not_established (assure/checkers/identity/grade.py:53); a requirement line no row phrases never holds (assure/checkers/identity/grade.py:520, assure/checkers/identity/grade.py:524)"
  },
  "C3": {
   "check": "properties:python/stdlib-http (assure/checkers/identity/adapters/python_stdlib_http/properties.py)",
   "evidence": "assure/checkers/identity/grade.py:53",
   "kind": "formal",
   "plain": {
    "evidence": "assure/checkers/identity/grade.py:53 @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "Nothing reads disproven unless the code really breaks the rule; a route whose purpose is not known reads not established.",
    "reason": "We read the verdict code (assure/checkers/identity/grade.py), and only a found break reads disproven; anything not understood reads not established."
   },
   "reading": "holds",
   "reason": "verdict-disproven-only-on-a-break: only fails maps to disproven in MAP_001 (assure/checkers/identity/grade.py:53); a line not understood or unmatched is never disproven (assure/checkers/identity/grade.py:520, assure/checkers/identity/grade.py:524); _span_pass demotes a disproven row inside a refused span to representation (assure/checkers/identity/grade.py:1235)"
  },
  "C4": {
   "check": "properties:python/stdlib-http (assure/checkers/identity/adapters/python_stdlib_http/properties.py)",
   "evidence": "serve/api.py:3412; serve/worker.py:420; serve/check.py:753",
   "kind": "formal",
   "plain": {
    "evidence": "serve/api.py:3412; serve/worker.py:420; serve/check.py:753 @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "The engine checks that its own code matches its pin before it runs.",
    "reason": "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."
   },
   "reading": "holds",
   "reason": "pin-before-engine-api: make_server verifies the pin (serve/api.py:3412) before the engine is imported (serve/api.py:3413); the module imports no engine byte at top level; pin-before-engine-worker: child_main verifies the pin (serve/worker.py:420) before the engine is imported (serve/worker.py:428); the module imports no engine byte at top level; pin-before-engine-check: main verifies the pin (serve/check.py:753) before the engine is imported (serve/check.py:763); the module imports no engine byte at top level"
  },
  "C5": {
   "check": "properties:python/stdlib-http (assure/checkers/identity/adapters/python_stdlib_http/properties.py)",
   "evidence": "serve/envelope.py:1545; serve/check.py:226; serve/worker.py:160; serve/worker.py:432; serve/api.py:1081; serve/api.py:1058",
   "kind": "formal",
   "plain": {
    "evidence": "serve/envelope.py:1545; serve/check.py:226; serve/worker.py:160; serve/worker.py:432; serve/api.py:1081; serve/api.py:1058 @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "Every verdict names the engine version it ran on.",
    "reason": "We read how verdicts are built (serve/envelope.py, serve/check.py), and every verdict carries the engine version it ran on."
   },
   "reading": "holds",
   "reason": "verdict-engine-block: build writes 'engine' from its required engine argument (serve/envelope.py:1545); verdict-engine-passed-check: run_check passes engine=engine to envelope.build (serve/check.py:226); verdict-engine-request-written: write_request writes 'engine' from its required engine argument (serve/worker.py:160); verdict-engine-from-request: child_main passes engine=doc.get('engine') to run_check (serve/worker.py:432); verdict-engine-from-pin: _run_job binds engine = self.pin_verify() (serve/api.py:1081) and hands it to self._run (serve/api.py:1092); verdict-engine-passed-api: _run passes engine=engine to worker.run_in_child (serve/api.py:1058)"
  },
  "C6": {
   "check": "properties:python/stdlib-http (assure/checkers/identity/adapters/python_stdlib_http/properties.py)",
   "evidence": "serve/api.py:609; serve/api.py:1849; serve/bundle.py:194; serve/bundle.py:606; serve/api.py:542; serve/meter.py:2217; serve/meter.py:2262",
   "kind": "formal",
   "plain": {
    "evidence": "serve/api.py:609; serve/api.py:1849; serve/bundle.py:194; serve/bundle.py:606; serve/api.py:542; serve/meter.py:2217; serve/meter.py:2262 @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "The limits the API publishes are the limits it enforces.",
    "reason": "We read the API (serve/api.py, serve/bundle.py), and the limits it publishes are the same values it enforces."
   },
   "reading": "holds",
   "reason": "limits-published-from-the-object: public_profiles publishes 'limits' as body_bytes = limits.body_bytes, file_bytes = limits.file_bytes, files = limits.files, json_depth = limits.json_depth (serve/api.py:609); body-cap-read-from-the-published-object: _read_body reads self.server.limits.body_bytes and refuses oversize_input (serve/api.py:1849); bundle-body-and-depth-caps-from-the-object: parse_json reads limits.body_bytes, limits.json_depth and refuses oversize_input (serve/bundle.py:194); bundle-file-caps-from-the-object: check_files reads limits.files, limits.file_bytes and refuses oversize_input (serve/bundle.py:606); rate-window-published-is-the-one-read: served_routes publishes 'rate_window' as RATE_WINDOWS[...] (serve/api.py:542) and _admit reads RATE_WINDOWS[...] (serve/api.py:1761); rate-limits-published-from-the-limiter: Meter.usage publishes 'limits' as requests_per_minute = self.limiter.rpm, records_per_day = self.limiter.rpd (serve/meter.py:2217); rate-admitted-through-the-limiter: Meter.admit_request reads self.limiter.admit (serve/meter.py:2262)"
  },
  "C7": {
   "check": "properties:python/stdlib-http (assure/checkers/identity/adapters/python_stdlib_http/properties.py)",
   "evidence": "serve/api.py:398",
   "kind": "formal",
   "plain": {
    "evidence": "serve/api.py:398 @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "An account cannot create a volume of requests beyond reliable limits.",
    "reason": "We read the API (serve/api.py), and every request that creates work passes a rate limit first."
   },
   "reading": "holds",
   "reason": "every-post-template-admitted: every POST template outside the declared exceptions admits on its RATE_WINDOWS window through its handler (13 templates; _admit maps minute+day to admit_request, minute to admit_rate) (serve/api.py:398)"
  },
  "C8": {
   "check": "properties:python/stdlib-http (assure/checkers/identity/adapters/python_stdlib_http/properties.py)",
   "evidence": "serve/api.py:2169; serve/store.py:840",
   "kind": "formal",
   "plain": {
    "evidence": "serve/api.py:2169; serve/store.py:840 @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "Sending the same check twice with the same idempotency key returns the first check and is not charged again.",
    "reason": "We read the check route (serve/api.py, serve/store.py), and a repeated idempotency key returns the first check before any charge."
   },
   "reading": "holds",
   "reason": "replay-before-charge: _post_check looks the key up under srv.idem_lock (serve/api.py:2169), replays a known check before any admission (serve/api.py:2189), and admits, records and submits only when the key is unknown (serve/api.py:2230; the record serve/api.py:2232 precedes the submit serve/api.py:2241); idempotency-record-written-once: put_idempotency links the record once (serve/store.py:840) and returns False when it already exists (serve/store.py:842)"
  },
  "C9": {
   "boundary_census": {
    "client_imports": [
     "hosted/pg.py imports psycopg",
     "serve/billing_relay.py imports socket",
     "serve/billing_stripe.py imports urllib.request",
     "serve/oidc_keys.py imports ssl",
     "serve/oidc_keys.py imports urllib.request",
     "serve/pin_cli.py imports http.client",
     "serve/pin_cli.py imports urllib.request",
     "serve/premium_client.py imports http.client",
     "serve/premium_client.py imports ssl",
     "serve/premium_client.py imports urllib.request"
    ],
    "live_source_calls": [
     "serve.oidc:GitHubKeys.__call__",
     "serve.oidc:GitHubKeys.__init__",
     "serve.oidc:GitHubKeys._from_file"
    ],
    "modules": [
     "action",
     "action.http_identity",
     "action.repository_manifest",
     "action.withhold",
     "assure",
     "assure._canonical",
     "assure.adapter_bridge",
     "assure.checkers",
     "assure.checkers.derive_process",
     "assure.checkers.identity",
     "assure.checkers.identity.adapters",
     "assure.checkers.identity.adapters.python_django",
     "assure.checkers.identity.adapters.python_django.candidate",
     "assure.checkers.identity.adapters.python_django.census",
     "assure.checkers.identity.adapters.python_django.decode_sites",
     "assure.checkers.identity.adapters.python_django.extract",
     "assure.checkers.identity.adapters.python_django.ingest",
     "assure.checkers.identity.adapters.python_django.parse",
     "assure.checkers.identity.adapters.python_django.readset",
     "assure.checkers.identity.adapters.python_fastapi",
     "assure.checkers.identity.adapters.python_fastapi.census_pins",
     "assure.checkers.identity.adapters.python_fastapi.decode_sites",
     "assure.checkers.identity.adapters.python_fastapi.extract",
     "assure.checkers.identity.adapters.python_fastapi.pipeline",
     "assure.checkers.identity.adapters.python_fastapi.readset",
     "assure.checkers.identity.adapters.python_stdlib_http",
     "assure.checkers.identity.adapters.python_stdlib_http.extract",
     "assure.checkers.identity.adapters.python_stdlib_http.pipeline",
     "assure.checkers.identity.adapters.python_stdlib_http.premises",
     "assure.checkers.identity.adapters.python_stdlib_http.properties",
     "assure.checkers.identity.explore",
     "assure.checkers.identity.grade",
     "assure.checkers.identity.proposal",
     "assure.checkers.identity.proposal._adapter",
     "assure.checkers.identity.proposal.python_django",
     "assure.checkers.identity.proposal.python_fastapi",
     "assure.checkers.identity.proposal.python_flask",
     "assure.checkers.identity.readset",
     "assure.checkers.identity.records",
     "assure.checkers.identity.registry",
     "assure.checkers.identity.served",
     "assure.declare",
     "assure.pricing",
     "hosted",
     "hosted.costs",
     "hosted.data_rule",
     "hosted.inference",
     "hosted.pg",
     "hosted.ports",
     "hosted.tiers",
     "runner.tools.codeauth",
     "runner.tools.codeauth.lean_check",
     "runner.tools.codeauth.maintain",
     "runner.tools.codeauth.quote",
     "runner.tools.codeauth.router",
     "runner.tools.codeauth.run",
     "runner.tools.codeauth.seats",
     "runner.tools.codeauth.seats.faithfulness",
     "runner.tools.codeauth.seats.proposal",
     "runner.tools.codeauth.seats.report",
     "runner.tools.codeauth.shadow",
     "runner.tools.shadow_router",
     "serve",
     "serve.api",
     "serve.billing",
     "serve.billing_relay",
     "serve.billing_stripe",
     "serve.bundle",
     "serve.bundle_keep",
     "serve.check",
     "serve.check_summary",
     "serve.cost_intents",
     "serve.coverage_proposals",
     "serve.declaration_proposal",
     "serve.declared_actionability",
     "serve.delivery",
     "serve.dev_fixture",
     "serve.envelope",
     "serve.explain_row",
     "serve.faithful",
     "serve.feedback",
     "serve.feedback_digest",
     "serve.feedback_status",
     "serve.fingerprints",
     "serve.formalisation",
     "serve.formalisation_worker",
     "serve.http_facts",
     "serve.input_readers",
     "serve.keys",
     "serve.lint",
     "serve.markers",
     "serve.meter",
     "serve.monthly_remodel",
     "serve.mysql_declaration_draft",
     "serve.oidc",
     "serve.oidc_keys",
     "serve.outcomes",
     "serve.pin",
     "serve.pin_cli",
     "serve.premium_client",
     "serve.premium_runner",
     "serve.premium_setup",
     "serve.premium_transport",
     "serve.profiles",
     "serve.promise_lines",
     "serve.proof_tree",
     "serve.render",
     "serve.report",
     "serve.report_page",
     "serve.requirements",
     "serve.requirements_adapter",
     "serve.requirements_compiler",
     "serve.secrets",
     "serve.setup_draft",
     "serve.setup_questions",
     "serve.shadow",
     "serve.shadow_api",
     "serve.stack_fingerprint",
     "serve.store",
     "serve.stored_methods",
     "serve.stored_methods_served",
     "serve.telemetry",
     "serve.upgrade_build",
     "serve.usage",
     "serve.worker"
    ],
    "unreadable": []
   },
   "check": "properties:python/stdlib-http (assure/checkers/identity/adapters/python_stdlib_http/properties.py)",
   "evidence": "serve/worker.py:56",
   "kind": "formal",
   "plain": {
    "evidence": "serve/worker.py:56 @ 8a819c21",
    "meaning": "Not shown either way: we could not read enough to say it holds, and we found nothing that breaks it.",
    "promise": "The API and the check process never contact anything outside the server.",
    "reason": "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."
   },
   "reading": "not established",
   "reason": "api-outbound-clients-declared reads not_established: serve/worker.py:56 imports local serve, whose code is outside the transitive read set; an unobserved helper cannot establish no outside contact"
  },
  "D1": {
   "check": "machine:job_lifecycle (hosted/MACHINE.json)",
   "evidence": "hosted/MACHINE.json#invariants/completes_at_most_once",
   "kind": "formal",
   "plain": {
    "evidence": "hosted/MACHINE.json#invariants/completes_at_most_once @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "A job completes at most once.",
    "reason": "We explored every state our job queue can reach (hosted/MACHINE.json) and found that a job completes at most once."
   },
   "reading": "holds",
   "reason": "completes_at_most_once holds on 736 steps; explored 13 abstract states of the reference queue"
  },
  "D2": {
   "check": "machine:job_lifecycle (hosted/MACHINE.json)",
   "evidence": "hosted/MACHINE.json#invariants/stale_lease_never_writes",
   "kind": "formal",
   "plain": {
    "evidence": "hosted/MACHINE.json#invariants/stale_lease_never_writes @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "A worker whose lease has lapsed writes nothing.",
    "reason": "We explored every state our job queue can reach (hosted/MACHINE.json) and found that a worker whose lease has lapsed writes nothing."
   },
   "reading": "holds",
   "reason": "stale_lease_never_writes holds on 93 steps; explored 13 abstract states of the reference queue"
  },
  "D3": {
   "check": "machine:job_lifecycle (hosted/MACHINE.json)",
   "evidence": "hosted/MACHINE.json#invariants/claim_exclusive",
   "kind": "formal",
   "plain": {
    "evidence": "hosted/MACHINE.json#invariants/claim_exclusive @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "Two workers never claim the same job.",
    "reason": "We explored every state our job queue can reach (hosted/MACHINE.json) and found that two workers never hold the same job."
   },
   "reading": "holds",
   "reason": "claim_exclusive holds on 515 steps; explored 13 abstract states of the reference queue"
  },
  "D4": {
   "check": "machine:job_lifecycle (hosted/MACHINE.json)",
   "evidence": "hosted/MACHINE.json#invariants/attempts_bounded",
   "kind": "formal",
   "plain": {
    "evidence": "hosted/MACHINE.json#invariants/attempts_bounded @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "A job is attempted at most its allowed number of times.",
    "reason": "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."
   },
   "reading": "holds",
   "reason": "attempts_bounded holds on 736 steps; explored 13 abstract states of the reference queue"
  },
  "D5": {
   "check": "machine:job_lifecycle (hosted/MACHINE.json)",
   "evidence": "hosted/MACHINE.json#invariants/refusal_never_retried",
   "kind": "formal",
   "plain": {
    "evidence": "hosted/MACHINE.json#invariants/refusal_never_retried @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "A job is retried only when the failure was not its own; a refusal is final.",
    "reason": "We explored every state our job queue can reach (hosted/MACHINE.json) and found that a refused job is never retried."
   },
   "reading": "holds",
   "reason": "refusal_never_retried holds on 354 steps; explored 13 abstract states of the reference queue"
  },
  "D6": {
   "check": "machine:job_lifecycle (hosted/MACHINE.json)",
   "evidence": "hosted/MACHINE.json#invariants/exit_typed_outcome",
   "kind": "formal",
   "plain": {
    "evidence": "hosted/MACHINE.json#invariants/exit_typed_outcome @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "Every way a job can end records a typed outcome.",
    "reason": "We explored every state our job queue can reach (hosted/MACHINE.json) and found that every ending records a typed outcome."
   },
   "reading": "holds",
   "reason": "exit_typed_outcome holds on 535 steps; explored 13 abstract states of the reference queue"
  },
  "D7": {
   "check": "machine:job_lifecycle (hosted/MACHINE.json)",
   "evidence": "hosted/MACHINE.json#transitions",
   "kind": "formal",
   "plain": {
    "evidence": "hosted/MACHINE.json#transitions @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "A job moves only along the allowed path.",
    "reason": "We explored every state our job queue can reach (hosted/MACHINE.json) and found that every move is one of the allowed moves."
   },
   "reading": "holds",
   "reason": "every observed move (8) is a declared transition; explored 13 abstract states of the reference queue"
  },
  "D8": {
   "check": "machine:job_lifecycle (hosted/MACHINE.json)",
   "evidence": "hosted/MACHINE.json#invariants/interrupt_writes_nothing",
   "kind": "formal",
   "plain": {
    "evidence": "hosted/MACHINE.json#invariants/interrupt_writes_nothing @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "If a worker is interrupted mid-job, nothing is written.",
    "reason": "We explored every state our job queue can reach (hosted/MACHINE.json) and found that an interrupted job writes nothing."
   },
   "reading": "holds",
   "reason": "interrupt_writes_nothing holds on 10 steps; explored 13 abstract states of the reference queue"
  },
  "E1": {
   "check": "promise_readers.data_code (ast over the tree)",
   "evidence": "serve/bundle.py (RUNNER_ONLY, from_directory), action/collect.py (_gather)",
   "kind": "formal",
   "plain": {
    "evidence": "serve/bundle.py (RUNNER_ONLY, from_directory), action/collect.py (_gather) @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "Only what a check needs leaves the customer's runner, never raw rows, names or values.",
    "reason": "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."
   },
   "reading": "holds",
   "reason": "only the withheld raw/ files leave the runner: REDACTION-MANIFEST.json is a runner-only record (RUNNER_ONLY, read by from_directory) and _gather returns withhold.apply(from_directory(...))"
  },
  "E2": {
   "check": "promise_readers.data_code (ast over the tree)",
   "evidence": "serve/worker.py (run_in_child), serve/bundle_keep.py (keep, includes_premium, PREMIUM_TIERS)",
   "kind": "formal",
   "plain": {
    "evidence": "serve/worker.py (run_in_child), serve/bundle_keep.py (keep, includes_premium, PREMIUM_TIERS) @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "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.",
    "reason": "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."
   },
   "reading": "holds",
   "reason": "run_in_child deletes the request directory in a finally on every exit path; bundle_keep.keep seals one copy only when includes_premium(tier), the tiers that include Premium (PREMIUM_TIERS: internal, usage, usd_20, usd_200), never the free tier"
  },
  "E3": {
   "check": "machine:data_rule (hosted.data_rule.read_promises)",
   "evidence": "hosted/data_rule.py",
   "kind": "formal",
   "plain": {
    "evidence": "hosted/data_rule.py @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "What we keep is minimal and kept briefly, then deleted with everything that belongs to it.",
    "reason": "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."
   },
   "reading": "holds",
   "reason": "every day-bounded class is kept at most 30 days, a tier-scoped class goes when the account leaves the tier and a class kept for the life of the account is deleted on request; declared, not derived: classes.signin_record.retention, classes.sealed_bundle.deletion_events, classes.collected_facts"
  },
  "E5": {
   "check": "machine:data_rule (hosted.data_rule.read_promises)",
   "evidence": "hosted/data_rule.py",
   "kind": "formal",
   "plain": {
    "evidence": "hosted/data_rule.py @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "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.",
    "reason": "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."
   },
   "reading": "holds",
   "reason": "product_data on by default for free, off for paid tiers, one setting (product_data); declared, not derived: product_data_settings"
  },
  "E6": {
   "check": "machine:data_rule (hosted.data_rule.read_promises)",
   "evidence": "hosted/data_rule.py",
   "kind": "formal",
   "plain": {
    "evidence": "hosted/data_rule.py @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "An enterprise account keeps none of its code or collected facts after the check ends.",
    "reason": "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."
   },
   "reading": "holds",
   "reason": "enterprise keeps none of its code or collected facts after the check ends; its private model only encrypted under its own key; verdicts kept under decision 8; declared, not derived: classes.collected_facts, classes.signin_record"
  },
  "E7": {
   "check": "promise_readers.data_code (ast over the tree)",
   "evidence": "hosted/data_rule.py (RESTORE_ONLY, declared)",
   "kind": "formal",
   "plain": {
    "evidence": "hosted/data_rule.py (RESTORE_ONLY, declared) @ 8a819c21",
    "meaning": "Not shown either way: we could not read enough to say it holds, and we found nothing that breaks it.",
    "promise": "Backups keep only what is needed to restore accounts and billing, briefly, and never a customer's verdicts or collected facts.",
    "reason": "We looked for a backup job and found none; the backup rule is written down (hosted/data_rule.py) but nothing runs it yet."
   },
   "reading": "not established",
   "reason": "no backup job in the tree; RESTORE_ONLY in hosted/data_rule.py is declared and read by no job, so a holds on it would be vacuous"
  },
  "E8": {
   "check": "machine:data_rule (hosted.data_rule.read_promises)",
   "evidence": "hosted/data_rule.py",
   "kind": "formal",
   "plain": {
    "evidence": "hosted/data_rule.py @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "Feedback and telemetry are kept only as long as they are useful, and never a requirement's text.",
    "reason": "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."
   },
   "reading": "holds",
   "reason": "feedback kept 12 months, telemetry 12 months; neither carries a requirement text field; declared, not derived: telemetry.months"
  },
  "E9": {
   "check": "machine:data_rule (hosted.data_rule.read_promises)",
   "evidence": "hosted/data_rule.py",
   "kind": "formal",
   "plain": {
    "evidence": "hosted/data_rule.py @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "A customer's private model is deleted when they ask, and soon after the account closes.",
    "reason": "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."
   },
   "reading": "holds",
   "reason": "the private model is deleted on request and 30 days after close"
  },
  "F1": {
   "check": "machine:billing (serve/billing_machine.py readings, read_f4)",
   "evidence": "serve/billing_machine.py",
   "kind": "formal",
   "plain": {
    "evidence": "serve/billing_machine.py @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "An account's plan and charges change only by something it agreed to or was given, and never twice for the same event.",
    "reason": "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."
   },
   "reading": "holds",
   "reason": "every applied event is one events.jsonl row, a repeated id changes nothing, the plan moves only by an applied event or a gift, every settled request is one charge row, a request settled twice changes no charge, and a charge without consent to overage never passes its hold, over 155 sequences of at most 3 steps (118 distinct: a replay before any event sends nothing); 35 gifts moved the plan"
  },
  "F2": {
   "check": "machine:billing (serve/billing_machine.py)",
   "evidence": "serve/billing_machine.py",
   "kind": "formal",
   "plain": {
    "evidence": "serve/billing_machine.py @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "When a customer leaves a paid plan, what was kept for it is deleted.",
    "reason": "We read our billing code (serve/billing_machine.py) and found that leaving a paid plan deletes what was kept for it."
   },
   "reading": "holds",
   "reason": "customer.subscription.deleted leaves no kept bundle and no sign-in record of the account, and a lapsed gift's recorded move to free leaves no sign-in record"
  },
  "F3": {
   "check": "machine:billing (serve/billing_machine.py readings, read_f4)",
   "evidence": "serve/billing_machine.py",
   "kind": "formal",
   "plain": {
    "evidence": "serve/billing_machine.py @ 8a819c21",
    "meaning": "Not shown either way: we could not read enough to say it holds, and we found nothing that breaks it.",
    "promise": "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.",
    "reason": "The overage budget this promise needs is not in this release yet, so there is nothing to read."
   },
   "reading": "not established",
   "reason": "contingent on the account overage budget (refs #3100, #3895), not on main; the machine gives no F3 row"
  },
  "F4": {
   "check": "machine:billing (serve/billing_machine.py readings, read_f4)",
   "evidence": "serve/billing_machine.py",
   "kind": "formal",
   "plain": {
    "evidence": "serve/billing_machine.py @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "Overage is charged at the published rate, and only within the budget the customer agreed.",
    "reason": "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."
   },
   "reading": "holds",
   "reason": "the charge row carries the basis at the published rate (hosted/tiers.json margin), and the hold whose post-paid part would pass the agreed budget is refused allowance_exhausted with nothing written"
  },
  "F5": {
   "check": "machine:billing (serve/billing_machine.py readings, read_f4)",
   "evidence": "serve/billing_machine.py",
   "kind": "formal",
   "plain": {
    "evidence": "serve/billing_machine.py @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "Every ledger is append-only, and every total is recomputed from its entries.",
    "reason": "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."
   },
   "reading": "holds",
   "reason": "every ledger (the four JSONL ledgers and ledger.sqlite3) only grew by appending after each event, settlement and usage report, overage_cents and each statement total equal the sums recomputed from the ledger rows, and each paid plan has one statement, over 155 sequences of at most 3 steps (118 distinct: a replay before any event sends nothing)"
  },
  "F6": {
   "check": "machine:customer plan and per-check costs",
   "evidence": "serve/api.py _usage; serve/meter.py check_costs; persisted customer ledgers",
   "kind": "formal",
   "plain": {
    "evidence": "serve/api.py _usage; serve/meter.py check_costs; persisted customer ledgers @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "A customer can always see their plan and what each check cost them.",
    "reason": "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."
   },
   "reading": "holds",
   "reason": "complete-body AST establishes account-bound all-period ledger selection and serialization; authenticated current plan and every historical check cost match the account ledgers; settled allowance/top-up/charge components, uncharged terminal failure, zero-cost work, plan changes and restart checked; known pending amounts, retry reconciliation, receipt SQL failure, stored-envelope fallback and accepted-marker recovery checked without monetary replay"
  },
  "F7": {
   "check": "run:statement (serve/billing.py Billing.statement)",
   "evidence": "serve/billing.py",
   "kind": "formal",
   "plain": {
    "evidence": "serve/billing.py @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "A statement shows the same figures a real bill would.",
    "reason": "We produced statements (serve/billing.py) for a gifted account and a paid one, and each showed the figures a real bill would."
   },
   "reading": "holds",
   "reason": "a 12-month gift's statement reads base USD 0, total USD 0; a paid usd_20 account's reads its USD 20.0 base"
  },
  "G1": {
   "check": "promise_readers.first_run",
   "evidence": "-",
   "kind": "formal",
   "plain": {
    "evidence": "- @ 8a819c21",
    "meaning": "Not shown either way: we could not read enough to say it holds, and we found nothing that breaks it.",
    "promise": "A drafted goal never claims more than its checks prove, and says what it covers.",
    "reason": "The goal drafter this promise is about is not in this release yet, so there is nothing to read."
   },
   "reading": "not established",
   "reason": "contingent on the goal drafter (refs #2376), not on main: no drafted goal to read"
  },
  "G2": {
   "check": "promise_readers.surfaces",
   "evidence": "action/build_dist.py (RECORD_RE, FLAG_LINE)",
   "kind": "formal",
   "plain": {
    "evidence": "action/build_dist.py (RECORD_RE, FLAG_LINE) @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "No file a customer reads or commits carries an internal flag or marker.",
    "reason": "We read the 45 files a customer reads or commits (docs, action, skills), and none carries an internal flag or marker."
   },
   "reading": "holds",
   "reason": "no internal record number or flag line on any surface read; 45 files read: docs/customer prose and openapi files, action/action.yml, action/skills, serve/profiles texts, and 5489 output-template literals of serve/render.py, action/entry.py, action/declaration_draft.py, action/withhold.py; docs/customer/samples is not read (served verdict copies)"
  },
  "G3": {
   "check": "promise_readers.surfaces",
   "evidence": "serve/outcomes.py (_TABLE, Refusal.__init__)",
   "kind": "formal",
   "plain": {
    "evidence": "serve/outcomes.py (_TABLE, Refusal.__init__) @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "Every refusal names what was refused and the field or input that fixes it.",
    "reason": "We read all 556 places our API and Action refuse (serve/, action/), and each names what was refused and why."
   },
   "reading": "holds",
   "reason": "556 Refusal( sites in serve/ and action/ read by ast, each with an outcome and a non-empty reason; 31 outcomes of serve/outcomes.py _TABLE each with a non-empty action, and Refusal.__init__ refuses any other outcome"
  },
  "G4": {
   "check": "promise_readers.first_run",
   "evidence": "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",
   "kind": "formal",
   "plain": {
    "evidence": "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 @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "Every served profile answers in readable words on its first run, in its verdict, its summary and its pull-request comment.",
    "reason": "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."
   },
   "reading": "holds",
   "reason": "every served profile (http-observed-baseline, mysql-declared-model, postgresql-declared-model, postgresql-observed-baseline, python-auth-declared-model) answers in words on its first run: every verdict row has its words, every comment rule is named by a sentence, and the summary lines are sentences"
  },
  "G5": {
   "check": "promise_readers.setup_qual",
   "evidence": "docs/validation/feedback-digest/",
   "kind": "premised",
   "plain": {
    "evidence": "docs/validation/feedback-digest/ @ 8a819c21",
    "meaning": "Not shown either way: we could not read enough to say it holds, and we found nothing that breaks it.",
    "premise": "A record of our own loop reading the feedback notes customers filed back over the API, with each one answered or routed.",
    "premised_means": "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.",
    "promise": "Every feedback note a customer files is read back over the API by Symbolia's own loop and answered or routed; none sits unread.",
    "reason": "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/).",
    "record": "none yet: no such record exists under docs/validation/feedback-digest/",
    "record_date": null
   },
   "reading": "not established",
   "reason": "no feedback digest record under docs/validation/feedback-digest/"
  },
  "R1": {
   "check": "http:http-observed-baseline (assure-self)",
   "evidence": "serve/api.py, deploy/Caddyfile (assure/checkers/http-observed-baseline/PROFILE.json#obligations/HTTP-STS-PRESENT)",
   "kind": "formal",
   "plain": {
    "evidence": "serve/api.py, deploy/Caddyfile (assure/checkers/http-observed-baseline/PROFILE.json#obligations/HTTP-STS-PRESENT) @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "Every answer tells browsers to speak to this API over HTTPS only.",
    "reason": "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."
   },
   "reading": "holds",
   "reason": "HTTP-STS-PRESENT holds on every path read (/healthz 200, / 404, /v1/profiles 401) with HEAD https://api.symbolia.ai (served), the tree's own server (serve/api.py) behind deploy/Caddyfile"
  },
  "R2": {
   "check": "http:http-observed-baseline (assure-self)",
   "evidence": "serve/api.py, deploy/Caddyfile (assure/checkers/http-observed-baseline/PROFILE.json#obligations/HTTP-FRAMING-CL-TE)",
   "kind": "formal",
   "plain": {
    "evidence": "serve/api.py, deploy/Caddyfile (assure/checkers/http-observed-baseline/PROFILE.json#obligations/HTTP-FRAMING-CL-TE) @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "No answer states both its length and that it is sent in chunks.",
    "reason": "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."
   },
   "reading": "holds",
   "reason": "HTTP-FRAMING-CL-TE holds on every path read (/healthz 200, / 404, /v1/profiles 401) with HEAD https://api.symbolia.ai (served), the tree's own server (serve/api.py) behind deploy/Caddyfile"
  },
  "R3": {
   "check": "http:http-observed-baseline (assure-self)",
   "evidence": "serve/api.py, deploy/Caddyfile (assure/checkers/http-observed-baseline/PROFILE.json#obligations/HTTP-CACHE-NO-STORE)",
   "kind": "formal",
   "plain": {
    "evidence": "serve/api.py, deploy/Caddyfile (assure/checkers/http-observed-baseline/PROFILE.json#obligations/HTTP-CACHE-NO-STORE) @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "Answers that describe the service are never stored by anything between the server and the customer.",
    "reason": "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."
   },
   "reading": "holds",
   "reason": "HTTP-CACHE-NO-STORE holds on every path read (/healthz 200, / 404, /v1/profiles 401) with HEAD https://api.symbolia.ai (served), the tree's own server (serve/api.py) behind deploy/Caddyfile"
  },
  "R4": {
   "check": "http:http-observed-baseline (assure-self)",
   "evidence": "serve/api.py, deploy/Caddyfile (assure/checkers/http-observed-baseline/PROFILE.json#obligations/HTTP-NOSNIFF-PRESENT)",
   "kind": "formal",
   "plain": {
    "evidence": "serve/api.py, deploy/Caddyfile (assure/checkers/http-observed-baseline/PROFILE.json#obligations/HTTP-NOSNIFF-PRESENT) @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "Browsers are told to take an answer's declared type at its word and never guess it from the bytes.",
    "reason": "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."
   },
   "reading": "holds",
   "reason": "HTTP-NOSNIFF-PRESENT holds on every path read (/healthz 200, / 404, /v1/profiles 401) with HEAD https://api.symbolia.ai (served), the tree's own server (serve/api.py) behind deploy/Caddyfile"
  },
  "R5": {
   "check": "http:http-observed-baseline (assure-self)",
   "evidence": "serve/api.py, deploy/Caddyfile (assure/checkers/http-observed-baseline/PROFILE.json#obligations/HTTP-NO-SET-COOKIE)",
   "kind": "formal",
   "plain": {
    "evidence": "serve/api.py, deploy/Caddyfile (assure/checkers/http-observed-baseline/PROFILE.json#obligations/HTTP-NO-SET-COOKIE) @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "The API never sets a cookie.",
    "reason": "We sent requests to api.symbolia.ai and to our own server code, and every answer read (/healthz, /, /v1/profiles) sets no cookie."
   },
   "reading": "holds",
   "reason": "HTTP-NO-SET-COOKIE holds on every path read (/healthz 200, / 404, /v1/profiles 401) with HEAD https://api.symbolia.ai (served), the tree's own server (serve/api.py) behind deploy/Caddyfile"
  },
  "R6": {
   "check": "identity:python/stdlib-http (assure-self)",
   "evidence": "assure/checkers/identity/adapters/python_stdlib_http/fixtures/assure-self/requirements.md:50",
   "kind": "formal",
   "plain": {
    "evidence": "assure/checkers/identity/adapters/python_stdlib_http/fixtures/assure-self/requirements.md:50 @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "A key issued to one account cannot read another account's verdicts.",
    "reason": "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."
   },
   "read": {
    "R46": "holds"
   },
   "reading": "holds",
   "reason": "as B10: a key reads only its own account's verdicts"
  },
  "R7": {
   "check": "identity:python/stdlib-http (assure-self)",
   "evidence": "assure/checkers/identity/adapters/python_stdlib_http/fixtures/assure-self/requirements.md:43",
   "kind": "formal",
   "plain": {
    "evidence": "assure/checkers/identity/adapters/python_stdlib_http/fixtures/assure-self/requirements.md:43 @ 8a819c21",
    "meaning": "We read this and it is true of this release.",
    "promise": "An API key is never written to any log line.",
    "reason": "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."
   },
   "read": {
    "R39": "holds"
   },
   "reading": "holds",
   "reason": "no logging site names a key; the request log record carries the key id, never its value"
  }
 }
}
