diff --git a/README.md b/README.md
index 8f6f83b0..152ed869 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,15 @@
-# OpsNormal
+# OpsNormal - local-only operator readiness tracking
-> **Local-only operator readiness tracking with deliberate constraints and integrity-verified recovery.**
+**A disciplined daily readiness instrument. Five sectors. Three states. Thirty days. No accounts, no backend, no telemetry. Built to survive stress, not to impress a browser tab.**
-[](https://github.com/bradsaucier/opsnormal/actions/workflows/ci.yml) [](https://github.com/bradsaucier/opsnormal/actions/workflows/deploy.yml) [](./CHANGELOG.md) [](#trust-contract)
+[](https://github.com/bradsaucier/opsnormal/actions/workflows/ci.yml)
+[](https://github.com/bradsaucier/opsnormal/actions/workflows/deploy.yml)
+[](https://github.com/bradsaucier/opsnormal/actions/workflows/codeql.yml)
+[](./CHANGELOG.md)
+[](./LICENSE)
+[](#trust-contract)
@@ -28,7 +33,31 @@
>
> There are no accounts, no backend data plane, no telemetry path, and no sync layer. State lives in IndexedDB. Durable recovery depends on operator-controlled JSON exports backed by integrity checks.
>
-> The operating boundary is documented in [28 ADRs](./docs/decisions/README.md), a published [security and trust boundary](./SECURITY.md), and a release pipeline that publishes only the exact CI-verified production artifact.
+> The operating boundary is documented in [29 ADRs](./docs/decisions/README.md), a published [security and trust boundary](./SECURITY.md), and a release pipeline that publishes only the exact CI-verified production artifact under a Sigstore-backed build-provenance attestation.
+
+## At a glance
+
+| Facet | Current posture |
+| ------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
+| Runtime | React 19, TypeScript, Tailwind CSS 4, Vite, `vite-plugin-pwa` |
+| Persistence | IndexedDB through Dexie 4; compound uniqueness on `[date+sectorId]` |
+| Deployment | Static PWA on GitHub Pages, custom domain `opsnormal.app` |
+| Data posture | Local only. No accounts, no backend, no analytics, no sync |
+| Release pipeline | Mainline integrity -> re-smoke CI-verified artifact in Chromium, WebKit, Firefox -> publish |
+| Release artifact | `dist-ci-verified` reused end-to-end; no separate deploy build |
+| Build provenance | Sigstore-backed attestation, verified on Pages release (ADR-0027) |
+| Static analysis | CodeQL `security-extended` + `security-and-quality` as a merge gate (ADR-0028) |
+| Coverage gates | 100% on `date`, `exportSerialization`, `entryWrittenCoordination`; calibrated per-file floors on `importService` and `appDb` |
+| Accessibility | Dedicated WCAG 2.1 A / AA Playwright scans with service workers blocked |
+| Decisions of record | 29 ADRs under [`docs/decisions/`](./docs/decisions/README.md) |
+
+## Built for, and not built for
+
+Built for operators who want a fixed, legible readiness picture instead of feature sprawl, prefer local control over hosted convenience, and will maintain their own export cadence and restore drills.
+
+Not built for users seeking cross-device cloud sync or account recovery, passive telemetry, social features, background data collection, custom categories, free-form journaling, or browser storage treated like a guaranteed archive.
+
+These are not missing features. They are deliberate constraints that protect the operating model.
## Operational model
@@ -94,6 +123,7 @@ OpsNormal runs on a shared-responsibility model. The repository makes hard commi
- Import validates structure before commit, applies replace gating, and fails closed on malformed or unsafe data
- Root-level and section-level error boundaries preserve recovery surfaces and keep export reachable during localized render faults
- Release publication reuses the exact `dist-ci-verified` artifact that passed mainline integrity instead of rebuilding a new deploy bundle
+- The released bundle carries a Sigstore-backed build-provenance attestation that Pipeline: Pages Release verifies before upload
### The operator commits to
@@ -120,7 +150,7 @@ To reduce that risk:
- If you already entered data in Safari on an Apple device, run a JSON export there first. Then install to Home Screen, open the installed app, and import that JSON file.
- If the app reopens looking like a clean install, restore immediately from the latest JSON export
-## Mobile history proof
+## Mobile history surface
Narrow screens switch from the 30-day grid to week groups with a daily brief so the history surface stays readable on phone-sized viewports.
@@ -131,20 +161,13 @@ Narrow screens switch from the 30-day grid to week groups with a daily brief so
---
-## Deployment and initialization
+## Release truth
-1. Open `https://opsnormal.app`
-2. On Apple devices, install to Home Screen before entering data if you intend to rely on the app there
-3. Record an initial status across the five fixed sectors in the environment you intend to keep using
-4. Run a test JSON export and keep the file somewhere you control
-5. Export routinely, especially before browser maintenance, profile changes, device transitions, or long periods of inactivity
+The Pages release pipeline is not a second build. It is a verification and publishing pipeline over the exact artifact that passed mainline integrity.
-### Apple device guidance
+On every push to `main`, Pipeline: Mainline Integrity runs lint, typecheck, Vitest coverage, Playwright Chromium, merge-blocking WebKit and Firefox smoke lanes, and a production build, then uploads the `dist-ci-verified` artifact and emits a Sigstore-backed build-provenance attestation. Pipeline: Pages Release then resolves that artifact by upstream run ID, verifies the attestation against repository, signer workflow, source reference, and triggering commit SHA, re-smokes Chromium, WebKit, and Firefox against the extracted bundle, and only then publishes. The bundle on `opsnormal.app` is the same bytes that passed verification.
-- If you are validating a Pages rollout or DNS cutover, the fallback deployment URL is `https://bradsaucier.github.io/opsnormal/`
-- Ordinary Safari tabs are subject to WebKit purge behavior after seven days of Safari use without user interaction on the site
-- On Apple devices, Safari browser tabs and installed Home Screen apps keep isolated website data
-- If you already entered data in Safari on an Apple device, run a JSON export there first. Then install to Home Screen, open the installed app, and import that JSON file.
+Third parties can verify a downloaded CI artifact archive with `gh attestation verify`. See [SECURITY.md](./SECURITY.md) and ADR-0027.
## Threat model and reliability posture
@@ -207,16 +230,28 @@ Quality is enforced through release gates, test coverage, and explicit design co
- GitHub Actions dependencies are pinned to immutable SHAs, and CI fails on high-severity npm advisories through `npm audit --audit-level=high`
- ADRs, the risk register, the test plan, and the release checklist keep constraints visible so the repo cannot drift quietly
+## First run
+
+1. Open `https://opsnormal.app`
+2. On Apple devices, install to Home Screen before entering data if you intend to rely on the app there
+3. Record an initial status across the five fixed sectors in the environment you intend to keep using
+4. Run a test JSON export and keep the file somewhere you control
+5. Export routinely, especially before browser maintenance, profile changes, device transitions, or long periods of inactivity
+
+If you are validating a Pages rollout or DNS cutover, the fallback deployment URL is `https://bradsaucier.github.io/opsnormal/`.
+
## Local build and verification
-Prerequisites: Ensure the local environment meets the engine contract defined in `package.json`. `devEngines` enforces the local Node and npm baseline before install, ci, and run commands.
+Prerequisites: ensure the local environment meets the engine contract defined in `package.json`. `devEngines` enforces the local Node and npm baseline before install, ci, and run commands.
+
+### Develop
```bash
npm ci
npm run dev
```
-Local verification and CI are aligned to supported LTS lines. For the full contribution workflow and merge expectations, read [CONTRIBUTING.md](./CONTRIBUTING.md).
+### Verify before pull request
```bash
npm run format:check
@@ -234,6 +269,8 @@ npm run test:e2e:firefox:smoke
`npm run format:check` verifies repository formatting with Prettier, and `npm run format` applies the repository formatting baseline locally. `npm run test:e2e` builds the e2e-mode harness bundle and runs the full Chromium suite. `npm run test:e2e:webkit` runs the narrow WebKit smoke gate that verifies rendering and IndexedDB I/O on a WebKit engine without claiming to reproduce Safari eviction behavior. `npm run test:e2e:firefox` runs the parallel Gecko smoke gate that verifies boot, IndexedDB persistence, service worker activation, the non-WebKit storage path, and the fallback download path without claiming to simulate live Firefox storage policy. Run `npm run build` before the `test:e2e:*:smoke` commands so the production-artifact smoke checks reuse a real `dist/` build and skip the harness-only specs.
+For the full contribution workflow and merge expectations, read [CONTRIBUTING.md](./CONTRIBUTING.md).
+
## Documentation matrix
This README stays focused on orientation and first use. Deeper proof, limits, and design constraints live in the repo docs.
@@ -242,14 +279,14 @@ This README stays focused on orientation and first use. Deeper proof, limits, an
| --------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
| [**Architecture overview**](./docs/architecture.md) | Runtime shape, persistence model, recovery posture, PWA behavior, and known limits |
| [**Risk register**](./docs/risk-register.md) | Known operational risks, browser-storage hazards, and current mitigations |
-| [WebKit CI coverage boundary](./docs/webkit-limitations.md) | What the merge-blocking WebKit lane proves, what it cannot prove, and how to triage failures |
-| [Firefox CI coverage boundary](./docs/firefox-limitations.md) | What the merge-blocking Firefox lane proves, what it cannot prove, and how to triage failures |
| [**Architecture Decision Records**](./docs/decisions/README.md) | Why the repo chose IndexedDB, local-only boundaries, export integrity rules, and related constraints |
| [**Test plan**](./docs/test-plan.md) | Verification strategy, release checks, and coverage priorities |
| [Release checklist](./docs/release-checklist.md) | Pre-release validation and operator-facing quality gates |
-| [Changelog](./CHANGELOG.md) | Public release history |
| [Security policy](./SECURITY.md) | Security model, trust boundaries, and accurate claim limits |
+| [WebKit CI coverage boundary](./docs/webkit-limitations.md) | What the merge-blocking WebKit lane proves, what it cannot prove, and how to triage failures |
+| [Firefox CI coverage boundary](./docs/firefox-limitations.md) | What the merge-blocking Firefox lane proves, what it cannot prove, and how to triage failures |
| [Design tokens](./docs/design-tokens.md) | Visual language, structural colors, state colors, and clipped geometry |
+| [Changelog](./CHANGELOG.md) | Public release history |
| [Contributing guide](./CONTRIBUTING.md) | Contribution rules that preserve repo scope |
| [Support policy](./SUPPORT.md) | Question paths, vulnerability reporting, and funding posture |
| [Code of conduct](./CODE_OF_CONDUCT.md) | Expected project conduct |
@@ -267,6 +304,8 @@ If you want to contribute, stay inside the operating boundary.
See [CONTRIBUTING.md](./CONTRIBUTING.md).
-## License
+## License and citation
+
+MIT License. Copyright © Bradley Saucier. See [LICENSE](./LICENSE).
-See [LICENSE](./LICENSE).
+If you reference OpsNormal in research, operations, or published work, cite the software using [CITATION.cff](./CITATION.cff).