Files
command-center/omp-docs/core/snapcompact.md
T
Frank ed3a43bff1 docs(core): snapcompact audit — measured shape/recall table, frank-archon image-count budget, 85% trigger law
Live probe against frank-archon (212,916-char archive, 8 planted facts):
auto shape 8on22-bw reads back 8/8 recall at 47% of raw-text billed
tokens; both denser grids drop characters. Lands the docs for the paired
live-config changes (thresholdPercent 95->85, imageCountBudget 16) and
records the catalog-only frame-pricing law (radiance ~2,400 tok/frame vs
the harness's blind 5,024 floor).

Refs #81
2026-10-27 18:37:31 -07:00

114 lines
5.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
type: concept
title: OMP Snapcompact — Bitmap-Frame Compaction
description: How snapcompact archives session history as bitmap frames, what shape frank-archon resolves to, the measured recall/billing table behind the fleet's settings, and the models.yml knobs that actually exist.
resource: https://github.com/can1357/oh-my-pi/tree/main/packages/snapcompact
tags:
- omp
- compaction
- snapcompact
- frank-archon
verified: 2026-10-27
timestamp: 2026-10-27
---
# OMP Snapcompact — Bitmap-Frame Compaction
Snapcompact is omp's automatic-maintenance method that replaces the LLM
summarizer call with a local, deterministic archival pass: discarded history is
serialized, whitespace-collapsed, and printed onto dense PNG frames of
pixel-font glyphs that a vision-capable model reads back directly. No model,
key, or network is involved, so it also serves overflow recovery. It runs only
when the current model's row declares `input` including `image`; otherwise
maintenance advances to the next method in `compaction.methodOrder`.
Fleet position (`agent/config.yml`): `methodOrder: [shake, snapcompact, soft,
handoff, remote]` — deterministic, lossless-first. Shake elides heavy blocks to
`artifact://` references before anything is archived; snapcompact then archives
what shake couldn't reclaim; the lossy LLM lanes (`soft`/`handoff`/`remote` via
frank-zealot) should never be reached while a vision endpoint is active.
## Shape resolution for the fleet
The frame shape (font grid + pitch + frame width) resolves from the **model
id** against a measured table, falling back to the **wire API family** when the
id is unmeasured:
| Matcher | Shape | Frame |
|---|---|---|
| claude (fable/mythos) | `11on16-bw` | 1932px |
| claude | `11on16-bw` | 1568px |
| gemini | `8on22-bw` | 2048px |
| gpt / codex | `8on22-bw` | 1568px |
| kimi | `8on22-bw` | 1568px |
| glm | `8on16-bw` | 1568px |
| openai-completions wire (unmeasured id) | `8on22-bw` | 1568px |
There is **no qwen matcher**: `frank-archon` (radiance, Qwen3.8 vision tower,
`openai-completions` wire) resolves via the wire fallback to `8on22-bw`
@1568px — which is 56 clean 28px token-rows for a Qwen-style ViT. `snapcompact.shape`
stays `auto`; forcing a variant would bypass the font-aware CJK escape hatch
(`silver16-bw`).
## Measured recall and billing (frank-archon, 2026-10-27)
A 212,916-char tool-traffic transcript with 8 planted unique facts was sent to
`frank-archon` four ways (probe: `@oh-my-pi/snapcompact` renderer, production
request shape, `omp` 18.12.5-era bundle):
| Leg | Frames | Billed prompt tokens | Recall |
|---|---|---|---|
| Plain text baseline | — | 63,066 | 8/8 |
| auto = `8on22-bw` | 14 | 33,533 | **8/8** |
| forced `8on16-bw` | 11 | 24,364 | 6/8 (dropped characters) |
| forced `11on16-bw` | 14 | 33,533 | 6/8 (dropped characters) |
Laws this established:
- **The default shape is the accurate one for the fleet.** The Qwen3.8 FP8
tower OCRs `8on22-bw` pixel fonts with full recall; both denser grids drop
single characters inside identifiers — matching upstream's toolbench finding
(spacing-tuned cells won everywhere; dense prose-era shapes erase line
structure).
- **Bitmap archive ≈ 47 % of the billed tokens of raw text at equal recall.**
- **True radiance billing is ~2,400 tokens/frame; the harness charges a blind
5,024 floor.** Unpriced custom endpoints get `FRAME_TOKEN_ESTIMATE` (5,024)
per frame in archive sizing, so archives plan roughly half the frames the
window actually fits. This is conservative (never overflows) and costs
recall-per-compaction.
## The knobs that exist (and the one that doesn't)
- `imageCountBudget: 16` (top-level models.yml row field, set on
`frank-archon`): the catalog never matches custom providers, so the
unknown-provider floor of **5 images per request** silently caps archives.
Radiance accepted 14 frames in one probe request; 16 leaves margin. Real
frame count stays bounded by the sizing law below.
- `imageTokenization` is **catalog-only** (compiled KDL compat rules; no
user-row key reaches the pricing path). A custom row cannot mark frames
verified or price them — until upstream prices `openai-completions` vision,
custom-endpoint archive capacity is count-bound.
- Archive sizing law: frames get **half the room left under the compaction
threshold** after system prompt, tools, and kept recent turns; the compacted
result targets ≤ 60 % of threshold, and post-compaction headroom must reach
the 80 % recovery band.
- `snapcompact.systemPrompt: none` and `snapcompact.toolResults: false` stay
off fleet-wide: imaging inline text is a token-cost lever that routes
always-loaded instructions through the OCR path — accuracy-negative.
## The 85 % trigger law
`compaction.thresholdPercent: 85` on frank-archon is load-bearing for the
max_tokens clamp documented in `agent/models.yml`:
`170,000 est × 1.03 + 16,384 ≤ 200,000`. At 95 % the clamp squeezes output to
~6 k near the trigger and the worst-case request overshoots the window, so
radiance **refuses** and compaction reroutes through the overflow-recovery
emergency path instead of the planned threshold pass.
## Follow-ups
- `frank-dragoon` / `frank-zealot` rows carry the same unpriced vision towers;
the count budget and probe apply to them but are unmeasured there.
- Re-run the probe after the next upstream snapcompact/omp release (renderer
and shape table move under us).