# snappy-os — state/index.md

Catalog of skills, libraries, scripts, wiki, and sources. The agent maintains
this file. Read it at the top of every loop alongside `program.md`. The five
invariants that govern everything below live in `state/CONSTITUTION.md` —
read that first if you haven't.

**Last updated:** 2026-05-03 · 195 skill folders on disk (snappy-talking scaffolded from skill-gap detector; openui-lang added 2026-05-01 as first-class Lang composition reference; snappy-chart + snappy-doing + snappy-enable + snappy-not-ask-try + snappy-remember + snappy-start scaffolded 2026-05-01 from skill-gap detector; email-send-tick + snappy-recover loaders rewritten to Vercel AGENTS.md format; 4 dashboards regenerated; snappy-chat-invariants added 2026-05-01) · live catalog at `https://skills.snappy.ai/_catalog.json` mirrors the subset with `tier: public`. Both the "Graduate" verb-skill and snappy-fix have been retired; "graduated" / "dormant" / "mature" / `frictions.ndjson` are all in CONSTITUTION's "Retired — do not reintroduce" list. Operator triages from `breakage-report.ndjson` and the eval ledger directly. If the count drifts, `state/lint/check.ts` flags it.

---

## Skills (195 total)

The three groupings below are by **eval mechanism**, not by quality grade. A sidecar is a packaging choice (a TypeScript module at `state/lib/<slug>.ts` or a script bundle at `state/bin/<slug>/`); plenty of prose-eval skills are equally load-bearing in production.

### Sidecar-backed (`state/bin/<slug>/` or `state/lib/<slug>.ts`)

| Skill | Eval | Sidecar |
|---|---|---|
| head-screen | auto (shape + freshness gate) | `state/bin/head-screen/server.ts` |
| image | auto (Gemini vision critic) | `state/bin/image/generate-iterate.sh` |
| content-polish | auto (`voice.checkTone()` — the thesis test) | `state/bin/content-polish/run.ts` |
| sweep | auto (shape gate) | `state/lib/sweep.ts` → `sweepAll()` |
| ship-lesson | auto (polish-gate + independent-fetch) | `state/bin/skool/upload-lesson.sh` |
| content-mine | auto (`requireCitations()` + robert-signal filter) | `state/bin/content-mine/tick.ts` |
| polish-digest | auto (shape + drift-signal telemetry) | `state/bin/polish-digest/run-cron.ts` |
| evolve | auto-shape (evolve.ndjson row-shape + kept/reverted decision) | `state/bin/evolve/run.ts` |
| brain-showcase | auto (shape gate — independent re-read of output markdown) | `state/bin/brain/showcase.ts` |
| brain-growth | auto (shape gate — core counts non-negative ints, rolling_mean_100 ∈ [0,1]∪null) | `state/bin/brain/growth.ts` |
| brain-capabilities | auto-shape (rows-written equals skills-scanned; classifier keyword-map drives verb_family) | `state/bin/brain/capabilities.ts` |
| brain-insights | auto-shape (deterministic detector — capability / pitfall / parity; monotonic cursor) | `state/bin/brain/insights.ts` |
| chat-drive | shape (lib export shape — `dispatchInChatUI`, `chatDriveAvailable`) | `state/lib/chat-drive.ts` |
| agent-recap | shape (lib export shape — `summarizeToday`, `summarizeRange`) | `state/lib/agent-recap.ts` |
| bundle-snapshot | shape (lib export shape — `snapshot` returns ContextPanel payload) | `state/lib/bundle-snapshot.ts` |
| artifacts | shape (lib export shape — `listArtifacts`, `createArtifact`; HTTP `GET/POST /artifacts`) | `state/lib/artifacts.ts` |

### Prose (auto-eval defined, sidecar pending)

| Skill | Eval |
|---|---|
| cockpit-audit | shape (10-point checklist artifact) |
| query-xano | auto (shape gate) |
| morning-brief | auto (non-empty or reason-empty) |
| ray-todo | auto (shape + non-empty-or-reason) |
| commitment-audit | auto (shape + orphan/silent-ship surface) |
| tool-scout | auto (telemetry shape) |
| ai-spend | auto (shape + total ≥ 0) |
| client-pulse | auto (shape + at-risk count) |
| dormant-ping | auto (shape + never-sent + tone-pass) |
| testimonial-ask | auto (shape + never-sent + tone-pass + cites-artifact) |
| testimonial-scan | auto (shape gate — actor `scoreTestimonial()`, auditor skill shape-check) |
| catchup | auto (shape + tone + four-signal presence) |
| bug-triage | auto (shape + clusters-unique) |
| commit-report | auto (shape — pure telemetry) |
| reconcile | auto (shape + source-presence; unmatched ≠ fail) |
| ray-update | auto (shape + polish-gate hard-chain) |
| gh-triage | auto (shape gate — actor `github.ts` fetch, auditor skill shape-check) |
| meeting-followup | auto (shape gate — key-points present, no speaker labels, recipient resolved) |
| linkedin-likes-only | auto (shape gate) |
| linkedin-post | auto (sidecar `state/bin/linkedin-post/run.ts` — voice gate → POST → URN re-GET; actor `createLinkedInPost`, auditor distinct GET) |
| linkedin-post-scraper | auto (shape gate) |
| memory-consolidation | auto (shape gate) |
| scrape-competitor-pricing-weekly | auto (shape gate) |
| skool-daily-post | auto (shape gate) |
| snappy-sync | auto (shape gate — actor `bin/cli.js`, auditor `manifest-compare.ts`) |
| snappy-recover | auto (shape gate — actor `state/bin/sync/{snapshot,restore,rollback}.sh`, auditor independent fetch) |
| snappy-statusline | auto (shape gate — render <100ms, all fields non-blank) |
| snappy-migrate | auto-shape (lints + dogfood probe; PID-self-correcting via AGENTS.md Known Pitfalls) |
| ui-components | auto-shape (prose-only authoring guide for snappy-chat tool/component pairs — TOOL_CALL_START/ARGS/END contract + 5 canonical shapes: DispatchCard, ProgressList, WorkingFolder, ContextPanel, FeedbackForm) |
| dogfood-loop | auto-shape (QA-and-fix cadence for snappy-chat — actor pushes intent via `chat-drive`, auditor reads post-shot via `desktop`, deliverable is `/tmp/dogfood-loop-report.md`) |
| frontend-dogfood | auto-shape (5 UX journeys: welcome → starter → response → save → navigate; actor `chat-drive`, auditor screenshot via openclaw bridge) |
| dashboard-builder | auto-shape (4 templates: BASIC/PIPELINE/SYSTEM/CHANNEL; `detectSkillType()` by frontmatter; `Query("get_evals")` for KPIs; atomic temp+rename write) |
| prompt-tuner | auto-shape (frontmatter + AGENTS.md presence gate) |
| slack | auto-shape (read-side Slack — channel list / DMs / mentions via `state/lib/slack.ts`; `Query("get_inbox_slack")` dashboard) |
| chat-edit | auto-shape (patch existing thread message via `POST /chat-edit` on head-screen server; endpoint pending wire-up) |
| chat-schedule | auto-shape (one-shot future dispatch via `POST /chat-schedule`; in-memory schedule queue; endpoint pending wire-up) |
| chat-recall | auto-shape (restore prior thread by threadId via `POST /chat-recall`; reads `dispatch-chat.ndjson`; endpoint pending wire-up) |
| openui-lang | auto-shape (first-class composition language reference — SKILL.md + AGENTS.md + prompt-fragment.md; loader carries the full Lang mental model — primitives, @builtin allowlist, Query/$variable/dot-pluck, variant pointer; companion server prompt cached at `state/config/openui-lang-prompt.txt`) |

### Manual eval

| Skill | Why |
|---|---|
| krisp-inbox | Dedup rule against ray-todo needs real data before auto eval can replace Robert review |
| snappy-chat-invariants | Reference catalog — shape eval (all four fields per invariant present); no actor function; lints that enforce each invariant are the real gate |

---

## Libraries (`state/lib/`)

| File | Purpose | Source |
|---|---|---|
| `env.ts` | Credential loader, reads `.env.cache` via symlink | kernel `snappy-settings/load.ts` |
| `log.ts` | Append-only ndjson logger + `newRunId()` | new |
| `eval.ts` | `score()` → local ndjson + optional POST to SNAPPY_EVAL_ENDPOINT; `fetchEvals()` pulls cross-machine trends | new — load-bearing |
| `head-screen.ts` | Canonical head-screen state schema + atomic read/write + freshness helpers | new |
| `http.ts` | `xanoGet/xanoPost/getJson` with bearer + retry | new |
| `voice.ts` | `checkTone()` + `requireCitations()` + `getToneGuide()` + `checkFlow()` + `FLOW_PROFILES` | kernel `snappy-positioning/api.ts` |
| `xano.ts` | Xano Metadata API. read: `listWorkspaces/listTables/describeTable/listApiGroups/findApiByName`; write: `createTable/addField/deleteField/createApiGroup/createApi/updateApi` (xanoscript push via `PUT /api/{id}`) | kernel `snappy-database/api.ts` |
| `content-engine.ts` | Raw SQL against `rb-content-engine.fly.dev` (Neon Postgres proxy — **NOT Xano**) | split from xano.ts 2026-04-16 |
| `pipeline.ts` | Orbiter enrichment QA read-only (10 fns incl edgeGaps, historyIntegrity) | kernel `snappy-pipeline/api.ts` |
| `dispatch.ts` | Cheap-labor dispatch via `pi` (haiku/sonnet/gemini/llama/qwen/deepseek) | kernel `snappy-dispatch/api.ts` |
| `sweep.ts` | Multi-channel inbox (Slack/Gmail/LinkedIn/Skool) — 741 lines | kernel `snappy-inbox-sweep/api.ts` |
| `linkedin-fetcher.ts` | LinkedIn DM reader (browser-based) | kernel |
| `skool-fetcher.ts` | Skool notification reader (browser-based) | kernel |
| `browse.ts` | agent-browser wrapper (canva re-export dropped) | kernel `snappy-browse/api.ts` |
| `email.ts` | Gmail API (service-account JWT work + OAuth personal); knowledge-graph enrichment stripped for now | kernel `snappy-email/api.ts` |
| `linkedin.ts` | LinkedIn API (posts, schedule) | kernel `snappy-linkedin/api.ts` |
| `slack.ts` | Slack API (channels, read, send) | kernel `snappy-slack/api.ts` |
| `telegram.ts` | Telegram bot | kernel `snappy-telegram/api.ts` |
| `testimonials.ts` | `getTestimonials()` + `scoreTestimonial()` rubric (content-engine SQL) | kernel `snappy-testimonials/api.ts` |
| `github.ts` | `listRepos/listPrs/getIssues/createPr/createIssue/createIssueComment` — GitHub REST, GITHUB_TOKEN | kernel `snappy-github/api.ts` |
| `krisp.ts` | Krisp headless HTTP client + meeting/action-item filters + cache read/write | kernel `snappy-krisp/api.ts` |
| `drive.ts` | Google Drive file search via service-account JWT (meeting recordings/transcripts) | kernel `snappy-ops/recipes/meeting-followup.ts` |

### Phase 0.5 port (61 libs ported mechanically from kernel)

| File | Source |
|---|---|
| `ads.ts` | kernel `snappy-ads/api.ts` |
| `ai-models.ts` | kernel `snappy-ai-models/api.ts` |
| `analytics.ts` | kernel `snappy-analytics/api.ts` |
| `api-sniffer.ts` | kernel `snappy-api-sniffer/api.ts` |
| `blog.ts` | kernel `snappy-blog/api.ts` |
| `box.ts` | kernel `snappy-box/api.ts` |
| `chain/api.ts` | kernel `snappy-chain/api.ts` (+ classify.ts, chains/) — **vendored dir** |
| `channel-contract/api.ts` | kernel `snappy-channel-contract/api.ts` (+ types.ts, verify.ts) — **vendored dir** |
| `client-orbiter.ts` | kernel `snappy-client-orbiter/api.ts` |
| `client-ray.ts` | kernel `snappy-client-ray/api.ts` |
| `client-scott.ts` | kernel `snappy-client-scott/api.ts` |
| `client-template.ts` | kernel `snappy-client-template/api.ts` |
| `client-total.ts` | kernel `snappy-client-total/api.ts` |
| `clients.ts` | kernel `snappy-clients/api.ts` |
| `community.ts` | kernel `snappy-community/api.ts` |
| `content.ts` | kernel `snappy-content/api.ts` (kernel-bug patch: stray realpathSync import) |
| `corpus.ts` | kernel `snappy-corpus/api.ts` |
| `course.ts` | kernel `snappy-course/api.ts` |
| `dashboard.ts` | kernel `snappy-dashboard/api.ts` (scaffold stub) |
| `database.ts` | kernel `snappy-database/api.ts` |
| `deploy.ts` | kernel `snappy-deploy/api.ts` |
| `desktop.ts` | kernel `snappy-desktop/api.ts` |
| `docs.ts` | kernel `snappy-docs/api.ts` |
| `dom-cartographer.ts` | kernel `snappy-dom-cartographer/api.ts` |
| `ffmpeg.ts` | kernel `snappy-ffmpeg/api.ts` |
| `freshbooks.ts` | kernel `snappy-freshbooks/api.ts` |
| `gateway.ts` | kernel `snappy-gateway/api.ts` |
| `gemini.ts` | kernel `snappy-gemini/api.ts` |
| `hooks.ts` | kernel `snappy-hooks/api.ts` |
| `imessage.ts` | kernel `snappy-imessage/api.ts` |
| `inbound.ts` | kernel `snappy-inbound/api.ts` |
| `inbox-sweep.ts` | kernel `snappy-inbox-sweep/api.ts` |
| `infra.ts` | kernel `snappy-infra/api.ts` |
| `maintenance.ts` | kernel `snappy-maintenance/api.ts` |
| `mine.ts` | kernel `snappy-mine/api.ts` |
| `notion.ts` | kernel `snappy-notion/api.ts` |
| `offer.ts` | kernel `snappy-offer/api.ts` |
| `openrouter.ts` | kernel `snappy-openrouter/api.ts` |
| `ops/api.ts` | kernel `snappy-ops/api.ts` (+ staged-action, registry, loops, recipes/) — **vendored dir** |
| `outbound.ts` | kernel `snappy-outbound/api.ts` |
| `playbook.ts` | kernel `snappy-playbook/api.ts` |
| `positioning.ts` | kernel `snappy-positioning/api.ts` |
| `post.ts` | kernel `snappy-post/api.ts` (kernel-bug patch: createPost→createLinkedInPost, sendMessage→sendSlackMessage) |
| `publish.ts` | kernel `snappy-publish/api.ts` |
| `remotion.ts` | kernel `snappy-remotion/api.ts` |
| `sales.ts` | kernel `snappy-sales/api.ts` |
| `scheduling.ts` | kernel `snappy-scheduling/api.ts` |
| `settings.ts` | kernel `snappy-settings/api.ts` (path patch: ./load.ts → ./env.ts) |
| `shell.ts` | kernel `snappy-shell/api.ts` |
| `skill.ts` | kernel `snappy-skill/api.ts` |
| `swarm.ts` | kernel `snappy-swarm/api.ts` (scaffold stub) |
| `sync.ts` | kernel `snappy-sync/api.ts` |
| `transcripts.ts` | kernel `snappy-transcripts/api.ts` |
| `update.ts` | kernel `snappy-update/api.ts` |
| `video.ts` | kernel `snappy-video/api.ts` |
| `walkthrough.ts` | kernel `snappy-walkthrough/api.ts` |
| `website.ts` | kernel `snappy-website/api.ts` |
| `whatsapp.ts` | kernel `snappy-whatsapp/api.ts` |
| `xano-dashboard.ts` | kernel `snappy-xano-dashboard/api.ts` |
| `xano-mcp.ts` | kernel `snappy-xano-mcp/api.ts` |
| `youtube.ts` | kernel `snappy-youtube/api.ts` |

---

## Executables (`state/bin/`)

| Dir / file | Purpose |
|---|---|
| `image/` | Nano Banana draft-inspect-edit loop, CDN upload, composite templates, logo contrast check |
| `head-screen/` | Local loopback status face: ctl/server/audit/launch + LaunchAgent template |
| `content-polish/run.ts` | The thesis test: checkTone → dispatch rewrite → re-check loop |
| `krisp/refresh.sh` | Daily dump of Krisp action-items + meetings via HTTP to `state/log/krisp/` |
| `action-item-draft/run.ts` | Krisp Loop closer — fetch action item + meeting → dispatch sonnet → write draft + score |
| `action-item-draft/backfill.ts` | Cold-start breaker — fires `run.ts` against top N open Krisp items in batch (concurrency 3); `--limit N`, `--dry-run` flags |
| `distill-approvals/run.ts` | Taste-loop reader — reads `approvals.ndjson`, buckets by (skill, shape), writes hints + per-day rollup |
| `distill-approvals/seed-synthetic.ts` | One-shot primer — plants 10 synthetic (draft, decision) tuples so distill emits real hints on first run; idempotent |
| `skool/` | `upload-lesson.sh`, `update-lesson.sh`, `lint-draft.sh`, `skool-auth-restore.sh` |

> **The wired Stop hook is `state/hooks/snappy-os-auto-regen.sh`.** It calls `state/regen/drain.sh` to emit briefs for both `state/log/regen-pending.txt` (loader-rewrite) and `state/log/eval-pending.txt` (run-this), then dispatches a headless `claude -p` subprocess to consume the brief. Older bin-side helpers (`state/bin/auto-regen.sh`, `state/bin/pid-drain.ts`) were deleted 2026-04-26 — the duplicate paths drifted CLAUDE.md and `bin/wire-hooks.js` against the actually-installed hook. See CLAUDE.md "How the system enforces itself" for the full loop.
| `provision-eval-endpoint.ts` | Idempotent create: `eval_rows` table + `Snappy OS ⚡` API group + endpoint shells |
| `deploy-eval-endpoint.ts` | Push `state/xano/eval/*.xs` into live Xano via Metadata API `PUT /api/{id}` (no editor) |
| `setup-eval-endpoint.ts` | One-shot onboarding: provision → deploy → contract → live (`npm run setup:eval-endpoint`) |
| `eval-server/server.ts` | Zero-dep Node reference implementation of the eval-endpoint contract; `npm run eval-server` |

---

## Lint (`state/lint/`)

| File | Purpose |
|---|---|
| `check.ts` | Structural lint: every skill has `eval:`, graduated skills reference existing sidecars, libs have no unresolved imports, no kernel-sibling paths, auto-ratio ≥ 50% |
| `rubric-shape.ts` | Analytic-rubric lint: every SKILL.md has `## Rubric` + ```yaml block with ≥3 criteria, each with `kind: deterministic\|judge` and a non-empty check. Backfill via `state/bin/skill/rubric-gen.ts` |
| `compare.ts` | End-of-port comparison harness: LoC delta, MCP ref count, mean eval score, cold-start bytes |
| `eval-endpoint-contract.ts` | Stub-server contract test for `POST /eval` + `GET /evals` (13 assertions, no network) |
| `eval-endpoint-live.ts` | Live contract probe against `SNAPPY_EVAL_ENDPOINT` — idempotency, filters, limit cap |
| `hooks-integrity.ts` | Walk `~/.claude/settings.json` + `~/.codex/hooks.json`; flag hook commands whose script is missing or non-executable, plus duplicate non-empty matchers under the same event. Exit 1 on any BROKEN. Stderr-only diagnostics — no log writes. |
| `codable-drift.ts` | Catch silent Codable decode drift between head-screen server JSON and snappy-shell Swift Codable structs. Parses `Sources/SnappyCore/DataClient.swift` + `Models/*.swift` for every `as: X.self` binding, hits the live GET endpoint at `127.0.0.1:3147`, and flags DRIFT (server keys with no Swift property — silently dropped) + MISSING (non-optional Swift properties the server doesn't ship). Recurses one level into array fields. CLI: `--swift-file <path>`, `--server-base <url>`. Exit 1 on any DRIFT/MISSING. Stderr-only — no log writes. |

---

## Recipes (`state/recipes/`)

Named hook bundles the user engages/disengages on demand. Hooks and cron
workers consult `state/engaged.json` via `state/bin/sync/is-engaged.sh`
and skip any recipe that isn't in the engaged list — safety valve.

| Recipe | Title | Default |
|---|---|---|
| `ambient-sync` | Stop pushes, SessionStart pulls — canonical stays shared | engaged |
| `pid-loop` | Low-score verbs regenerate; aggregate scores fuel quorum | engaged |
| `nightly-digest` | SessionStart shows "what changed while you were away" | disengaged |

CLI: `snappy-os recipes` · `snappy-os engage <name>` · `snappy-os disengage <name>`.

---

## Docs (`state/docs/`)

Organized by external system / role. Filenames describe what the doc is, not when it was authored.

**External systems we talk to:**

| Path | Purpose |
|---|---|
| `gateway/endpoints.md` | Cloudflare worker @ `skills.snappy.ai` — auth, catalog, sync, well-known routes |
| `gateway/selftest.md` | Manual curl probes to verify gateway after deploys touching auth |
| `xano/endpoints.md` | Xano API — POST /eval, GET /evals (the shared PID eval endpoint) |
| `xano/schema.md` | Xano table definitions, copied from `snappy-database/tables.md` |
| `runtime/hooks.md` | Per-runtime hook surfaces (Stop, SessionStart, install path) |
| `runtime/hooks-per-runtime.md` | Hook wiring matrix — claude-code / codex / openclaw / pi |
| `runtime/benchmark.md` | Per-runtime aggregate + per-pair detail |
| `runtime/gap-cursor.md`, `runtime/gap-windsurf.md` | Runtime parity gap notes |

**Internal procedures (`runbooks/`):**

| Path | Purpose |
|---|---|
| `runbooks/disaster-recovery.md` | Bucket versioning, snapshot/restore/rollback, cross-region backup |
| `runbooks/secrets-rotation.md` | DO creds, per-tenant key, Wrangler token, audit trail |
| `runbooks/cross-machine-playbook.md` | Verify cross-machine sync via tracer file + sha |
| `runbooks/bootstrap-walkthrough.md` | Joe Blow step-by-step new-machine bootstrap |
| `runbooks/initial-population.md` | Robert's machine populates DO via Worker |
| `runbooks/invite-walkthrough.md` | End-to-end new-user invite, both sides of the handshake |
| `runbooks/real-dir-migration.md` | migrate-realdirs.sh, divergence resolution policy |

**Architecture / mental-model prose (`guides/`):** pid-loop, autopilot, recipes, observability, multi-tenant, schema-versioning, sync-primitives, symlink-topology, worker-architecture, bandwidth, ci-for-sync, security, stack, business-map, brain, brain-capabilities, agent-health, scope, evolve-status.

**Frozen point-in-time reports (`audits/`):** `*-2026-04-18.md`, `bootstrap-smoke-2026-04-17.md`. Rule: filename ends in `YYYY-MM-DD` → audits.

---

## Xano source (`state/xano/`)

| File | Deployed to |
|---|---|
| `eval/post-eval.xs` | workspace 5 / group 1639 (`Snappy OS ⚡`) / api 30372 — POST /eval |
| `eval/get-evals.xs` | workspace 5 / group 1639 (`Snappy OS ⚡`) / api 30373 — GET /evals |
| `eval/eval-row.schema.json` | JSON Schema mirror of `EvalRow` — for non-TS integrators |

---

## Sources (`sources/`) — human-owned, immutable

| Path | Purpose |
|---|---|
| `positioning/voice.md` | §4a banned phrases canonical source |
| `course/kernel-drafts` | Symlink → `snappy-kernel/skills/snappy-course/data` (read-only pointer) |

---

## Logs (`state/log/`)

| File | Shape |
|---|---|
| `chain.ndjson` | `{ts, run_id, skill, action, ...}` — one line per skill action |
| `evals.ndjson` | `{ts, skill, run_id, score, primary_issue, ...}` — the thesis metric |
| `dispatches.ndjson` | `{ts, run_id, model, cost, latency, ...}` — cheap-labor audit |
| `head-screen.json` | Canonical local display state written by `state/bin/head-screen/ctl.ts` |
| `head-screen-events.ndjson` | Optional event trail for head-screen writes (`set` / `reset`) |
| `pending-eval.ndjson` | manual-eval skills log here for weekly Robert review |
| `port.ndjson` | wave checkpoints from this bootstrap |
| `lint-check.ndjson` | structural lint run history |
| `comparison-report.md` | end-of-port head-to-head kernel vs mini |

---

## Port outcome (from `state/lint/compare.ts`)

| Metric | Kernel | Mini | Delta |
|---|---|---|---|
| Total LoC (excl sources/) | 149,560 | 16,573 | **-88.9%** |
| MCP references (`mcp__`) | 117 | 0 | **-117** |
| Skill count | 19 recipes | 25 skills | +6 |
| Auto-eval ratio | N/A (no evals) | 95.8% | new layer |
| Eval mean score | N/A | 0.889 across 9 rows | new layer |

**Thesis verdict:** proven. The content-polish skill caught 4 planted
violations that the kernel's self-report shipped as clean
(run_id `faf81844-176`, Wave 2 gate). Every wave ran end-to-end from plain
shell + `npx tsx`, no hooks, no MCP.
<!-- kernel-ok: documentation of the porting process / catalog -->
