{
  "schema": "ghostget-claims-v2",
  "plan": "kb/plans/formal-verification-assurance.md",
  "notVerified": [
    "Provider behaviour on third-party sites.",
    "Correctness of Bun, JavaScriptCore, the operating-system filesystem beyond the modelled `StatePort` semantics, WHATWG URL parsing (covered only differentially), GitHub, npm, Sigstore, and Vercel.",
    "Hostile in-process plugin code, which `AGENTS.md` already treats as trusted.",
    "Hostile processes running as the same user.",
    "Sentence-level coverage inside a guideline. A guideline counts as covered when its rule lists every claim that quotes it; a sentence of a covered guideline may still have no claim, and review of the guideline digest is the only check."
  ],
  "assumptions": [
    {
      "id": "bun-runtime",
      "statement": "Bun and JavaScriptCore execute the sources and the test runner as specified."
    },
    {
      "id": "filesystem-atomic-rename",
      "statement": "Same-volume rename and link are atomic."
    },
    {
      "id": "filesystem-durability",
      "statement": "Data and directory entries that were fsynced persist across a crash or power loss."
    },
    {
      "id": "same-user-trusted",
      "statement": "Processes running as the same operating-system user are trusted; file modes and owner-only sockets separate users."
    },
    {
      "id": "process-liveness",
      "statement": "Process ID, process start time, and boot identity readings are truthful."
    },
    {
      "id": "monotonic-clock",
      "statement": "The injected monotonic clock never runs backward."
    },
    {
      "id": "whatwg-url",
      "statement": "Bun's URL parser implements the WHATWG URL Standard."
    },
    {
      "id": "dns-tls",
      "statement": "The operating-system resolver and the TLS stack behave as specified."
    },
    {
      "id": "sha256",
      "statement": "SHA-256 is collision resistant."
    },
    {
      "id": "encryption",
      "statement": "The authenticated encryption primitives and the operating-system key storage are sound."
    },
    {
      "id": "media-tools",
      "statement": "yt-dlp, ffmpeg, and whisper.cpp report metadata faithfully and honor the arguments they are given."
    },
    {
      "id": "provider-behaviour",
      "statement": "Third-party providers behave as their observed contracts describe."
    },
    {
      "id": "plugin-trusted",
      "statement": "Source plugins are trusted in-process code; portable execution contains ordinary failures, not hostile code."
    },
    {
      "id": "github-api",
      "statement": "GitHub's REST, GraphQL, and Actions APIs report repository, run, and Release state truthfully."
    },
    {
      "id": "github-enforcement",
      "statement": "GitHub enforces rulesets, environments, concurrency groups, immutable Releases, and token permissions as configured."
    },
    {
      "id": "sigstore",
      "statement": "Sigstore and `gh attestation verify` verify attestation bundles correctly."
    },
    {
      "id": "npm-registry",
      "statement": "The npm registry enforces version immutability, trusted publishing, and provenance as documented."
    },
    {
      "id": "vercel",
      "statement": "Vercel builds and serves deployments as its project settings and APIs report."
    },
    {
      "id": "administrator-readback",
      "statement": "A signed-in administrator performs the documented live readbacks and reports them faithfully."
    },
    {
      "id": "ci-runner",
      "statement": "GitHub-hosted runners execute the reviewed workflow faithfully."
    },
    {
      "id": "verification-tools",
      "statement": "The pinned Quint, Apalache, JDK, elan, and Lean releases are sound for the outcomes they report."
    },
    {
      "id": "edge-runtime",
      "statement": "The Vercel Edge runtime implements the Web Platform APIs the edge code uses."
    }
  ],
  "guides": [
    {
      "path": "AGENTS.md",
      "managedBlocks": [
        {
          "name": "hraness-public-copy",
          "digest": "3bfebb2763dc564771dba1e3ceb04170fce994399b7e6e67437334cf99300cbf",
          "reason": "Synced Hraness public-copy policy for prose; it states no property of the package, CLI, website, or release."
        },
        {
          "name": "hraness-articles",
          "digest": "0a072ea0c181dfdc8e2710f50d2baa4642deaf6e96b887dd988ae9882cc0a6bf",
          "reason": "Synced Hraness article policy for blog posts. website/blog.test.ts checks each post's review record, score, and provenance note and keeps non-indexable posts out of discovery; no automated check covers the prose rules."
        },
        {
          "name": "hraness-launch",
          "digest": "a3ab882bdc9403441f635f765ee3599f88a2c2c1261706f467b24f58f9b951ec",
          "reason": "Synced Hraness launch-kit policy for mockups, the launch post, social kit, and film. website/launch/launch.test.ts pins the launch facts to the provider directory, this register, the homepage, and package.json; no automated check covers the prose rules."
        },
        {
          "name": "hraness-delivery",
          "digest": "a4e0480f3225579f69f3098d42f490c0190b555b60bbfd45659cd2e179df14b0",
          "reason": "Synced Hraness delivery and workstation laws, including production-data preservation, runtime-enforced approvals, and delivery-gate guards; no automated check in this repository covers them."
        },
        {
          "name": "hraness-ci",
          "digest": "1486c84e5fec6062e3c67d4a3509fab274467df31424a8ffc07dc38a900686cf",
          "reason": "Synced Hraness CI baseline for admission speed and the Required gate; it states no property of the package, CLI, website, or release."
        },
        {
          "name": "hraness-releases",
          "digest": "405d2510c33ffd0c5944d2572319206fccaa9308c40b546f2c63e233ba4b92b9",
          "reason": "Synced Hraness release page standard. website/release-notes.test.ts checks the page shape, the changelog section failures, and the trailing identity record; the claim release-receipt-bot-and-body-prefix covers the publication readback."
        },
        {
          "name": "algal-skills",
          "digest": "34d9d322ecc66cbc7608480876028b5dccde1f44631fc6f2198ba9c23d417cab",
          "reason": "Synced contributor tooling instructions for the algal skill pack; it states no property of the package, CLI, website, or release."
        }
      ]
    },
    {
      "path": "edge/AGENTS.md",
      "managedBlocks": []
    },
    {
      "path": "src/control/AGENTS.md",
      "managedBlocks": []
    },
    {
      "path": "verification/AGENTS.md",
      "managedBlocks": []
    },
    {
      "path": "website/AGENTS.md",
      "managedBlocks": []
    }
  ],
  "excludedGuides": [
    {
      "prefix": ".agents/skills/",
      "reason": "Reusable repository-maintenance skill guides; they direct agent workflows and state no property of the package, CLI, website, or release."
    },
    {
      "prefix": "kb/",
      "reason": "Knowledge-vault authoring guides; `bun run kb:check` validates the vault, and they state no product property."
    }
  ],
  "rules": [
    {
      "guide": "AGENTS.md",
      "anchor": "Use Bun 1.3.14. Complete",
      "digest": "04a03c959fcac1804562b47803d63c414cf2507f1161d47b16b55486882d43c3",
      "claims": [
        "ci-source-coverage-contract"
      ]
    },
    {
      "guide": "AGENTS.md",
      "anchor": "CI covers the complete",
      "digest": "b3b5c6eedd590bb7f8187d6bfc5beb3018c4f865fa2ea00a9e403e20eac0481e",
      "claims": [
        "ci-source-coverage-contract"
      ]
    },
    {
      "guide": "AGENTS.md",
      "anchor": "Follow `WRITING.md` for",
      "digest": "01f533e4c8f504f9bf87d3965a3e80e16e3d833cdd4679bd221b8177fa78bf16",
      "exempt": "Prose style rule; it states no property of the package, CLI, website, or release."
    },
    {
      "guide": "AGENTS.md",
      "anchor": "Apply unreasonably robust",
      "digest": "33436be55a1991b5a0abd77c672982730fd6ef8115b53a58ae89a3b58fed8912",
      "exempt": "Engineering method; the laws it asks for are claimed under the example-and-property and lifecycle-model rules."
    },
    {
      "guide": "AGENTS.md",
      "anchor": "Deliver changes to",
      "digest": "d5ddd8b4c3aabff1ab590beea212f00054ef6f5f87df2b7bda8905ea3d1101c3",
      "claims": [
        "protect-main-ruleset"
      ]
    },
    {
      "guide": "AGENTS.md",
      "anchor": "Pin Hraness dependencies",
      "digest": "fea4cfb480cc3e2db31cf85a317dae6768025342556ee01442e5b5c29ce68c38",
      "claims": [
        "hraness-deps-immutable-pins"
      ]
    },
    {
      "guide": "AGENTS.md",
      "anchor": "Extract a shared",
      "digest": "0a6c062ce46c3d63971138aefb093fa5ce46faab0b0632f44aa0bf21edab9826",
      "exempt": "Package-extraction process rule; it states no property of shipped behaviour."
    },
    {
      "guide": "AGENTS.md",
      "anchor": "For UI work, consume",
      "digest": "c797148100753b64a06d07c817723780770b44ee86ad9d98995e6f8472b054b5",
      "claims": [
        "hraness-deps-immutable-pins"
      ]
    },
    {
      "guide": "AGENTS.md",
      "anchor": "Freeze shared interfaces",
      "digest": "19c68a6f3179b717e43fea22bd8cb061ea77e2310599a63fd2e4544fcd019fdd",
      "exempt": "Parallel-work coordination rule for contributors; it states no property of shipped behaviour."
    },
    {
      "guide": "AGENTS.md",
      "anchor": "Keep mandatory rules",
      "digest": "922413428d559a12875c06b57cf548fd9517d9ae965c247d84df8db54c4f1df5",
      "exempt": "Documentation placement rule; `bun run kb:check` validates guide shape."
    },
    {
      "guide": "AGENTS.md",
      "anchor": "Keep Ghostget a bring-your-own-agent",
      "digest": "f1b0792d6bf160325b1f936c8e752944f739867334eaeac30a287744196855e7",
      "exempt": "Product-scope rule; no automated check covers it, and it states no safety or integrity property."
    },
    {
      "guide": "AGENTS.md",
      "anchor": "Keep exactly one",
      "digest": "83595470b91701607d5b181c7bee58b076c35c1d43f322b32b17398849b11262",
      "exempt": "Skill-packaging rule; it states no safety or integrity property."
    },
    {
      "guide": "AGENTS.md",
      "anchor": "Keep `website/` informational:",
      "digest": "4441f3ef230757117da50c0f5c425fadb1d4347a37e48c868dc28129fff18d64",
      "claims": [
        "website-informational-only"
      ]
    },
    {
      "guide": "AGENTS.md",
      "anchor": "Keep the package",
      "digest": "261ce9fd568f28911279f1155443465444ac9e0c8c714a2947a7b37a86b5e086",
      "claims": [
        "package-root-import-inert"
      ]
    },
    {
      "guide": "AGENTS.md",
      "anchor": "Expose bounded semantic",
      "digest": "4b89180c66920ab6af7d2e918f1f48af5d793739a0e5f24a6b19e7bf0a05504f",
      "claims": [
        "no-caller-selected-raw-controls",
        "web-gateway-policy-admitted-https-only",
        "web-gateway-pinned-transport",
        "web-gateway-durable-audit-precedes-network"
      ]
    },
    {
      "guide": "AGENTS.md",
      "anchor": "Keep media acquisition",
      "digest": "334727c4be56daed3f21d69bcde511551135ac72dbc52fcd66f289bc466d6cac",
      "claims": [
        "media-single-finite-item",
        "media-reject-drm-auth-bypass",
        "media-promote-only-after-verification"
      ]
    },
    {
      "guide": "AGENTS.md",
      "anchor": "Treat source plugins",
      "digest": "117b62a4830e03d385fa9c603a6c3cfbb66c2b577795db5841120cdd5861af15",
      "claims": [
        "portable-plugin-explicit-trust",
        "portable-host-capability-denial"
      ]
    },
    {
      "guide": "AGENTS.md",
      "anchor": "Parse every foreign",
      "digest": "ebb31571d51114853f2d48fceaa0ca82196cf3569f847ae92a5d5d914dacb6e4",
      "claims": [
        "strict-foreign-parsing",
        "verification-itf-strict"
      ]
    },
    {
      "guide": "AGENTS.md",
      "anchor": "Keep installed support",
      "digest": "08d7906185cff7a1a39e9301bb081325f3c6ac525e4e37822b86aed7383e7c05",
      "claims": [
        "catalog-unique-ownership"
      ]
    },
    {
      "guide": "AGENTS.md",
      "anchor": "Keep built-in durable",
      "digest": "e1355d1f0bb1fd466e68666ebf048d1afc87e9e30c3f1a58d9da01cf1bac2c0f",
      "claims": [
        "contract-hash-environment-invariant",
        "contract-closure-lazy-revalidation",
        "portable-identity-artifact-bound"
      ]
    },
    {
      "guide": "AGENTS.md",
      "anchor": "Bind every authenticated",
      "digest": "bb225298908cfc6cfdbd974226219eae3b4ef629a69ea69c9fe7ec1558fd9d9a",
      "claims": [
        "auth-request-binding",
        "no-silent-transport-switch"
      ]
    },
    {
      "guide": "AGENTS.md",
      "anchor": "Keep mutations behind",
      "digest": "6c1b57c08ce5d6b78885085633120f5491b9635f02be0d906ddcecdb6e523f8b",
      "claims": [
        "mutation-exact-preview-confirmation",
        "confirmed-write-at-most-once",
        "portable-retained-release",
        "indeterminate-never-retried",
        "indeterminate-cleared-only-by-evidence"
      ]
    },
    {
      "guide": "AGENTS.md",
      "anchor": "Keep raw authenticated",
      "digest": "b411993227481d73cec767f174f12b27bde314ee87354380111a3eb91dbd193c",
      "claims": [
        "secrets-out-of-artifacts"
      ]
    },
    {
      "guide": "AGENTS.md",
      "anchor": "Pair concrete behavior",
      "digest": "6010a3de6abb915c885ce7916f61cc7029f220347f2700b23022e7193f33ed24",
      "claims": [
        "identifier-roundtrip"
      ]
    },
    {
      "guide": "AGENTS.md",
      "anchor": "Model consequential lifecycle",
      "digest": "cbccd27b03f72885e2785c620ad75e079af93d02ffecda9092a506e2ade140fd",
      "claims": [
        "property-seed-replay",
        "lifecycle-injected-clocks",
        "verification-shrink-promotion"
      ]
    },
    {
      "guide": "AGENTS.md",
      "anchor": "Keep the Bun runner",
      "digest": "e725eff065f68cf5517187961cc9af8a240eb394efb7e7d370f238b92ce4add1",
      "claims": [
        "runner-timeout-policy"
      ]
    },
    {
      "guide": "AGENTS.md",
      "anchor": "Treat a checker timeout,",
      "digest": "27f3f1fb1faa0f8d523b2efd9703c277230892910615b16d515874d70ca389e4",
      "claims": [
        "verification-inconclusive-not-evidence"
      ]
    },
    {
      "guide": "AGENTS.md",
      "anchor": "Count a Quint model",
      "digest": "cf5c1582b8c29733c252c44ae1898005b671967142bd947fbd618b6f3fc650d4",
      "claims": [
        "verification-quint-smoke",
        "verification-model-replay-required"
      ]
    },
    {
      "guide": "AGENTS.md",
      "anchor": "Promote every recorded",
      "digest": "392cafa46eb2db0567c0390e0737063be6bf2da87486f45a9353f4f154d72753",
      "claims": [
        "verification-shrink-promotion"
      ]
    },
    {
      "guide": "AGENTS.md",
      "anchor": "Pin Quint, Apalache,",
      "digest": "3e03126462af081c8720140567274301d0f78312cfaa3799d0deff0ebb789edb",
      "claims": [
        "verification-tools-pinned"
      ]
    },
    {
      "guide": "AGENTS.md",
      "anchor": "When you add or change",
      "digest": "15c69c605f640fad53e29f515cd377e08ce6e9b622935fc01e7bd60eea2b81b1",
      "claims": [
        "verification-register-complete",
        "verification-claim-scope"
      ]
    },
    {
      "guide": "AGENTS.md",
      "anchor": "Treat this repository",
      "digest": "020865a99fea66baf8beda5b9f89b95c4bb9be854541554cc25e677c3421a33d",
      "exempt": "Editorial scope rule for repository prose; no automated check covers it."
    },
    {
      "guide": "AGENTS.md",
      "anchor": "Follow `docs/publishing.md` for",
      "digest": "ebda3186be651ae04901f89e2ecfacf91f3cf53bdd171f1cfee798aaf4e5a72d",
      "claims": [
        "release-tag-direct-lightweight",
        "release-attest-checkout-free-reauthorized",
        "release-five-file-contract",
        "release-failed-jobs-rerun-recovers-publish",
        "release-workflow-isolation",
        "npm-publish-after-canonical-only",
        "npm-failure-never-blocks-canonical",
        "npm-no-token-no-staged-no-dispatch",
        "immutable-releases-enabled-before-tag"
      ]
    },
    {
      "guide": "AGENTS.md",
      "anchor": "Treat the Release",
      "digest": "a26e2705378a84214653ab0c2b8cebd4c9b6f1395faa9f2763fa7960bcc8b8dd",
      "claims": [
        "mutable-presentation-not-authority"
      ]
    },
    {
      "guide": "AGENTS.md",
      "anchor": "Keep the `npm-release`",
      "digest": "bcfec7c6fd743878ccdf6a8aa2df2a29ceb26ed19ce8d8a75fb12c2090d981d0",
      "claims": [
        "npm-release-env-sole-reference",
        "npm-release-env-config",
        "npm-trusted-publisher-binding"
      ]
    },
    {
      "guide": "AGENTS.md",
      "anchor": "At setup, after any",
      "digest": "5bbdba1d796aabf05f10d2c0d9a7821ed789beb6363977d8c058e52d9a723039",
      "claims": [
        "tag-ruleset-creation-only",
        "tag-ruleset-immutable",
        "tag-rulesets-two-split-pairs",
        "no-integration-tag-bypass",
        "protect-main-ruleset",
        "vercel-project-config"
      ]
    },
    {
      "guide": "AGENTS.md",
      "anchor": "`.github/workflows/auto-tag.yml` releases",
      "digest": "444e9a6014b24b99f0d14ab92d3952c14884bec7aa1f120b750ead8c9bb33994",
      "exempt": "Release delegation: auto-tag and owner-session tagging govern who creates the tag, while the release-entry, reauthorization, ruleset, and readback claims cover what must hold."
    },
    {
      "guide": "AGENTS.md",
      "anchor": "Bind every Release",
      "digest": "7109211194f848477134cfb76a1b3579d1863e1d7faf69f7b6a7b8c7e396f8a7",
      "claims": [
        "release-trigger-exact-tag-push-only",
        "release-reauthorize-attempt-before-checkout",
        "release-reauthorize-only-actions-read"
      ]
    },
    {
      "guide": "AGENTS.md",
      "anchor": "Before `publish_npm` sets",
      "digest": "f084c6401d5ec910b17a4328c2df347a430fcf48543fca9ee492635ed369c772",
      "claims": [
        "npm-reauthorize-before-oidc",
        "npm-artifact-by-numeric-id-bound",
        "npm-clean-defaults-latest-tag",
        "npm-admit-registry-identity-provenance",
        "npm-reread-canonical-before-publish",
        "npm-packed-manifest-publication-settings",
        "npm-registry-state-admission"
      ]
    },
    {
      "guide": "AGENTS.md",
      "anchor": "The `@hraness/ghostget` npm",
      "digest": "6d2c9682861a9202860570f4d80bc9c883770419bf23f7550ea42711ef8d5a05",
      "claims": [
        "npm-no-content-policy"
      ]
    },
    {
      "guide": "AGENTS.md",
      "anchor": "A matching archive",
      "digest": "0a5f8c27d65bb7d71ddd7d1a9714f22a94d3662f5707413204fccfa5ddf45c27",
      "claims": [
        "release-attestation-before-mutation"
      ]
    },
    {
      "guide": "AGENTS.md",
      "anchor": "`costs.json` at the",
      "digest": "c44f8aec6f670f5c834b844c6341eb30e6bf6f1799bdf8d9cd3e2aa383bc846b",
      "claims": [
        "cost-surface-registry"
      ]
    },
    {
      "guide": "AGENTS.md",
      "anchor": "Bound every input",
      "digest": "308bafb0200b0b64ce578e6f0f3c7c003d11bc4611572d8abd0749cedba2cad1",
      "claims": [
        "bounded-inputs"
      ]
    },
    {
      "guide": "AGENTS.md",
      "anchor": "No writes on read",
      "digest": "60e82065129c0dcb3faa5540e64502ec93039b6de2c966216817c54aeeccfedd",
      "claims": [
        "no-writes-on-read-paths",
        "read-path-read-capability",
        "tui-snapshot-read-only",
        "read-path-auth-check-read-only",
        "read-projection-admission-exemption",
        "read-path-preparation-read-only",
        "read-projection-key-exemption"
      ]
    },
    {
      "guide": "AGENTS.md",
      "anchor": "`repair-signals` is a",
      "digest": "26580b332f602a30309d0b140bb5a19e0253a99c7e6a27ae4c759e100b774b9c",
      "claims": [
        "repair-signals-private",
        "repair-inspection-no-demand",
        "repair-handoff-no-authority"
      ]
    },
    {
      "guide": "AGENTS.md",
      "anchor": "Derived state is",
      "digest": "ca28b8a18860f357379e3011a62a0bf11d7faa76bd0278fd311d1128c8dbbda3",
      "claims": [
        "derived-state-rebuildable"
      ]
    },
    {
      "guide": "AGENTS.md",
      "anchor": "Every mutation carries",
      "digest": "9b3a925b95b4d8f64f3d4ae75a647846875507a358c44b68e963186094a17be9",
      "claims": [
        "mutation-idempotency-key"
      ]
    },
    {
      "guide": "AGENTS.md",
      "anchor": "Analytics and metering",
      "digest": "2fac5cdd5fe9d2a772bb68388b3acd53267f7b1c7ac7270525d93db88621c5ba",
      "claims": [
        "analytics-allowlist-byte-ceiling"
      ]
    },
    {
      "guide": "AGENTS.md",
      "anchor": "Content bytes live",
      "digest": "a3ea1cbb18b40da26bd6a6d1205008169a1a3d4946164f7d02df7fbe0a194ec2",
      "claims": [
        "content-bytes-in-content-store"
      ]
    },
    {
      "guide": "AGENTS.md",
      "anchor": "Run `bun run check:cost-surfaces`",
      "digest": "a1dcb08ead7a301c9d4829f1306f0cd6ddf6ebdfaba0598a862d17c1cfa77384",
      "claims": [
        "cost-surface-registry"
      ]
    },
    {
      "guide": "edge/AGENTS.md",
      "anchor": "Keep every file here",
      "digest": "1edc6f655fecadcfd37968e69e4c35a3af5e9285e1ec15da36bf39c4e7db44f8",
      "claims": [
        "edge-no-node-imports"
      ]
    },
    {
      "guide": "edge/AGENTS.md",
      "anchor": "Honor Accept q-values,",
      "digest": "02842091349ded955e9e928eff4c60a197549350603be428d18a7d6d658ee8e2",
      "claims": [
        "edge-accept-406-only-when-empty",
        "edge-vary-accept"
      ]
    },
    {
      "guide": "edge/AGENTS.md",
      "anchor": "Unknown document paths",
      "digest": "da952cf175678f6b368df4e330979aa50e3f296fac9ac3539b6be2b1f1f791d2",
      "claims": [
        "edge-unknown-404"
      ]
    },
    {
      "guide": "src/control/AGENTS.md",
      "anchor": "`protocol.ts` is the",
      "digest": "9a2306f4269aa9506bc7ef0ad1d97078e5799b2d71d0f929fcef216aeb8729ab",
      "claims": [
        "agent-channel-cannot-escalate",
        "control-verbs-human-gated",
        "control-protocol-bounded-reject-drift",
        "tui-input-cannot-bypass-review",
        "tui-restores-terminal-state",
        "control-single-helper-owner"
      ]
    },
    {
      "guide": "src/control/AGENTS.md",
      "anchor": "`service.ts` composes current",
      "digest": "60f389510d09bd2f7b66bb5f9d1b2ae54d0c53aae913b53a33b69874426e581f",
      "claims": [
        "openapi-inert-until-activation",
        "no-cached-authorization-across-change"
      ]
    },
    {
      "guide": "src/control/AGENTS.md",
      "anchor": "`web-policy.ts`, `web-gateway.ts` and",
      "digest": "726925ec349b40d8a7d9d6c26f61d1bee5b65923f8bd4efb4e51b80285abe591",
      "claims": [
        "web-gateway-pinned-transport",
        "gateway-rejects-private-addresses",
        "web-gateway-durable-audit-precedes-network",
        "gateway-activity-excludes-sensitive"
      ]
    },
    {
      "guide": "src/control/AGENTS.md",
      "anchor": "Connection and helper shutdown",
      "digest": "b74b15450711232c076242ca6010dc7bdff5b25346127d3583f466fe2495144e",
      "claims": [
        "shutdown-settles-before-custody-release"
      ]
    },
    {
      "guide": "verification/AGENTS.md",
      "anchor": "Keep this directory,",
      "digest": "609e4c4ac2427b7bffde96c908965bd068666564ef4671499121d6d51da43be3",
      "claims": [
        "verification-unpublished"
      ]
    },
    {
      "guide": "verification/AGENTS.md",
      "anchor": "Change a claim together",
      "digest": "d91d8ac6b98ea18adcb8ea17dcdf69c0827c040a524ddfe12517436dab7a1d19",
      "claims": [
        "verification-claim-scope"
      ]
    },
    {
      "guide": "verification/AGENTS.md",
      "anchor": "Record every Quint",
      "digest": "f30a2b9a673543fabbefc671aee75168540ee5d7e01cc8e96ee3e9c4df778305",
      "claims": [
        "verification-model-replay-required"
      ]
    },
    {
      "guide": "verification/AGENTS.md",
      "anchor": "Give a Quint model `nightly`",
      "digest": "dba8a285d34fd63e049ad92b6075c24df1f8fd46afb57658a0772ccaa653ac9a",
      "claims": [
        "verification-nightly-depth"
      ]
    },
    {
      "guide": "verification/AGENTS.md",
      "anchor": "List every reducer source",
      "digest": "52bcb0843fe0e9d8ae90b373dda3b5130c5a3e3f443b686fbdce2d4861a4192f",
      "claims": [
        "verification-source-mutants"
      ]
    },
    {
      "guide": "verification/AGENTS.md",
      "anchor": "Keep the Lean project",
      "digest": "e6cafc5d709902a85345bd4212e0f83b9ddb360f831c6bb272c0ee9037e95c2b",
      "claims": [
        "verification-lean-trusted-base"
      ]
    },
    {
      "guide": "verification/AGENTS.md",
      "anchor": "Keep generated traces,",
      "digest": "d34fe5068d3f632120be811005a6545778e06ab543fef1b32126f785956977cd",
      "claims": [
        "verification-unpublished"
      ]
    },
    {
      "guide": "verification/AGENTS.md",
      "anchor": "Run every fast-check",
      "digest": "7df39d14c30575c4c00960e03d5f2074b31616bb0d6ae954c317e7f3a2a3cac1",
      "claims": [
        "property-seed-replay",
        "verification-shrink-promotion"
      ]
    },
    {
      "guide": "verification/AGENTS.md",
      "anchor": "For a soak,",
      "digest": "dae3bb8431187d1cb2e3842e7c2cdab6fe9324e55d8f876b611e29abecfb15cf",
      "claims": [
        "property-soak-multiplier"
      ]
    },
    {
      "guide": "website/AGENTS.md",
      "anchor": "Keep the homepage's",
      "digest": "4d7522fc40358d1097d16614adf75f39da08c9e811da608a39e0df41eb02251a",
      "exempt": "Presentation rule for the informational website; it states no safety or integrity property."
    },
    {
      "guide": "website/AGENTS.md",
      "anchor": "Ordinary HTML pages",
      "digest": "9a65ce2e380571249f1599a78038f25946da703bb359fb199a77671af096f7c8",
      "exempt": "Presentation rule for the informational website; it states no safety or integrity property."
    },
    {
      "guide": "website/AGENTS.md",
      "anchor": "Keep the page useful",
      "digest": "06f62cdf536a9556d356b62f6aacbc237f8e69deeb1c2962ad8c45ceb28648d8",
      "exempt": "Presentation rule for the informational website; it states no safety or integrity property."
    },
    {
      "guide": "website/AGENTS.md",
      "anchor": "Keep every product",
      "digest": "b724aa34d496cfce87d638c2b9b1b9f86ce66cfd3ed1c8e37e0a930e3cb2af2c",
      "exempt": "Editorial accuracy rule for website copy; no automated check covers it."
    },
    {
      "guide": "website/AGENTS.md",
      "anchor": "Derive release identity",
      "digest": "596d63d7d1165351776479ad9e333d68f8005d4c4ef89c414d9bf5e8f44b053c",
      "claims": [
        "website-release-identity-from-package"
      ]
    },
    {
      "guide": "website/AGENTS.md",
      "anchor": "Keep the Agent Skill",
      "digest": "72a871d8cb23e0674100f47fc8944b9a8ebf916fac583471f22f6ed24abfd95f",
      "claims": [
        "website-release-identity-from-package"
      ]
    },
    {
      "guide": "website/AGENTS.md",
      "anchor": "Keep the checked-in",
      "digest": "2b98cb24a1a49981bcb48aa1cd2e5149a20de188eee07864f758c2f961ef3c4a",
      "claims": [
        "vercel-build-admission-fail-closed",
        "preview-builds-independent"
      ]
    },
    {
      "guide": "website/AGENTS.md",
      "anchor": "Keep Vercel project",
      "digest": "48f2d8998279059b2a74c9938ac8e1cc6a2f061e18b6367c2a438e5520b05de3",
      "claims": [
        "website-no-vercel-mutation-in-workflows",
        "vercel-project-config"
      ]
    },
    {
      "guide": "website/AGENTS.md",
      "anchor": "Keep canonical metadata,",
      "digest": "3b3f0c5251dcd711b6251cb4eb34659144cc43a9decd0b03b601bd77f3acd91a",
      "exempt": "Search-metadata presentation rule; it states no safety or integrity property."
    },
    {
      "guide": "website/AGENTS.md",
      "anchor": "Share images come only",
      "digest": "63f59838cd0f1d27b2d67298b4b41343749f88ec382b10c419257e66512ba472",
      "exempt": "Social-image presentation rule; it states no safety or integrity property."
    },
    {
      "guide": "website/AGENTS.md",
      "anchor": "Keep ordinary reference",
      "digest": "565a9105cb81bd4643ec63da534bf4efebbb4506d1a519638a05f56797818b63",
      "exempt": "Presentation rule for website guides and editorial images; it states no safety or integrity property."
    },
    {
      "guide": "website/AGENTS.md",
      "anchor": "The HTML 404 renders",
      "digest": "c34425a70895c13e96541c1283f008b887acf1aeb5c5b848209ca84c603964d9",
      "exempt": "Presentation rule for the informational website; it states no safety or integrity property."
    },
    {
      "guide": "website/AGENTS.md",
      "anchor": "Public content pages",
      "digest": "8a064dd611e5b50e576beda80d2208546bcc3dcc0a7f559e7536620032f5a0bd",
      "claims": [
        "edge-accept-406-only-when-empty",
        "edge-vary-accept",
        "edge-unknown-404"
      ]
    },
    {
      "guide": "website/AGENTS.md",
      "anchor": "Keep analytics canonical-host-only,",
      "digest": "ecd60a698093267d53dfe30e5af5528b9ffe124e38549e9e1871d0fea7ce60ca",
      "claims": [
        "analytics-allowlist-byte-ceiling"
      ]
    },
    {
      "guide": "website/AGENTS.md",
      "anchor": "Do not add private",
      "digest": "4efd0e5d5c57d95a78e23dec31eb90723e5dc579c71386fdbe4cc976bb1ac365",
      "claims": [
        "analytics-allowlist-byte-ceiling"
      ]
    },
    {
      "guide": "website/AGENTS.md",
      "anchor": "Preserve semantic headings,",
      "digest": "283268b644f8710c0a1a910f1b40dc181980c07d351fca610841630b52e6e339",
      "exempt": "Accessibility presentation rule; it states no safety or integrity property."
    },
    {
      "guide": "website/AGENTS.md",
      "anchor": "Public copy (page",
      "digest": "5f77956c52f5a40f202d481b25d7529cbefa19022d4cb81ffd47fbfb6525a42d",
      "exempt": "Public-copy style rule; it states no safety or integrity property."
    },
    {
      "guide": "website/AGENTS.md",
      "anchor": "The one-line description",
      "digest": "1d5350bff03a0c907e2e2249266fa224518b78d9be2692d8174a2e8586e286b1",
      "exempt": "Public-copy consistency rule that the website build enforces; it states no safety or integrity property."
    },
    {
      "guide": "website/AGENTS.md",
      "anchor": "On a public page,",
      "digest": "4c1a10f0703d28481d287727610bef9ab34ddcf11128354375ccca04ba28b424",
      "exempt": "Public-copy vocabulary rule; it states no safety or integrity property."
    },
    {
      "guide": "website/AGENTS.md",
      "anchor": "Describe a sibling",
      "digest": "849bce5d8099234d6ddbd47c1abc89235c590fe53eb82df31f68c216793ea8e6",
      "exempt": "Editorial accuracy rule for sibling-product copy; no automated check covers it."
    },
    {
      "guide": "website/AGENTS.md",
      "anchor": "Use product names",
      "digest": "0549aa77a44f2dc46d4dfcba85087a549461e179348f24479fe3767a260db887",
      "exempt": "Public-copy naming rule; it states no safety or integrity property."
    }
  ],
  "claims": [
    {
      "id": "package-root-import-inert",
      "statement": "Importing the package root `@hraness/ghostget` does not start the CLI, inspect local state, load built-in providers, or access the network.",
      "area": "runtime",
      "source": {
        "path": "AGENTS.md",
        "quote": "Keep the package root import side-effect-free. Importing `@hraness/ghostget` must not start the CLI, inspect local state, load built-in providers, or access the network."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "scripts/package-smoke.ts",
        "src/cli.test.ts",
        "src/contracts.test.ts"
      ],
      "assumptions": [
        "bun-runtime"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked.",
        "The package smoke guards filesystem, HTTP, DNS, socket, and fetch entry points while it imports the packed root; it does not intercept child processes or environment reads."
      ]
    },
    {
      "id": "runner-timeout-policy",
      "statement": "Bun runner timeout and concurrency live only in package.json; no test calls setDefaultTimeout or passes per-test runner timeouts.",
      "area": "runtime",
      "source": {
        "path": "AGENTS.md",
        "quote": "Keep the Bun runner timeout and concurrency policy in `package.json`; test bodies"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/test-harness-policy.test.ts"
      ],
      "assumptions": [
        "bun-runtime"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "property-seed-replay",
      "statement": "Every fast-check property runs through assertProperty or assertAsyncProperty, so GHOSTGET_PROPERTY_SEED and GHOSTGET_PROPERTY_PATH replay, the seed corpus, and the soak multiplier apply; no other fast-check runner appears outside test-support.",
      "area": "runtime",
      "source": {
        "path": "AGENTS.md",
        "quote": "retain fast-check's seed and shrink path. Replay one exact property with `GHOSTGET_PROPERTY_SEED`, `GHOSTGET_PROPERTY_PATH`"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/test-harness-policy.test.ts",
        "src/test-support.test.ts"
      ],
      "assumptions": [
        "bun-runtime"
      ],
      "notVerified": [
        "The policy scan is static: it follows fast-check's default, namespace, and named imports, the `fc` re-export of `test-support`, and dynamic loads by literal specifier, but not a runner reached through another module's re-export or a computed member name.",
        "It covers `src/`, `scripts/`, `edge/`, and `website/`; tests elsewhere are not scanned."
      ],
      "alsoQuotes": [
        {
          "path": "verification/AGENTS.md",
          "quote": "Run every fast-check property through `assertProperty` or `assertAsyncProperty` from `src/test-support.ts`"
        }
      ]
    },
    {
      "id": "property-soak-multiplier",
      "statement": "GHOSTGET_PROPERTY_RUNS accepts only a canonical integer from 1 to 100 and multiplies every helper-run property's run count and interruption budget, including seed corpus replays.",
      "area": "verification",
      "source": {
        "path": "verification/AGENTS.md",
        "quote": "For a soak, set `GHOSTGET_PROPERTY_RUNS` to an integer from 1 to 100."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/test-support.test.ts"
      ],
      "assumptions": [
        "bun-runtime"
      ],
      "notVerified": [
        "No nightly workflow runs the soak yet; the multiplier is checked only in a child process at multiplier 3.",
        "The soak's runner timeout is set on its command line, so a soak that outgrows it fails as a runner timeout rather than a property failure."
      ]
    },
    {
      "id": "lifecycle-injected-clocks",
      "statement": "Consequential lifecycle reducers take injected clocks and randomness; wall-clock jumps cannot extend or prematurely expire leases or proofs.",
      "area": "runtime",
      "source": {
        "path": "AGENTS.md",
        "quote": "keep clocks and randomness injected"
      },
      "layer": "stateful-model",
      "status": "evidenced",
      "evidence": [
        "src/control/approval-broker-clock.model.test.ts",
        "src/control/approval-broker.test.ts",
        "src/control/gateway.test.ts",
        "src/effect-architecture.test.ts",
        "src/linked-device-lifecycle-journal.property.test.ts"
      ],
      "assumptions": [
        "bun-runtime",
        "monotonic-clock"
      ],
      "notVerified": [
        "The stateful model covers the approval broker's pending requests and allow-once grants: their expiry follows only the injected monotonic clock across wall-clock jumps of up to ten days either way, applied to both the injected wall clock and the ambient `Date.now()`. Other lifecycle reducers, such as the portable plugin invocation leases and the linked-device lifecycle journal, are not modelled under clock jumps; they rely on their example and property tests and on the effect-architecture rule that rejects ambient clocks and randomness in checked modules.",
        "The default monotonic clock is `performance.now()`; the model injects it and does not check that the platform clock is itself monotonic, which is the `monotonic-clock` assumption.",
        "Injected randomness is covered only by the effect-architecture ambient-random rule, not by a model."
      ],
      "properties": [
        {
          "path": "src/control/approval-broker-clock.model.test.ts",
          "test": "property: pending requests and allow-once grants expire by the injected monotonic clock alone, whatever the wall clock does"
        }
      ]
    },
    {
      "id": "no-caller-selected-raw-controls",
      "statement": "No semantic provider operation or gateway call accepts caller-selected provider headers, cookies, selectors, scripts, shell commands, or arbitrary file paths; such inputs are rejected before any provider I/O.",
      "area": "providers",
      "source": {
        "path": "AGENTS.md",
        "quote": "Never add caller-selected provider headers, cookies, selectors, scripts, shell commands, or arbitrary file access."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/client-boundary.test.ts",
        "src/model.test.ts",
        "src/provider-plugin-host.test.ts",
        "src/runtime.test.ts"
      ],
      "assumptions": [
        "provider-behaviour"
      ],
      "notVerified": [
        "No property test covers this law yet; only the enumerated example cases are checked."
      ]
    },
    {
      "id": "web-gateway-policy-admitted-https-only",
      "statement": "The public web gateway dispatches only bounded HTTPS GET and HEAD retrieval requests that the web policy admits, with no request body and no ambient authentication.",
      "area": "web-gateway",
      "source": {
        "path": "AGENTS.md",
        "quote": "The separate public web gateway accepts only explicitly policy-admitted HTTPS retrieval URLs"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/control/gateway.test.ts",
        "src/control/interface-cli.test.ts",
        "src/control/validation.test.ts",
        "src/operation-permission.property.test.ts"
      ],
      "assumptions": [
        "filesystem-durability",
        "whatwg-url",
        "dns-tls"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "web-policy-deny-dominates",
      "statement": "Web policy decision is default-deny; deny beats ask beats allow, adding a deny rule never widens the result, and domain/path/query-key prefix matching is exact.",
      "area": "web-gateway",
      "source": {
        "path": "SECURITY.md",
        "quote": "under explicit domain, path, and query-key rules"
      },
      "layer": "lean",
      "status": "evidenced",
      "evidence": [
        "verification/lean/GhostgetVerification/WebPolicy.lean",
        "verification/lean/Differential.lean",
        "scripts/verification-lean-oracle.ts",
        "scripts/verification-lean-web-policy.test.ts",
        "src/control/gateway.test.ts",
        "src/control/validation.test.ts"
      ],
      "assumptions": [
        "filesystem-durability",
        "whatwg-url",
        "dns-tls"
      ],
      "notVerified": [
        "The Lean model covers the decision, the limits, and rule matching in checkWebRequest over parsed rules and an already parsed URL. WHATWG URL parsing, publicUrl, parseWebRule, and DNS and TLS are assumptions, not proofs.",
        "Strings are modelled as lists of characters. That equals the production UTF-16 startsWith only because parseWebRule and publicUrl admit ASCII origins, paths, and query keys; the proof does not check that admission.",
        "The differential test runs the unchanged web-policy.ts over an in-memory private state store, not the real store and its helper. It samples three origins, one a string prefix of another, three path segments, and four query keys, so it checks only its generated cases."
      ]
    },
    {
      "id": "web-gateway-pinned-transport",
      "statement": "Gateway retrieval uses the pinned transport: one validated DNS address, redirects disabled, revocation/cancellation rechecked after DNS before dispatch, and no retry to another address after an ambiguous transport failure.",
      "area": "web-gateway",
      "source": {
        "path": "AGENTS.md",
        "quote": "through its pinned transport and durable audit boundary."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/control/gateway.test.ts",
        "src/pinned-https.test.ts"
      ],
      "assumptions": [
        "filesystem-durability",
        "whatwg-url",
        "dns-tls"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ],
      "alsoQuotes": [
        {
          "path": "src/control/AGENTS.md",
          "quote": "no redirects or ambient credentials"
        }
      ]
    },
    {
      "id": "gateway-rejects-private-addresses",
      "statement": "The gateway rejects private, loopback, and other non-public addresses (including IPv4-mapped IPv6) after resolution.",
      "area": "web-gateway",
      "source": {
        "path": "SECURITY.md",
        "quote": "private addresses"
      },
      "layer": "differential",
      "status": "evidenced",
      "evidence": [
        "src/public-address.ts",
        "src/public-address.test.ts",
        "src/pinned-https.test.ts",
        "src/control/validation.test.ts",
        "verification/vectors/generate.py",
        "verification/vectors/addresses.json",
        "scripts/verification-vectors.test.ts"
      ],
      "assumptions": [
        "filesystem-durability",
        "whatwg-url",
        "dns-tls"
      ],
      "notVerified": [
        "The pinned transport checks every resolved answer with Ghostget's own allowlist, `src/public-address.ts`, because the `@hraness/wordcell` 0.24.0 resolver admits the IPv4-translated range `::ffff:0:0:0/96`, the rest of `::/8`, IPv6 outside `2000::/3`, and `192.88.99.0/24` (`kb/plans/kb-ip-classifier-proposal.md`). The Wordcell check still runs first, so its over-blocking of `192.0.0.0/16` still refuses those addresses.",
        "The Python generator restates the same IANA special-purpose table from the registries, independently of the TypeScript, and compares verdicts on block edges, seeded random addresses, embedded IPv4 forms, and text forms. A row missing from both tables would not be caught; the vectors check the implementation of the table, not the table against the live registries.",
        "Page capture, derivation, and the derivation network proxy (`src/browser.ts`, `src/derive.ts`, `src/model.ts`, `src/derivation-network-proxy.ts`) still rely on the Wordcell classifier alone; this claim covers the gateway's pinned transport only.",
        "DNS answers, the operating system's socket layer, and TLS are assumed; the check covers the address the transport connects to, not routing beyond it."
      ],
      "alsoQuotes": [
        {
          "path": "src/control/AGENTS.md",
          "quote": "public pinned DNS"
        }
      ]
    },
    {
      "id": "public-url-matches-url-crate-oracle",
      "statement": "`publicUrl` makes the same admission decision as an independent reading of the web gateway URL policy over the Rust `url` crate, and every URL that either side admits parses to the same WHATWG components.",
      "area": "web-gateway",
      "source": {
        "path": "kb/plans/formal-verification-assurance.md",
        "quote": "a `url`-crate differential for `publicUrl`"
      },
      "layer": "differential",
      "status": "evidenced",
      "evidence": [
        "verification/oracles/src/url_policy.rs",
        "scripts/verification-oracles.test.ts"
      ],
      "assumptions": [
        "whatwg-url"
      ],
      "notVerified": [
        "URL candidates come from a sampled grammar plus named examples; this is not a proof over all strings.",
        "The oracle restates the written policy, so a rule that the policy text and the implementation both omit goes unnoticed.",
        "Known parser differences are named in the test and checked to leave the gateway refusing the input: Bun percent-encodes `^` in paths and the `url` crate 2.5.8 does not; Bun accepts an IPv6 literal such as `[::1:]` and drops the leading `/.` from a non-special path such as `m:/.a`; and the `url` crate keeps a drive-letter segment such as `c:` before `..` in an https: path.",
        "Address classification after DNS resolution is a separate claim, `gateway-rejects-private-addresses`."
      ]
    },
    {
      "id": "web-gateway-durable-audit-precedes-network",
      "statement": "A durable audit record exists before any gateway network dispatch, and a failed final audit, revocation, redirect, or oversized body withholds output; crash recovery preserves unknown requests without retrying them.",
      "area": "web-gateway",
      "source": {
        "path": "AGENTS.md",
        "quote": "through its pinned transport and durable audit boundary."
      },
      "layer": "stateful-model",
      "status": "evidenced",
      "evidence": [
        "src/control/web-gateway.ts",
        "src/control/activity.ts",
        "src/control/web-gateway.property.test.ts",
        "src/control/gateway.test.ts"
      ],
      "assumptions": [
        "filesystem-durability",
        "whatwg-url",
        "dns-tls"
      ],
      "notVerified": [
        "The model drives the production `WebGateway`, `ActivityStore` and `ApprovalBroker` on a real state home, with a scripted `GatewayTransport` in place of DNS, TLS and sockets. That the pinned transport itself connects only to the address it checked is covered by `gateway-rejects-private-addresses` and its tests, not by this model.",
        "A crash is modelled as abandoning the in-flight call and reopening the store in the same process; a real process death between the SQLite commit and the socket write rests on SQLite's commit durability, under the filesystem-durability assumption.",
        "The model samples its schedules: CI runs 15 schedules of up to 8 requests over twelve scenarios."
      ],
      "alsoQuotes": [
        {
          "path": "src/control/AGENTS.md",
          "quote": "durable metadata before dispatch"
        }
      ],
      "properties": [
        {
          "path": "src/control/web-gateway.property.test.ts",
          "test": "property: gateway output and network dispatch follow a committed durable audit row, and recovery never retries"
        }
      ]
    },
    {
      "id": "gateway-activity-excludes-sensitive",
      "statement": "Gateway activity storage never contains request bodies, query values or strings, secrets, response bodies, raw transport errors, or a URL digest.",
      "area": "web-gateway",
      "source": {
        "path": "src/control/AGENTS.md",
        "quote": "Request bodies, query values, secrets, response bodies and raw transport errors must not enter activity storage."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/control/gateway.test.ts"
      ],
      "assumptions": [
        "filesystem-durability",
        "whatwg-url",
        "dns-tls"
      ],
      "notVerified": [
        "No property test covers this law yet; only the enumerated example cases are checked."
      ]
    },
    {
      "id": "gateway-only-mode-restricts-routing",
      "statement": "A state home in gateway-only mode restricts Ghostget command routing to policy-admitted operations; contracts catalog/check/repair are unavailable and capabilities report the reduced surface.",
      "area": "web-gateway",
      "source": {
        "path": "SECURITY.md",
        "quote": "Gateway-only mode restricts Ghostget command routing"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/control/interface-cli.test.ts",
        "src/control/registry-helper.test.ts",
        "src/storage-state-home.test.ts"
      ],
      "assumptions": [
        "filesystem-durability",
        "same-user-trusted",
        "whatwg-url",
        "dns-tls"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked.",
        "Gateway-only mode is not an operating-system network sandbox; a same-user process can bypass the application policy."
      ]
    },
    {
      "id": "agent-channel-cannot-escalate",
      "statement": "Requests on the owner-only agent socket cannot grant approvals, alter policy or permissions, connect accounts, import credentials, or resolve secrets.",
      "area": "control",
      "source": {
        "path": "src/control/AGENTS.md",
        "quote": "Agent requests cannot grant approvals, alter policy, connect accounts, or resolve secrets."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/control/approval-broker.test.ts",
        "src/control/helper-lifecycle.test.ts",
        "src/control/validation.test.ts"
      ],
      "assumptions": [
        "same-user-trusted"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "control-verbs-human-gated",
      "statement": "Control verbs that grant an approval, loosen a permission, replace web rules, activate an interface, connect or disconnect an account, or install the login item require a confirmed T1+T2 human gate before any administrative request is sent; only strictly tightening inputs (deny) run without it, and admin-socket frames without the owner's capability never reach the handler.",
      "area": "control",
      "source": {
        "path": "src/control/AGENTS.md",
        "quote": "every verb that grants, loosens, connects,"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/control/registry.test.ts",
        "src/control/admin-socket.test.ts"
      ],
      "assumptions": [
        "same-user-trusted"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked.",
        "The gate itself (terminal presence and confirmation) is desktop-foundation's `requireHuman`; its tests live in that package.",
        "The admin capability file is not a boundary against processes of the same user."
      ]
    },
    {
      "id": "control-protocol-bounded-reject-drift",
      "statement": "Administrative and agent control protocols are bounded and reject unknown fields, unsupported methods, oversized or malformed frames, and nested contract drift before dispatch.",
      "area": "control",
      "source": {
        "path": "src/control/AGENTS.md",
        "quote": "Keep both protocols bounded and reject drift before dispatch."
      },
      "layer": "property",
      "status": "evidenced",
      "evidence": [
        "src/control/helper-client.test.ts",
        "src/control/validation.test.ts"
      ],
      "assumptions": [
        "same-user-trusted"
      ],
      "notVerified": [
        "Generated inputs are sampled at the configured run count; this is not a proof over all inputs."
      ],
      "properties": [
        {
          "path": "src/control/helper-client.test.ts",
          "test": "helper rejects malformed envelopes and nested contract drift"
        },
        {
          "path": "src/control/validation.test.ts",
          "test": "strict parsers reject every generated unknown key"
        }
      ]
    },
    {
      "id": "tui-input-cannot-bypass-review",
      "statement": "Terminal input, including pasted or unbracketed bursts, cannot issue confirmation or approval without the complete account and exact revision/digest review being displayed.",
      "area": "control",
      "source": {
        "path": "src/control/AGENTS.md",
        "quote": "Terminal input, including pasted text, must never bypass that review."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/control/tui.test.ts"
      ],
      "assumptions": [
        "same-user-trusted"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "tui-restores-terminal-state",
      "statement": "The TUI restores terminal state (raw mode, cursor, alternate screen) before waiting for helper cancellation and custody settlement, including on failure and signals.",
      "area": "control",
      "source": {
        "path": "src/control/AGENTS.md",
        "quote": "Restore terminal state before waiting for helper cancellation and custody settlement."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/control/tui.test.ts"
      ],
      "assumptions": [
        "same-user-trusted"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "managed-policy-corrupt-denies",
      "statement": "Once operation permissions are enabled, a missing or corrupt policy denies access and never falls back to unmanaged behaviour.",
      "area": "control",
      "source": {
        "path": "SECURITY.md",
        "quote": "Enabling operation permissions establishes a persistent managed marker: missing or corrupt policy then denies access."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/control/policy-privacy.test.ts",
        "src/operation-permission.test.ts"
      ],
      "assumptions": [
        "same-user-trusted"
      ],
      "notVerified": [
        "No property test covers this law yet; only the enumerated example cases are checked."
      ]
    },
    {
      "id": "openapi-inert-until-activation",
      "statement": "User OpenAPI documents remain inert drafts until exact conditional activation and never create arbitrary (authenticated) HTTP executors.",
      "area": "control",
      "source": {
        "path": "src/control/AGENTS.md",
        "quote": "User OpenAPI documents remain inert until exact conditional activation and never create arbitrary HTTP executors."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/control/interface-cli.test.ts",
        "src/control/interfaces.test.ts"
      ],
      "assumptions": [
        "same-user-trusted"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "control-single-helper-owner",
      "statement": "The control verbs and TUI share exactly one helper owner per state home; a second controller does not acquire custody.",
      "area": "control",
      "source": {
        "path": "src/control/AGENTS.md",
        "quote": "The control verbs and TUI share one helper owner per state home."
      },
      "layer": "stateful-model",
      "status": "evidenced",
      "evidence": [
        "src/control/helper.ts",
        "src/control/owner.ts",
        "src/control/helper-owner.property.test.ts",
        "src/control/helper-client.test.ts",
        "src/control/helper-lifecycle.test.ts",
        "src/control/tui.test.ts"
      ],
      "assumptions": [
        "same-user-trusted",
        "filesystem-durability"
      ],
      "notVerified": [
        "The model drives the production owner record (`inspectControlOwner` and `commitControlOwner`) in one process. Process liveness is a fake that the model controls, so `processOwnerStatus`'s own inspection of real processes is outside it; its tests are in `src/process-identity.test.ts`.",
        "Contenders interleave only between inspection and commit. That two separate processes cannot both win the create-if-absent or compare-and-swap write rests on the storage layer's exclusive create and locked replace, under the filesystem-durability assumption.",
        "That the menu and the TUI reach the one helper through its socket, rather than starting their own, rests on the listed example tests only.",
        "The model samples its schedules: CI runs 30 schedules of up to 20 commands over three contenders."
      ],
      "properties": [
        {
          "path": "src/control/helper-owner.property.test.ts",
          "test": "property: at most one live contender holds helper custody across inspect and commit races, crashes, restarts, and unknown owners"
        }
      ]
    },
    {
      "id": "no-cached-authorization-across-change",
      "statement": "Authorization is never cached across a changed account, policy, interface, or executable closure; an A-to-B-to-A account change invalidates grants and previewed plans.",
      "area": "control",
      "source": {
        "path": "src/control/AGENTS.md",
        "quote": "Display optimizations must not cache authorization across a changed account, policy, interface or executable closure."
      },
      "layer": "stateful-model",
      "status": "evidenced",
      "evidence": [
        "src/control/account-revision.test.ts",
        "src/control/connections.test.ts",
        "src/operation-authority.property.test.ts",
        "src/operation-permission.test.ts",
        "src/operation-permission.ts",
        "src/runtime.ts"
      ],
      "assumptions": [
        "same-user-trusted"
      ],
      "notVerified": [
        "The model covers one provider-API account: the bundled LinkedIn interface with `posts.read` and `posts.publish`, on a real state home with a counting executor in place of the provider. Web-session, local CLI, linked-device, portable-plugin and messaging-composite routes share `validateFreshPlan` and the permission layer but rest on the listed example tests.",
        "A closure or contract change is simulated by registries whose `implementationClosureHash` or `contractImplementationHash` differ within one process; a real upgrade that loads a different registry in a new process is not modelled.",
        "The display path, `describeOperationPermissions` with its snapshot-local reuse, is checked only by the listed example tests; the model checks that execution never uses authorization from before a change.",
        "`ask` is modelled without a human answer, so it never dispatches; the approval broker's own binding is `approvals.qnt`'s.",
        "The model samples its schedules: CI runs 2 schedules of up to 8 commands, and the nightly soak runs 20 times as many. Each command spawns the bound state helper for every state operation, so a schedule costs tens of seconds."
      ],
      "properties": [
        {
          "path": "src/operation-authority.property.test.ts",
          "test": "property: authority never outlives a change of account incarnation, realm, interface, closure, contract or policy"
        }
      ]
    },
    {
      "id": "grant-binds-exact-identity",
      "statement": "Operation grants bind the exact account incarnation, manifest, contract, and executable closure; a change to any of them, or a changed approval, invalidates the prior grant.",
      "area": "control",
      "source": {
        "path": "SECURITY.md",
        "quote": "Grants bind the exact account incarnation, manifest, contract, and executable closure. A changed account, interface, implementation, or approval invalidates the prior grant."
      },
      "layer": "stateful-model",
      "status": "evidenced",
      "evidence": [
        "src/control/approval-broker.test.ts",
        "src/operation-authority.property.test.ts",
        "src/operation-permission.test.ts",
        "src/operation-permission.ts"
      ],
      "assumptions": [
        "same-user-trusted"
      ],
      "notVerified": [
        "This claim was planned for a Quint model. It is evidenced instead by a stateful model over the production permission layer, which checks after every grant that the capability digest is equal for the same exact identity and distinct from every digest of another identity, and that preparation, reads and confirmations follow only the policy of the current identity.",
        "The model covers one provider-API account: the bundled LinkedIn interface with `posts.read` and `posts.publish`, on a real state home with a counting executor in place of the provider. Web-session, local CLI, linked-device, portable-plugin and messaging-composite routes share `validateFreshPlan` and the permission layer but rest on the listed example tests.",
        "The contract axis changes the contract implementation identity that `providerContractHash` folds in; a changed contract definition or version reaches the digest through the installed manifest, which the model varies only by display name.",
        "A changed approval is modelled as a changed policy entry (allow, ask or deny) for the current identity; a human approval answered through the broker is not modelled here.",
        "The model samples its schedules: CI runs 2 schedules of up to 8 commands, and the nightly soak runs 20 times as many. Each command spawns the bound state helper for every state operation, so a schedule costs tens of seconds."
      ],
      "properties": [
        {
          "path": "src/operation-authority.property.test.ts",
          "test": "property: authority never outlives a change of account incarnation, realm, interface, closure, contract or policy"
        }
      ]
    },
    {
      "id": "approval-allow-once",
      "statement": "An allow-once approval admits one exact pending request at most once (allowed implies uses ≤ 1), including across client crash, expiry, and reconnect; drift, expiry, and shutdown revoke proofs.",
      "area": "control",
      "source": {
        "path": "kb/plans/formal-verification-assurance.md",
        "quote": "Model digest binding at dispatch, lease expiry, crash, and reconnect. The invariant `allowed ⇒ uses ≤ 1` drives the fix for D13."
      },
      "layer": "quint",
      "status": "evidenced",
      "evidence": [
        "scripts/verification-approvals-replay.test.ts",
        "src/control/approval-broker.test.ts",
        "src/control/connections.test.ts",
        "verification/quint/approvals.qnt"
      ],
      "assumptions": [
        "same-user-trusted"
      ],
      "notVerified": [
        "verification/quint/approvals.qnt checks one request, two holders and an anonymous caller, with at most two crashes and two policy changes per trace, to Quint simulation depth 20 and Apalache length 10. Its ITF replay drives the production ApprovalBroker with 1,000 traces of up to 30 steps. Longer schedules, more requests, and more callers are sampled only by the fast-check model in src/control/approval-broker.test.ts.",
        "The model covers the broker alone. Connection reconnect, dispatch digest binding outside the broker, and control-service shutdown are covered only by the listed example tests.",
        "Plan defect D13 is fixed: the broker binds each allow-once grant to its holder's use secret at request or first allowed check. The Quint variants stepShared, stepFirstCheck and stepAdmitBeforeAwait reproduce the pre-fix defects, and the replay shows the production broker refuses each of their violating traces."
      ]
    },
    {
      "id": "shutdown-settles-before-custody-release",
      "statement": "Connection and helper shutdown settle owned work before custody is released.",
      "area": "control",
      "source": {
        "path": "src/control/AGENTS.md",
        "quote": "Connection and helper shutdown must settle owned work before custody is released."
      },
      "layer": "stateful-model",
      "status": "evidenced",
      "evidence": [
        "src/control/helper.ts",
        "src/control/connections.ts",
        "src/control/helper-shutdown.property.test.ts",
        "src/control/connections.test.ts",
        "src/control/helper-lifecycle.test.ts"
      ],
      "assumptions": [
        "same-user-trusted"
      ],
      "notVerified": [
        "The helper model drives the production shutdown sequencer, `settleHelperShutdown`, with the steps `runControlHelper` passes it replaced by recorders over a set of in-flight requests. That `runControlHelper` passes the real steps and tracks every request in its active set rests on reading it and on `src/control/helper-lifecycle.test.ts`, which starts and stops the real helper.",
        "The wait covers requests in flight when shutdown begins. Clients are disconnected first, so no socket request can start later; a native stdio frame arriving after shutdown began is not modelled.",
        "A request that never settles holds shutdown open. Provider calls end when the service's shutdown signal aborts them; a call that ignores its signal is outside the model.",
        "The connection model drives the production `Connections` class with a fake sign-in probe; real browser sign-in and provider verifiers are outside it.",
        "The models sample their schedules: CI runs 200 helper schedules of up to 14 commands and 12 connection schedules of up to 8 commands over two attempts."
      ],
      "properties": [
        {
          "path": "src/control/helper-shutdown.property.test.ts",
          "test": "property: helper shutdown settles every in-flight request before closing the service and releases the owner once, last"
        },
        {
          "path": "src/control/helper-shutdown.property.test.ts",
          "test": "property: closing connections aborts sign-in so no verification or commit survives shutdown"
        }
      ]
    },
    {
      "id": "media-single-finite-item",
      "statement": "Media acquisition admits exactly one finite item and rejects playlists/collections and live or non-finite streams.",
      "area": "media",
      "source": {
        "path": "AGENTS.md",
        "quote": "Keep media acquisition to one authorized, accessible, finite, non-DRM item. Reject playlists, live streams"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/media/archive.test.ts",
        "src/media/args.test.ts",
        "src/media/metadata.property.test.ts",
        "src/media/metadata.test.ts",
        "src/media/source-router.property.test.ts",
        "src/media/yt-dlp.test.ts"
      ],
      "assumptions": [
        "filesystem-atomic-rename",
        "media-tools"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked.",
        "Probe and capture are separate yt-dlp calls, and capture does not recheck live or DRM status."
      ]
    },
    {
      "id": "media-reject-drm-auth-bypass",
      "statement": "Media acquisition rejects affirmative DRM, unsupported authentication, and access-control bypasses, and Ghostget never supplies decryption keys or bypass flags to media tools.",
      "area": "media",
      "source": {
        "path": "AGENTS.md",
        "quote": "affirmative DRM, unsupported authentication, and access-control bypasses."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/media/archive.test.ts",
        "src/media/metadata.test.ts",
        "src/media/yt-dlp.test.ts"
      ],
      "assumptions": [
        "filesystem-atomic-rename",
        "media-tools"
      ],
      "notVerified": [
        "No property test covers this law yet; only the enumerated example cases are checked."
      ]
    },
    {
      "id": "media-promote-only-after-verification",
      "statement": "A media item is promoted only after its inspectable archive, versioned manifest, and SHA-256 records pass complete verification; a revision chain has exactly one head.",
      "area": "media",
      "source": {
        "path": "AGENTS.md",
        "quote": "Promote an item only after its inspectable archive, versioned manifest, and SHA-256 records pass complete verification."
      },
      "layer": "quint",
      "status": "evidenced",
      "evidence": [
        "scripts/verification-media-replay.test.ts",
        "src/media/archive.property.test.ts",
        "src/media/archive.test.ts",
        "src/media/lock.test.ts",
        "src/media/manifest.property.test.ts",
        "src/media/manifest.test.ts",
        "src/media/revision.property.test.ts",
        "verification/quint/media.qnt"
      ],
      "assumptions": [
        "filesystem-atomic-rename",
        "media-tools"
      ],
      "notVerified": [
        "verification/quint/media.qnt checks promotedVerified (no revision is promoted without passing closed verification of its staged item) with the other media invariants to Quint simulation depth 12 over 3,000 samples and Apalache length 8. Its ITF replay drives production mediaUrl on the yt-dlp pipeline for 300 traces and runs the real verifyMediaItem on every revision the model calls ok after every step. The stepUnverified variant violates promotedVerified, and a replay whose staged verification answers success diverges at the first failing capture.",
        "The model has one kind of capture that fails verification: an unrecorded file beside a derivative. Hash mismatches, manifest version and schema faults, and archive layout faults reach promotion only through the same verifyMediaItem call and are covered by the listed manifest and archive tests, which check only their enumerated or sampled cases.",
        "The direct HTTP pipeline verifies its staged item through the same call but is not replayed against the model; only its example tests apply.",
        "\"Exactly one head\" is checked as the replay reads it: the lineage is the sequence-ordered revision leaves on disk and the head is the last. The model's noPromotionWithoutLock and noForeignRevision show that only the lock holder's own staged item is renamed into the lineage; unique sequence-numbered leaves that bind their predecessor rest on the listed revision tests."
      ]
    },
    {
      "id": "media-crash-lineage-progress",
      "statement": "Each capture subject has one revision lineage with a single head, and a crash or power loss during staging or promotion never leaves that lineage permanently invalid.",
      "area": "media",
      "source": {
        "path": "kb/plans/formal-verification-assurance.md",
        "quote": "The progress property \"a crash never makes a lineage permanently invalid\" drives D10."
      },
      "layer": "quint",
      "status": "evidenced",
      "evidence": [
        "scripts/verification-media-replay.test.ts",
        "src/media/archive.property.test.ts",
        "src/media/archive.test.ts",
        "src/media/lock.test.ts",
        "src/media/manifest-durability.test.ts",
        "src/media/quarantine.test.ts",
        "src/media/revision.property.test.ts",
        "src/media/revision.test.ts",
        "verification/quint/media.qnt"
      ],
      "assumptions": [
        "filesystem-atomic-rename",
        "filesystem-durability",
        "process-liveness",
        "media-tools"
      ],
      "notVerified": [
        "Progress is checked as a safety invariant, not as liveness under fairness. verification/quint/media.qnt's lineageRecoverable says a crash or power loss damages a lineage only by tearing a revision, a torn revision never sits below the head, and discovery never answers invalid for a lineage whose only damage is a torn revision; the next locked start quarantines a torn head and recaptures, which the ITF replay drives through production mediaUrl for 300 traces. promotedDurable says every promotion flushed the staged tree and the revision parent before the rename and the revision and staging parents after it, and the replay derives each revision's flag from the flushes production made.",
        "The stepNoSync variant (promotion without the flushes, as before D10) violates promotedDurable and lineageRecoverable, and stepNoRepair (a torn head answered invalid, as before D10) violates lineageRecoverable. Deleting production's post-rename flush of the revision parent makes the replay diverge.",
        "Power loss is modelled, not observed: the model tears the head at any time and an older revision only when its promotion was not flushed, so a drive that acknowledges a flush it does not keep is outside the model. F_FULLFSYNC runs in the macOS CI job; on Linux and on filesystems that refuse it, the flush falls back to fsync, which gives no drive-cache guarantee.",
        "Plan defect D10 is fixed: the staging tree and its parent directories are fsynced before and after the promotion rename, and a start that finds a torn head moves it to the quarantine instead of stopping the lineage.",
        "Repair quarantines at most one torn head per capture; the direct pipeline promotes durably but does not repair a torn head, and it is not replayed against the model.",
        "Quarantined revisions stay until their owner removes them; `ghostget media quarantine` lists them and removes nothing."
      ]
    },
    {
      "id": "media-lock-exclusion",
      "statement": "Media item locks exclude concurrent owners; release never removes a replacement lock and final publication is an atomic same-volume rename.",
      "area": "media",
      "source": {
        "path": "SECURITY.md",
        "quote": "Media locks coordinate Ghostget processes, and final publication uses an atomic same-volume rename."
      },
      "layer": "quint",
      "status": "evidenced",
      "evidence": [
        "scripts/verification-media-replay.test.ts",
        "src/media/lock.test.ts",
        "verification/quint/media.qnt"
      ],
      "assumptions": [
        "filesystem-atomic-rename",
        "same-user-trusted",
        "process-liveness",
        "media-tools"
      ],
      "notVerified": [
        "verification/quint/media.qnt checks two processes on one revision lineage to Quint simulation depth 12 and Apalache length 8. Its noPromotionWithoutLock invariant restates the guard at the rename, so the checkers show only that the unfenced variant breaks it; noForeignRevision is the lock law the model derives, and the replay is what binds the guard to production. Its ITF replay drives production mediaUrl and the item lock with 300 traces in one test process, not the plan's 1,000: on the CI runner 1,000 traces took 159 seconds and pushed the verification step to 13.6 minutes. In the replay, runs interleave at the capture and flush gates, a crash rewrites the lock to a dead PID, and heartbeat loss is an aged lock file. Truly concurrent processes, other filesystems, and network volumes are not exercised.",
        "The atomicity of a same-volume rename is an assumption (filesystem-atomic-rename), not a checked property.",
        "Plan defect D11 is fixed: promotion renames only through the lock's fence, which checks the token and inode immediately before the rename, and a stale heartbeat is reclaimable even when its PID answers. The Quint variant stepUnfenced reproduces the unfenced rename, and the replay shows production refuses each of its violating traces."
      ]
    },
    {
      "id": "media-cancellation-stops-work",
      "statement": "Cancelling a media acquisition stops every process it started, including ffmpeg and HLS grandchildren; a cancellation that arrives before promotion prevents a `created` result, both pipelines discard staging on every error, and when Ghostget exits or receives an unhandled SIGINT, SIGTERM, or SIGHUP it kills every active media process group.",
      "area": "media",
      "source": {
        "path": "kb/plans/formal-verification-assurance.md",
        "quote": "D9: spawn in a process group and kill the group. Check cancellation before promotion."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "scripts/verification-media-replay.test.ts",
        "src/media/archive.test.ts",
        "src/media/process-group.test.ts",
        "src/media/process-parent-exit.test.ts",
        "src/media/process.test.ts",
        "verification/quint/media.qnt"
      ],
      "assumptions": [
        "filesystem-atomic-rename",
        "media-tools"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked; the grouped-termination property samples scripted exit points, not every signal interleaving.",
        "A SIGKILL of Ghostget itself, or a kernel or power failure, runs no exit handler, so a detached media tool group can outlive it.",
        "A signal Ghostget inherited as ignored, such as SIGHUP under nohup, stays ignored, so the group keeps running until Ghostget exits for another reason.",
        "The group kill reaches only processes that stay in the tool's process group; a helper that calls setsid() or setpgid() leaves the group and is not stopped.",
        "On Windows media tools run without a process group, so only the direct child is signalled.",
        "Plan defect D9 is fixed: yt-dlp runs in its own process group and cancellation signals the group, and the promotion fence checks cancellation immediately before the rename. verification/quint/media.qnt checks that a cancelled yt-dlp capture never answers created, its stepLateCancel variant reproduces the pre-fix promotion, and its replay drives production mediaUrl. The direct HTTP pipeline and grandchild process termination are not modelled."
      ]
    },
    {
      "id": "media-verify-recomputes-hashes",
      "statement": "`ghostget verify` recomputes SHA-256 records and detects later archive changes.",
      "area": "media",
      "source": {
        "path": "SECURITY.md",
        "quote": "SHA-256 records that `ghostget verify` recomputes"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/media/archive.test.ts",
        "src/media/cli.test.ts"
      ],
      "assumptions": [
        "filesystem-atomic-rename",
        "media-tools"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "media-no-shell-no-ambient-config",
      "statement": "Media tools are invoked with an argv array without a shell, and ambient yt-dlp configuration is ignored unless explicitly selected.",
      "area": "media",
      "source": {
        "path": "SECURITY.md",
        "quote": "Ghostget invokes media tools without a shell, ignores ambient yt-dlp configuration unless the user explicitly selects that mode"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/media/args.test.ts",
        "src/media/process.test.ts",
        "src/media/yt-dlp.test.ts"
      ],
      "assumptions": [
        "filesystem-atomic-rename",
        "media-tools"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "media-no-persist-transport-secrets",
      "statement": "Media archives never persist cookies, request headers, signed media URLs, raw yt-dlp metadata, or transport fragments; diagnostics redact URL paths and credentials.",
      "area": "media",
      "source": {
        "path": "SECURITY.md",
        "quote": "does not persist cookies, request headers, signed media URLs, raw yt-dlp metadata, or transport fragments"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/media/archive.test.ts",
        "src/media/metadata.test.ts",
        "src/media/process.test.ts"
      ],
      "assumptions": [
        "filesystem-atomic-rename",
        "media-tools"
      ],
      "notVerified": [
        "No property test covers this law yet; only the enumerated example cases are checked."
      ]
    },
    {
      "id": "direct-media-fixed-role-names",
      "statement": "The direct-media adapter reads a bounded range, identifies media from bytes, and stores fixed role names rather than URL basenames.",
      "area": "media",
      "source": {
        "path": "SECURITY.md",
        "quote": "It reads a bounded range, identifies media from bytes, and stores fixed role names instead of URL basenames."
      },
      "layer": "property",
      "status": "evidenced",
      "evidence": [
        "src/media/archive.property.test.ts",
        "src/media/http-capture.test.ts",
        "src/media/http-probe.property.test.ts"
      ],
      "assumptions": [
        "filesystem-atomic-rename",
        "media-tools"
      ],
      "notVerified": [
        "Generated inputs are sampled at the configured run count; this is not a proof over all inputs."
      ],
      "properties": [
        {
          "path": "src/media/http-probe.property.test.ts",
          "test": "property: chunk partitioning cannot hide bytes beyond the probe declaration"
        },
        {
          "path": "src/media/archive.property.test.ts",
          "test": "property: opaque raw IDs never enter archive or focused path segments"
        }
      ]
    },
    {
      "id": "transcription-setup-no-download",
      "statement": "Local transcription setup never downloads whisper.cpp, its model, or libraries, and rechecks the selected executable, model, and observable runtime closure.",
      "area": "media",
      "source": {
        "path": "SECURITY.md",
        "quote": "Ghostget records and rechecks the selected executable, model, and observable non-platform runtime closure"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/media/local-transcription.test.ts",
        "src/media/runtime-closure.test.ts",
        "src/media/transcriber-config.test.ts"
      ],
      "assumptions": [
        "filesystem-atomic-rename",
        "media-tools"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "portable-plugin-explicit-trust",
      "statement": "Portable plugin code executes only after an explicit trust decision bound to the exact verified content-addressed bundle; `plugin check` never executes plugin code.",
      "area": "plugins",
      "source": {
        "path": "AGENTS.md",
        "quote": "require an explicit trust decision for the exact verified bundle."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/args.test.ts",
        "src/provider-plugin-lifecycle.test.ts",
        "src/provider-plugin-package.test.ts",
        "src/provider-plugin-store.test.ts"
      ],
      "assumptions": [
        "plugin-trusted"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "portable-host-capability-denial",
      "statement": "The portable child-process host denies undeclared capabilities, foreign origins, and out-of-bound results, and executes only the verified runtime bytes even if the installed path is rewritten.",
      "area": "plugins",
      "source": {
        "path": "AGENTS.md",
        "quote": "Treat portable child-process execution as ordinary-failure containment"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/provider-plugin-host.test.ts",
        "src/provider-plugin-portable-runtime.test.ts"
      ],
      "assumptions": [
        "plugin-trusted"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "catalog-unique-ownership",
      "statement": "The validated active catalog rejects duplicate plugin, route, or operation ownership, independent of insertion order, before any command can use it.",
      "area": "plugins",
      "source": {
        "path": "AGENTS.md",
        "quote": "Reject duplicate plugin, route, or operation ownership before a command can use it."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/contracts-catalog.test.ts",
        "src/operation-permission.property.test.ts",
        "src/platform-catalog.property.test.ts",
        "src/provider-plugin-portable-registry.test.ts",
        "src/provider-plugin-registry.test.ts"
      ],
      "assumptions": [
        "plugin-trusted"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "contract-hash-environment-invariant",
      "statement": "Built-in durable contract hashes are versioned and identical across package layout and execution environment.",
      "area": "plugins",
      "source": {
        "path": "AGENTS.md",
        "quote": "Keep built-in durable contract hashes versioned and invariant across package layout and execution environment."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/model.test.ts",
        "src/provider-plugin-package.test.ts",
        "src/provider-plugin-registry.test.ts",
        "src/web-session-contracts.test.ts"
      ],
      "assumptions": [
        "plugin-trusted"
      ],
      "notVerified": [
        "No property test covers this law yet; only the enumerated example cases are checked.",
        "Nothing forces a contract version bump when the source closure changes."
      ]
    },
    {
      "id": "contract-closure-lazy-revalidation",
      "statement": "The source/dependency closure is derived automatically, snapshotted at registry startup, and revalidated before and after lazy runtime load; a changed closure is rejected rather than executed.",
      "area": "plugins",
      "source": {
        "path": "AGENTS.md",
        "quote": "Derive the exact current source/dependency closure automatically, snapshot it at registry startup, and revalidate it before and after lazy runtime load"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/beeper-local-plugin.test.ts",
        "src/provider-plugin-registry.test.ts"
      ],
      "assumptions": [
        "plugin-trusted"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked.",
        "Revalidation compares disk bytes under a single-writer assumption, so an A→B→A edit between the checks passes."
      ]
    },
    {
      "id": "portable-identity-artifact-bound",
      "statement": "Portable-plugin identity is bound to its exact verified artifact; artifact tampering changes identity separately from the logical descriptor, and identity extensions are rejected.",
      "area": "plugins",
      "source": {
        "path": "AGENTS.md",
        "quote": "Portable-plugin identity must remain bound to its exact verified artifact."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/provider-plugin-portable-identity.test.ts",
        "src/provider-plugin-portable-registry.test.ts",
        "src/recovery.test.ts",
        "src/run-journal.property.test.ts"
      ],
      "assumptions": [
        "plugin-trusted"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "plugin-lifecycle-serialized",
      "statement": "Plugin update, disable, and removal are refused while the old bundle still owns live or unknown work (invocation leases, confirmations, run journals, recovery capsules, linked-device lifecycles).",
      "area": "plugins",
      "source": {
        "path": "docs/plugins.md",
        "quote": "Ghostget refuses a transition while the old bundle still owns live or unknown work."
      },
      "layer": "stateful-model",
      "status": "evidenced",
      "evidence": [
        "src/provider-plugin-invocation-lease.property.test.ts",
        "src/provider-plugin-invocation-lease.test.ts",
        "src/provider-plugin-lifecycle-kernel.test.ts",
        "src/provider-plugin-portable-runtime.test.ts"
      ],
      "assumptions": [
        "plugin-trusted"
      ],
      "notVerified": [
        "The stateful model drives `inspectPortableProviderPluginQuiescence`, the check that update, disable, and removal call, through injected listings of up to 24 generated steps over two bundles: invocation leases with a live, dead, or unknown owner, confirmation plans and claims, run journals (active, released, retaining recovery, or holding assets), run receipts, recovery capsules, linked-device lifecycles, malformed entries of each kind, and an unexpected state entry. The listings are the model's own, so how the real stores list and parse those files is covered only by their tests.",
        "That the store calls this check under its catalog lock before each transition, and leaves the activation unchanged when it throws, is covered only by the named example tests in src/provider-plugin-portable-runtime.test.ts, for a live invocation lease, a cleanup-unsafe lease, and a confirmation plan.",
        "Work that starts between the check and the store's commit is excluded only by the store's lock and each work kind's own admission; no model covers that interleaving."
      ],
      "properties": [
        {
          "path": "src/provider-plugin-lifecycle-kernel.test.ts",
          "test": "a bundle may change exactly when it owns no live or unknown work"
        }
      ]
    },
    {
      "id": "portable-pack-reproducible",
      "statement": "`plugin pack` verifies the fixed file set and produces reproducible, relocation-stable bytes; undeclared files are refused.",
      "area": "plugins",
      "source": {
        "path": "docs/plugins.md",
        "quote": "`pack` verifies the fixed file set and produces reproducible bytes."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/provider-plugin-lifecycle.test.ts",
        "src/provider-plugin-package.test.ts"
      ],
      "assumptions": [
        "plugin-trusted"
      ],
      "notVerified": [
        "No property test covers this law yet; only the enumerated example cases are checked."
      ]
    },
    {
      "id": "portable-no-ambient-authority",
      "statement": "Portable plugins receive no shell, package manager, ambient environment, raw auth locator, unrestricted filesystem, redirect, automatic retry, or caller-chosen network primitive; native code and undeclared module imports are rejected.",
      "area": "plugins",
      "source": {
        "path": "docs/plugins.md",
        "quote": "It receives no shell, package manager, ambient environment, raw auth locator"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/provider-plugin-host.test.ts",
        "src/provider-plugin-import-analysis.test.ts",
        "src/provider-plugin-module-analysis.test.ts",
        "src/provider-plugin-package.test.ts"
      ],
      "assumptions": [
        "plugin-trusted"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "portable-session-material-sinks",
      "statement": "Cookie material is bound only to a cookie jar and OAuth material only to the Authorization header, for exact-origin HTTPS with bounded bodies.",
      "area": "plugins",
      "source": {
        "path": "docs/plugins.md",
        "quote": "opaque cookie material bound only to a cookie jar and OAuth material bound only to the Authorization header"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/provider-plugin-auth.test.ts",
        "src/provider-plugin-host.test.ts"
      ],
      "assumptions": [
        "plugin-trusted"
      ],
      "notVerified": [
        "No property test covers this law yet; only the enumerated example cases are checked."
      ]
    },
    {
      "id": "portable-state-cas",
      "statement": "Versioned namespaced plugin state supports exact-byte compare-and-exchange so overlapping invocations cannot silently overwrite each other.",
      "area": "plugins",
      "source": {
        "path": "docs/plugins.md",
        "quote": "Namespaced state supports exact-byte compare-and-exchange."
      },
      "layer": "property",
      "status": "evidenced",
      "evidence": [
        "src/provider-plugin-portable-runtime.test.ts"
      ],
      "assumptions": [
        "plugin-trusted"
      ],
      "notVerified": [
        "Generated inputs are sampled at the configured run count; this is not a proof over all inputs."
      ],
      "properties": [
        {
          "path": "src/provider-plugin-portable-runtime.test.ts",
          "test": "compare-exchange prevents concurrent lost updates and stale deletes"
        }
      ]
    },
    {
      "id": "portable-cannot-declare-local-cli",
      "statement": "Portable protocol v1 packages cannot declare the local-cli transport or request native process authority.",
      "area": "plugins",
      "source": {
        "path": "docs/local-cli-providers.md",
        "quote": "Portable plugin protocol v1 cannot declare `local-cli`."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/provider-plugin-package.test.ts"
      ],
      "assumptions": [
        "plugin-trusted"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "cleanup-unsafe-irreversible",
      "statement": "Once a cleanup barrier is marked unsafe, later native proof cannot reverse that settlement or release durable admission.",
      "area": "plugins",
      "source": {
        "path": "docs/effect-read-runtime.md",
        "quote": "once it marks a barrier unsafe, later native proof cannot reverse that settlement or release the durable admission"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/provider-plugin-cleanup-barrier.test.ts",
        "src/web-session-cleanup-admission.test.ts"
      ],
      "assumptions": [
        "plugin-trusted"
      ],
      "notVerified": [
        "No property test covers this law yet; only the enumerated example cases are checked."
      ]
    },
    {
      "id": "strict-foreign-parsing",
      "statement": "Every foreign manifest, package, message, plan, receipt, response, and CLI value is parsed from `unknown` and rejects extra fields, malformed bounds, accessors, non-plain prototypes, ambiguous ownership, smuggled keys, and drift.",
      "area": "parsing",
      "source": {
        "path": "AGENTS.md",
        "quote": "Parse every foreign manifest, package, message, plan, receipt, response, and CLI value from `unknown`; reject extra fields, malformed bounds, ambiguous ownership, and drift."
      },
      "layer": "property",
      "status": "evidenced",
      "evidence": [
        "src/browser-admission.property.test.ts",
        "src/contracts-check.test.ts",
        "src/contracts-shape.test.ts",
        "src/control/validation.test.ts",
        "src/linked-device-lifecycle-journal.property.test.ts",
        "src/local-cli-tool-identity.test.ts",
        "src/provider-plugin-portable.property.test.ts",
        "src/run-journal.property.test.ts"
      ],
      "assumptions": [],
      "notVerified": [
        "Key-set checks inside browser-injected script text run in the foreign page’s context and cannot import the shared helper; they are kept self-contained and are outside this AST-scanned rule (their bytes feed contract hashes, which pin them).",
        "The lint guards the equality-compare shape in non-test TypeScript under src/; a local exactKeys variant in local-cli-tool-identity.ts keeps its optional-key semantics, and the injected hasExactKeys dependency in confirmed-write-platform.ts is a separately owned local implementation."
      ],
      "properties": [
        {
          "path": "src/contracts-shape.test.ts",
          "test": "property: matches exact key-set equality on arbitrary key sets"
        },
        {
          "path": "src/contracts-shape.test.ts",
          "test": "property: an unsupported key at any object path is rejected by the parser and the schema"
        }
      ]
    },
    {
      "id": "read-result-proto-roundtrip",
      "statement": "An own `__proto__` key in foreign JSON stays visible to exact-key parsing, and `parseInvokeReadResult` round-trips any JSON output, including objects with an own `__proto__` key.",
      "area": "parsing",
      "source": {
        "path": "kb/plans/formal-verification-assurance.md",
        "quote": "D6: fix the `__proto__` round trip and promote seed 455347073 to a named test."
      },
      "layer": "property",
      "status": "evidenced",
      "evidence": [
        "src/browser-admission.property.test.ts",
        "src/contracts-invoke-read.test.ts",
        "src/contracts-shape.test.ts",
        "src/provider-plugin-registry-semantic.test.ts"
      ],
      "assumptions": [],
      "notVerified": [
        "Generated inputs are sampled at the configured run count; this is not a proof over all inputs."
      ],
      "properties": [
        {
          "path": "src/contracts-invoke-read.test.ts",
          "test": "property: bounded arbitrary outputs round-trip; an unsupported key at any envelope path is rejected"
        }
      ]
    },
    {
      "id": "contracts-schema-parser-agree",
      "statement": "Contract JSON Schemas are generated from the same shape table as the parsers; parser and schema agree on arbitrary values and reject every unsupported key.",
      "area": "contracts",
      "source": {
        "path": "docs/contracts.md",
        "quote": "The schema is generated from the same shape table the parser uses, so the two cannot drift."
      },
      "layer": "property",
      "status": "evidenced",
      "evidence": [
        "src/contracts-schema.test.ts",
        "src/contracts-shape.test.ts"
      ],
      "assumptions": [],
      "notVerified": [
        "Generated inputs are sampled at the configured run count; this is not a proof over all inputs."
      ],
      "properties": [
        {
          "path": "src/contracts-shape.test.ts",
          "test": "property: valid documents round-trip and validate; parse and schema agree on arbitrary values"
        },
        {
          "path": "src/contracts-shape.test.ts",
          "test": "property: an unsupported key at any object path is rejected by the parser and the schema"
        }
      ]
    },
    {
      "id": "contracts-inspection-read-only",
      "statement": "Catalog, check, schema, and repair inspection never bind an account or contact a provider.",
      "area": "contracts",
      "source": {
        "path": "docs/contracts.md",
        "quote": "Catalog, check, schema, and repair inspection are read-only projections. They never bind an account or contact a provider."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/contracts-check.test.ts",
        "src/contracts-cli.test.ts"
      ],
      "assumptions": [],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "public-authority-code-owned",
      "statement": "An operation is public only when it is an observed, dispatch-free, built-in R1 web-session read declaring access public; manifests cannot opt into public execution.",
      "area": "contracts",
      "source": {
        "path": "docs/contracts.md",
        "quote": "A web-session operation is `public` only when"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/contracts-catalog.test.ts",
        "src/web-session-authentication-policy.test.ts"
      ],
      "assumptions": [],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "collection-plan-read-only-bounded",
      "statement": "collection-plan.v1 requires risk R1 and sideEffect none and enforces bounds (64 accounts, 8 reads per account, 128 total, 16 metric keys, delay ≤ 600000 ms, input ≤ 32 keys depth 8, canonical credential-free target URLs).",
      "area": "contracts",
      "source": {
        "path": "docs/contracts.md",
        "quote": "`semantics.risk` must be `R1` and `semantics.sideEffect` must be `none`; v1 plans are read-only by construction."
      },
      "layer": "property",
      "status": "evidenced",
      "evidence": [
        "src/contracts-plan.test.ts"
      ],
      "assumptions": [],
      "notVerified": [
        "Generated inputs are sampled at the configured run count; this is not a proof over all inputs."
      ],
      "properties": [
        {
          "path": "src/contracts-plan.test.ts",
          "test": "property: generated plans round-trip through JSON, flatten in order, and validate against the schema"
        },
        {
          "path": "src/contracts-plan.test.ts",
          "test": "property: every parser rejection of a generated mutation is a schema violation or a documented semantic rule"
        }
      ]
    },
    {
      "id": "contract-check-single-gap",
      "statement": "Each checked read reports at most one gap chosen by the fixed precedence; reads has exactly plan.reads indexed entries and ok is true exactly when every verdict is ok.",
      "area": "contracts",
      "source": {
        "path": "docs/contracts.md",
        "quote": "Each read reports at most one gap, chosen in this order"
      },
      "layer": "property",
      "status": "evidenced",
      "evidence": [
        "src/contracts-check.test.ts"
      ],
      "assumptions": [],
      "notVerified": [
        "Generated inputs are sampled at the configured run count; this is not a proof over all inputs."
      ],
      "properties": [
        {
          "path": "src/contracts-check.test.ts",
          "test": "property: checking is deterministic and idempotent and never leaves the closed gap set"
        },
        {
          "path": "src/contracts-check.test.ts",
          "test": "property: reads derived from the catalog bind ok with the exact installed contract"
        }
      ]
    },
    {
      "id": "invoke-read-envelope-consistency",
      "statement": "R1 invoke envelopes are consistent: receipt status/runId equal top-level fields, cache outcome matches status, failed results have null output and a readFailure whose disposition matches its category, output bounded to depth 64 and 4,000,000 nodes.",
      "area": "contracts",
      "source": {
        "path": "docs/contracts.md",
        "quote": "Invoke result: `receipt.status` and `receipt.runId` equal the top-level fields"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/contracts-invoke-read.test.ts"
      ],
      "assumptions": [],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "read-failure-disposition-table",
      "statement": "Read failure retry dispositions come from one closed table (retry-once-after-60s, repair-auth, grant-permission, do-not-retry).",
      "area": "contracts",
      "source": {
        "path": "docs/contracts.md",
        "quote": "`readFailureDispositions` exports the same closed table."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/ghostget.test.ts",
        "src/providers/read-failure.test.ts"
      ],
      "assumptions": [],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "read-runtime-zero-dispatch",
      "statement": "R1 reads store a provisional receipt before execution, accept only zero-dispatch outcomes, and store the final receipt before returning output.",
      "area": "contracts",
      "source": {
        "path": "docs/effect-read-runtime.md",
        "quote": "`readInvocationProgram` stores the provisional receipt before starting execution. It accepts only zero-dispatch success or failure"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/read-client.test.ts",
        "src/read-effect.test.ts"
      ],
      "assumptions": [],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "canonical-json-injective",
      "statement": "canonicalJson over plain JSON (null, booleans, safe integers, strings of UTF-16 code units, arrays, and objects with distinct keys) is injective up to member order, gives the same text for any member insertion order, and never writes a NUL code unit; its UTF-16 code-unit key order is total and locale-independent.",
      "area": "encoding",
      "source": {
        "path": "kb/plans/formal-verification-assurance.md",
        "quote": "Canonical JSON over an inductive `Json` with UTF-16 key order: the encoder is injective, parse-then-encode is the identity on canonical output, and key order is total."
      },
      "layer": "lean",
      "status": "evidenced",
      "evidence": [
        "scripts/verification-lean-encodings.test.ts",
        "src/canonical-json.test.ts",
        "src/local-cli-surface-contract.test.ts",
        "src/model.test.ts",
        "verification/lean/GhostgetVerification/Encodings/CanonicalJson.lean",
        "verification/lean/GhostgetVerification/Encodings/CanonicalJsonProofs.lean"
      ],
      "assumptions": [
        "bun-runtime",
        "verification-tools"
      ],
      "notVerified": [
        "The Lean theorems are about a Lean model of the encoder. The differential test checks that the TypeScript agrees with that model on generated values, not on every value.",
        "Parse-then-encode being the identity on canonical output is not proved.",
        "Numbers are modelled as safe integers only; fractions, exponents, and the JavaScript engine's number formatting are not modelled.",
        "The model starts from a plain JSON value. The TypeScript checks that reject undefined members, cycles, symbols, getters, and non-plain objects are not modelled."
      ]
    },
    {
      "id": "canonical-json-rejects-non-json",
      "statement": "`canonicalJson` rejects sparse arrays, non-plain prototypes (Map, Date, typed arrays), accessors, and symbols rather than emitting invalid or colliding output.",
      "area": "encoding",
      "source": {
        "path": "kb/plans/formal-verification-assurance.md",
        "quote": "D5: make `canonicalJson` reject non-plain prototypes, sparse arrays, accessors, and symbols"
      },
      "layer": "property",
      "status": "evidenced",
      "evidence": [
        "src/canonical-json.test.ts",
        "src/client-boundary.test.ts"
      ],
      "assumptions": [],
      "notVerified": [
        "Generated inputs are sampled at the configured run count; this is not a proof over all inputs."
      ],
      "properties": [
        {
          "path": "src/canonical-json.test.ts",
          "test": "property: every value fast-check can build encodes exactly when it is in the JSON domain"
        },
        {
          "path": "src/canonical-json.test.ts",
          "test": "property: a domain violation at any nesting depth is rejected"
        }
      ]
    },
    {
      "id": "canonical-json-matches-rfc8785-oracle",
      "statement": "For every I-JSON value, which excludes lone surrogates, `canonicalJson` writes the same text as an independent RFC 8785 canonicalizer, and it reproduces the committed golden canonical forms, number texts, SHA-256 digests, and script-literal escapes.",
      "area": "encoding",
      "source": {
        "path": "kb/plans/formal-verification-assurance.md",
        "quote": "Add a dev-only Rust crate under `verification/oracles/` with an RFC 8785 canonicalizer"
      },
      "layer": "differential",
      "status": "evidenced",
      "evidence": [
        "verification/oracles/src/jcs.rs",
        "verification/vectors/generate.py",
        "verification/vectors/jcs.json",
        "scripts/verification-oracles.test.ts",
        "scripts/verification-vectors.test.ts"
      ],
      "assumptions": [
        "sha256"
      ],
      "notVerified": [
        "Generated values are sampled at the configured run count, and the golden vectors are a fixed corpus; neither is a proof over all inputs.",
        "`canonicalJson` writes a lone surrogate as JSON.stringify escapes it, where RFC 8785 refuses the input; the vector test pins this difference.",
        "Duplicate member names never reach `canonicalJson`, because `JSON.parse` keeps the last one; refusing them is a parser's job, not the canonicalizer's.",
        "The Rust oracle and the Python generator were written from RFC 8785 without reference to the TypeScript, but by the same author, so a misreading all three share would pass. The oracle's number digits come from Rust's correctly rounded formatting, and one misreading of the shortest-digit rule at powers of two was found in review and fixed."
      ]
    },
    {
      "id": "media-identity-hashes-match-golden-vectors",
      "statement": "The media provider identity and source asset key, the authorization-context digest, the native runtime closure digest, the retained revision content digest, and UTF-8 byte ordering reproduce golden vectors from an independent Python generator.",
      "area": "media",
      "source": {
        "path": "kb/plans/formal-verification-assurance.md",
        "quote": "Commit Python-generated golden vectors for hashes and encodings to `verification/vectors/`."
      },
      "layer": "differential",
      "status": "evidenced",
      "evidence": [
        "verification/vectors/generate.py",
        "verification/vectors/hashes.json",
        "scripts/verification-vectors.test.ts"
      ],
      "assumptions": [
        "sha256"
      ],
      "notVerified": [
        "The vectors are a fixed corpus; they pin the byte layout, not a property of all inputs.",
        "Injectivity of the length framing is `hash-framing-injective`, which Phase 5 addresses."
      ]
    },
    {
      "id": "hash-framing-injective",
      "statement": "The length-framed hash input (a 4-byte label length, an 8-byte payload length, the label, and the payload, per section) determines its sections; the contract hash preimage (canonical JSON as UTF-8, a 0x00 byte, then the implementation hash) determines the JSON bytes and the implementation hash; and the NUL-joined confirmed-write intent key preimage determines the intent's fields.",
      "area": "encoding",
      "source": {
        "path": "kb/plans/formal-verification-assurance.md",
        "quote": "The length-framed hash input and the `json ‖ 0x00 ‖ 32-byte` suffix are injective."
      },
      "layer": "lean",
      "status": "evidenced",
      "evidence": [
        "scripts/verification-lean-encodings.test.ts",
        "src/media/runtime-closure.property.test.ts",
        "verification/lean/GhostgetVerification/Encodings/HashFraming.lean",
        "verification/lean/GhostgetVerification/Encodings/Units.lean"
      ],
      "assumptions": [
        "sha256",
        "verification-tools"
      ],
      "notVerified": [
        "SHA-256 is not modelled; that distinct preimages give distinct hashes rests on the sha256 assumption.",
        "The Lean theorems are about Lean models of the preimages. The differential test checks that updateLengthFramedHash, providerContractHash, localCliContractHash, and intentLedgerPath agree with those models on generated inputs, not on every input.",
        "UTF-8 injectivity is not proved, so the contract theorem stops at the UTF-8 bytes of the canonical JSON rather than the JSON value.",
        "The intent key theorem assumes every field is ASCII and NUL-free, as validated identifiers and hex hashes are; the model does not check that callers only pass such fields.",
        "Framing lengths must fit their headers (labels under 2^32 bytes, payloads under 2^64 bytes); the TypeScript does not check this.",
        "Other NUL-separated preimages (the per-hash idempotency key in ledgerPath, web-session contracts, predecessor-compatible contract hashes, provider-plugin package and module-analysis hashes) and the separate framing copy in src/provider-plugin.ts are not covered."
      ]
    },
    {
      "id": "identifier-roundtrip",
      "statement": "Identifier grammars and route/operation composite keys satisfy parse(format(x)) = x and are unambiguous.",
      "area": "encoding",
      "source": {
        "path": "AGENTS.md",
        "quote": "Add property tests for strict parsers, canonical encodings, identifiers, ordering, round trips"
      },
      "layer": "lean",
      "status": "evidenced",
      "evidence": [
        "scripts/verification-lean-encodings.test.ts",
        "src/contracts-repair.test.ts",
        "src/local-cli-tool-identity.test.ts",
        "src/platform-catalog.property.test.ts",
        "src/provider-plugin-registry.test.ts",
        "verification/lean/GhostgetVerification/Encodings/RouteKey.lean"
      ],
      "assumptions": [
        "verification-tools"
      ],
      "notVerified": [
        "The Lean proof covers the provider plugin registry keys: the route key `<transport>:<surfaceId>` and the exact-contract key `<transport>:<surfaceId>/<operation>@<contractVersion>`, over the four transports and the surface ID and operation name grammars. Session-secret file names are the separate claim session-secret-filename-injective. Other identifier grammars, such as adapter, auth, and run IDs, portable operation identities, cursor tokens, and platform catalog IDs, are covered only by the listed example and property tests, not by a proof.",
        "The Lean theorems are about a Lean model of the key functions and grammars. The differential test checks that `routeKey`, `operationKey`, `isProviderPluginSurfaceId`, and `isProviderPluginOperationName` agree with that model on generated inputs, not on every input, and the grammars are modelled by hand from their regular expressions.",
        "The registry has no production parser for its keys; the Lean parser is a witness that a key determines its parts. A contract version is modelled as a natural number written in decimal; the registry's own check that it is a positive safe integer is not modelled."
      ]
    },
    {
      "id": "auth-request-binding",
      "statement": "Every authenticated request is bound to one exact account realm, provider target, transport, contract version, and implementation identity; drift in any of them rejects the request and consumes prepared plans.",
      "area": "authentication",
      "source": {
        "path": "AGENTS.md",
        "quote": "Bind every authenticated request to one exact account realm, provider target, transport, contract version, and implementation identity."
      },
      "layer": "stateful-model",
      "status": "evidenced",
      "evidence": [
        "src/auth-storage.test.ts",
        "src/beeper-message-like-me-source.test.ts",
        "src/client-boundary.test.ts",
        "src/local-cli-durable-identity.test.ts",
        "src/operation-authority.property.test.ts",
        "src/operation-permission.ts",
        "src/runtime.test.ts",
        "src/runtime.ts",
        "src/web-session-authentication-policy.test.ts"
      ],
      "assumptions": [
        "provider-behaviour"
      ],
      "notVerified": [
        "The model covers one provider-API account: the bundled LinkedIn interface with `posts.read` and `posts.publish`, on a real state home with a counting executor in place of the provider. Web-session, local CLI, linked-device, portable-plugin and messaging-composite routes share `validateFreshPlan` and the permission layer but rest on the listed example tests.",
        "The model varies the account incarnation, the account realm (a record for a different subject under the same ID), the interface bytes, the executable closure and the contract implementation identity. The provider target and transport are fixed by the LinkedIn contract, and a transport or contract-version change reaches a plan only through the manifest bytes it binds; neither is varied on its own.",
        "Saved plans bind the reviewed contract implementation identity (`contractImplementationHash`), which is stable across builds of one built-in plugin version, not the exact closure. Under managed permissions the grant binds the exact closure, so a changed closure dispatches nothing until the new identity is granted; without managed permissions a closure change that keeps the reviewed contract identity does not consume a plan.",
        "A plan refused only by policy is kept for a later confirmation under current authority, by design; every other refusal consumes it.",
        "The model samples its schedules: CI runs 2 schedules of up to 8 commands, and the nightly soak runs 20 times as many. Each command spawns the bound state helper for every state operation, so a schedule costs tens of seconds."
      ],
      "properties": [
        {
          "path": "src/operation-authority.property.test.ts",
          "test": "property: authority never outlives a change of account incarnation, realm, interface, closure, contract or policy"
        }
      ]
    },
    {
      "id": "no-silent-transport-switch",
      "statement": "Ghostget never silently switches between official API, browser session, linked-device, or portable transports; error text cannot grant a transport switch.",
      "area": "authentication",
      "source": {
        "path": "AGENTS.md",
        "quote": "Never silently switch transport."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/beeper-local-plugin.test.ts",
        "src/ghostget.test.ts",
        "src/pinned-https.test.ts",
        "src/providers/linkedin-company-program.test.ts",
        "src/providers/linkedin-self-program.test.ts"
      ],
      "assumptions": [
        "provider-behaviour"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "mutation-exact-preview-confirmation",
      "statement": "A mutation dispatches only after an exact preview and a confirmation whose digest binds that preview; each plan is consumed exactly once, and expired, drifted, or altered plans are consumed without dispatch.",
      "area": "mutations",
      "source": {
        "path": "AGENTS.md",
        "quote": "Keep mutations behind exact preview, confirmation, durable dispatch, and at-most-once evidence."
      },
      "layer": "stateful-model",
      "status": "evidenced",
      "evidence": [
        "src/confirmed-write-program.test.ts",
        "src/control/registry-helper.test.ts",
        "src/messaging-runtime-composite.test.ts",
        "src/operation-authority.property.test.ts",
        "src/operation-permission.test.ts",
        "src/runtime.test.ts",
        "src/runtime.ts"
      ],
      "assumptions": [
        "filesystem-durability",
        "provider-behaviour"
      ],
      "notVerified": [
        "The model covers one provider-API account: the bundled LinkedIn interface with `posts.read` and `posts.publish`, on a real state home with a counting executor in place of the provider. Web-session, local CLI, linked-device, portable-plugin and messaging-composite routes share `validateFreshPlan` and the permission layer but rest on the listed example tests. The model's write is single-dispatch; multi-part and composite plans rest on the listed example tests.",
        "An altered plan is modelled by flipping one byte of the saved plan file; other alterations rest on the strict plan parser's tests. A crash between consuming a plan and its durable dispatch is the fence model's (`confirmed-write-at-most-once`), not this one's.",
        "Expiry is modelled by confirming a day later through the injected clock.",
        "The model samples its schedules: CI runs 2 schedules of up to 8 commands, and the nightly soak runs 20 times as many. Each command spawns the bound state helper for every state operation, so a schedule costs tens of seconds."
      ],
      "properties": [
        {
          "path": "src/operation-authority.property.test.ts",
          "test": "property: authority never outlives a change of account incarnation, realm, interface, closure, contract or policy"
        }
      ]
    },
    {
      "id": "confirmed-write-at-most-once",
      "statement": "For every intent (account realm, provider target, operation id, canonical input), provider effects are at most 1 + duplicate successors, including across reconnect and manifest-hash changes.",
      "area": "mutations",
      "source": {
        "path": "AGENTS.md",
        "quote": "durable dispatch, and at-most-once evidence."
      },
      "layer": "quint",
      "status": "evidenced",
      "evidence": [
        "scripts/verification-fence-replay.test.ts",
        "src/confirmed-write-intent-fence.test.ts",
        "src/run-journal.property.test.ts",
        "src/run-journal.test.ts",
        "src/runtime.test.ts",
        "verification/quint/fence.qnt"
      ],
      "assumptions": [
        "filesystem-durability",
        "provider-behaviour"
      ],
      "notVerified": [
        "The model is bounded: three runs of one intent, one reconnect, one manifest upgrade, one duplicate-risk successor per source run (a successor may itself be a source), 5,000 simulated samples of up to 12 steps, and Apalache to length 8.",
        "The replay drives every seeded trace through the pure fence cores with an in-memory store, and five of them, a greedy cover of every action result the seeded traces take, through the file-backed state layer on a real state home: `createRunJournal`, `updateRunJournal`, `listRunJournalSnapshots`, `acquireConfirmedWriteLedgers` (the intent ledger, then the hash-keyed ledger), `repairInterruptedRunJournals` with its receipt and ledger projection, and `releaseReconciledRunRecovery`. It does not run the `confirmInvocation` program, so plan validation, recovery capsules, and `claimDuplicateRiskSource`'s receipt, capsule, and ledger rechecks are covered only by the listed example tests.",
        "Owner acceptance of the duplicate risk, the preview's successor check, election of a source across a same-subject reconnect (the model's source must bind the current auth record), and a successor whose election fails at its dispatch boundary are not modelled; the model disables that dispatch, and the listed example tests cover production failing the run before any request.",
        "The dedupe window's expiry, partial multi-dispatch runs, and journals from before the intent fence are not modelled."
      ]
    },
    {
      "id": "portable-retained-release",
      "statement": "An indeterminate portable write's intent fence opens only on a not-applied observation that Ghostget itself obtained from the plugin's declared readback, bound to the run, its intent, auth realm, and manifest; a source whose elected duplicate successor settled is superseded, which releases its recovery material and lets its plugin bundle be removed while its indeterminate ledger still fences the intent.",
      "area": "mutations",
      "source": {
        "path": "AGENTS.md",
        "quote": "Never retry or clear an indeterminate dispatch; reconcile it from separately obtained exact evidence."
      },
      "layer": "quint",
      "status": "evidenced",
      "evidence": [
        "scripts/verification-retained-replay.test.ts",
        "src/provider-plugin-host.test.ts",
        "src/provider-plugin-package.test.ts",
        "src/provider-plugin-portable-runtime.test.ts",
        "src/provider-plugin-protocol.test.ts",
        "src/run-journal.test.ts",
        "verification/quint/retained.qnt"
      ],
      "assumptions": [
        "filesystem-durability",
        "provider-behaviour"
      ],
      "notVerified": [
        "The model is bounded: one source run, at most one elected successor, one retry of the base intent, 2,000 simulated samples of up to 12 steps, and Apalache to length 8. Auth rotation, manifest upgrades, chains of successors, successor readback, and assets are not modelled.",
        "Whether the plugin declared a readback is chosen by the trace, and the readback's answer is modelled as the provider's truth or unknown: a plugin whose declared read-only operation reports not-applied after an applied effect breaks the bound, which the seeded `stepUntruthfulReadback` mutant shows. The readback is trusted plugin code under the same trust boundary as its write.",
        "The replay drives every seeded trace through the pure cores (`transitionRunJournal`, `intentFenceBlocker`, `observedNotAppliedRelease`, `duplicateSourceSupersession`, `reconciledRecoveryRelease`) and `inspectPortableProviderPluginQuiescence` with an in-memory journal list. The file-backed store, the child host's protocol 2 frames, and the create-once observation record are covered only by the listed example tests.",
        "No owner-approval route reaches portable not-applied reconciliation; a plugin without a readback declaration stays on the explicit-input path, which never releases the ledger.",
        "Supersession runs at plugin install, disable, and removal and in the doctor repair pass, not at the moment the successor settles."
      ]
    },
    {
      "id": "indeterminate-never-retried",
      "statement": "An indeterminate (post-dispatch uncertain) mutation is never retried; a lost acknowledgement never permits another remote submission.",
      "area": "mutations",
      "source": {
        "path": "AGENTS.md",
        "quote": "Never retry or clear an indeterminate dispatch"
      },
      "layer": "quint",
      "status": "evidenced",
      "evidence": [
        "scripts/verification-fence-replay.test.ts",
        "src/confirmed-write-intent-fence.test.ts",
        "src/control/gateway.test.ts",
        "src/derive.test.ts",
        "src/imessage-direct-plugin.test.ts",
        "src/linked-device-lifecycle-journal.test.ts",
        "src/linked-device-lifecycle-runtime.test.ts",
        "src/portable-run-recovery.test.ts",
        "src/run-journal.property.test.ts",
        "src/runtime.test.ts",
        "verification/quint/fence.qnt"
      ],
      "assumptions": [
        "filesystem-durability",
        "provider-behaviour"
      ],
      "notVerified": [
        "The fence model checks the confirmed-write path (`posts.publish`-shaped R3 web-session writes with one planned dispatch): no intent is dispatched twice, and a later dispatch of the same effect is only an elected duplicate-risk successor of an indeterminate source. It is bounded to three runs, one reconnect, one manifest upgrade, 5,000 simulated samples of up to 12 steps, and Apalache to length 8.",
        "The replay drives the fence cores on every seeded trace and the file-backed journal, ledger, repair, and reconciliation layer on a five-trace cover of their action results, not the `confirmInvocation` program, the provider transports, or owner acceptance of the duplicate risk.",
        "Linked-device lifecycle, local CLI, iMessage, derive, and control-gateway paths, and partial multi-dispatch runs, are covered only by the listed example and property tests."
      ]
    },
    {
      "id": "indeterminate-cleared-only-by-evidence",
      "statement": "An indeterminate dispatch fence is released only from separately obtained exact evidence (plugin readback or owner approval), never from caller-typed hashes.",
      "area": "mutations",
      "source": {
        "path": "AGENTS.md",
        "quote": "reconcile it from separately obtained exact evidence."
      },
      "layer": "quint",
      "status": "evidenced",
      "evidence": [
        "scripts/verification-fence-replay.test.ts",
        "src/ghostget.test.ts",
        "src/portable-run-recovery.test.ts",
        "src/provider-plugin-portable-runtime.test.ts",
        "src/provider-plugin-reconciliation.property.test.ts",
        "src/run-journal.test.ts",
        "src/web-session-recovery.test.ts",
        "verification/quint/fence.qnt"
      ],
      "assumptions": [
        "filesystem-durability",
        "provider-behaviour"
      ],
      "notVerified": [
        "The fence model abstracts the evidence: one reconcile action stands for applied plugin readback or owner approval. The in-memory replay checks that `reconciledRecoveryRelease` and `transitionRunJournal` settle a reconciled run and keep its ledger; the file-backed replay settles it through `releaseReconciledRunRecovery`. That a source with an elected successor keeps its recovery material is covered only by the listed example tests.",
        "The replay does not call `recordNotAppliedClaim`: its not-applied action changes no journal in the replay world, so that `recordNotAppliedClaim` releases nothing is covered only by the listed example tests.",
        "The web-session reconciler and the CLI and portable parsers of reconciliation input are covered only by the listed example and property tests.",
        "Terminalizing a run from supplied evidence says nothing about provider liveness."
      ]
    },
    {
      "id": "recovery-auth-continuity",
      "statement": "Reconciliation and duplicate-risk successor election accept a current auth record other than the run's exact record only when it keeps the locator ID and kind and names the provider subject that the run's encrypted recovery capsule recorded; a capsule with no recorded subject still needs the exact record.",
      "area": "mutations",
      "source": {
        "path": "docs/effect-confirmed-write-runtime.md",
        "quote": "locator ID and kind and names the provider subject that the run's encrypted recovery capsule recorded."
      },
      "layer": "property",
      "status": "evidenced",
      "evidence": [
        "src/confirmed-write-intent-fence.test.ts",
        "src/provider-plugin-portable-runtime.test.ts",
        "src/recovery.test.ts",
        "src/runtime.test.ts",
        "src/web-session-recovery.test.ts"
      ],
      "assumptions": [
        "encryption",
        "provider-behaviour",
        "same-user-trusted"
      ],
      "notVerified": [
        "The check compares subject strings. That one subject names one provider account rests on how the auth record's subject was bound, by a plugin subject probe or by the operator; a subject typed onto another account's credentials is not detected here.",
        "The property test samples the pure `recoveryAuthContinuity` decision; its use by the web-session reconciler, the portable reconciler, and successor election is covered only by the listed example tests.",
        "The intent fence itself stays keyed by locator ID: a fulfilled run under other auth bytes is still withheld rather than replayed, because run journals do not record the subject."
      ],
      "properties": [
        {
          "path": "src/recovery.test.ts",
          "test": "property: only exact bytes or the recorded provider subject continue a run's realm"
        }
      ]
    },
    {
      "id": "intent-fence-readback",
      "statement": "`ghostget doctor` reads every confirmed-write intent claim back against its run journal without writing, reports malformed, orphaned, stale, drifted, misplaced, and repeated claims as unhealthy, and names claims and runs only by opaque key and run ID.",
      "area": "mutations",
      "source": {
        "path": "docs/effect-confirmed-write-runtime.md",
        "quote": "`ghostget doctor` reads the fence back without writing, after its repair pass."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/confirmed-write-intent-fence.test.ts",
        "src/ghostget.test.ts"
      ],
      "assumptions": [
        "filesystem-durability",
        "same-user-trusted"
      ],
      "notVerified": [
        "The readback is not modelled; only the listed example tests cover it, and they plant an orphaned, a malformed, and an off-chain claim but not every issue kind.",
        "The readback reads at most 10,000 directory entries and then reports itself truncated; it does not re-derive the hash-keyed ledgers.",
        "Doctor runs its journal repair pass before the readback, so the readback describes the state after that repair."
      ]
    },
    {
      "id": "durable-boundaries-before-dispatch",
      "statement": "Confirmation claim, plan consumption, provisional receipt, idempotency ledger, and recovery capsule reach durable storage before remote dispatch; dispatch is refused if the capsule cannot be stored.",
      "area": "mutations",
      "source": {
        "path": "docs/effect-confirmed-write-runtime.md",
        "quote": "Confirmation claims, plan consumption, provisional receipt, idempotency ledger and recovery capsule must reach their existing durable boundaries before remote dispatch."
      },
      "layer": "stateful-model",
      "status": "evidenced",
      "evidence": [
        "src/confirmed-write-program.test.ts",
        "src/runtime.test.ts",
        "src/state-crash-harness.fixture.ts",
        "src/state-crash-harness.test.ts",
        "src/state-crash-port.test-support.ts",
        "src/state-crash-preload.test-support.ts"
      ],
      "assumptions": [
        "filesystem-durability",
        "provider-behaviour"
      ],
      "notVerified": [
        "The crash harness samples its schedules: CI runs one fast-check schedule of up to four commands per crash mode, each crashing at one generated boundary, so it does not visit every boundary of every operation.",
        "Crashes land only on the state and path helpers' filesystem effects. Writes the runtime process makes directly, such as the provider-effect ground truth, are outside the crash port.",
        "Power loss is modelled by the port, not observed: it rolls back, newest first, created, linked, renamed, and unlinked entries whose directory was not fsynced after the effect, and truncates data not fsynced after its write. Directory tree removals are treated as durable when they return, and a real filesystem may keep or lose unsynced effects in other combinations.",
        "One runtime process mutates the state at a time; concurrent confirmations under crash are not modelled here.",
        "The harness checks outcomes: no crossing repeats, none is forgotten, and a crossing leaves a durable started journal. It does not check separately that each named record (claim, plan consumption, receipt, ledger, capsule) was durable, and it re-confirms with a freshly saved plan, so replaying a consumed plan digest after a crash is not exercised.",
        "That dispatch is refused when the recovery capsule cannot be stored rests on the listed example tests only."
      ],
      "properties": [
        {
          "path": "src/state-crash-harness.test.ts",
          "test": "a crash just before a durable boundary never repeats or forgets a crossing"
        },
        {
          "path": "src/state-crash-harness.test.ts",
          "test": "a crash just after a durable boundary never repeats or forgets a crossing"
        },
        {
          "path": "src/state-crash-harness.test.ts",
          "test": "a torn data write never repeats or forgets a crossing"
        },
        {
          "path": "src/state-crash-harness.test.ts",
          "test": "power loss at a durable boundary never repeats or forgets a crossing"
        }
      ]
    },
    {
      "id": "journal-stale-writer-rejected",
      "statement": "Dispatch callbacks persist transitions against one current journal cell; a stale or competing callback cannot reuse an older journal snapshot (content-hash CAS).",
      "area": "mutations",
      "source": {
        "path": "docs/effect-confirmed-write-runtime.md",
        "quote": "A stale or competing callback cannot reuse an older journal snapshot."
      },
      "layer": "property",
      "status": "evidenced",
      "evidence": [
        "src/confirmed-write-program.test.ts",
        "src/run-journal.property.test.ts",
        "src/run-journal.test.ts"
      ],
      "assumptions": [
        "filesystem-durability",
        "provider-behaviour"
      ],
      "notVerified": [
        "Generated inputs are sampled at the configured run count; this is not a proof over all inputs."
      ],
      "properties": [
        {
          "path": "src/run-journal.property.test.ts",
          "test": "a lost native acknowledgement never permits a stale journal write in a bounded dispatch schedule"
        }
      ]
    },
    {
      "id": "journal-invariant-inductive",
      "statement": "assertJournalInvariants is inductive under transitionRunJournal and dispatch counters are monotone; skipped, duplicate, or contradictory progress is rejected.",
      "area": "mutations",
      "source": {
        "path": "kb/plans/formal-verification-assurance.md",
        "quote": "`assertJournalInvariants` is inductive under `transitionRunJournal`, and the dispatch counters are monotone."
      },
      "layer": "lean",
      "status": "evidenced",
      "evidence": [
        "verification/lean/GhostgetVerification/RunJournal.lean",
        "verification/lean/Differential.lean",
        "scripts/verification-lean-oracle.ts",
        "scripts/verification-lean-run-journal.test.ts",
        "src/run-journal.property.test.ts",
        "src/run-journal.test.ts"
      ],
      "assumptions": [
        "filesystem-durability",
        "provider-behaviour"
      ],
      "notVerified": [
        "The proof is about a Lean model of assertJournalInvariants, the parseDispatch bounds, and transitionRunJournal. The differential test ties the model to the TypeScript on generated journals and events only; it is not a proof that the TypeScript equals the model.",
        "The transition's own guards do not preserve the invariant alone: an explicit no-op success before the confirmation is consumed and a duplicate successor naming its own run are rejected only by the final parseRunJournal. The production-shape theorem holds by construction, because the model rechecks the invariant; the substantive results are that the guarded step keeps the invariant outside those two events and that the final parse rejects exactly those two.",
        "Adapter, auth, owner identity, digests, the final origin, error text, the 64 KiB bound, durable storage, and the compare-and-swap write in updateRunJournal are outside the model."
      ]
    },
    {
      "id": "public-rejection-preserved",
      "statement": "The confirmed-write public boundary preserves the exact selected rejection value, including undefined, null, and other falsey values.",
      "area": "mutations",
      "source": {
        "path": "docs/effect-confirmed-write-runtime.md",
        "quote": "The public boundary keeps the exact selected rejection, including `undefined`, `null` and other falsey values."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/confirmed-write-program.test.ts"
      ],
      "assumptions": [
        "filesystem-durability",
        "provider-behaviour"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "messaging-composite-ordered-prefix",
      "statement": "A messaging turn is one composite confirmation and one ordered, prefix-durable run: the accepted prefix is monotone, at most one part is dispatching or indeterminate, and no part is redispatched.",
      "area": "messaging",
      "source": {
        "path": "SECURITY.md",
        "quote": "A messaging turn is one composite confirmation and one ordered, prefix-durable run."
      },
      "layer": "quint",
      "status": "evidenced",
      "evidence": [
        "scripts/verification-messaging-replay.test.ts",
        "src/messaging-action-store.test.ts",
        "src/messaging-confirmation-recovery.test.ts",
        "src/messaging-provider-identity-collision.test.ts",
        "src/messaging-runtime-composite.test.ts",
        "src/messaging-runtime-execution.test.ts",
        "verification/quint/messaging.qnt"
      ],
      "assumptions": [
        "filesystem-durability",
        "provider-behaviour"
      ],
      "notVerified": [
        "The Quint model covers one run of three parts; Apalache checks it to depth 10 and seeded simulation samples 2,000 runs of up to 12 steps. Neither is a proof for longer runs or more parts.",
        "The replay drives `transitionMessagingRun` and the runtime's `messagingRecoveryEvent` over 1,000 seeded traces. It does not cover the durable journal writes, file locking, or the provider adapters around them.",
        "A provider history window may evict the accepted prefix before recovery reads it."
      ]
    },
    {
      "id": "messaging-recovery-model",
      "statement": "Beeper and Message Like Me recovery retain a live or indeterminate owner and never reclaim it until death is proved.",
      "area": "messaging",
      "source": {
        "path": "kb/plans/formal-verification-assurance.md",
        "quote": "Add a `fc.commands` model for Beeper and Message Like Me recovery."
      },
      "layer": "stateful-model",
      "status": "evidenced",
      "evidence": [
        "src/beeper-message-like-me-recovery.model.test.ts",
        "src/beeper-message-like-me-recovery.test.ts"
      ],
      "assumptions": [
        "filesystem-durability",
        "process-liveness",
        "provider-behaviour"
      ],
      "notVerified": [
        "The fast-check model covers the export admission claim: acquisition, helper launch, bind, settle, cleanup-unsafe, release, stale controllers, parent or helper death or unreadable liveness, and reboot, over 10 generated sequences of up to 10 commands on a real claim file. Liveness readings come from the model through test-only seams, answered as a truthful processOwnerStatus would; real process-start and boot identity reading is covered by src/process-identity.test.ts.",
        "The directory-lease recovery (raw working directories and bundle stages) is covered only by the listed example tests. A dead owner's launching lease is reclaimed once its recorded deadline passes, so that path treats the deadline, not a proved child death, as the end of the launch.",
        "Two seeded defects are killed by the model: taking over an owner whose liveness cannot be read, and taking over a cleanup-unsafe admission in the same boot."
      ],
      "properties": [
        {
          "path": "src/beeper-message-like-me-recovery.model.test.ts",
          "test": "retains a live or indeterminate owner and takes over only after death is proved"
        }
      ]
    },
    {
      "id": "messaging-stop-on-drift",
      "statement": "Before every remaining part, current provider state is rechecked and the run stops on foreign activity, edit, retraction, participant or provider drift, permanent failure, partial work, or possible completion.",
      "area": "messaging",
      "source": {
        "path": "SECURITY.md",
        "quote": "Ghostget checks current provider state before every remaining part and stops on foreign activity, edit, retraction, participant drift, provider drift"
      },
      "layer": "property",
      "status": "evidenced",
      "evidence": [
        "src/messaging-automation.test.ts",
        "src/messaging-runtime-execution.test.ts"
      ],
      "assumptions": [
        "filesystem-durability",
        "provider-behaviour"
      ],
      "notVerified": [
        "The property runs the production composite runtime through a synthetic provider plugin, for one to three parts with at most one adverse event per run: an incoming or extra outgoing message, an edit, a deletion, a reordering, a participant or provider-revision change on the route, a failure before or after the durable fence, a malformed result, or a deadline or abort before or after the fence. It checks the terminal state, proven prefix, stop reason, and dispatch count against a reference model. CI runs 6 generated runs; two seeded runtime defects are killed.",
        "Two or more adverse events in one run, and the real Beeper, iMessage, and WhatsApp plugins' own drift readings, are covered only by the listed example tests.",
        "The claim was scheduled as a stateful model; it is evidenced by a property over single-event schedules instead, because each part's recheck is independent of the earlier parts' events."
      ],
      "properties": [
        {
          "path": "src/messaging-runtime-execution.test.ts",
          "test": "stops on every drift, failure, or cancellation at the modelled part and never resubmits"
        }
      ]
    },
    {
      "id": "messaging-transition-inductive",
      "statement": "The messaging run reducer invariant is inductive under transitionMessagingRun.",
      "area": "messaging",
      "source": {
        "path": "kb/plans/formal-verification-assurance.md",
        "quote": "The same inductive-invariant proof for `transitionMessagingRun`."
      },
      "layer": "lean",
      "status": "evidenced",
      "evidence": [
        "verification/lean/GhostgetVerification/MessagingRun.lean",
        "verification/lean/Differential.lean",
        "scripts/verification-lean-oracle.ts",
        "scripts/verification-lean-messaging-run.test.ts",
        "src/messaging-action-store.test.ts"
      ],
      "assumptions": [
        "filesystem-durability",
        "provider-behaviour"
      ],
      "notVerified": [
        "The proof is about a Lean model of assertRun, the structural checks of parseRun, and transitionMessagingRun. The differential test ties the model to the TypeScript on generated runs of up to eight parts only; it is not a proof that the TypeScript equals the model.",
        "The transition's own guards do not preserve the invariant alone: an accepted part whose provider message ID repeats one in the accepted prefix is rejected only by the final parseRun. The production-shape theorem holds by construction, because the model rechecks the invariant; the substantive results are that the guarded step keeps the invariant outside that event and that the final parse rejects exactly that event.",
        "Part text, digests, reply references, delivery and read fields, context evidence, encryption, durable storage, and the compare-and-swap write in updateMessagingRun are outside the model."
      ]
    },
    {
      "id": "messaging-uncertain-not-resubmitted",
      "statement": "Cancellation never proves an already-started action was unsent; uncertain submits are reconciled by exact run identity and never resubmitted.",
      "area": "messaging",
      "source": {
        "path": "docs/messaging-automation.md",
        "quote": "reconcile its exact run identity without resubmitting uncertain work."
      },
      "layer": "property",
      "status": "evidenced",
      "evidence": [
        "src/beeper-message-like-me-recovery.test.ts",
        "src/messaging-automation.test.ts",
        "src/messaging-confirmation-recovery.test.ts",
        "src/messaging-runtime-execution.test.ts"
      ],
      "assumptions": [
        "filesystem-durability",
        "provider-behaviour"
      ],
      "notVerified": [
        "The property checks that a deadline or abort after the durable fence, a failure after it, or a malformed result leaves the run indeterminate at that part with possibleSubmittedPartIndex set, never failed-before-dispatch; that confirming the same plan again is refused without another provider attempt; and that the stored run read back by its run identity is unchanged. CI runs 6 generated runs over the synthetic provider plugin. A seeded defect that records a post-fence failure as unsent is killed.",
        "Reconciliation of an indeterminate part against provider state, and Beeper and Message Like Me recovery, are covered only by the listed example tests and the recovery model; the property does not resolve an indeterminate part.",
        "The claim was scheduled as a stateful model; it is evidenced by a property over single-event schedules instead."
      ],
      "properties": [
        {
          "path": "src/messaging-runtime-execution.test.ts",
          "test": "stops on every drift, failure, or cancellation at the modelled part and never resubmits"
        }
      ]
    },
    {
      "id": "messaging-capability-io-private",
      "statement": "Messaging route, context, reply, and provider references enter only through stdin or owner-only files and leave only through explicit atomic mode-0600 artifacts, never argv or ordinary output.",
      "area": "messaging",
      "source": {
        "path": "SECURITY.md",
        "quote": "These values enter through stdin or checked owner-only files and leave only through explicit atomic mode-`0600` artifacts."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/args.test.ts",
        "src/messaging-private-output-boundary.test.ts"
      ],
      "assumptions": [
        "filesystem-durability",
        "provider-behaviour"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "messaging-encrypted-no-plaintext-fallback",
      "statement": "Messaging route, context, preview, and execution state is encrypted at rest with authenticated reference binding; authentication failure, expiry, generation drift, or implementation drift makes records unusable and never falls back to plaintext.",
      "area": "messaging",
      "source": {
        "path": "SECURITY.md",
        "quote": "Ghostget encrypts route, context, preview, and execution state at rest"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/cursor-token.test.ts",
        "src/messaging-action-store.test.ts",
        "src/messaging-runtime-execution.test.ts",
        "src/messaging-store.test.ts"
      ],
      "assumptions": [
        "filesystem-durability",
        "provider-behaviour"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "messaging-output-outside-state-root",
      "statement": "Explicit messaging output paths are distinct from each other and outside the Ghostget state root, so plaintext exports cannot replace keys, plans, runs, or receipts.",
      "area": "messaging",
      "source": {
        "path": "SECURITY.md",
        "quote": "Explicit messaging output paths must be distinct and outside the Ghostget state root"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/messaging-private-output-boundary.test.ts",
        "src/messaging-runtime-composite.test.ts"
      ],
      "assumptions": [
        "filesystem-durability",
        "provider-behaviour"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "messaging-automation-group-epochs",
      "statement": "Observed group binding drift permanently disables the old enrollment and its grants; a replacement enrollment has a new ID and cannot import prior-roster baseline bodies, historical backfill or unknown message mutations.",
      "area": "messaging",
      "source": {
        "path": "docs/messaging-automation.md",
        "quote": "Observed group binding drift permanently invalidates that enrollment."
      },
      "layer": "property",
      "status": "evidenced",
      "evidence": [
        "src/messaging-automation-groups.test.ts",
        "verification/mutants.json",
        "src/messaging-automation.test.ts",
        "src/messaging-automation-server.test.ts",
        "src/providers/imessage-automation.test.ts",
        "src/providers/beeper-automation.test.ts",
        "src/providers/whatsapp-automation.test.ts",
        "src/providers/whatsapp-automation-runtime.test.ts"
      ],
      "assumptions": [
        "filesystem-durability",
        "provider-behaviour"
      ],
      "notVerified": [
        "The model samples 30 schedules of up to 14 actions plus retained workload seeds over the production SQLite host with injected providers. It covers polling, sending, roster changes (including an authoritative empty roster) and restoration, restart, title changes and lookup faults; it does not exhaust arbitrary concurrent schedules or prove provider liveness. Two seeded defects, transient binding invalidation and group reads from the unrestricted provider archive, are killed by their named regression tests.",
        "History isolation trusts the reviewed provider's original creation timestamp and cursor semantics. It does not cover a compromised provider or host, or a roster change restored between every authoritative observation.",
        "The provider effect-boundary checks use synthetic adapters; no real account, pairing, message send or delivery qualification is implied."
      ],
      "properties": [
        {
          "path": "src/messaging-automation-groups.test.ts",
          "test": "bounded group lifecycle schedules never revive an observed old binding"
        }
      ]
    },
    {
      "id": "messaging-automation-grant-scoped",
      "statement": "The owner messaging host requires explicit allow grants for messaging.automation.* operations; old messaging.send allow, ask, deny, or unmanaged policy provide no unattended authority, and changed manifests or closures invalidate grants.",
      "area": "messaging",
      "source": {
        "path": "docs/messaging-automation.md",
        "quote": "An old `messaging.send` allow does not authorize this host. `ask`, `deny`, and an unmanaged policy do not provide unattended authority."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/messaging-automation-server.test.ts",
        "src/messaging-automation.test.ts"
      ],
      "assumptions": [
        "filesystem-durability",
        "provider-behaviour"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "messaging-automation-bounds",
      "statement": "The messaging automation protocol rejects a second ordinary in-flight request and enforces frame (24 MiB), response (32 MiB), and asset (16 MiB each, 64 MiB total, 32 entries, canonical Base64 with checked SHA-256) bounds.",
      "area": "messaging",
      "source": {
        "path": "docs/messaging-automation.md",
        "quote": "Frames are bounded to 24 MiB; responses to 32 MiB. Assets use canonical Base64 and a checked SHA-256, at most 16 MiB each, 64 MiB total and 32 entries."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/messaging-automation-server.test.ts",
        "src/messaging-automation.test.ts"
      ],
      "assumptions": [
        "filesystem-durability",
        "provider-behaviour"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "helper-mutual-exclusion",
      "statement": "The state helper's three-phase claim and the path helper's per-leaf claim each admit at most one critical-section holder, including with stale-owner reaping and non-atomic readdir.",
      "area": "storage",
      "source": {
        "path": "kb/plans/formal-verification-assurance.md",
        "quote": "The invariant is `|{p : critical(p)}| ≤ 1`."
      },
      "layer": "quint",
      "status": "evidenced",
      "evidence": [
        "scripts/verification-path-claim-replay.test.ts",
        "scripts/verification-state-claim-replay.test.ts",
        "src/browser-snapshots.test.ts",
        "src/path-helper.test.ts",
        "src/read-projections.test.ts",
        "src/storage-cas.test.ts",
        "verification/quint/path-claim.qnt",
        "verification/quint/state-claim.qnt"
      ],
      "assumptions": [
        "filesystem-atomic-rename",
        "process-liveness",
        "same-user-trusted"
      ],
      "notVerified": [
        "verification/quint/state-claim.qnt checks two state helpers with at most one kill. A listing may report the other claim at any phase it had since the listing began, or not at all after it changed. CI runs 20,000 simulated samples of up to 12 steps and Apalache to length 8. The replay runs the production listing and stage decision on real claim files for 2,000 traces; concurrent helper processes run only in the example tests. Three or more helpers, an owner whose liveness cannot be inspected, and the eight-listing retry bound are not modelled.",
        "When listings are not atomic, both state-helper claims can reach `held`. The later one then fails with \"state mutation arbitration admitted two owners\" instead of entering, so mutual exclusion holds but that request fails.",
        "The path-helper model is bounded: three helpers, at most one kill, kills only at pause points, 10,000 simulated samples of up to 12 steps, Apalache to length 6, and 60 replayed traces.",
        "A path helper from before the reaper election can move a live claim away without restoring it. A current helper that claims afterwards finds that claim in the quarantine, releases its own claim, and fails; the residue sweep keeps the quarantine until the claim's PID exits. Liveness is by PID alone, so a reused PID keeps such a quarantine, and blocks the leaf, until that PID exits; this also applies to a current reaper killed between moving a dead claim into its quarantine and removing it, when the dead claim's PID is reused. Only src/path-helper.test.ts covers this, the Quint model has no such helper, and nothing stops an old helper that claims third."
      ]
    },
    {
      "id": "state-cas-no-rollback",
      "statement": "Private state writes are compare-and-swap: exactly one overlapping writer for an exact snapshot succeeds, a stale writer never rolls state back or resurrects a removed file, disappearance is a conflict, and symlinks are never followed.",
      "area": "storage",
      "source": {
        "path": "docs/plugins.md",
        "quote": "exact-byte compare-and-exchange"
      },
      "layer": "stateful-model",
      "status": "evidenced",
      "evidence": [
        "src/auth-storage.test.ts",
        "src/session-secrets.test.ts",
        "src/storage-cas.model.test.ts",
        "src/storage-cas.test.ts"
      ],
      "assumptions": [
        "filesystem-atomic-rename",
        "same-user-trusted"
      ],
      "notVerified": [
        "The stateful model runs 12 schedules of up to 8 commands against the real bound state helper on one file under `session-secrets`: conditional writes and removals that hold a current or stale snapshot, an unconditional recreate, and a swap of the file for a symbolic link to a file outside the state layout. It checks the sequential interleavings it generates. Genuinely overlapping writers are covered only by the cross-process example test in src/storage-cas.test.ts, for two writers.",
        "A symbolic link in a parent directory, and the path helper that writes outside `GHOSTGET_STATE_HOME`, are not in the model; the example tests cover only their enumerated cases.",
        "Crashes during a compare-and-swap are covered by the state-crash-consistency claim, not by this model."
      ],
      "properties": [
        {
          "path": "src/storage-cas.model.test.ts",
          "test": "stale snapshots never roll state back, resurrect a removed file, or follow a link"
        }
      ]
    },
    {
      "id": "state-crash-consistency",
      "statement": "A crash or power loss at any durable state-helper or path-helper boundary leaves each private file with its old or its new content, never a torn one; a session-secret read afterwards returns the old value, the new value, or nothing, a completed removal stays removed, and the next write succeeds.",
      "area": "storage",
      "source": {
        "path": "kb/plans/formal-verification-assurance.md",
        "quote": "power-loss truncation"
      },
      "layer": "stateful-model",
      "status": "evidenced",
      "evidence": [
        "src/state-crash-harness.fixture.ts",
        "src/state-crash-harness.test.ts",
        "src/state-crash-port.test-support.ts",
        "src/state-crash-preload.test-support.ts"
      ],
      "assumptions": [
        "filesystem-atomic-rename",
        "filesystem-durability",
        "process-liveness",
        "same-user-trusted"
      ],
      "notVerified": [
        "The harness samples its schedules: CI runs two fast-check schedules each for session secrets and private files, each command crashing at one generated boundary. Only a single private-file replacement is swept at every boundary under power loss.",
        "Power loss is modelled by the port, not observed: it rolls back, newest first, created, linked, renamed, and unlinked entries whose directory was not fsynced after the effect, and truncates data not fsynced after its write. Directory tree removals are treated as durable when they return, and a real filesystem may keep or lose unsynced effects in other combinations.",
        "A crashed session-secret write may lose the previous value; the law allows that outcome and does not check that the old value survives.",
        "One process mutates the state at a time; overlapping writers under crash are not modelled here."
      ],
      "properties": [
        {
          "path": "src/state-crash-harness.test.ts",
          "test": "a crash at any durable boundary leaves the old value, the new value, or nothing"
        },
        {
          "path": "src/state-crash-harness.test.ts",
          "test": "a crash at any durable boundary leaves the old or the new value, never a torn one"
        }
      ]
    },
    {
      "id": "session-secret-filename-injective",
      "statement": "sessionSecretFileName is injective on valid (namespace, authId) coordinates, and parseSessionSecretFileName reads every name it writes back to that coordinate.",
      "area": "storage",
      "source": {
        "path": "kb/plans/formal-verification-assurance.md",
        "quote": "Identifier grammars, and route, operation, and session-secret composite keys: `parse ∘ format = id` and the keys are unambiguous."
      },
      "layer": "lean",
      "status": "evidenced",
      "evidence": [
        "scripts/verification-lean-encodings.test.ts",
        "src/session-secrets.test.ts",
        "verification/lean/GhostgetVerification/Encodings/SessionSecret.lean"
      ],
      "assumptions": [
        "filesystem-atomic-rename",
        "same-user-trusted",
        "verification-tools"
      ],
      "notVerified": [
        "The Lean theorems are about a Lean model of the naming and parsing functions. The differential test checks that the TypeScript agrees with that model on generated names, not on every name.",
        "The name grammar is modelled by hand from its regular expression.",
        "File removal, adoption of ambiguous historical files, and filesystem behaviour are not modelled, so two properties are covered only by the listed tests: removing one account never deletes or blocks another account's files, and single-coordinate and auth-wide removal both take an ambiguous historical file only for the coordinate its envelope names, by compare-and-swap on the bytes that named it.",
        "Ownership of an ambiguous historical file is read from its envelope header without decryption, so a same-user writer that forges the header can direct its removal; that writer could already delete the file directly."
      ]
    },
    {
      "id": "no-writes-on-read-paths",
      "statement": "Read paths never mutate state; reads may only cache.",
      "area": "storage",
      "source": {
        "path": "AGENTS.md",
        "quote": "No writes on read paths. Reads may cache; they never mutate."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/contract-repair-cli.test.ts",
        "src/contract-repair-inbox.test.ts",
        "src/control/policy-privacy.test.ts",
        "src/control/read-capability.test.ts",
        "src/cursor-token.test.ts",
        "src/linked-device-lifecycle-journal.test.ts",
        "src/provider-plugin-store.test.ts",
        "src/providers/whatsapp-interaction-projection-helper.test.ts",
        "src/read-path-incarnation.test.ts",
        "src/read-path-preparation.test.ts"
      ],
      "assumptions": [
        "filesystem-atomic-rename",
        "same-user-trusted"
      ],
      "notVerified": [
        "Evidence is by named example. Whole-state-tree fingerprints taken before and after cover a cache read (hit, miss, first read, and a leftover admission claim whose owner is dead), a revalidation, a capability read, and `invoke --cache-only`; omni materialization, control inspection, confirmation preparation, and the operation-permission description are checked only for not creating an incarnation. No static or exhaustive check shows that every command that reads is write-free; a new read path is covered only once it takes the typed `AuthIncarnationReader` capability and has its own test.",
        "The D14 exemptions are writes by design and are tested as the only permitted changes: a cache read may create and release its own admission claim, remove a claim whose recorded owner is proven dead, and create the projection encryption key and its store-key marker when they are absent.",
        "Only the control snapshot, its account and permission listings, the auth checks of cache reads, live-read publication, and omni materialization, read-path invocation preparation, confirmation preparation, and the operation-permission account identity take a typed read capability; explicit invocation preparation, including the messaging route, context, and action preparations, still creates a missing auth incarnation as an admitted execution path."
      ]
    },
    {
      "id": "read-path-read-capability",
      "statement": "A read path receives a branded read capability with only read members, such as `AuthIncarnationReader`, not an environment that reaches writers; a structurally similar unbranded object is rejected by the type checker.",
      "area": "storage",
      "source": {
        "path": "AGENTS.md",
        "quote": "Hand a read path a read capability with no writer members, such as `AuthIncarnationReader`, not an environment that reaches writers."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/control/read-capability.test.ts",
        "src/read-path-incarnation.test.ts",
        "src/read-path-preparation.test.ts"
      ],
      "assumptions": [
        "bun-runtime"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked; the type assertions run under `bun run typecheck`.",
        "The brand exists only in the type system; code that casts through `unknown` can still forge a capability.",
        "Only the control snapshot, its account and permission listings, the auth checks of cache reads, live-read publication, and omni materialization, read-path invocation preparation, confirmation preparation, and the operation-permission account identity take the typed capability; other read paths are not covered."
      ]
    },
    {
      "id": "tui-snapshot-read-only",
      "statement": "The control snapshot that `ghostget status` and `ghostget tui --snapshot` read, and its account and permission listings, take no admission and create no state; auth incarnations are created only by account saves, the control-service startup backfill, and admitted execution paths.",
      "area": "storage",
      "source": {
        "path": "AGENTS.md",
        "quote": "The control snapshot that `ghostget status` and `ghostget tui --snapshot` read, and its account and permission listings, take no admission and create no state; account saves, the control-service startup backfill, and admitted execution paths create auth incarnations."
      },
      "layer": "property",
      "status": "evidenced",
      "evidence": [
        "src/control/read-capability.test.ts"
      ],
      "assumptions": [
        "filesystem-atomic-rename",
        "same-user-trusted"
      ],
      "notVerified": [
        "Generated inputs are sampled at the configured run count; this is not a proof over all inputs.",
        "The law fingerprints only the read-projection control tree; writes elsewhere in the state home are covered only by the example snapshot test."
      ],
      "properties": [
        {
          "path": "src/control/read-capability.test.ts",
          "test": "for any set of legacy accounts and orphaned claims, listing revisions write nothing and match the admitted revision exactly when an incarnation exists"
        }
      ]
    },
    {
      "id": "read-path-auth-check-read-only",
      "statement": "The auth checks of a cache read, a live-read publication, and an omni materialization read the auth incarnation through `AuthIncarnationReader`; a missing incarnation reads as changed and none is created.",
      "area": "storage",
      "source": {
        "path": "AGENTS.md",
        "quote": "The auth checks of a cache read, a live-read publication, and an omni materialization read the incarnation through `AuthIncarnationReader`, so a missing incarnation reads as changed and nothing is created."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/read-path-incarnation.test.ts"
      ],
      "assumptions": [
        "filesystem-atomic-rename",
        "same-user-trusted"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked.",
        "The omni example observes the incarnation only between materialization and the next source preparation; read-path preparation itself is covered by read-path-preparation-read-only."
      ]
    },
    {
      "id": "read-projection-admission-exemption",
      "statement": "The only admission write a read-projection cache read makes is its own admission claim, which it creates and releases, and the removal of a claim whose recorded owner is proven dead; the claim carries no data.",
      "area": "storage",
      "source": {
        "path": "AGENTS.md",
        "quote": "First, a read-projection cache read may create and release its own admission claim and remove a claim whose recorded owner is proven dead, because it must exclude a concurrent projection transition; the claim is coordination state with no data."
      },
      "alsoQuotes": [
        {
          "path": "AGENTS.md",
          "quote": "The exemptions cover nothing else."
        }
      ],
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/read-projections.test.ts"
      ],
      "assumptions": [
        "filesystem-atomic-rename",
        "process-liveness",
        "same-user-trusted"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked.",
        "No check establishes that a cache read writes nothing beyond its own claim and dead-owner removal."
      ]
    },
    {
      "id": "read-path-preparation-read-only",
      "statement": "Read-path invocation preparation (capability and omni reads, cache-only invocations, and control-plane inspection), confirmation preparation, and the operation-permission account identity read the auth incarnation through `AuthIncarnationReader`; a missing incarnation fails closed and none is created, while explicit invocation preparation remains the admitted execution path that may create one.",
      "area": "storage",
      "source": {
        "path": "AGENTS.md",
        "quote": "Read-path preparation (capability and omni reads, cache-only invocations, and control-plane inspection), confirmation preparation, and the operation-permission account identity bind the current incarnation the same way: they read it through `AuthIncarnationReader`, fail closed when it is missing, and create none."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/read-path-preparation.test.ts"
      ],
      "assumptions": [
        "filesystem-atomic-rename",
        "same-user-trusted"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked: one missing incarnation per read path, on a fresh state home.",
        "The cache-only `ghostget invoke` branch is driven in process through `main` with a stubbed cache read, not through the installed binary; the retry preparation after a discarded live read is checked by type and review only.",
        "Explicit invocation preparation, including the messaging route, context, and action preparations, still creates a missing incarnation as an admitted execution path."
      ]
    },
    {
      "id": "read-projection-key-exemption",
      "statement": "A cache read creates at most the projection encryption key and its store-key marker, only when they are absent; a later cache read writes nothing.",
      "area": "storage",
      "source": {
        "path": "AGENTS.md",
        "quote": "Second, a cache read may create the projection encryption key and its store-key marker when they are absent, because a miss returns the query key that this encryption key derives; each is created at most once per state home and holds no user data."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/read-path-incarnation.test.ts"
      ],
      "assumptions": [
        "filesystem-atomic-rename",
        "same-user-trusted"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked.",
        "The example checks a cache read after preparation on a fresh state home; it does not cover concurrent first reads or a legacy store that needs only its marker."
      ]
    },
    {
      "id": "derived-state-rebuildable",
      "statement": "Derived state is rebuildable from authoritative state and lives in the cheapest serving tier; only authoritative state uses transactional storage.",
      "area": "storage",
      "source": {
        "path": "AGENTS.md",
        "quote": "Derived state is rebuildable and lives in the cheapest tier that can serve it."
      },
      "layer": "not-verified",
      "status": "not-verified",
      "evidence": [],
      "assumptions": [
        "filesystem-atomic-rename",
        "same-user-trusted"
      ],
      "notVerified": [
        "No automated check covers this claim.",
        "Only the `costs.json` kind classification is checked; rebuildability and tier placement are not."
      ]
    },
    {
      "id": "content-bytes-in-content-store",
      "statement": "Content bytes live only in the content store; the control plane holds references and metadata.",
      "area": "storage",
      "source": {
        "path": "AGENTS.md",
        "quote": "Content bytes live in the content store; the control plane keeps references and metadata only."
      },
      "layer": "not-verified",
      "status": "not-verified",
      "evidence": [
        "src/control/gateway.test.ts"
      ],
      "assumptions": [
        "filesystem-atomic-rename",
        "same-user-trusted"
      ],
      "notVerified": [
        "No automated check covers this claim as stated; the listed tests check only related cases."
      ]
    },
    {
      "id": "secrets-out-of-artifacts",
      "statement": "The code paths that the cited tests exercise keep raw authenticated traffic, cookies, tokens, profiles, private content, and local paths out of the receipts, logs, diagnostics, and captured evidence they produce.",
      "area": "privacy",
      "source": {
        "path": "AGENTS.md",
        "quote": "Keep raw authenticated traffic, cookies, tokens, profiles, private content, and local paths out of Git, tests, receipts, logs, and diagnostics."
      },
      "layer": "property",
      "status": "evidenced",
      "evidence": [
        "scripts/verification-tools.test.ts",
        "src/auth-storage.test.ts",
        "src/control/gateway.test.ts",
        "src/control/interface-cli.test.ts",
        "src/derive-review.test.ts",
        "src/ghostget.test.ts",
        "src/har-internal.test.ts",
        "src/media/archive.test.ts",
        "src/media/process.test.ts",
        "src/run-journal.test.ts"
      ],
      "assumptions": [
        "same-user-trusted",
        "encryption"
      ],
      "notVerified": [
        "Generated inputs are sampled at the configured run count; this is not a proof over all inputs.",
        "Modules outside the cited tests are not checked, and nothing scans output for secrets in general.",
        "Git history, test fixtures, and CI logs are not mechanically scanned."
      ],
      "properties": [
        {
          "path": "src/har-internal.test.ts",
          "test": "property: arbitrary identifier-shaped path segments and JSON map keys never survive evidence"
        },
        {
          "path": "scripts/verification-tools.test.ts",
          "test": "never lets a replaced path, a marker, or a control character through"
        }
      ]
    },
    {
      "id": "secrets-at-rest-encrypted-private",
      "statement": "Provider session material is stored encrypted with authenticated ciphertext and private modes, invalidated on auth incarnation rotation, and never re-keyed beside existing ciphertext.",
      "area": "privacy",
      "source": {
        "path": "README.md",
        "quote": "Replacing or removing an auth locator rotates its local lifetime identity, so old projection and provider-session ciphertext cannot revive after recreation."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/auth-storage.test.ts",
        "src/nonstate-storage.test.ts",
        "src/session-secrets.test.ts"
      ],
      "assumptions": [
        "same-user-trusted",
        "encryption"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "confirmation-plans-encrypted",
      "statement": "Confirmation plan inputs are encrypted at rest with authenticated metadata; a missing or replaced key never causes key replacement or ciphertext overwrite.",
      "area": "privacy",
      "source": {
        "path": "skills/ghostget/references/social-platform-routing.md",
        "quote": "Ghostget's plan owns encrypted confirmed input and attachment bundles for its lifecycle."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/ghostget.test.ts",
        "src/runtime.test.ts"
      ],
      "assumptions": [
        "same-user-trusted",
        "encryption"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "browser-admission-cap-two",
      "statement": "At most two locally owned browser acquisitions run concurrently across processes sharing one state home.",
      "area": "browser-admission",
      "source": {
        "path": "SECURITY.md",
        "quote": "Ghostget caps locally owned browser acquisition at two across processes sharing one state home"
      },
      "layer": "stateful-model",
      "status": "evidenced",
      "evidence": [
        "src/browser-admission.model.test.ts",
        "src/browser-admission.property.test.ts",
        "src/browser-admission.test.ts"
      ],
      "assumptions": [
        "filesystem-atomic-rename",
        "process-liveness"
      ],
      "notVerified": [
        "The fast-check model drives production acquireBrowserAdmission and acquireCaptureBrowserWithAdmission against real slot files in one state home, with simulated processes that all reuse one PID, an injected monotonic clock that jumps on every read, owner deaths, unreadable liveness, and reboots. CI runs 8 generated sequences of up to 10 commands. Process and boot identity and owner liveness come from the model through the dependency seams, answered as a truthful processOwnerStatus would; the real readings are covered by src/process-identity.test.ts.",
        "The acquisitions run one at a time in one process; concurrent creates from separate processes are covered by the listed example and property tests, and the slot create relies on the atomic create-if-absent the filesystem-atomic-rename assumption names.",
        "Seeded defects that reclaim every claim, or a same-boot claim whose owner reads as dead, are killed by the model.",
        "The claim was scheduled as a Quint model with production replay; it is evidenced by the stateful model instead."
      ],
      "properties": [
        {
          "path": "src/browser-admission.model.test.ts",
          "test": "never runs more than two acquisitions, never reclaims a same-boot claim, and never launches after expiry"
        }
      ]
    },
    {
      "id": "browser-admission-no-pid-reuse-reclaim",
      "statement": "PID reuse alone cannot reclaim a browser admission claim; automatic reclamation requires a verified prior boot and same-boot claims stay occupied after owner death.",
      "area": "browser-admission",
      "source": {
        "path": "SECURITY.md",
        "quote": "PID reuse alone cannot reclaim a claim. Automatic reclamation requires a verified prior operating-system boot"
      },
      "layer": "stateful-model",
      "status": "evidenced",
      "evidence": [
        "src/browser-admission.model.test.ts",
        "src/browser-admission.property.test.ts",
        "src/browser-admission.test.ts",
        "src/process-identity.test.ts"
      ],
      "assumptions": [
        "filesystem-atomic-rename",
        "process-liveness"
      ],
      "notVerified": [
        "The fast-check model drives production acquireBrowserAdmission and acquireCaptureBrowserWithAdmission against real slot files in one state home, with simulated processes that all reuse one PID, an injected monotonic clock that jumps on every read, owner deaths, unreadable liveness, and reboots. CI runs 8 generated sequences of up to 10 commands. Process and boot identity and owner liveness come from the model through the dependency seams, answered as a truthful processOwnerStatus would; the real readings are covered by src/process-identity.test.ts.",
        "The model checks that a same-boot claim stays occupied after its owner dies or becomes unreadable, and that only a claim from an earlier boot is reclaimed. That a boot identity really changes at reboot and that a process-start identity really distinguishes reused PIDs are assumptions of process-liveness, checked only by the listed example tests.",
        "A seeded defect that reclaims a same-boot claim whose owner reads as dead is killed by the model.",
        "The claim was scheduled as a Quint model with production replay; it is evidenced by the stateful model instead."
      ],
      "properties": [
        {
          "path": "src/browser-admission.model.test.ts",
          "test": "never runs more than two acquisitions, never reclaims a same-boot claim, and never launches after expiry"
        }
      ]
    },
    {
      "id": "browser-admission-malformed-reduces-capacity",
      "statement": "A malformed claim, unverifiable owner, or unsafe state path reduces available capture capacity and never creates an extra slot.",
      "area": "browser-admission",
      "source": {
        "path": "SECURITY.md",
        "quote": "A malformed claim, an unverifiable owner, or an unsafe state path reduces available capture capacity and never creates an extra slot."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/browser-admission.property.test.ts",
        "src/browser-admission.test.ts"
      ],
      "assumptions": [
        "filesystem-atomic-rename",
        "process-liveness"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "browser-admission-no-launch-after-deadline",
      "statement": "Admission polling is budgeted to min(remaining capture time, 30 s), and deadline revalidation plus conditional rollback prevent a browser launch after expiry.",
      "area": "browser-admission",
      "source": {
        "path": "SECURITY.md",
        "quote": "deadline revalidation and conditional rollback prevent a browser launch after expiry"
      },
      "layer": "stateful-model",
      "status": "evidenced",
      "evidence": [
        "src/browser-admission.model.test.ts",
        "src/browser-admission.test.ts"
      ],
      "assumptions": [
        "filesystem-atomic-rename",
        "process-liveness",
        "monotonic-clock"
      ],
      "notVerified": [
        "The fast-check model drives production acquireBrowserAdmission and acquireCaptureBrowserWithAdmission against real slot files in one state home, with simulated processes that all reuse one PID, an injected monotonic clock that jumps on every read, owner deaths, unreadable liveness, and reboots. CI runs 8 generated sequences of up to 10 commands. Process and boot identity and owner liveness come from the model through the dependency seams, answered as a truthful processOwnerStatus would; the real readings are covered by src/process-identity.test.ts.",
        "The model checks every sleep against min(remaining capture time, 30 s, the timeout), that no admission is returned at or after that bound, and that a whole capture launches its browser at most once, under a held slot, before its deadline, with no more time than remains. Browser launch is a stub; what a real browser does with its timeout is not checked.",
        "Seeded defects that drop the deadline revalidation after a create, launch with no time left, or raise the polling cap to 60 s are killed by the model."
      ],
      "properties": [
        {
          "path": "src/browser-admission.model.test.ts",
          "test": "never runs more than two acquisitions, never reclaims a same-boot claim, and never launches after expiry"
        }
      ]
    },
    {
      "id": "repair-signals-private",
      "statement": "Repair signals are bounded and contain no account ID, subject, input or input hash, provider output, URL, credential, raw diagnostic, or HAR.",
      "area": "repair-signals",
      "source": {
        "path": "AGENTS.md",
        "quote": "Keep failed-invocation signals free of account identifiers, inputs, private content, and raw errors."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/contract-repair-cli.test.ts",
        "src/contract-repair-inbox.test.ts",
        "src/contracts-repair.test.ts"
      ],
      "assumptions": [
        "filesystem-atomic-rename"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "repair-inspection-no-demand",
      "statement": "Catalog, check, cache-only, and identity-only inspection records no repair demand.",
      "area": "repair-signals",
      "source": {
        "path": "AGENTS.md",
        "quote": "Catalog/check/cache-only/identity-only inspection must not record demand."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/contract-repair-cli.test.ts",
        "src/contract-repair-inbox.test.ts",
        "src/contracts-repair-lifecycle.test.ts"
      ],
      "assumptions": [
        "filesystem-atomic-rename"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "repair-handoff-no-authority",
      "statement": "Every repair handoff fixes `authority.recapture`, `retry`, `activate`, and `publish` to false; repair signals never authorize capture, retry, activation, or publication, and changed contracts remain unverified candidates.",
      "area": "repair-signals",
      "source": {
        "path": "AGENTS.md",
        "quote": "Repair handoffs never authorize capture, retry, activation, or publication; changed contracts remain unverified candidates."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/contract-repair-cli.test.ts",
        "src/contracts-repair-lifecycle.test.ts",
        "src/contracts-repair.test.ts"
      ],
      "assumptions": [
        "filesystem-atomic-rename"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "repair-inbox-budget",
      "statement": "The contract-repair inbox holds at most 128 entries, 2048 bytes per signal, and 262144 bytes total; full storage refuses new leads without evicting live ones.",
      "area": "repair-signals",
      "source": {
        "path": "costs.json",
        "quote": "budget\": { \"maxEntries\": 128, \"maxBytes\": 262144, \"maxBytesPerSignal\": 2048 }"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/contract-repair-inbox.test.ts"
      ],
      "assumptions": [
        "filesystem-atomic-rename"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "repair-inbox-ttl",
      "statement": "Repair inbox entries are hidden after 30 days and compacted only on the next admitted write; duplicate delivery never rewrites an entry.",
      "area": "repair-signals",
      "source": {
        "path": "costs.json",
        "quote": "Hidden after 30 days; expired entries are compacted on the next admitted write"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/contract-repair-inbox.test.ts"
      ],
      "assumptions": [
        "filesystem-atomic-rename"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "repair-storage-failure-isolated",
      "statement": "Malformed, unsafe, or contended repair storage never changes the original operation outcome, and inspection never repairs or replaces the cache.",
      "area": "repair-signals",
      "source": {
        "path": "docs/contracts.md",
        "quote": "Malformed, unsafe, or contended storage never changes the original operation outcome."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/contract-repair-inbox.test.ts"
      ],
      "assumptions": [
        "filesystem-atomic-rename"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "local-cli-digest-authority",
      "statement": "A local-CLI binding executes only an executable whose exact SHA-256 matches the reviewed tool identity; reported versions are drift checks, not authority.",
      "area": "local-cli",
      "source": {
        "path": "docs/local-cli-providers.md",
        "quote": "the exact executable SHA-256, which is the execution authority"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/beeper-local-plugin.test.ts",
        "src/local-cli-tool-identity.test.ts"
      ],
      "assumptions": [
        "provider-behaviour"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "local-cli-identity-change-invalidates",
      "statement": "Changing the tool identity changes the operation implementation and contract hash, so old previews, receipts, caches, and recovery evidence cannot authorize new bytes.",
      "area": "local-cli",
      "source": {
        "path": "docs/local-cli-providers.md",
        "quote": "Changing the tool identity changes the operation's implementation and contract hash, so old previews, receipts, caches, and recovery evidence cannot silently authorize the new bytes."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/local-cli-durable-identity.test.ts"
      ],
      "assumptions": [
        "provider-behaviour"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "local-cli-fixed-argument-positions",
      "statement": "Caller values fill only reviewed argument positions and cannot select a command, flag, endpoint, target, env var, header, shell fragment, or output path.",
      "area": "local-cli",
      "source": {
        "path": "docs/local-cli-providers.md",
        "quote": "Caller values may fill only reviewed argument positions."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/beeper-local-plugin.test.ts",
        "src/providers/beeper-local-runtime.internal.test.ts"
      ],
      "assumptions": [
        "provider-behaviour"
      ],
      "notVerified": [
        "No property test covers this law yet; only the enumerated example cases are checked."
      ]
    },
    {
      "id": "local-cli-command-coverage-ledger",
      "statement": "Every upstream canonical command maps to exactly one semantic operation or one explicit unavailable reason, and R4 destructive commands are unavailable to provider dispatch.",
      "area": "local-cli",
      "source": {
        "path": "docs/local-cli-providers.md",
        "quote": "Map every canonical command to one semantic Ghostget operation or one explicit unavailable reason."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/beeper-local-plugin.test.ts"
      ],
      "assumptions": [
        "provider-behaviour"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "local-cli-isolated-env",
      "statement": "Local-CLI children start without a shell, with a minimal environment and operation-private directories, and inherit no credentials, targets, proxies, debug overrides, or user plugins.",
      "area": "local-cli",
      "source": {
        "path": "docs/local-cli-providers.md",
        "quote": "Start the process directly without a shell. Give it a minimal environment and operation-private config, data, cache, and temporary directories."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/imessage-direct-plugin.test.ts",
        "src/providers/beeper-local-runtime.internal.test.ts"
      ],
      "assumptions": [
        "provider-behaviour"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "local-cli-birth-time-readiness",
      "statement": "Local-CLI readiness requires a nonzero immutable directory birth time for operation-private roots and reports the transport unavailable before staging credentials otherwise.",
      "area": "local-cli",
      "source": {
        "path": "docs/local-cli-providers.md",
        "quote": "The temporary filesystem must expose a nonzero immutable directory birth time for operation-private roots."
      },
      "layer": "not-verified",
      "status": "not-verified",
      "evidence": [],
      "assumptions": [
        "provider-behaviour"
      ],
      "notVerified": [
        "No automated check covers this claim, and no plan phase schedules one.",
        "No test exercises the birth-time readiness requirement."
      ]
    },
    {
      "id": "local-cli-post-spawn-indeterminate",
      "statement": "Once a local-CLI mutation child starts, any failure (timeout, signal, malformed or lost response) is post-dispatch indeterminate and is never retried.",
      "area": "local-cli",
      "source": {
        "path": "docs/local-cli-providers.md",
        "quote": "Never retry a mutation after the child may have reached the provider."
      },
      "layer": "quint",
      "status": "evidenced",
      "evidence": [
        "scripts/verification-local-cli-replay.test.ts",
        "src/imessage-direct-plugin.test.ts",
        "src/providers/beeper-direct-messaging.test.ts",
        "verification/quint/local-cli.qnt"
      ],
      "assumptions": [
        "provider-behaviour"
      ],
      "notVerified": [
        "verification/quint/local-cli.qnt checks one confirmed local-CLI mutation of one or two children, with a dispatch-boundary refusal and seven post-start faults (deadline timeout, signal, nonzero exit, malformed response, lost response, the child's own not-started report, and a failure while recording the acceptance), to Quint simulation depth 8 and Apalache length 8. Its ITF replay compares 1,000 traces with executeImsgDirectOperation for the iMessage send and executeBeeperLocalOperation for Beeper presence.set, one child or the bounded typing-then-paused pair. The traces reduce to a few dozen distinct runner scripts; each script runs once per runtime on a fresh store and every trace is compared with that run.",
        "The replay replaces runImsgRpc and runBeeperCli with a scripted runner at their seam, so how a real deadline, signal, or lost pipe becomes a thrown error or exit status is covered only by their example tests. The other Beeper mutations share the same dispatch loop and catch but are not replayed; their acknowledgement parsing and readbacks are covered only by the listed example tests.",
        "Reconciliation from separately obtained evidence, and the kernel's durable journal behind beforeDispatch, are outside this model; fence.qnt covers them."
      ]
    },
    {
      "id": "cost-surface-registry",
      "statement": "Every product data surface (table, bucket, stream, dynamic route, blob, provider meter) is registered in costs.json with kind, retention class, owner, and budget; an unregistered surface fails check:cost-surfaces.",
      "area": "costs",
      "source": {
        "path": "AGENTS.md",
        "quote": "A new table, bucket, stream, dynamic route, blob, or provider meter fails `check:cost-surfaces` until it registers."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "scripts/check-cost-surfaces.mjs",
        "scripts/ci-pr-gate.test.ts"
      ],
      "assumptions": [],
      "notVerified": [
        "Only the enumerated example cases are checked.",
        "No unit test covers the surface detector in `scripts/check-cost-surfaces.mjs`."
      ],
      "alsoQuotes": [
        {
          "path": "AGENTS.md",
          "quote": "Run `bun run check:cost-surfaces` before handoff whenever a data surface changes."
        }
      ]
    },
    {
      "id": "bounded-inputs",
      "statement": "The parsers and stores that the cited tests exercise bound their inputs before storage or provider I/O: request bytes, row counts, page sizes, batch sizes, retry counts, and event payloads.",
      "area": "costs",
      "source": {
        "path": "AGENTS.md",
        "quote": "Bound every input before storage or provider I/O"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/article-draft-document.test.ts",
        "src/contract-repair-inbox.test.ts",
        "src/contracts-plan.test.ts",
        "src/control/approval-broker.test.ts",
        "src/control/gateway.test.ts",
        "src/control/validation.test.ts",
        "src/messaging-automation-server.test.ts",
        "src/omni-limits.test.ts",
        "src/provider-plugin-host.test.ts",
        "src/provider-plugin-registry.test.ts"
      ],
      "assumptions": [],
      "notVerified": [
        "Only the enumerated example cases are checked.",
        "Modules without a cited test are not checked, and no static scan finds an unbounded input elsewhere."
      ]
    },
    {
      "id": "mutation-idempotency-key",
      "statement": "Every mutating route declares `idempotency: local-at-most-once` with a dedupe window of at least 60 seconds, so a retried write is refused while an unsettled same-intent journal exists and while a fulfilled journal’s dedupe window or duplicate-intent record still holds — a provider charge happens at most once per intent within its window. `idempotency: none` routes are dispatch-free by contract. After the window expires, a retry is admitted as a new charged attempt.",
      "area": "costs",
      "source": {
        "path": "AGENTS.md",
        "quote": "Every mutation carries an idempotency key; a retried write never double-charges storage, quota, or provider spend."
      },
      "layer": "property",
      "status": "evidenced",
      "evidence": [
        "src/contract-repair-inbox.test.ts",
        "src/idempotency-fence.property.test.ts",
        "src/idempotency-inventory.test.ts",
        "src/run-journal.test.ts",
        "src/runtime.test.ts"
      ],
      "assumptions": [],
      "notVerified": [
        "The boundary is the dedupe window: a fulfilled journal fulfills its intent while the window holds (or while a duplicate-intent record exists) and an expired window admits a fresh charged attempt. Provider-internal retries below the dispatch boundary, and any provider-side quota accounting, are outside this claim.",
        "Storage and quota are bounded per-attempt journal artifacts rather than metered charges; each attempt writes its own plan, claim, and receipt, so the at-most-once guarantee covers provider dispatch, not artifact growth.",
        "The fence predicate is exercised directly over production intentFenceBlocker on synthesized journals; the property does not re-derive the reducer transitions that produce those ledger states."
      ],
      "properties": [
        {
          "path": "src/idempotency-fence.property.test.ts",
          "test": "property: the fulfilled blocker is the same-intent journal whose dedupe ends last"
        },
        {
          "path": "src/idempotency-fence.property.test.ts",
          "test": "a succeeded journal fences while its dedupe window holds and admits after expiry"
        },
        {
          "path": "src/idempotency-fence.property.test.ts",
          "test": "a duplicate-intent record fences a settled predecessor at every clock reading"
        }
      ]
    },
    {
      "id": "analytics-allowlist-byte-ceiling",
      "statement": "Analytics events come from a checked allowlist (page lifecycle, web vitals, budgeted redacted exceptions, page-not-found events, the two GitHub links, four named CTA clicks, two named install-command copies) with a byte ceiling per event, canonical-host-only, cookieless, and personless. Only the portfolio attribution query parameters are retained.",
      "area": "website",
      "source": {
        "path": "AGENTS.md",
        "quote": "Analytics and metering events come from a checked allowlist with a byte ceiling per event."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "website/analytics.test.ts"
      ],
      "assumptions": [
        "vercel"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked.",
        "No test asserts a per-event byte ceiling."
      ],
      "alsoQuotes": [
        {
          "path": "website/AGENTS.md",
          "quote": "Keep analytics canonical-host-only, cookieless, personless"
        },
        {
          "path": "website/AGENTS.md",
          "quote": "cookies, replay, identity, feature flags, broad autocapture, console capture"
        }
      ]
    },
    {
      "id": "website-release-identity-from-package",
      "statement": "Website release identity and install commands derive from the validated root package.json; the skill install command pins hraness/ghostget#v<package version>.",
      "area": "website",
      "source": {
        "path": "website/AGENTS.md",
        "quote": "Derive release identity and install commands from the validated root `package.json`; never copy a version into page source."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "website/site.test.ts",
        "website/skill-install-command.test.ts"
      ],
      "assumptions": [
        "vercel"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ],
      "alsoQuotes": [
        {
          "path": "website/AGENTS.md",
          "quote": "pin its skills source to `hraness/ghostget#v<package version>`"
        }
      ]
    },
    {
      "id": "vercel-build-admission-fail-closed",
      "statement": "A marked or Vercel-signalled build requires the exact marker, VERCEL=1, valid VERCEL_ENV, and exact VERCEL_GIT_COMMIT_REF; production requires `main` and non-production rejects it; inconsistent state fails before build.",
      "area": "website",
      "source": {
        "path": "website/AGENTS.md",
        "quote": "A marked or otherwise Vercel-signaled build must have the exact marker, `VERCEL=1`, a valid `VERCEL_ENV`, and an exact nonempty `VERCEL_GIT_COMMIT_REF`"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "website/vercel-build.test.ts"
      ],
      "assumptions": [
        "vercel"
      ],
      "notVerified": [
        "No property test covers this law yet; only the enumerated example cases are checked."
      ]
    },
    {
      "id": "preview-builds-independent",
      "statement": "Preview builds do not depend on npm or GitHub release availability.",
      "area": "website",
      "source": {
        "path": "website/AGENTS.md",
        "quote": "Preview and local builds perform no release verification and remain independently buildable"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "website/vercel-build.test.ts"
      ],
      "assumptions": [
        "vercel"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "website-no-vercel-mutation-in-workflows",
      "statement": "Checked-in workflows stay token-free for Vercel and never mutate project settings, call the Vercel API, redeploy, alias, or promote; promotion outcome uses token-free public HTTPS plus read-only GitHub evidence.",
      "area": "website",
      "source": {
        "path": "docs/publishing.md",
        "quote": "Checked-in workflows never mutate project settings, call the Vercel API, or perform an alias or promote operation"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "scripts/npm-release-workflow.test.ts"
      ],
      "assumptions": [
        "vercel"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ],
      "alsoQuotes": [
        {
          "path": "website/AGENTS.md",
          "quote": "Checked-in workflows remain token-free and never mutate project settings, call Vercel APIs, alias, or promote"
        }
      ]
    },
    {
      "id": "edge-same-origin-retrieval",
      "statement": "Edge negotiation retrieves only same-origin sibling assets: the retrieved origin equals the request origin for every request path, including `//host/x.md`.",
      "area": "edge",
      "source": {
        "path": "kb/plans/formal-verification-assurance.md",
        "quote": "D12: require `retrieved.origin === request.origin` and add the property."
      },
      "layer": "property",
      "status": "evidenced",
      "evidence": [
        "edge/negotiation.test.ts"
      ],
      "assumptions": [
        "whatwg-url",
        "edge-runtime"
      ],
      "notVerified": [
        "Generated inputs are sampled at the configured run count; this is not a proof over all inputs."
      ],
      "properties": [
        {
          "path": "edge/negotiation.test.ts",
          "test": "property: every retrieved URL keeps the request origin"
        }
      ]
    },
    {
      "id": "edge-accept-406-only-when-empty",
      "statement": "Over parsed Accept media ranges, document negotiation returns 406 exactly when the header has ranges and no offered representation has a best matching range with q above 0; a selected representation is offered, accepted with q above 0, and has the highest q among the acceptable representations.",
      "area": "edge",
      "source": {
        "path": "edge/AGENTS.md",
        "quote": "Honor Accept q-values, set `Vary: Accept`, and return `406` only when no owned representation remains."
      },
      "layer": "lean",
      "status": "evidenced",
      "evidence": [
        "edge/negotiation.test.ts",
        "scripts/verification-lean-encodings.test.ts",
        "verification/lean/GhostgetVerification/Edge/Negotiation.lean"
      ],
      "assumptions": [
        "whatwg-url",
        "edge-runtime",
        "verification-tools"
      ],
      "notVerified": [
        "The Lean theorems are about a Lean model of the selection. The differential test checks that negotiateDocumentRepresentation agrees with that model on generated headers, not on every header.",
        "The Accept header parser (parseAcceptMediaRanges) is not modelled; the differential test parses each header with the TypeScript.",
        "Tie-breaking after q (specificity, header order, server preference) is only sampled, and response headers such as Vary: Accept are covered only by the listed tests."
      ],
      "alsoQuotes": [
        {
          "path": "website/AGENTS.md",
          "quote": "return `406` only when no owned representation remains"
        }
      ]
    },
    {
      "id": "edge-vary-accept",
      "statement": "Negotiated document responses set Vary: Accept.",
      "area": "edge",
      "source": {
        "path": "edge/AGENTS.md",
        "quote": "set `Vary: Accept`"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "edge/negotiation.test.ts"
      ],
      "assumptions": [
        "whatwg-url",
        "edge-runtime"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ],
      "alsoQuotes": [
        {
          "path": "website/AGENTS.md",
          "quote": "set `Vary: Accept`"
        }
      ]
    },
    {
      "id": "edge-unknown-404",
      "statement": "Unknown document paths stay HTTP 404 and serve the static markdown 404 body.",
      "area": "edge",
      "source": {
        "path": "edge/AGENTS.md",
        "quote": "Unknown document paths stay HTTP 404 and serve the static markdown 404 body."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "edge/negotiation.test.ts"
      ],
      "assumptions": [
        "whatwg-url",
        "edge-runtime"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ],
      "alsoQuotes": [
        {
          "path": "website/AGENTS.md",
          "quote": "Unknown paths stay HTTP 404"
        }
      ]
    },
    {
      "id": "edge-no-node-imports",
      "statement": "Edge files import no Node, Bun, website build, or filesystem modules, and middleware.ts imports only edge/.",
      "area": "edge",
      "source": {
        "path": "edge/AGENTS.md",
        "quote": "Keep every file here free of Node, Bun, website build, and filesystem imports."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "edge/imports.test.ts",
        "edge/tsconfig.json"
      ],
      "assumptions": [
        "whatwg-url",
        "edge-runtime"
      ],
      "notVerified": [
        "Only static import declarations and `import()` calls with literal specifiers are scanned; test files under `edge/` run on Bun and are not scanned."
      ]
    },
    {
      "id": "release-trigger-exact-tag-push-only",
      "statement": "The Release workflow runs only on a protected direct tag push (no workflow_dispatch); the entry job rejects any event whose sender is not owner User 894119 or hraness-release-tagger[bot] Bot 337004703 matching the run actor, or whose repository is not public Ghostget ID 1425391521.",
      "area": "release",
      "source": {
        "path": "AGENTS.md",
        "quote": "Bind every Release run at entry to a protected tag-push event and embedded sender owned by User `894119` or `hraness-release-tagger[bot]` Bot `337004703` (matching the run actor) in public Ghostget repository ID `1425391521`."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "scripts/npm-release-workflow.test.ts"
      ],
      "assumptions": [
        "github-api",
        "github-enforcement"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "release-source-ci-admission-exact",
      "statement": "Release admits source only with the exact commit's successful default-branch CI run on its current attempt: exact repository, workflow ID/path, main-push source and tree, every CI job successful with its real checkout log, and recorded workflow/lock hashes and toolchain versions; missing, failed, skipped, ambiguous, stale-attempt, or drifting evidence blocks.",
      "area": "release",
      "source": {
        "path": "docs/publishing.md",
        "quote": "It requires the exact repository, active workflow ID/path, main-push source and tree"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "scripts/github-release-artifact.test.ts"
      ],
      "assumptions": [
        "github-api",
        "github-enforcement"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "release-source-codeql-exact-four-languages",
      "statement": "Source admission requires exactly the Actions, JavaScript/TypeScript, Python, and Rust CodeQL jobs and analyses on the exact source and current main; missing or extra languages, or two exact-source CodeQL runs, are rejected.",
      "area": "release",
      "source": {
        "path": "docs/publishing.md",
        "quote": "Admission requires exactly those four jobs and analyses, with missing or extra languages rejected."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "scripts/github-release-artifact.test.ts"
      ],
      "assumptions": [
        "github-api",
        "github-enforcement"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "release-source-codeql-pr-association",
      "statement": "The CodeQL PR comparison is accepted via its returned PR association; the exact 'View all branch alerts' summary is a fallback only when the association array is empty, never when a nonempty association contradicts.",
      "area": "release",
      "source": {
        "path": "docs/publishing.md",
        "quote": "A nonempty contradictory association never falls back to the summary."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "scripts/github-release-artifact.test.ts"
      ],
      "assumptions": [
        "github-api",
        "github-enforcement"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "release-source-evidence-72h-freshness",
      "statement": "Every required CI and CodeQL job must have completed within 72 hours of admission with valid, non-future timestamps, and each analysis must fall inside its attempt's language-job interval; mutable run update times never establish freshness.",
      "area": "release",
      "source": {
        "path": "docs/publishing.md",
        "quote": "Every required CI and CodeQL job must have completed within 72 hours of admission"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "scripts/github-release-artifact.test.ts"
      ],
      "assumptions": [
        "monotonic-clock",
        "github-api",
        "github-enforcement"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "release-source-no-caller-receipt",
      "statement": "The source-CI helper resamples control evidence before returning, never reruns CI, and never accepts a caller-supplied receipt.",
      "area": "release",
      "source": {
        "path": "docs/publishing.md",
        "quote": "The helper samples the control evidence again before returning"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "scripts/github-release-artifact.test.ts"
      ],
      "assumptions": [
        "github-api",
        "github-enforcement"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "release-fresh-build-before-capability",
      "statement": "After admission Release performs a fresh frozen install and deterministic build, checks dist and bun.lock cleanliness, and the new npm archive passes the strict artifact parser and isolated consumer smoke before any attestation or publication capability exists.",
      "area": "release",
      "source": {
        "path": "docs/publishing.md",
        "quote": "Its new exact npm archive passes the strict artifact parser and isolated consumer smoke before attestation or publication capability is available."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "scripts/ci-pr-gate.test.ts",
        "scripts/github-release-artifact.test.ts"
      ],
      "assumptions": [
        "github-api",
        "github-enforcement"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "release-tag-direct-lightweight",
      "statement": "A release tag is one direct lightweight v<version> tag on the admitted commit; annotated tags are rejected and a historical tag is never overwritten, annotate-converted, moved or deleted to recover a run.",
      "area": "release",
      "source": {
        "path": "AGENTS.md",
        "quote": "Keep direct lightweight tags"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "scripts/release-ref-authority.test.ts"
      ],
      "assumptions": [
        "github-api",
        "github-enforcement"
      ],
      "notVerified": [
        "No property test covers this law yet; only the enumerated example cases are checked."
      ]
    },
    {
      "id": "release-manifest-strict-binding",
      "statement": "release-manifest.json is parsed strictly and must bind repository, name, version, tag, source C, workflow authority W, run ID/attempt and archive size/SHA-256/SHA-512 to the requested values.",
      "area": "release",
      "source": {
        "path": "docs/publishing.md",
        "quote": "`release-manifest.json`, the strict `hraness-github-release-v1` identity, including repository/name/version/tag, source `C`, reviewed workflow authority `W`, run ID/attempt, and archive size/SHA-256/SHA-512."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "scripts/github-release-artifact.test.ts",
        "website/github-release-artifact.test.ts"
      ],
      "assumptions": [
        "github-api",
        "github-enforcement"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "release-file-specific-size-bounds",
      "statement": "Archive transfer is capped at 12 MiB from v0.18.1 (8 MiB earlier), receipt and manifest at 1 MiB, checksums and provenance at 8 MiB, applied uniformly by preparation, downloads, draft readbacks, attestation and npm handoff without relaxing digest or inventory checks.",
      "area": "release",
      "source": {
        "path": "docs/publishing.md",
        "quote": "The transfer envelope admits an archive of at most 12 MiB from `v0.18.1`; earlier archives retain their 8 MiB limit"
      },
      "layer": "property",
      "status": "evidenced",
      "evidence": [
        "scripts/github-release-artifact.test.ts",
        "website/github-release-artifact.test.ts"
      ],
      "assumptions": [
        "github-api",
        "github-enforcement"
      ],
      "notVerified": [
        "Generated inputs are sampled at the configured run count; this is not a proof over all inputs."
      ],
      "properties": [
        {
          "path": "scripts/github-release-artifact.test.ts",
          "test": "property: foreign archive sizes are accepted exactly within the versioned transfer bound"
        }
      ]
    },
    {
      "id": "release-archive-receipt-ustar-agreement",
      "statement": "The archive and npm receipt must agree on every safe USTAR entry, mode, count, size and integrity; extra files, traversal, links, malformed receipts, unsafe package configuration and mismatched bytes are rejected, and both tar consumers agree on hostile USTAR headers.",
      "area": "release",
      "source": {
        "path": "docs/publishing.md",
        "quote": "Reject extra files, traversal, links, malformed receipts, unsafe package configuration, and mismatched bytes."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "scripts/github-release-artifact.test.ts",
        "scripts/npm-release-workflow.test.ts"
      ],
      "assumptions": [
        "github-api",
        "github-enforcement"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "release-attest-checkout-free-reauthorized",
      "statement": "A separate checkout-free attest job reauthorizes owner/run/tag before requesting OIDC and invokes pinned actions/attest; attest and publish_npm are the only jobs with id-token: write.",
      "area": "release",
      "source": {
        "path": "AGENTS.md",
        "quote": "a separate checkout-free OIDC attestation job"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "scripts/npm-release-workflow.test.ts"
      ],
      "assumptions": [
        "github-api",
        "github-enforcement"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "release-single-contents-write-job",
      "statement": "Across all workflows, the Release publish job is the only job with contents: write; workflow defaults are contents: read and no workflow uses write-all.",
      "area": "release",
      "source": {
        "path": "docs/publishing.md",
        "quote": "the checked workflow census leaves only the Release `publish` job with a `contents: write` `GITHUB_TOKEN`"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "scripts/npm-release-workflow.test.ts"
      ],
      "assumptions": [
        "github-api",
        "github-enforcement"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "release-existing-release-single-latest-check",
      "statement": "An exact Release that already existed gets one immediate Latest check and never enters the convergence loop; after either path the terminal tag, main, control, by-tag and Latest reads must bind the same tag, ID and publication time.",
      "area": "release",
      "source": {
        "path": "docs/publishing.md",
        "quote": "An exact Release that already existed gets one immediate Latest check and never enters this convergence loop"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "scripts/release-provider-outcome.test.ts"
      ],
      "assumptions": [
        "github-api",
        "github-enforcement"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "release-receipt-bot-and-body-prefix",
      "statement": "Every publication readback requires Actions bot ID 41898282 of type Bot and a deterministic trailing identity record binding repository, tag, source SHA and GITHUB_RUN_ID after notes rendered from the tagged changelog section; target_commitish is informational only and the protected tag must peel to C.",
      "area": "release",
      "source": {
        "path": "docs/publishing.md",
        "quote": "Every publication readback instead requires Actions bot ID `41898282` with type `Bot` and a deterministic trailing identity record binding repository, tag, source SHA, and `GITHUB_RUN_ID`"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "scripts/npm-release-workflow.test.ts",
        "scripts/release-provider-outcome.test.ts",
        "website/release-notes.test.ts"
      ],
      "assumptions": [
        "github-api",
        "github-enforcement"
      ],
      "notVerified": [
        "No property test covers this law yet; only the enumerated example cases are checked."
      ]
    },
    {
      "id": "release-reauthorize-attempt-before-checkout",
      "statement": "Before the sole write-capable job checks out source, the current attempt's actor and triggering_actor must each be owner User 894119 or hraness-release-tagger[bot] Bot 337004703 and the attempt must bind Release workflow ID 389238077, its exact path, the verified direct tag object and current-main ancestry; reruns by any other identity fail closed.",
      "area": "release",
      "source": {
        "path": "AGENTS.md",
        "quote": "Before the sole write-capable job checks out source, use only `actions:read` to bind the exact current attempt—including both `actor` and `triggering_actor`"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "scripts/npm-release-workflow.test.ts"
      ],
      "assumptions": [
        "github-api",
        "github-enforcement"
      ],
      "notVerified": [
        "No property test covers this law yet; only the enumerated example cases are checked."
      ]
    },
    {
      "id": "release-reauthorize-only-actions-read",
      "statement": "The reauthorization before checkout uses only actions:read; no Release job holds Administration or calls ruleset/rule-suite endpoints.",
      "area": "release",
      "source": {
        "path": "AGENTS.md",
        "quote": "use only `actions:read`"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "scripts/npm-release-workflow.test.ts"
      ],
      "assumptions": [
        "github-api",
        "github-enforcement"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "release-version-monotone-stable",
      "statement": "A new stable package version must exceed every completed stable Release; a higher raw tag alone is an incomplete request, and the publication path exhausts the bounded completed stable-Release ordering census before creating or publishing a draft.",
      "area": "release",
      "source": {
        "path": "docs/publishing.md",
        "quote": "Choose a new stable package version greater than every completed stable Release. A raw tag is a request, not a completed publication."
      },
      "layer": "stateful-model",
      "status": "evidenced",
      "evidence": [
        "scripts/github-release-publish-model.test.ts",
        "scripts/npm-release-workflow.test.ts",
        "scripts/release-provider-outcome.test.ts",
        "scripts/release-ref-authority.test.ts"
      ],
      "assumptions": [
        "github-api",
        "github-enforcement"
      ],
      "notVerified": [
        "The publisher model drives the production `publishCanonicalRelease` and its bounded asset downloader against an in-memory fake of GitHub; that GitHub behaves like the fake (drafts invisible to the by-tag endpoint, one published Release per tag, `gh release upload` resolving a tag to its published Release or else the newest draft) is the `github-api` assumption.",
        "CI samples up to 1,000 schedules of at most 12 commands; it does not enumerate every interleaving.",
        "The census law itself (a target is admitted exactly when it exceeds every completed stable Release in the 500-Release window) is the sampled property in `scripts/release-provider-outcome.test.ts`; the model checks that a clean census precedes each draft creation and publication, and that success never leaves a higher completed stable Release.",
        "GitHub has no conditional create or publish, so a stable Release that completes between the last census and the PATCH is caught only by the census repeated after publication, which fails the run but cannot undo the already immutable publication. A stable Release that completes after that last census, while the terminal Latest read still names the target, is not detected, and the model injects no such completion."
      ],
      "properties": [
        {
          "path": "scripts/github-release-publish-model.test.ts",
          "test": "stateful model: every schedule of attempts, faults, and foreign releases keeps the publisher's write laws"
        }
      ]
    },
    {
      "id": "release-five-file-contract",
      "statement": "The canonical GitHub Release publishes, independently of npm, exactly five files: the packed `.tgz`, `npm-pack.json`, `release-manifest.json` (`hraness-github-release-v1`), `SHA256SUMS` covering the preceding three in order, and `provenance.jsonl`; duplicate, unknown, foreign-URL, or uncommitted assets are rejected.",
      "area": "release",
      "source": {
        "path": "AGENTS.md",
        "quote": "publish the exact five-file archive/packing-receipt/manifest/checksums/provenance contract independently of npm."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "scripts/github-release-artifact.test.ts",
        "website/github-release-artifact.test.ts"
      ],
      "assumptions": [
        "github-api",
        "github-enforcement"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "release-attestation-before-mutation",
      "statement": "Before GitHub mutation, the attestation bundle must cryptographically verify for all four subjects with signed certificate repository/owner IDs, source/ref, workflow, GitHub-hosted push and run ID/attempt exactly matching; a matching archive hash or predicate metadata alone is not authority.",
      "area": "release",
      "source": {
        "path": "AGENTS.md",
        "quote": "A matching archive hash is insufficient release authority. Before GitHub mutation, require successful cryptographic verification"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "scripts/github-release-artifact.test.ts",
        "scripts/npm-release-workflow.test.ts",
        "website/github-release-artifact.test.ts"
      ],
      "assumptions": [
        "github-api",
        "github-enforcement",
        "sigstore"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "release-draft-create-only-on-exact-404",
      "statement": "A draft is created only after an authenticated exact REST 404 by tag plus bounded inventory discovery shows none exists; any other lookup failure aborts.",
      "area": "release",
      "source": {
        "path": "docs/publishing.md",
        "quote": "Only an authenticated exact REST 404 permits draft creation; other lookup failures abort."
      },
      "layer": "stateful-model",
      "status": "evidenced",
      "evidence": [
        "scripts/github-release-artifact.test.ts",
        "scripts/github-release-publish-model.test.ts"
      ],
      "assumptions": [
        "github-api",
        "github-enforcement"
      ],
      "notVerified": [
        "The publisher model drives the production `publishCanonicalRelease` and its bounded asset downloader against an in-memory fake of GitHub; that GitHub behaves like the fake (drafts invisible to the by-tag endpoint, one published Release per tag, `gh release upload` resolving a tag to its published Release or else the newest draft) is the `github-api` assumption.",
        "CI samples up to 1,000 schedules of at most 12 commands; it does not enumerate every interleaving.",
        "The model's lookup faults are HTTP 500 and 403, a status and exit code that disagree, an unparseable response, a 404 with another body, and an unreadable inventory; other malformed responses rest on the parser's example tests."
      ],
      "properties": [
        {
          "path": "scripts/github-release-publish-model.test.ts",
          "test": "stateful model: every schedule of attempts, faults, and foreign releases keeps the publisher's write laws"
        }
      ]
    },
    {
      "id": "release-upload-missing-only-no-clobber",
      "statement": "Publication uploads only missing exact asset names without clobber, then downloads each asset by ID within its byte bound and compares bytes and SHA-256 to the verified local artifact before and after publication.",
      "area": "release",
      "source": {
        "path": "docs/publishing.md",
        "quote": "downloads each exact asset ID with its admitted byte bound, and compares its actual bytes and SHA-256"
      },
      "layer": "stateful-model",
      "status": "evidenced",
      "evidence": [
        "scripts/github-release-artifact.test.ts",
        "scripts/github-release-publish-model.test.ts"
      ],
      "assumptions": [
        "github-api",
        "github-enforcement"
      ],
      "notVerified": [
        "The publisher model drives the production `publishCanonicalRelease` and its bounded asset downloader against an in-memory fake of GitHub; that GitHub behaves like the fake (drafts invisible to the by-tag endpoint, one published Release per tag, `gh release upload` resolving a tag to its published Release or else the newest draft) is the `github-api` assumption.",
        "CI samples up to 1,000 schedules of at most 12 commands; it does not enumerate every interleaving.",
        "Stored-byte corruption is injected only between publisher invocations, not between an upload and its own readback."
      ],
      "properties": [
        {
          "path": "scripts/github-release-publish-model.test.ts",
          "test": "stateful model: every schedule of attempts, faults, and foreign releases keeps the publisher's write laws"
        }
      ]
    },
    {
      "id": "release-draft-resume-exact-only",
      "statement": "A pre-existing draft or published Release from the same attesting attempt, including one that a failed-jobs rerun of that run resumes, resumes only with matching Actions bot, source receipt, body, tag, and every already-uploaded asset; a mismatched draft or another attempt fails closed and is never deleted, recreated, clobbered, or relabeled.",
      "area": "release",
      "source": {
        "path": "docs/publishing.md",
        "quote": "A matching partial draft or published Release from the same attesting attempt, including one a failed-jobs rerun of that run resumes, may resume only with matching source, bot, body, and every already uploaded asset."
      },
      "layer": "stateful-model",
      "status": "evidenced",
      "evidence": [
        "scripts/github-release-artifact.test.ts",
        "scripts/github-release-publish-model.test.ts",
        "scripts/verification-release-replay.test.ts"
      ],
      "assumptions": [
        "github-api",
        "github-enforcement"
      ],
      "notVerified": [
        "The publisher model drives the production `publishCanonicalRelease` and its bounded asset downloader against an in-memory fake of GitHub; that GitHub behaves like the fake (drafts invisible to the by-tag endpoint, one published Release per tag, `gh release upload` resolving a tag to its published Release or else the newest draft) is the `github-api` assumption.",
        "CI samples up to 1,000 schedules of at most 12 commands; it does not enumerate every interleaving.",
        "The model represents a failed-jobs rerun as a further invocation of the same attesting attempt, because the rerun publishes that attempt's attested manifest; that the rerun receives that manifest is covered by the `release-failed-jobs-rerun-recovers-publish` claim, not here."
      ],
      "properties": [
        {
          "path": "scripts/github-release-publish-model.test.ts",
          "test": "stateful model: every schedule of attempts, faults, and foreign releases keeps the publisher's write laws"
        }
      ]
    },
    {
      "id": "release-single-publish-patch",
      "statement": "The only publication mutation is one PATCH turning the admitted draft non-draft and requesting Latest after the complete five-file readback; no deletion, tag movement or rollback is ever issued.",
      "area": "release",
      "source": {
        "path": "docs/publishing.md",
        "quote": "The only publication PATCH changes the admitted draft to non-draft and requests Latest after the complete five-file readback."
      },
      "layer": "stateful-model",
      "status": "evidenced",
      "evidence": [
        "scripts/github-release-artifact.test.ts",
        "scripts/github-release-publish-model.test.ts",
        "scripts/npm-release-workflow.test.ts"
      ],
      "assumptions": [
        "github-api",
        "github-enforcement"
      ],
      "notVerified": [
        "The publisher model drives the production `publishCanonicalRelease` and its bounded asset downloader against an in-memory fake of GitHub; that GitHub behaves like the fake (drafts invisible to the by-tag endpoint, one published Release per tag, `gh release upload` resolving a tag to its published Release or else the newest draft) is the `github-api` assumption.",
        "CI samples up to 1,000 schedules of at most 12 commands; it does not enumerate every interleaving.",
        "The model rejects any command outside the publisher's exact reads and three write shapes, so a DELETE, a tag write, or a second PATCH fails it; Git ref writes made outside `publishCanonicalRelease` are covered only by the workflow's example tests."
      ],
      "properties": [
        {
          "path": "scripts/github-release-publish-model.test.ts",
          "test": "stateful model: every schedule of attempts, faults, and foreign releases keeps the publisher's write laws"
        }
      ]
    },
    {
      "id": "release-closure-check-before-each-write",
      "statement": "Before each draft creation, missing-asset upload and publication, the helper proves C<=M on fully qualified main and tag refs, requires unchanged release-control closure, and observes two equal combined main-plus-tag advertisements around the proof.",
      "area": "release",
      "source": {
        "path": "docs/publishing.md",
        "quote": "Before each draft creation, missing-asset upload, and publication, fetch only the fully qualified governed main and tag refs, prove `C<=M`, and require unchanged release controls"
      },
      "layer": "stateful-model",
      "status": "evidenced",
      "evidence": [
        "scripts/github-release-publish-model.test.ts",
        "scripts/release-ref-authority.test.ts"
      ],
      "assumptions": [
        "github-api",
        "github-enforcement"
      ],
      "notVerified": [
        "The publisher model drives the production `publishCanonicalRelease` and its bounded asset downloader against an in-memory fake of GitHub; that GitHub behaves like the fake (drafts invisible to the by-tag endpoint, one published Release per tag, `gh release upload` resolving a tag to its published Release or else the newest draft) is the `github-api` assumption.",
        "CI samples up to 1,000 schedules of at most 12 commands; it does not enumerate every interleaving.",
        "The model checks that a successful `publication-prewrite` run of the ref-authority helper on current main immediately precedes each draft creation, upload, and publication, and that a failing helper blocks the write. It treats the helper as a black box: its `C<=M` proof, release-control closure, and two equal combined advertisements are covered only by the example tests in `scripts/release-ref-authority.test.ts`."
      ],
      "properties": [
        {
          "path": "scripts/github-release-publish-model.test.ts",
          "test": "stateful model: every schedule of attempts, faults, and foreign releases keeps the publisher's write laws"
        }
      ]
    },
    {
      "id": "release-completed-release-original-identity",
      "statement": "A completed Release is accepted only with its original signed identity and exact bot/body receipt; a newly rebuilt artifact never satisfies an existing Release, and a front-run Release or one from another run fails closed.",
      "area": "release",
      "source": {
        "path": "docs/publishing.md",
        "quote": "A completed release is accepted only with its original signed identity, never with a newly rebuilt artifact."
      },
      "layer": "stateful-model",
      "status": "evidenced",
      "evidence": [
        "scripts/github-release-artifact.test.ts",
        "scripts/github-release-publish-model.test.ts",
        "scripts/npm-release-workflow.test.ts"
      ],
      "assumptions": [
        "github-api",
        "github-enforcement"
      ],
      "notVerified": [
        "The publisher model drives the production `publishCanonicalRelease` and its bounded asset downloader against an in-memory fake of GitHub; that GitHub behaves like the fake (drafts invisible to the by-tag endpoint, one published Release per tag, `gh release upload` resolving a tag to its published Release or else the newest draft) is the `github-api` assumption.",
        "CI samples up to 1,000 schedules of at most 12 commands; it does not enumerate every interleaving.",
        "The model covers the bot author (including an owner-authored completed Release that copies the exact receipt body and asset bytes), exact receipt body, and stored bytes; the signed attestation identity is verified before publication and covered by the `release-attestation-before-mutation` claim's example tests, not by the model."
      ],
      "properties": [
        {
          "path": "scripts/github-release-publish-model.test.ts",
          "test": "stateful model: every schedule of attempts, faults, and foreign releases keeps the publisher's write laws"
        }
      ]
    },
    {
      "id": "release-latest-convergence-bounded",
      "statement": "When creating a missing Release with an existing published predecessor, the workflow pins one older immutable Latest predecessor; Latest may only remain that predecessor or advance to the exact target within at most twelve 5-second absolute slots in a 60-second monotonic deadline; any third identity, regression, drift, clock regression or exhaustion fails closed.",
      "area": "release",
      "source": {
        "path": "docs/publishing.md",
        "quote": "GitHub's Latest projection may remain only that exact predecessor or advance to the exact created target while the workflow makes at most twelve observations at absolute five-second slots inside one 60-second monotonic deadline."
      },
      "layer": "property",
      "status": "evidenced",
      "evidence": [
        "scripts/github-release-publish-model.test.ts",
        "scripts/release-provider-outcome.test.ts"
      ],
      "assumptions": [
        "monotonic-clock",
        "github-api",
        "github-enforcement"
      ],
      "notVerified": [
        "The property drives `waitForLatestRelease` with a fake API, monotonic clock, and sleeper. The production publisher's `gh api` reader ignores the per-request timeout it is passed and bounds each read only by its 120-second command timeout; a read that completes after the 60-second deadline fails closed, so the deadline bounds acceptance, not wall time.",
        "The publisher model checks that a fresh publication reads Latest as the target after its terminal authority proof, and one example test in it drives a lagging Latest projection through the production wait on a fake clock; the stateful schedules themselves project Latest immediately.",
        "The publisher model checks that no draft is created while Latest is a completed Release under a non-stable tag, which the completed-Release census skips; the other refusals of `exactLatestPredecessor` (a mutable, malformed, or not strictly older Latest) rest on its example tests in the same file.",
        "How quickly GitHub's Latest projection converges is not verified; the window is a fail-closed ceiling."
      ],
      "properties": [
        {
          "path": "scripts/release-provider-outcome.test.ts",
          "test": "property: Latest converges only through the exact predecessor to the exact target inside twelve absolute slots and 60 seconds"
        }
      ]
    },
    {
      "id": "release-first-publication-empty-history",
      "statement": "The first stable Release requires an authenticated exact Latest 404 agreeing with a complete bounded inventory containing no published non-prerelease Release, repeats the absence census before publication, and requires the exact immutable target as Latest after publication. Malformed, denied, ambiguous, or contradictory prepublication Latest responses permit no mutation.",
      "area": "release",
      "source": {
        "path": "docs/publishing.md",
        "quote": "For the first stable Release, an authenticated exact 404 for Latest must agree with a complete bounded inventory containing no published non-prerelease Release."
      },
      "layer": "stateful-model",
      "status": "evidenced",
      "evidence": [
        "scripts/github-release-publish-model.test.ts",
        "scripts/release-provider-outcome.test.ts"
      ],
      "assumptions": [
        "github-api",
        "github-enforcement"
      ],
      "notVerified": [
        "The publisher model drives production against an in-memory GitHub fake; actual provider response formats and immutability remain the github-api and github-enforcement assumptions.",
        "CI samples up to 1,000 schedules of at most 12 commands from both empty and predecessor-present initial histories; it does not enumerate every interleaving.",
        "First publication requires immediate exact Latest readback. A lagging or absent projection fails closed after immutable publication and must recover through the original attested attempt.",
        "GitHub has no conditional publish; terminal readback detects covered drift after publication but cannot undo an immutable Release."
      ],
      "properties": [
        {
          "path": "scripts/github-release-publish-model.test.ts",
          "test": "stateful model: every schedule of attempts, faults, and foreign releases keeps the publisher's write laws"
        }
      ]
    },
    {
      "id": "release-never-delete-published",
      "statement": "A published immutable Release is never deleted or rewritten, even if terminal readback fails after publication; historical versions, tags and assetless Releases are preserved.",
      "area": "release",
      "source": {
        "path": "docs/publishing.md",
        "quote": "Preserve that immutable release and inspect current authority; never delete or rewrite it."
      },
      "layer": "stateful-model",
      "status": "evidenced",
      "evidence": [
        "scripts/github-release-artifact.test.ts",
        "scripts/github-release-publish-model.test.ts"
      ],
      "assumptions": [
        "github-api",
        "github-enforcement"
      ],
      "notVerified": [
        "The publisher model drives the production `publishCanonicalRelease` and its bounded asset downloader against an in-memory fake of GitHub; that GitHub behaves like the fake (drafts invisible to the by-tag endpoint, one published Release per tag, `gh release upload` resolving a tag to its published Release or else the newest draft) is the `github-api` assumption.",
        "CI samples up to 1,000 schedules of at most 12 commands; it does not enumerate every interleaving.",
        "The model starts with either empty release history or one assetless predecessor Release; larger histories and tag deletion outside the publisher are not modelled, and the tag rulesets that forbid tag deletion are `github-enforcement` configuration."
      ],
      "properties": [
        {
          "path": "scripts/github-release-publish-model.test.ts",
          "test": "stateful model: every schedule of attempts, faults, and foreign releases keeps the publisher's write laws"
        }
      ]
    },
    {
      "id": "stable-release-concurrency-no-cancel-pending",
      "statement": "The stable-release concurrency group serializes Release runs without cancelling a pending tag run.",
      "area": "release",
      "source": {
        "path": "docs/publishing.md",
        "quote": "The workflow's `stable-release` concurrency group and npm's version immutability serialize publication"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "scripts/npm-release-workflow.test.ts"
      ],
      "assumptions": [
        "github-api",
        "github-enforcement"
      ],
      "notVerified": [
        "The test checks the workflow's single `stable-release` concurrency group with `cancel-in-progress: false` and `queue: max`, and that no job declares its own group. That GitHub then queues pending runs in order is the `github-enforcement` assumption; GitHub still cancels pending runs beyond 100 in the group.",
        "No live run has exercised three overlapping tag pushes."
      ]
    },
    {
      "id": "release-failed-jobs-rerun-recovers-publish",
      "statement": "Re-running only the failed jobs of a Release run publishes the exact bytes that an earlier attempt of the same run attested: the publisher downloads the carried artifact only by its numeric ID behind an exact-identity guard, admits a manifest whose attempt is no later than the current attempt of the same run, and requires every signed certificate to name that attempt. The canonical download admits an attesting attempt whose publication failed only when a strictly later completed attempt of the same run proves all four canonical jobs in its own job inventory: the current attempt, or one of at most three exact intermediate attempts when the current attempt did not publish.",
      "area": "release",
      "source": {
        "path": "AGENTS.md",
        "quote": "The GitHub publisher downloads the attested artifact only by numeric artifact ID behind an exact-identity guard, so a failed-jobs rerun publishes the exact bytes and signed attempt its run already attested, never another run's or a later attempt's."
      },
      "layer": "quint",
      "status": "evidenced",
      "evidence": [
        "scripts/github-release-artifact.test.ts",
        "scripts/npm-release-workflow.test.ts",
        "scripts/verification-release-replay.test.ts",
        "verification/quint/release.qnt"
      ],
      "assumptions": [
        "github-api",
        "github-enforcement"
      ],
      "notVerified": [
        "The model and its replay cover the handoff's attempt and signature binding and the canonical download's admission. Downloading the carried artifact by numeric ID behind the exact-identity guard is checked only by the listed example tests.",
        "That GitHub carries the verify and attestation outputs and their artifact into a failed-jobs rerun, and reports every job of an attempt, carried or not, under that attempt, are assumptions about GitHub Actions; CI does not check them.",
        "A failed attestation job cannot be recovered this way, because attestation downloads the build of its own attempt; re-running all jobs rebuilds under a new attempt, which the draft body check rejects.",
        "The model covers one run of up to three attempts; Apalache checks it to depth 10 and seeded simulation samples 2,000 runs of up to 12 steps."
      ]
    },
    {
      "id": "release-workflow-isolation",
      "statement": "The Release workflow owns only the immutable Release and its npm mirror; it never reads, creates, or updates a website deployment ref, receives no additional credentials, and never waits for Vercel; website deployment follows merges to `main` directly.",
      "area": "release",
      "source": {
        "path": "AGENTS.md",
        "quote": "it never reads, creates, or updates a website deployment ref, receives no additional credentials, and never waits for Vercel"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "scripts/npm-release-workflow.test.ts"
      ],
      "assumptions": [
        "github-api",
        "github-enforcement"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "mutable-presentation-not-authority",
      "statement": "Release display title, run display name, actor logins and receipt body are presentation; authority comes only from stable numeric IDs/types, the protected tag and immutable Release coordinates, and the sampled source receipt is revalidated on every accepted Release read.",
      "area": "release",
      "source": {
        "path": "AGENTS.md",
        "quote": "Treat the Release display title, Actions workflow-run display name, actor logins, and receipt body as mutable presentation or control-plane data."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "scripts/npm-release-workflow.test.ts",
        "scripts/release-provider-outcome.test.ts"
      ],
      "assumptions": [
        "github-api",
        "github-enforcement"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "npm-publish-after-canonical-only",
      "statement": "publish_npm runs only after verify, attest and publish succeed (the immutable GitHub Release exists) and publishes the identical canonical bytes; canonical publication has no dependency on npm.",
      "area": "npm",
      "source": {
        "path": "AGENTS.md",
        "quote": "The same tag Release run then publishes the identical canonical bytes to npm"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "scripts/npm-release-workflow.test.ts"
      ],
      "assumptions": [
        "github-api",
        "npm-registry"
      ],
      "notVerified": [
        "The test checks the job graph: `publish_npm` transitively needs exactly `authorize`, `verify`, `attest`, and `publish`, no canonical job needs an npm job, and no job or step carries an `if:` or `continue-on-error` that could run npm after a failed prerequisite or let a canonical job succeed without its work. That GitHub skips a job whose needed jobs did not succeed is the `github-enforcement` assumption.",
        "The identical-bytes half rests on the enumerated example tests of the npm job's artifact-by-ID, archive-hash, and canonical-Release re-read steps."
      ]
    },
    {
      "id": "npm-failure-never-blocks-canonical",
      "statement": "An npm failure never unpublishes or blocks the GitHub Release.",
      "area": "npm",
      "source": {
        "path": "AGENTS.md",
        "quote": "an npm failure is rerun from the same run and never blocks canonical publication."
      },
      "layer": "quint",
      "status": "evidenced",
      "evidence": [
        "scripts/npm-release-workflow.test.ts",
        "scripts/verification-release-replay.test.ts",
        "verification/quint/release.qnt"
      ],
      "assumptions": [
        "github-api",
        "npm-registry"
      ],
      "notVerified": [
        "The model takes the job order (npm after the immutable Release) from the `needs` of `.github/workflows/release.yml`; it does not check that workflow file.",
        "The replay drives the publisher handoff, promotion authority, and canonical download validators. The draft, resume, and Latest convergence of `publishCanonicalRelease` are modeled but not replayed.",
        "The model covers one run of up to three attempts; Apalache checks it to depth 10 and seeded simulation samples 2,000 runs of up to 12 steps."
      ]
    },
    {
      "id": "npm-reauthorize-before-oidc",
      "statement": "Before npm setup or OIDC minting, publish_npm reauthorizes the current attempt identically to the GitHub publisher (actor and triggering_actor each owner 894119 or tagger bot 337004703, repository 1425391521, workflow 389238077 at its path, protected tag, verified SHA, main ancestry); reruns by any other identity fail closed.",
      "area": "npm",
      "source": {
        "path": "AGENTS.md",
        "quote": "Before `publish_npm` sets up npm or mints OIDC, bind its current attempt—including both `actor` and `triggering_actor`—to owner User `894119`"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "scripts/npm-release-workflow.test.ts"
      ],
      "assumptions": [
        "github-api",
        "npm-registry"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "npm-job-checkout-free-minimal-permissions",
      "statement": "publish_npm is checkout-free, runs no product source, bun, scripts, NPM_TOKEN or NODE_AUTH_TOKEN, and declares exactly actions: read, contents: read, id-token: write.",
      "area": "npm",
      "source": {
        "path": "docs/publishing.md",
        "quote": "It is checkout-free, runs no product source or `bun install`, declares only `actions: read`, `contents: read`, and `id-token: write`"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "scripts/npm-release-workflow.test.ts"
      ],
      "assumptions": [
        "github-api",
        "npm-registry"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "npm-artifact-by-numeric-id-bound",
      "statement": "publish_npm downloads the attested artifact only by numeric artifact ID and binds all five files to the verify job's SHA-256 hashes and bundle digest, and the manifest to the verified source, tag, workflow, run and package, before handing off only archive and receipt.",
      "area": "npm",
      "source": {
        "path": "AGENTS.md",
        "quote": "Download the attested canonical artifact only by numeric artifact ID and bind all five files to the verify hashes and bundle digest."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "scripts/npm-release-workflow.test.ts"
      ],
      "assumptions": [
        "github-api",
        "npm-registry"
      ],
      "notVerified": [
        "No property test covers this law yet; only the enumerated example cases are checked."
      ]
    },
    {
      "id": "npm-clean-defaults-latest-tag",
      "statement": "Before publishing, ambient npm_config_tag is absent, user/global/project npm config is empty, pinned npm 11.19.0's default tag is proven to be latest, and npm publish runs without --tag.",
      "area": "npm",
      "source": {
        "path": "AGENTS.md",
        "quote": "Scrub ambient tag variables and project, user, and global npm configuration; prove pinned npm's clean default tag is `latest`;"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "scripts/npm-release-workflow.test.ts"
      ],
      "assumptions": [
        "github-api",
        "npm-registry"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "npm-admit-registry-identity-provenance",
      "statement": "@hraness/ghostget@<version> is advertised as available only after admit_npm proves the registry tarball matches the canonical archive, pinned Pacote and Sigstore TUF verify signatures and present attestations for every installed non-dev registry-origin package from its lock-bound actual inventory, and strict identity checks bind the root publish and SLSA attestations to the tag push, verified commit and release.yml within a bounded propagation window.",
      "area": "npm",
      "source": {
        "path": "AGENTS.md",
        "quote": "Require the exact public registry package and its npm provenance to match the canonical archive in `admit_npm` before advertising registry availability"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "scripts/npm-release-workflow.test.ts",
        "scripts/npm-installed-signatures.mjs"
      ],
      "assumptions": [
        "github-api",
        "sigstore",
        "npm-registry"
      ],
      "notVerified": [
        "No property test covers this law yet; only the enumerated example cases are checked."
      ]
    },
    {
      "id": "npm-no-token-no-staged-no-dispatch",
      "statement": "No npm token, staged publish, separate dispatch workflow, or human step follows the tag push; npm-stage.yml does not exist.",
      "area": "npm",
      "source": {
        "path": "AGENTS.md",
        "quote": "No dispatch, staged publish, token, or human step follows the tag push"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "scripts/npm-release-workflow.test.ts"
      ],
      "assumptions": [
        "github-api",
        "npm-registry"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "npm-no-content-policy",
      "statement": "The @hraness/ghostget package carries no contentPolicy declaration and no DISCLOSURE file.",
      "area": "npm",
      "source": {
        "path": "AGENTS.md",
        "quote": "the package carries no `contentPolicy` declaration and no `DISCLOSURE` file"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "scripts/npm-release-workflow.test.ts"
      ],
      "assumptions": [
        "github-api",
        "npm-registry"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "npm-reread-canonical-before-publish",
      "statement": "Immediately before npm publish, the immutable canonical Release is re-read by tag: immutable, non-draft, non-prerelease, Actions-bot author, exact source and attempt receipt, exactly five uploaded assets, and archive digest and size equal to the handed-off tarball; returned identity and integrity must match.",
      "area": "npm",
      "source": {
        "path": "AGENTS.md",
        "quote": "re-read the immutable canonical Release immediately before `npm publish` without `--tag`"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "scripts/npm-release-workflow.test.ts"
      ],
      "assumptions": [
        "github-api",
        "npm-registry"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "npm-packed-manifest-publication-settings",
      "statement": "The independently parsed packed manifest must have private omitted or false, no contentPolicy, no top-level tag, and publishConfig exactly {access: public, canonical registry}; scoped registries, proxies, credentials and any other publication setting are rejected.",
      "area": "npm",
      "source": {
        "path": "AGENTS.md",
        "quote": "permit no top-level `tag` plus only `publishConfig.access=public` and the canonical npm registry—reject scoped registries, proxies, credentials, and all other publication settings."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "scripts/npm-release-workflow.test.ts"
      ],
      "assumptions": [
        "github-api",
        "npm-registry"
      ],
      "notVerified": [
        "No property test covers this law yet; only the enumerated example cases are checked."
      ]
    },
    {
      "id": "npm-registry-state-admission",
      "statement": "npm mutation is admitted only when the version is absent and public latest is strictly older (publish), or the same version is public with the exact canonical dist.integrity (skip, no second write); every other state, including same version with different bytes or an unprovable registry state, fails closed.",
      "area": "npm",
      "source": {
        "path": "AGENTS.md",
        "quote": "Admit only an absent registry version newer than public `latest`, or the same version already public with the exact canonical integrity (skip without a second write); never overwrite a published version."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "scripts/npm-release-workflow.test.ts"
      ],
      "assumptions": [
        "github-api",
        "npm-registry"
      ],
      "notVerified": [
        "No property test covers this law yet; only the enumerated example cases are checked."
      ]
    },
    {
      "id": "npm-publish-at-most-once-per-version",
      "statement": "Across any sequence of attempts and reruns of a Release run, an attempt issues `npm publish` only when the registry readback shows the version absent; an ambiguous write resolves by readback and never blind-retries. When the readback lags a rerun can issue a second publish, which npm's per-version immutability refuses, so a published version's bytes never change.",
      "area": "npm",
      "source": {
        "path": "docs/publishing.md",
        "quote": "The workflow's `stable-release` concurrency group and npm's version immutability serialize publication"
      },
      "layer": "property",
      "status": "evidenced",
      "evidence": [
        "scripts/npm-publish-model.test.ts",
        "scripts/npm-release-workflow.test.ts"
      ],
      "assumptions": [
        "github-api",
        "github-enforcement",
        "npm-registry"
      ],
      "notVerified": [
        "The sampled rerun property in `scripts/npm-publish-model.test.ts` runs the real registry-admission and publish step scripts against a fake npm registry: each attempt issues at most one `npm publish`, only after an absent readback, never changes a held version, and never reports success after an ambiguous or failed write.",
        "The named registry-lag test shows a rerun whose readback still answers absent can issue a second `npm publish`; npm's per-version immutability refuses it, and the held bytes stay canonical. The registry's own immutability is the `npm-registry` assumption; the workflow's responsibility is the absent-readback gate and readback-only ambiguity resolution."
      ],
      "properties": [
        {
          "path": "scripts/npm-publish-model.test.ts",
          "test": "property: each attempt issues at most one npm publish, only after an absent readback, and never changes a held version"
        }
      ]
    },
    {
      "id": "npm-release-env-sole-reference",
      "statement": "Only the `publish_npm` job references the `npm-release` environment or mints an npm OIDC token; it is the sole environment in `release.yml`, and no other workflow names it.",
      "area": "npm",
      "source": {
        "path": "AGENTS.md",
        "quote": "Only `publish_npm` may reference it or mint an npm OIDC token"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "scripts/ci-pr-gate.test.ts",
        "scripts/npm-release-workflow.test.ts"
      ],
      "assumptions": [
        "github-api",
        "npm-registry"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked.",
        "The test covers `release.yml` only; plan Phase 6 adds the scan that no other workflow names the environment."
      ]
    },
    {
      "id": "npm-release-env-config",
      "statement": "GitHub environment npm-release has administrator bypass disabled, no reviewers, no secrets, sole protection rule branch_policy, and the single custom deployment policy tag v* with no branch admitted.",
      "area": "npm",
      "source": {
        "path": "AGENTS.md",
        "quote": "Keep the `npm-release` environment fail closed: administrator bypass disabled, no reviewers, no secrets, sole protection rule `branch_policy`, and the single custom deployment policy `tag` `v*` with no branch admitted."
      },
      "layer": "configuration-readback",
      "status": "not-verified",
      "evidence": [
        "scripts/npm-release-workflow.test.ts"
      ],
      "assumptions": [
        "github-api",
        "github-enforcement",
        "npm-registry",
        "administrator-readback"
      ],
      "notVerified": [
        "Live settings are confirmed only by administrator readback; CI cannot read them or detect drift.",
        "The listed tests check only the checked-in side of the contract."
      ]
    },
    {
      "id": "npm-trusted-publisher-binding",
      "statement": "The npm trusted publisher for @hraness/ghostget names exactly hraness/ghostget, release.yml and environment npm-release; no other relationship exists, package access requires 2FA and disallows tokens, and no npm token is stored in GitHub.",
      "area": "npm",
      "source": {
        "path": "AGENTS.md",
        "quote": "the npm trusted publisher names `release.yml` and this environment."
      },
      "layer": "configuration-readback",
      "status": "not-verified",
      "evidence": [],
      "assumptions": [
        "github-api",
        "npm-registry",
        "administrator-readback"
      ],
      "notVerified": [
        "Live settings are confirmed only by administrator readback; CI cannot read them or detect drift."
      ]
    },
    {
      "id": "tag-ruleset-creation-only",
      "statement": "In each tag ruleset pair, the creation-only ruleset has the exact rule set [creation] and always-bypass actors exactly User 894119 plus, for the stable v* pair only, the hraness-release-tagger App 5164973 Integration; it never authorizes update or deletion.",
      "area": "control-plane",
      "source": {
        "path": "AGENTS.md",
        "quote": "In each pair, the creation-only ruleset must have exact rule `creation`; its always-bypass actors are exactly User `894119` plus, for the stable `v*` pair only, the `hraness-release-tagger` App `5164973` `Integration`; it must never authorize update or deletion."
      },
      "layer": "configuration-readback",
      "status": "not-verified",
      "evidence": [],
      "assumptions": [
        "github-enforcement",
        "administrator-readback"
      ],
      "notVerified": [
        "Live settings are confirmed only by administrator readback; CI cannot read them or detect drift."
      ]
    },
    {
      "id": "tag-ruleset-immutable",
      "statement": "In each tag ruleset pair, the immutable ruleset has exact rules [deletion, update] and no bypass actors; it never authorizes creation.",
      "area": "control-plane",
      "source": {
        "path": "AGENTS.md",
        "quote": "The immutable ruleset must have no bypass actors and exact deletion plus update rules; it must never authorize creation."
      },
      "layer": "configuration-readback",
      "status": "not-verified",
      "evidence": [],
      "assumptions": [
        "github-enforcement",
        "administrator-readback"
      ],
      "notVerified": [
        "Live settings are confirmed only by administrator readback; CI cannot read them or detect drift."
      ]
    },
    {
      "id": "tag-rulesets-two-split-pairs",
      "statement": "Exactly four active repository tag rulesets form two split creation-only and immutable pairs, one targeting only `refs/tags/v*` and one targeting only `refs/tags/desktop-v*-macos-arm64`; any other active tag ruleset is drift, and the split semantics, not the ruleset IDs or names, carry the authority.",
      "area": "control-plane",
      "source": {
        "path": "AGENTS.md",
        "quote": "read back all four active repository tag rulesets. They form two split pairs: one pair targets only `refs/tags/v*`, and the other targets only `refs/tags/desktop-v*-macos-arm64`."
      },
      "layer": "configuration-readback",
      "status": "not-verified",
      "evidence": [],
      "assumptions": [
        "github-enforcement",
        "administrator-readback"
      ],
      "notVerified": [
        "Live settings are confirmed only by administrator readback; CI cannot read them or detect drift."
      ],
      "alsoQuotes": [
        {
          "path": "AGENTS.md",
          "quote": "Any other active tag ruleset is drift."
        }
      ]
    },
    {
      "id": "immutable-releases-enabled-before-tag",
      "statement": "Repository immutable Releases stay enabled: administrator readback confirms enabled=true at setup, after any control change, and during drift recovery, and each Release run's immutable-release readback fails closed on a mutable Release.",
      "area": "control-plane",
      "source": {
        "path": "AGENTS.md",
        "quote": "Keep immutable Releases enabled; an administrator re-reads that setting at setup, after any control change, and during drift recovery, and every Release run's immutable-release readback still fails closed on a mutable Release."
      },
      "layer": "configuration-readback",
      "status": "not-verified",
      "evidence": [],
      "assumptions": [
        "github-enforcement",
        "administrator-readback"
      ],
      "notVerified": [
        "Live settings are confirmed only by administrator readback; CI cannot read them or detect drift.",
        "An administrator could change the setting between readbacks; only the per-run immutable-release readback would then detect it."
      ]
    },
    {
      "id": "no-integration-tag-bypass",
      "statement": "Neither GitHub Actions nor any Integration other than the hraness-release-tagger App (stable v* tag creation only) has a release-tag ruleset bypass.",
      "area": "control-plane",
      "source": {
        "path": "AGENTS.md",
        "quote": "Never give GitHub Actions or any other Integration a release-tag bypass."
      },
      "layer": "configuration-readback",
      "status": "not-verified",
      "evidence": [],
      "assumptions": [
        "github-enforcement",
        "administrator-readback"
      ],
      "notVerified": [
        "Live settings are confirmed only by administrator readback; CI cannot read them or detect drift."
      ]
    },
    {
      "id": "protect-main-ruleset",
      "statement": "Protect-main has no bypass actors, requires the pull-request path and exact Required CI check, approval minimum zero and require_code_owner_review=false while only one eligible code owner exists.",
      "area": "control-plane",
      "source": {
        "path": "AGENTS.md",
        "quote": "Protect-main has no bypass actors and retains pull-request admission plus the exact Required CI check. Keep its approval minimum at zero and `require_code_owner_review=false` until a second eligible independent code owner exists."
      },
      "layer": "configuration-readback",
      "status": "not-verified",
      "evidence": [
        "scripts/ci-pr-gate.test.ts"
      ],
      "assumptions": [
        "github-enforcement",
        "administrator-readback"
      ],
      "notVerified": [
        "Live settings are confirmed only by administrator readback; CI cannot read them or detect drift.",
        "The listed tests check only the checked-in side of the contract."
      ],
      "alsoQuotes": [
        {
          "path": "AGENTS.md",
          "quote": "Never force-push or bypass the gate."
        }
      ]
    },
    {
      "id": "vercel-project-config",
      "statement": "Vercel project `prj_TZbDZ38ABPan158IqnczgsuTu6Ue` under team `team_UAd1iD2XogJlbFg4h14mRaPM` is linked to GitHub repository ID `1425391521` with `link.productionBranch=main`, `autoExposeSystemEnvs=true`, and persistent `autoAssignCustomDomains=true`.",
      "area": "control-plane",
      "source": {
        "path": "AGENTS.md",
        "quote": "keep exact project `prj_TZbDZ38ABPan158IqnczgsuTu6Ue`, team `team_UAd1iD2XogJlbFg4h14mRaPM`, GitHub repository ID `1425391521`, `link.productionBranch=main`, `autoExposeSystemEnvs=true`, and persistent `autoAssignCustomDomains=true`"
      },
      "layer": "configuration-readback",
      "status": "not-verified",
      "evidence": [],
      "assumptions": [
        "github-enforcement",
        "vercel",
        "administrator-readback"
      ],
      "notVerified": [
        "Live settings are confirmed only by administrator readback; CI cannot read them or detect drift."
      ],
      "alsoQuotes": [
        {
          "path": "website/AGENTS.md",
          "quote": "with `link.productionBranch=main`, `autoExposeSystemEnvs=true`, and `autoAssignCustomDomains=true`"
        }
      ]
    },
    {
      "id": "committed-binaries-reproducible",
      "statement": "Bundled native messaging runtimes are accepted only as exact pinned bytes.",
      "area": "supply-chain",
      "source": {
        "path": "docs/messaging-automation.md",
        "quote": "Only exact pinned bytes are accepted."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/providers/messaging-native-install.test.ts",
        "src/scripts/install-whatsapp-protocol.test.ts"
      ],
      "assumptions": [
        "ci-runner"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked.",
        "The bundled-runtime install case runs only on darwin-arm64, so only the arm64 `macos-15` job of the macOS CI suite runs it; Linux CI skips it."
      ]
    },
    {
      "id": "committed-binaries-provenance",
      "statement": "The committed native messaging binaries (imsg, wacli) carry a reviewed patch stack over a pinned upstream commit; Required CI recomputes every recorded pin from the checked-in bytes, and the nightly macOS job rebuilds each artifact from pinned source — wacli byte-for-byte, imsg as a pinned-recipe build whose non-deterministic signed bytes are recorded honestly.",
      "area": "supply-chain",
      "source": {
        "path": "kb/plans/formal-verification-assurance.md",
        "quote": "Build imsg and wacli in CI from pinned source with provenance, and stop committing binaries."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "scripts/messaging-runtime-provenance.ts",
        "scripts/messaging-runtime-provenance.test.ts",
        ".github/workflows/ci.yml",
        ".github/workflows/verification-nightly.yml"
      ],
      "assumptions": [
        "ci-runner"
      ],
      "notVerified": [
        "imsg is not byte-reproducible: its provenance record reports signedBytesIdentical false and cleanRebuilds 0, so the nightly evidence for imsg is that the pinned recipe builds an arm64 Mach-O under the pinned Swift toolchain — not that the committed bytes re-derive. A deterministic unsigned-build comparison would need upstream link determinism work.",
        "Neither binary has live provider qualification (account pairing, send, delivery); artifact admission and live qualification stay separate.",
        "The nightly rebuild asserts the recorded patch-stack tip commit, but upstream repository content is admitted by commit pin plus patch digests, not by a second reviewer."
      ]
    },
    {
      "id": "hraness-deps-immutable-pins",
      "statement": "Hraness dependencies are pinned to reviewed immutable releases or full commits, never sibling paths, submodules, or main.",
      "area": "supply-chain",
      "source": {
        "path": "AGENTS.md",
        "quote": "Pin Hraness dependencies to reviewed immutable releases or full commits."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "website/site.test.ts"
      ],
      "assumptions": [
        "ci-runner"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked.",
        "`website/site.test.ts` asserts only the design-kit, site-footer, and ui pins; the other Hraness dependencies, and rejection of branches, sibling paths, and submodules, are not checked."
      ],
      "alsoQuotes": [
        {
          "path": "AGENTS.md",
          "quote": "consume shared design-kit or `@hraness/ui` primitives only at immutable versions"
        }
      ]
    },
    {
      "id": "ci-source-coverage-contract",
      "statement": "The `Required` job succeeds only when every source CI job succeeds, including `verification`, and each source job runs the checked checkout, toolchain, source-identity, and frozen-install template with SHA-pinned actions, unpersisted credentials, and least permissions.",
      "area": "ci",
      "source": {
        "path": "AGENTS.md",
        "quote": "Complete `Required` PR CI is the normal final source integration gate for executable and documentation changes"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "scripts/ci-pr-gate.test.ts",
        "scripts/github-release-artifact.test.ts",
        "scripts/npm-release-workflow.test.ts"
      ],
      "assumptions": [
        "github-enforcement",
        "ci-runner"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ],
      "alsoQuotes": [
        {
          "path": "AGENTS.md",
          "quote": "CI covers the complete Linux aggregate and a selected macOS suite."
        }
      ]
    },
    {
      "id": "verification-inconclusive-not-evidence",
      "statement": "A Quint, Apalache, or Lean run passes only on its exact success outcome; a timeout, interruption, violation, unparsed output, or a successful compile or typecheck alone fails `bun run verify` and the `verification` job.",
      "area": "verification",
      "source": {
        "path": "AGENTS.md",
        "quote": "Treat a checker timeout, an inconclusive or unparsed checker result, and a successful compile or typecheck alone as missing evidence"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "scripts/verification-tools.test.ts"
      ],
      "assumptions": [
        "ci-runner",
        "verification-tools"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "verification-tools-pinned",
      "statement": "Quint 0.32.0, Apalache 0.62.2, the Temurin 21.0.12.1+1 JDK, elan 4.2.4, and Lean v4.34.0 are pinned exactly, and every downloaded checker archive, the JDK included, is admitted only at its pinned size and SHA-256.",
      "area": "verification",
      "source": {
        "path": "AGENTS.md",
        "quote": "Pin Quint, Apalache, the JDK, elan, and Lean to exact versions, and admit every downloaded checker archive only at its pinned SHA-256."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        ".github/workflows/ci.yml",
        "scripts/verification-tools.test.ts",
        "verification/lean/lean-toolchain"
      ],
      "assumptions": [
        "ci-runner",
        "verification-tools"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "verification-quint-smoke",
      "statement": "The Quint smoke model typechecks, passes seeded simulation and bounded Apalache checking of `mutualExclusion`, both checkers find the violation in its unguarded mutant, 1,000 seeded ITF traces replay through a TypeScript reference lock, and the replay rejects a defective lock and every mutant trace that breaks mutual exclusion.",
      "area": "verification",
      "source": {
        "path": "AGENTS.md",
        "quote": "Pair every model with a seeded mutant or pre-fix variant that its checkers must find."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "scripts/verification-lock-replay.test.ts",
        "scripts/verification-tools.test.ts",
        "verification/quint/lock.qnt",
        "verification/quint/models.json"
      ],
      "assumptions": [
        "ci-runner",
        "verification-tools"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked.",
        "The smoke model is toolchain evidence: its traces replay through a TypeScript reference lock, not production code."
      ]
    },
    {
      "id": "verification-nightly-depth",
      "statement": "`bun run ./scripts/verification-tools.ts quint-nightly` checks every Quint model at its recorded `nightly` bounds, which the parser rejects when any bound falls below its CI bound or none deepens it; the soak multiplies the run count and time limit of every `assertProperty` and `assertAsyncProperty` by an explicit `GHOSTGET_PROPERTY_RUNS` from 2 to 100; and `.github/workflows/verification-nightly.yml` runs both with the reducer mutants on a schedule, read-only, SHA-pinned, and outside `Required`.",
      "area": "verification",
      "source": {
        "path": "verification/AGENTS.md",
        "quote": "Give a Quint model `nightly` bounds only when they deepen its CI bounds and none falls below them. Keep `.github/workflows/verification-nightly.yml` read-only and outside `Required`"
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        ".github/workflows/verification-nightly.yml",
        "scripts/ci-pr-gate.test.ts",
        "scripts/verification-soak.ts",
        "scripts/verification-tools.test.ts",
        "src/test-support.test.ts",
        "verification/quint/models.json"
      ],
      "assumptions": [
        "ci-runner",
        "verification-tools"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked; `Required` checks the nightly configuration, not a nightly run.",
        "The nightly workflow has not run on `main` yet. Its first scheduled run after merge is the first CI evidence at the deeper bounds and soak multiplier.",
        "Only `verification/quint/lock.qnt`, the toolchain smoke model with a `reference` replay target, lists `nightly` bounds. The six production models run in the nightly at their CI bounds, so the nightly deepens no model of production code until one lists `nightly` bounds.",
        "A nightly failure blocks no merge or release. Only the quarterly review in `docs/claims-review.md` checks that failures were triaged, and no automated check enforces that review.",
        "The serialized omni runtime test file is outside the soak."
      ]
    },
    {
      "id": "verification-source-mutants",
      "statement": "Every mutant in `verification/mutants.json` changes exactly one occurrence of a guard in `src/run-journal.ts`, `src/messaging-action-store.ts`, or `src/linked-device-lifecycle-journal.ts` and still transpiles, and `bun run ./scripts/verification-mutants.ts` reports it killed only when its fully named test passes alone on unmodified source and is the only failing test on the mutant; a timeout, another failure, or unparsed output is inconclusive and fails the run.",
      "area": "verification",
      "source": {
        "path": "verification/AGENTS.md",
        "quote": "List every reducer source mutant in `mutants.json` with its defect and the full name of the one test that must fail."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "scripts/verification-mutants.ts",
        "scripts/verification-tools.test.ts",
        "verification/mutants.json"
      ],
      "assumptions": [
        "ci-runner",
        "verification-tools"
      ],
      "notVerified": [
        "`Required` checks only that each mutant applies, compiles, and names a declared test; the kill runs happen in the nightly workflow.",
        "The manifest lists hand-picked guards. It is not a mutation score over the reducers, and StrykerJS was evaluated and not adopted (see `docs/claims-review.md`)."
      ]
    },
    {
      "id": "verification-itf-strict",
      "statement": "The ITF reader accepts only the value encodings Quint and Apalache write; bounds a trace's bytes, states, variables, nesting depth, value count, and string bytes; and rejects extra fields, duplicate set members and map keys, non-canonical integers, and states that are misindexed or do not assign exactly the declared variables.",
      "area": "verification",
      "source": {
        "path": "AGENTS.md",
        "quote": "Parse every foreign manifest, package, message, plan, receipt, response, and CLI value from `unknown`; reject extra fields, malformed bounds, ambiguous ownership, and drift."
      },
      "layer": "property",
      "status": "evidenced",
      "evidence": [
        "scripts/verification-itf.test.ts"
      ],
      "assumptions": [
        "ci-runner",
        "verification-tools"
      ],
      "notVerified": [
        "Generated inputs are sampled at the configured run count; this is not a proof over all inputs.",
        "CI reads only the traces that the pinned Quint and Apalache releases write; another release may write an encoding the reader rejects."
      ],
      "properties": [
        {
          "path": "scripts/verification-itf.test.ts",
          "test": "every container level counts once against the depth bound"
        },
        {
          "path": "scripts/verification-itf.test.ts",
          "test": "bounds every string in UTF-8 bytes wherever the trace holds one"
        },
        {
          "path": "scripts/verification-itf.test.ts",
          "test": "a set or map is rejected exactly when two members or keys denote the same value"
        },
        {
          "path": "scripts/verification-itf.test.ts",
          "test": "a JSON number is read exactly when it is a safe integer other than -0"
        },
        {
          "path": "scripts/verification-itf.test.ts",
          "test": "#bigint text is read exactly when it is a canonical decimal integer of at most 78 digits"
        },
        {
          "path": "scripts/verification-itf.test.ts",
          "test": "every state must carry its own index and assign exactly the declared variables"
        }
      ]
    },
    {
      "id": "verification-lean-trusted-base",
      "statement": "The core-only Lean project builds with warnings as errors; every theorem listed in `proofs.json` exists as a theorem whose kernel statement matches its recorded SHA-256; for each seeded defect, the audit checks at the kernel-term level that the defect has the guarded definition's type and that the refutation states exactly the negation of the guarded theorem with the defect in place of the guarded definition; the axiom audit and source scan reject `sorry`, `admit`, native evaluation, unlisted axioms, and other trust escapes; and a seeded `sorry` canary must fail the build and the audit on every run.",
      "area": "verification",
      "source": {
        "path": "verification/AGENTS.md",
        "quote": "the audit rejects `sorry`, `admit`, native evaluation, unlisted axioms, and other trust escapes."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "scripts/verification-tools.test.ts",
        "verification/lean/AxiomAudit.lean",
        "verification/lean/GhostgetVerification/Smoke.lean",
        "verification/lean/proofs.json"
      ],
      "assumptions": [
        "ci-runner",
        "verification-tools"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked.",
        "The smoke theorems state nothing about Ghostget code, and the Lean kernel and toolchain are trusted.",
        "The negation check compares kernel terms syntactically; a refutation that is only definitionally equal to the negation is rejected, not accepted."
      ]
    },
    {
      "id": "verification-model-replay-required",
      "statement": "Every Quint model records its invariants, seeds, bounds, a mutant, and a replay test, and the register accepts an evidenced Quint claim only when it cites a model whose replay test drives production code.",
      "area": "verification",
      "source": {
        "path": "AGENTS.md",
        "quote": "Count a Quint model as conformance evidence only after an ITF trace replay test drives production code through its traces; until then it is design evidence."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "scripts/verification-claims.test.ts",
        "scripts/verification-tools.test.ts",
        "verification/quint/models.json"
      ],
      "assumptions": [
        "ci-runner",
        "verification-tools"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ],
      "alsoQuotes": [
        {
          "path": "verification/AGENTS.md",
          "quote": "Set the replay target to `production` only when the replay test drives production code"
        }
      ]
    },
    {
      "id": "verification-register-complete",
      "statement": "Every guideline in the scanned `AGENTS.md` guides maps to exactly one register rule whose digest matches its current text and which lists at least one claim or an exemption reason, and every evidence path in the register exists.",
      "area": "verification",
      "source": {
        "path": "AGENTS.md",
        "quote": "When you add or change a rule in an `AGENTS.md`, update its claims and rule digest in `verification/claims.json` in the same change."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "scripts/verification-claims.test.ts"
      ],
      "assumptions": [
        "ci-runner",
        "verification-tools"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ]
    },
    {
      "id": "verification-claim-scope",
      "statement": "Every claim carries its layer, status, assumptions, and a non-empty not-verified scope, and `docs/assurance.md` is generated from the register and fails its freshness test when stale.",
      "area": "verification",
      "source": {
        "path": "AGENTS.md",
        "quote": "Give every claim its not-verified scope, and regenerate `docs/assurance.md`."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "docs/assurance.md",
        "scripts/verification-claims.test.ts"
      ],
      "assumptions": [
        "ci-runner",
        "verification-tools"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ],
      "alsoQuotes": [
        {
          "path": "verification/AGENTS.md",
          "quote": "Keep a claim `planned` with its plan phase until its layer runs in CI."
        }
      ]
    },
    {
      "id": "verification-shrink-promotion",
      "statement": "Every failing seed recorded in the seed corpus is replayed by its named property and cites a named example test registered beside that property.",
      "area": "verification",
      "source": {
        "path": "AGENTS.md",
        "quote": "Promote every recorded shrink or failing seed to a named example test."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "src/test-harness-policy.test.ts",
        "src/test-support.test.ts",
        "src/contracts-invoke-read.test.ts"
      ],
      "assumptions": [
        "bun-runtime"
      ],
      "notVerified": [
        "Only failures someone records in `verification/seeds/corpus.json` are checked; a shrink fixed without a corpus entry is not.",
        "The check confirms that the cited regression test is registered, not that it exercises the recorded input; only the `contracts-invoke-read` entry pins its generated input with `fc.sample`."
      ],
      "alsoQuotes": [
        {
          "path": "AGENTS.md",
          "quote": "then promote a minimized failure to a named regression"
        },
        {
          "path": "verification/AGENTS.md",
          "quote": "Record a failing seed and shrink path in `seeds/corpus.json` under the property's name"
        }
      ]
    },
    {
      "id": "verification-unpublished",
      "statement": "The published package excludes `verification/`, the verification scripts, and checker downloads, and generated traces, Lean build output, and downloaded checkers stay out of Git.",
      "area": "verification",
      "source": {
        "path": "verification/AGENTS.md",
        "quote": "Keep this directory, the verification scripts, and the checker downloads out of the published package."
      },
      "layer": "example",
      "status": "evidenced",
      "evidence": [
        "scripts/verification-tools.test.ts"
      ],
      "assumptions": [
        "ci-runner",
        "verification-tools"
      ],
      "notVerified": [
        "Only the enumerated example cases are checked."
      ],
      "alsoQuotes": [
        {
          "path": "verification/AGENTS.md",
          "quote": "Keep generated traces, build output, and downloaded tools out of Git."
        }
      ]
    },
    {
      "id": "website-informational-only",
      "statement": "`website/` explains and documents Ghostget and contains no agent runtime, authenticated product surface, or browser-based substitute for the CLI and SDK.",
      "area": "website",
      "source": {
        "path": "AGENTS.md",
        "quote": "Keep `website/` informational: it may explain and document Ghostget, but must not grow an agent runtime, authenticated product surface, or browser-based substitute for the CLI and SDK."
      },
      "layer": "not-verified",
      "status": "not-verified",
      "evidence": [],
      "assumptions": [
        "vercel"
      ],
      "notVerified": [
        "No automated check inspects `website/` for authenticated surfaces, credential handling, or runtime features; review alone enforces this boundary."
      ]
    },
    {
      "id": "intent-fence-subject-across-locators",
      "statement": "New run journals record the provider subject their auth record named; before dispatch, the confirmed-write fence also refuses while an unsettled run of the same provider target, operation, canonical input, and duplicate-risk source recorded the same subject under a different auth locator, both in its journal scan and in a recheck after its own claim is on record. Journals without a subject keep the per-locator fence and stay valid.",
      "area": "mutations",
      "source": {
        "path": "docs/effect-confirmed-write-runtime.md",
        "quote": "the fence also refuses while an unsettled run of the same provider target, operation, and canonical input"
      },
      "layer": "quint",
      "status": "evidenced",
      "evidence": [
        "scripts/verification-fence-replay.test.ts",
        "src/confirmed-write-intent-fence.test.ts",
        "src/run-journal.test.ts",
        "verification/quint/fence.qnt"
      ],
      "assumptions": [
        "filesystem-durability",
        "same-user-trusted"
      ],
      "notVerified": [
        "Subjects are compared as strings. The operator may type a subject, so two locators that record one subject are fenced as one account even when they are not; this only refuses more. Two locators of one account with no recorded subject, or a run recorded before journals kept the subject, are not fenced against each other.",
        "Two runs that race past their scans may both refuse at the recheck; neither dispatches, and each is retried after the other settles. No progress law is checked.",
        "The fence model has two locators, one subject, three runs, 5,000 simulated samples of up to 12 steps, and Apalache to length 8; the replay drives the subject scan and recheck through the pure fence cores and a five-trace file-backed cover, not the `confirmInvocation` program, which the listed example tests cover.",
        "A succeeded run under another locator neither fences nor replays across locators, by design."
      ]
    }
  ]
}
