[{"data":1,"prerenderedAt":4},["ShallowReactive",2],{"Xd2XSAHBHY":3},"# Calculator\n\nCalculator is the reference PrismPM product: one authoritative application\nmodel plus one authoritative production-system model become a portable Pages\napplication and complete A/B service releases.\n\nThe production SDK migration is not yet released. Its SDK/template locks and\nworkflow image/commit bindings must be rendered from the accepted public SDK\nand runtime images before opening the new devcontainer or running production\nCI. The historical baseline record remains explicitly unsealed until the\npublic crates, regenerated Pages closure, and complete clean verification\ntranscripts are available. These checks fail when release evidence is absent.\n\n## Build, push, run\n\nOpen the repository in its devcontainer. The container is the exact SDK image\nrecorded in `prismpm.lock`; the host needs only Git, Docker, and a devcontainer\nclient. Only Docker's read-only `config.json` crosses into the container; host\nCLI plugins cannot shadow the SDK-owned Buildx and Compose plugins.\n\n```console\njust setup\njust build\nsource .prism/repository-evidence/releases.env\nprismpm push \"$CALCULATOR_RELEASE_A\"\nprismpm push \"$CALCULATOR_RELEASE_B\"\nprismpm run --detach --target compose-local \"$CALCULATOR_RELEASE_B\"\n```\n\nNo command compiles PrismPM source, searches the host `PATH` for a fallback, or\nregenerates during push, pull, run, or deploy. Cargo consumes the exact\n`prism-calculator` and `prism-stdlib` versions from the public registry.\nThe protected production workflow isolates the read-only build job from the\nOIDC/package-write candidate publication job, derives signing policy and\nSigstore trust material inside the SDK, signs and promotes the unchanged root\nto candidate, pushes it, accepts a clean pull, then promotes and pushes the same\nroot as accepted with its lifecycle evidence. A final read-only clean job pulls\nthe releases and uses `verify-release` to cryptographically replay the complete\nsignature and candidate-to-accepted promotion chain. After the full\nacceptance lifecycle, the protected job signs and verifies one canonical\nclosure over every deployment, rollback, restore, and retirement evidence\nreferrer before the final push.\n\n## Inspect and deploy\n\n```console\nprismpm inspect \"$CALCULATOR_RELEASE_B\"\nprismpm verify-release \"$CALCULATOR_RELEASE_B\"\nplan=$(prismpm --json plan --target kubernetes-kind \"$CALCULATOR_RELEASE_B\")\nprismpm deploy --target kubernetes-kind \\\n  --plan \"$(printf '%s' \"$plan\" | node -e 'let s=\"\";process.stdin.on(\"data\",d=>s+=d).on(\"end\",()=>process.stdout.write(JSON.parse(s).plan_digest))')\" \\\n  \"$CALCULATOR_RELEASE_B\"\nprismpm status --target kubernetes-kind \"$CALCULATOR_RELEASE_B\"\nprismpm rollback --target kubernetes-kind \"$CALCULATOR_RELEASE_A\"\nprismpm backup --target compose-local \"$CALCULATOR_RELEASE_B\"\nprismpm finalize-contract --target compose-local --authorized \"$CALCULATOR_RELEASE_B\"\nprismpm template check\nprismpm lock check\n```\n\n`just accept-production` requires `CALCULATOR_RELEASE_A` and\n`CALCULATOR_RELEASE_B` to name the exact accepted GHCR digest references; it\nfails rather than silently building unsigned local substitutes. It performs\nthe authenticated registry round trip and exercises real Compose and\nKubernetes 1.36.4/Kind targets. It proves readiness, HTTP and View\nacceptance, OIDC user/auditor policy, idempotency and concurrency, complete i64\nboundaries, ordered isolated history, outbox/audit deduplication, dependency\noutage and recovery, OpenTelemetry receipt and redaction, SLOs, A-to-B\nmigration, managed drift, rollback, destructive-downgrade refusal, logical\nbackup/restore to a clean target, and authorized reverse-order cleanup.\nThe Compose gate also launches the generated foreground supervisor, sends it a\nreal interrupt, requires its reverse-dependency graceful-shutdown result, and\nproves that no managed process remains.\nRelease B first remains binary-compatible with A through its expand phase. The\nseparately authorized, idempotent `finalize-contract` operation executes the\nmodeled SQL and records B as the minimum compatible data release; subsequent A\ndeployment and rollback attempts must fail with `PP7601` without changing the\ntarget.\n\nThe Compose and Kind gates call the generated service rather than substituting\na test server. They exercise every arithmetic operation at signed-64-bit\nboundaries, accepted domain errors, the closed HTTP error surface, OIDC\nsignature/issuer/audience/time/subject/role failures, subject isolation,\ndefault and explicit pagination, concurrent idempotency, and the generated\nOpenAPI-only View. Compose additionally replays the same outbox event twice and\nqueries PostgreSQL to prove one audit row, then inspects exported Collector\nsignals for correlation and the absence of the modeled redaction canary. The\nView acceptance obtains a real empty-role OIDC principal for its API-produced\n403/access-denied state and stops the deployed database for its failure/retry\nstate; it never intercepts or fabricates an HTTP response. Kind\ndeploys A first through the pinned ingress-nginx controller and the modeled TLS\nIngress, proves both static retained PV/PVC bindings, and exercises the API and\nView without a port-forward. It observes process, database, broker, issuer,\nCollector, network-policy, credential, resource-limit, and managed-drift\nfailures; proves recovery and a stopped B migration; observes the live A/B\ncompatibility window; rotates the Ingress certificate and modeled late-bound\nOIDC signing key; rolls back while\ncompatible; finalizes the contract gate; and rejects the unsafe downgrade\nbefore authorized retirement.\nThe final Kind backup is restored into a newly created cluster, so the clean\ntarget has neither source-cluster API objects nor retained host-path bytes;\nPrismPM then compares the full logical PostgreSQL dump and reruns the generated\nAPI and View acceptance through TLS ingress. Both restore targets are then\nretired through PrismPM itself, including their recorded target-profile\nbinding, so the complete gate can run again without hidden target state.\n\nFor each A/B release, `just accept-conformance` executes the SDK-shipped\nrunner against every public capability ID and registered diagnostic trigger in\nthat locked SDK. PrismPM binds the canonical transcript to the exact release,\ncapability-coverage, SDK, and runner digests, then exercises the independent\nacceptance-attachment boundary. This complements the Calculator-specific live\nscenarios; it does not replace them with inferred or file-existence evidence.\n\n## Authoritative model\n\n- [`src/Calculator.lex.tex`](src/Calculator.lex.tex) is the unchanged\n  getting-started application authority. It defines checked signed-64-bit\n  arithmetic, Cargo/Core-Wasm, Holo/1, View, and the portable Pages profile.\n- [`src/CalculatorSystem.lex.tex`](src/CalculatorSystem.lex.tex) imports that\n  exact application module. It is the only authority for service interfaces,\n  JSON/HTTP, OIDC, history/idempotency, CloudEvents/outbox, PostgreSQL,\n  observability, Compose/Kubernetes topology, migrations, operations, and\n  releases A and B.\n\nLexLean generates Lean; lean4-prod compiles generated declarations. There is no\nhandwritten Lean and no handwritten Calculator API, SQL, event, UI, or\ndeployment behavior.\n\n[`CALCULATOR-VERIFICATION.md`](CALCULATOR-VERIFICATION.md) maps the Calculator\nmodel and acceptance surfaces to their concrete gates. `VERIFICATION.md` is\nthe byte-bound universal template policy and is intentionally not\nCalculator-specific.\n\n## Generated production closure\n\nEach immutable product release includes:\n\n- OpenAPI 3.2 and AsyncAPI 3.1 interfaces and CloudEvents 1.0 facts;\n- generated browser/API/audit-worker behavior and production typed View;\n- PostgreSQL schema plus A/B expand-compatible migration;\n- Compose and Kubernetes 1.36.4 target projections;\n- Calculator `.holo`, Core-Wasm, packages, component-image references;\n- SPDX 3 BOM, SLSA/in-toto provenance, oracle validation, signature and\n  lifecycle evidence; and\n- `projections/capability-coverage.json`, mapping every public PrismPM 0.3.0\n  feature and diagnostic family to modeled positive/negative acceptance. Each\n  row is explicitly public and binds its exact PrismPM register source, its\n  generated projection row, and either byte-sorted authority IDs from the\n  locked standards catalog or an explicit Prism-owned `none` reason.\n\n`just update-system-projection` is the only supported way to update the\ncommitted public-feature matrix. It uses the locked SDK to build release B,\nvalidates the complete generated system projection, validates every strict\nfeature/diagnostic/source/output/authority link, and then installs only the\nexact generated `artifacts/feature-coverage.json` bytes with their checksum and\ncanonical generation evidence. `just verify-system-projection` independently\nrebuilds and byte-compares that committed projection.\n\n`just vv` checks the committed public projection against a fresh generated\nbuild and reproduces A, B, Pages, and each complete OCI graph from two clean\nabsolute roots on the same architecture. The separate architecture matrix\nrequires every platform-independent generated byte to match. The model permits\nonly the child image selected from each pinned multi-platform runtime index to\ndiffer between `linux/amd64` and `linux/arm64`; the semantic snapshot,\ninterfaces, target projections, root manifest, and referrers do not.\nThat classification and comparison are made only by the SDK's canonical\n`prismpm/platform-equivalence/1` report; Calculator supplies the two clean\narchitecture roots and does not maintain a second exclusion list.\n\nThe canonical `prismpm/calculator-baseline/1` record preserves the exact\nhistorical application and deployed Pages identities, including the observed\nabsence of the claimed 0.1.0 crates. Its separate remediation closure can be\nsealed only after the regenerated projection, current public crates, and all\nclean command transcripts are independently verified. Every repository,\nbrowser, and production gate rejects an unsealed baseline.\nHistorical artifacts are always reconstructed from the historical Pages/release\ncommit recorded under `historical`; sealing advances the separate repository\nexecution binding to the input-ready commit without rewriting that history.\nThe exact former `RELEASE-CANDIDATE.json` bytes remain preserved as\n`artifacts/historical-release-candidate.json` and are compared directly with\nthat historical commit even after the obsolete top-level candidate file and\nlocal registry are removed.\nThe plan against which that candidate was accepted is likewise preserved at\n`artifacts/historical-plan-05sep26.md`; its fixed title and byte digest are\nchecked locally rather than depending on a mutable external working-tree path.\n\nThe final release renderer takes the exact public SDK image, shared Action\ncommit, reviewed template policy commit, and public runtime image index:\n\n```console\nbootstrap/render.sh SDK@sha256:DIGEST UOR-Foundation/PrismPM/action@COMMIT TEMPLATE_POLICY_COMMIT ghcr.io/uor-foundation/prismpm-runtime@sha256:DIGEST\n```\n\nIt installs the SDK's exact `standards.lock`, parses and updates the A/B runtime\nartifact records in the authoritative system model, and regenerates\n`lexlean.lock` through that SDK. It never patches a generated projection. The\ndevcontainer, every workflow, all three locks, the system source, and the\nLexLean lock form one render transaction: any failed phase restores every\npreexisting byte and removes outputs that did not exist before the attempt.\n\nThe pre-seal bootstrap phase is `just baseline-input`: before the first seal\nexists, it validates the draft record, runs the same local, Compose, clean\nKind, conformance, reproducibility, package, browser, and live-Pages checks,\nand emits canonical `calculator/baseline-input-evidence/1` bytes under\n`.prism/repository-evidence/`. It does not publish, promote, or deploy through\nthe protected release workflow. Its digest is recorded as the Calculator\nbaseline input; after sealing, ordinary `just vv`, browser, Pages, production,\nand CI paths continue to require the seal.\n\nCapture the five required clean executions inside the exact SDK image from\n`prismpm.lock`. The capture tool runs an argument vector directly and checks\nclean Git state before and after, for example:\n\n```console\nPRISMPM_EXECUTION_IMAGE=\"$SDK_IMAGE\" PRISMPM_EXECUTION_KIND=devcontainer \\\n  node /path/to/calculator-example/scripts/capture-baseline-run.mjs \\\n  https://github.com/UOR-Foundation/PrismPM 1 \"$SDK_IMAGE\" /evidence/prismpm-1.json -- just vv\n```\n\nThe exact evidence filenames and commands are `prismpm-1.json` / `just vv`,\n`prismpm-2.json` / `just vv`, `calculator-example-1.json` /\n`just baseline-input`, `lexlean-1.json` / `just vv`, and\n`lean4-prod-1.json` / `just ci`. Each canonical file binds its repository,\nfull HEAD object ID, repeat, clean-worktree result, SDK manifest, exit result,\nand complete base64-encoded stdout/stderr. Run `just seal-baseline /evidence`\nonly after all five pass. It rejects missing, extra, stale, dirty, failed,\nnoncanonical, or tampered evidence; copies the immutable files under\n`artifacts/baseline-evidence`; updates all run and repository bindings;\nvalidates the closed schema; rewrites checksums; and refuses overwrite.\n\n## Pages profile\n\nThe public portable Calculator remains at\n\u003Chttps://uor-foundation.github.io/calculator-example/>. It is a self-contained\nsix-file Holo/1/wasm application, not the stateful service target.\n\n```console\njust accept-pages\n```\n\nThat gate compares every served HTTPS byte with the generated local closure,\nruns modeled browser trace equivalence against the live HTTPS origin, checks\nWCAG 2.2 A/AA behavior, and records a canonical publication closure containing\nthe exact commit, URL, six asset sizes/digests, and corrected `index.html`\nidentity. Before the first seal, a protected manual Pages run with\n`baseline-bootstrap: true` publishes that already generated closure while the\nrecord still says the correction is absent. Its projection-bootstrap gate is\nconfined to Pages and compares the committed six files with fresh generator\noutput and then with the live site. `just prepare-baseline YYYY-MM-DD` may mark\nthe projection present only after that live comparison succeeds; normal pushes\nand every later deployment still require the sealed baseline.\n\nThe first corrected publication has an explicit, non-circular sequence:\n\n1. In the locked SDK, run `just update-application-projection`; it replaces\n   only the six application evidence files and six Pages files with the exact\n   `prismpm build`/`prismpm verify` output, then rewrites `SHA256SUMS`.\n2. Run `just update-system-projection` and then\n   `just verify-system-projection`; this installs only the generator's strict\n   release-B public-feature matrix. Run `just verify-application-projection`,\n   review both generic-generator diffs, and commit those projection inputs.\n3. Dispatch the Pages workflow on protected `main` with\n   `baseline-bootstrap: true`. This is the sole pre-seal publication path; it\n   rejects existing remediation claims, publishes without rebuilding, and\n   compares every live byte and browser behavior with the committed output.\n4. After the exact generated `prism-calculator` and SDK-carried\n   `prism-stdlib` archives are public, run `just prepare-baseline YYYY-MM-DD`.\n   It downloads both crates and the live Pages closure, requires byte equality\n   with the local candidates, and writes the input-ready unsealed record.\n5. Commit that input record, run `just baseline-input`, retain its canonical\n   evidence, and seal only after every recorded repository transcript exists.\n   All subsequent Pages runs take the ordinary sealed-only path.\n\nOrdinary Pages publication is part of the protected production graph. The\nproduction workflow passes the exact accepted release-B digest to the reusable\nPages workflow only after a clean GHCR pull and independent `verify-release`.\nThat workflow repeats the clean pull and trust replay, requires the complete\naccepted signature closure, extracts all six `view/browser/*` assets from the\nimmutable release, and byte-compares them with `public/` before deployment. It\ndoes not invoke source generation, build, or application verification in this\npublication mode; those checks have already passed before the accepted graph\nwas created.\nA push or pull request therefore validates Pages but cannot publish it; only a\nprotected ref can use either publication path, and the manual\nbaseline-bootstrap sequence above is the only deliberately confined\npre-accepted exception.\n\nThe `Publish exact generated Calculator crate` workflow is the only pre-seal\ncrate-publication path. It runs on a protected ref in the `crates-io`\nenvironment, obtains a short-lived token through crates.io trusted publishing,\nand uses the SDK's pinned Cargo. Cargo first packages the generated source\nclosure and must byte-match PrismPM's attested `.crate`; after publication the\nworkflow independently checks both the crates.io registry checksum and the\ndownloaded archive bytes. Configure the crates.io trusted publisher for this\nrepository, workflow filename, and environment—no long-lived Cargo token is\naccepted. The short-lived token is removed from the environment before model\nfetch, build, verification, packaging, and public-registry inspection; it is\nprovided only to the single pinned `cargo publish` child process.\n\n## SDK and template updates\n\nThe devcontainer, Actions, `prismpm.lock`, and `template.lock` all select the\nsame immutable SDK manifest. The initial migration invokes\n`bootstrap/render.sh` with the exact public SDK, Action, reviewed template\npolicy-input commit, and runtime index; because neither lock exists in the\nhistorical repository, that one transaction consumes the reviewed migration\nworktree and produces both locks together. After they are committed, every\nlater render rejects an untracked, dirty, or one-lock policy state. Updates are\nexplicit reviewable patches:\n\n```console\nprismpm lock update --sdk-image NAME@sha256:DIGEST\nprismpm template update --sdk-image NAME@sha256:DIGEST \\\n  --template-revision FULL_COMMIT\n```\n\nNo template or SDK update mutates the default branch implicitly.\n\n## Licenses\n\nLicensed under either Apache License 2.0 or MIT, at your option.\n",1791060125596]