diff --git a/README.md b/README.md
index 10d8b2e..6d7abee 100644
--- a/README.md
+++ b/README.md
@@ -22,7 +22,7 @@ Render order (top → bottom): **info · prayers · money · zai (one row per wi
| **prayers** | All five prayers with wall times, from [aladhan](https://api.aladhan.com) (cached per local day, stale-marker on degradation). Past prayers get a dim `✓`; the next prayer is green with a countdown on its segment only — `Fajr 04:15 (7h 03m)`. |
| **money** | API spend + token volume per window: `REPO $68.36 (1.3B)` (all-time for the current project) · `DAY` (since 00:00 local) · `7DAY` / `30DAY` (rolling, hour-aligned). Token volumes are dim, from the same sessions scan. |
| **zai** | One row per quota window — ` zai 5hrs …` / ` zai 7DAY …` — each `LABEL usage%/elapsed% (pace · reset · absolute)`, e.g. `5hrs 16%/26% (30m under · 3h 42m · Mon Oct 12 00:54)` / `7DAY 33%/32% (1h 41m over · 4d 19h · Fri Oct 16 16:12)`. **Provider-gated**: renders only while the active model's provider is `zai` (or the provider is unreadable); vanishes entirely on other providers. |
-| **versions** | ` omp 18.11.0 · sl 0.8.4 · tern 0.7.2` — host from one `--version` spawn of the **running omp binary** (`process.execPath`, so it is install-agnostic (brew/npm/curl/source) and correct even for sessions resumed across an upgrade); plugin from its own package.json; tern from the `TERM_PROGRAM`/`TERM_PROGRAM_VERSION` env the [Tern terminal](https://stencil.so) sets — **Tern-gated**: strict env match, segment omitted outside Tern or when the version is unknown. Omitted entirely when no version is known — never a placeholder. |
+| **versions** | ` omp 18.12.1 · sl 0.8.5 · tern 0.7.2` — host from one `--version` spawn of the **running omp binary** (`process.execPath`, so it is install-agnostic (brew/npm/curl/source) and correct even for sessions resumed across an upgrade); plugin from its own package.json; tern from the `TERM_PROGRAM`/`TERM_PROGRAM_VERSION` env the [Tern terminal](https://stencil.so) sets — **Tern-gated**: strict env match, segment omitted outside Tern or when the version is unknown. Omitted entirely when no version is known — never a placeholder. |
**Pace** — `window × (usage% − elapsed%)/100` — renders `1h 36m over` (orange: burning faster than the clock, quota exhausts early by that much) or `30m under` (green: behind the clock). Percent heat: accent < 70%, warning ≥ 70%, error ≥ 90% — raw, so over-quota stays error-red while display caps at `100%+`.
diff --git a/assets/hero.svg b/assets/hero.svg
index ab2e353..765643d 100644
--- a/assets/hero.svg
+++ b/assets/hero.svg
@@ -40,7 +40,7 @@
zai 7DAY 33%/31% (3h 22m over · 4d 19h · Fri Oct 16 03:45)
- omp 18.11.0 · sl 0.8.4 · tern 0.7.2
+ omp 18.12.1 · sl 0.8.5 · tern 0.7.2
omp native statusline closes the block — placement tracked upstream (oh-my-pi #11100)
diff --git a/docs/COMPATIBILITY.md b/docs/COMPATIBILITY.md
index 2759c08..7c22888 100644
--- a/docs/COMPATIBILITY.md
+++ b/docs/COMPATIBILITY.md
@@ -41,3 +41,14 @@ Per-run authoritative record, created on first use per `.omp/commands/compat-upd
- **Render sim (formatter-level)**: ✓ all line families exact-equality-asserted against suite-approved strings (zai 5hrs under-pace, prayer, info, versions ×3 contract shapes incl. target probe `versionLine({omp:"18.11.0", sl:"0.8.4"})` + tern variant, money, paceText, heat edges) — throwaway `/tmp` script mirroring the `test/lines.test.ts` stub-theme pattern, run under node v26.10.0.
- **Verdict**: **COMPATIBLE** → docs-only **patch** release 0.8.4. Version depictions synced in one pass: README feature-table row + `assets/hero.svg` versions tspan → `omp 18.11.0 · sl 0.8.4 · tern 0.7.2` (README `/sl` sample and `assets/dataflow.svg` carry no numeric version depiction). No layout change; `src/versions.ts` comment unchanged (#15680 stamps session entries, not the `--version`-spawn mechanism).
- **Ship**: branch `chore/omp-18.11.0-compat` → PR to main → tag `v0.8.4` → CI publish → npm propagation probes → `omp plugin install --force` → live tmux render check (isolated socket).
+
+## omp 18.12.1 (2026-10-18)
+
+- **Target**: omp v18.12.1; running binary (Tern-managed, `~/Library/Application Support/Tern/omp/versions/18.12.1`) already 18.12.1 at run time. Baseline: 18.11.0 (v0.8.4).
+- **Research span**: v18.11.1 + v18.11.2 + v18.11.3 + v18.12.0 + v18.12.1, both sources (GitHub release bodies via `gh api`, changelog embedded in the running 18.12.1 binary — target sections identical).
+- **Findings**: 18.11.1 — additive `ctx.ui.getEditorComponent()` (editor-wrapping; unused by this plugin), standalone-binary crash fix for extensions that clear `require.cache` (this one doesn't). 18.11.2 — breaking `resolveGatewayApiKey`/`buildGatewayApiKeyResolver` signature change in `@oh-my-pi/pi-ai/auth-gateway` (never imported), `memory.save` entries stored as `stated` (unused API), scrollback fix #15820 for status widgets staying taller after a turn (host-side improvement for this widget's `setWidget` class), Mnemopi truncated-trailing-JSONL counting fix #14582 (reader-side; session-JSONL schema untouched). 18.11.3 — breaking extension `ui.approve()` host contract (`"once"/"session"/"deny"` instead of a boolean; this plugin never calls `approve` — grep-verified), auth-gateway SSE keepalive. 18.12.0 — breaking env swap `PI_CODEX_ZSTD`→`PI_REQUEST_COMPRESSION` (request-body compression, unrelated), breaking `encodeSixel` 4th arg + `FindStats.errors` split (unused), additive native-statusline option `statusLine.segmentOptions.pi.showProfile` (omp's own statusline segments, not extension `setWidget` widgets — no interaction). 18.12.1 — breaking eval `display()` removal + pi-tui `numberedCode`/`readContentCode`/`nativeDiff` path-vs-language (compile-time-unreachable: zero `@oh-my-pi/*` imports), tmux Kitty-passthrough image fallback, pi-natives grammar memory-leak fix, proxy compression-resend fix.
+- **Surface**: **UNCHANGED** — no `ctx.ui.setWidget/setStatus/notify`, `ctx.models.current().provider`, `ctx.modelRegistry.getApiKeyForProvider`, `ctx.sessionManager.getSessionName`, `ctx.setInterval`, `session_start`/`model_select`, theme `{fg, sessionAccentInputs}`, or `src/money.ts` JSONL-field change. All four in-span breaking items land in subsystems this plugin never imports.
+- **Gates**: `pnpm typecheck` ✓; `pnpm test:run` 62/62 ✓, 0 fail.
+- **Render sim (formatter-level)**: ✓ 20/20 checks — all line families exact-equality-asserted against suite-approved strings (info, prayer, zai full-row + heat bands + capped `100%+` + both-windows + empty, versions ×5 contract shapes incl. target probe `versionLine({omp:"18.12.1", sl:"0.8.5"})`, money, paceText, heat edges, formatResetAbs/formatGregorian/formatWeekday vectors) — throwaway `/tmp` script mirroring the `test/lines.test.ts` stub-theme pattern.
+- **Verdict**: **COMPATIBLE** → docs-only **patch** release 0.8.5. Version depictions synced in one pass: README feature-table row + `assets/hero.svg` versions tspan → `omp 18.12.1 · sl 0.8.5 · tern 0.7.2` (README `/sl` sample and `assets/dataflow.svg` carry no numeric version depiction). No layout change; `src/versions.ts` comment unchanged (`--version`-spawn mechanism untouched in 18.11.x/18.12.x).
+- **Ship**: branch `chore/omp-18.12.1-compat` → PR to main → tag `v0.8.5` → CI publish → npm propagation probes → `omp plugin install --force` → live tmux render check (isolated socket).
diff --git a/package.json b/package.json
index 7194305..c09aaf2 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@getpipher/omp-statusline",
- "version": "0.8.4",
+ "version": "0.8.5",
"description": "Six-line omp statusline widget: hijri clock, prayer times, API-spend ledger (REPO/DAY/7DAY/30DAY, subagent-inclusive), per-window zai coding-plan quota rows (provider-gated), and an omp/sl/tern version row.",
"keywords": [
"pi-package",