# Integrity

For a drag-and-drop check in the browser, use the [verify page](/verify). Viewer banners come from the published `k2f/public/contracts/banners.json` (generated from the engine).

## Viewer Banners

- `SIGNED`
- `UNSIGNED`
- `SIGNED_BUT_BROKEN`
- `BROKEN_INTEGRITY`
- `UNLOCKED`

## Viewer banners

Viewers must surface integrity status derived from `IntegrityStatus`. The banner **code** is always available via `banner()` / `k2f-open`; default UI uses **tiered visibility** (like PDF viewers):

| Banner | When | Default UI |
|--------|------|------------|
| `SIGNED` | Valid signature and hash chain | Compact positive strip |
| `UNSIGNED` | Self-consistent, unsigned | Hidden (quiet read) |
| `SIGNED_BUT_BROKEN` | Signature file invalid or tampered | Prominent warning |
| `BROKEN_INTEGRITY` | Content, appearance, or font failure | Prominent warning |
| `UNLOCKED` | Package not compiled | Compact draft strip |

Embedders may pass `banner: "full"` for the legacy verbose strip on every state, or `banner: "off"` / `no-banner` to hide chrome entirely. Broken states must never be silently treated as signed.

`BROKEN_INTEGRITY` and `SIGNED_BUT_BROKEN` must **not** be treated as signed.

## Integrity verification

`k2f verify` and `inspect_package` return status codes:

| Code | Meaning |
|------|---------|
| `VALID` | Lock matches semantic content, theme, fonts, and the **reader's** engine identity |
| `UNSIGNED` | Self-consistent unsigned package (hash `VALID` or `ENGINE_MISMATCH`) |
| `SIGNED` | Self-consistent package and valid Ed25519 signature |
| `SIGNED_BUT_BROKEN` | Signature present but hash or crypto check failed |
| `UNLOCKED` | No `document.K2F.lock` |
| `CONTENT_CHANGED` | Semantic tree changed since lock |
| `APPEARANCE_CHANGED` | Theme, fonts, page config, or unbound engine identity changed since lock |
| `ENGINE_MISMATCH` | Hash chain matches the lock's recorded engine; reader's `engine_version` / `engine_commit_sha` differs |
| `FONT_MISSING` | Required embedded fonts absent |

Additional package errors: `SCHEMA_INVALID`, `NODE_ID`, `UNEXPECTED_PATH`, `UNKNOWN_PAINT_OP`, `PDF_IS_NOT_A_SOURCE`, `IMAGE_SIZE`, `SVG_TEXT`.

In-browser check: [Verify](https://k2f.dev/verify). Banner rules: [Integrity](https://k2f.dev/integrity).

## Verify codes

From the published `k2f/public/contracts/verify-codes.json`.

- `VALID`
- `UNLOCKED`
- `UNSIGNED`
- `SIGNED`
- `SIGNED_BUT_BROKEN`
- `CONTENT_CHANGED`
- `APPEARANCE_CHANGED`
- `ENGINE_MISMATCH`
- `FONT_MISSING`
- `SCHEMA_INVALID`
- `NODE_ID`
- `UNEXPECTED_PATH`
- `UNKNOWN_PAINT_OP`
- `PDF_IS_NOT_A_SOURCE`
- `IMAGE_SIZE`
- `SVG_TEXT`
