<!-- Exploration-leg final report, read-only sweep of ~/lane-worktrees/hands-flagship pinned at trunk f669b097f, 2026-08-14, engine: sonnet (Explore). Banked verbatim as census receipt. -->

## Class-universe census — machinery at pin `f669b097f` (mvahpets.com truth book, `/Users/robertsanchez/lane-worktrees/hands-flagship`)

**1. FACTS (phone/email/address/hours values) — EXISTS.**
`npm run edit:fact -- <factId> <newValue> [--dry-run] [--sweep]` (`scripts/edit-cli.ts:1393-1394`, sweep dispatch `:1864-1908`). Single write door `writeFactValueIn` (`scripts/lib/fact-value-writer.ts:467`) — re-reads stored value/type, requires a `FactNature` statement, runs `assertNonDestructiveReplacement` (destructive-blank-rail) + Change-Safety Guard, then commits + updates anchor records atomically. `edit:fact --sweep` → `runSweep` (`scripts/lib/edit-sweep.ts:435`) splits holders into `exact` (auto-applied atomically) vs `embedded` (named candidates, never auto-written). `scripts/guard/genome-fact-writer.ts:147` is a second, git-lineage-writing lane (`writeGenomeFact`) that funnels through the same blank-rail invariant — documented as a separate lane, not a competing writer.

**2. COPY/TEXT (headlines, body wording) — EXISTS.**
`EditResolution` union (`scripts/lib/edit-resolution.ts:114-241`) names the decision space exactly: `edit` / `sweep` / `bind-then-edit` / `bind-all-then-sweep` / `claim-edit` / `ask` / `refuse` / `needs-human` / `facts`. `edit:headline` (`scripts/edit-cli.ts:3795-3869`, `cmdCarrierGroup`) resolves a "carrier group" of sibling text facts composing one visual block via `scripts/il-edit/carrier-group.ts` (block-boundary law, block tags at `:42`), then sends explicit replacements through the same `edit:fact` door. `bind.ts:runBind` (`scripts/il-edit/ops/bind.ts:781`) turns an unbound visible span into an editable `generic-text-v1` fact (or `structured-data-v1` when the byte position is explicitly a JSON-LD span, `:707-708`), byte-neutral until the paired edit applies.

**3. STRUCTURE (add/remove elements, list items) — PARTIAL, and narrower than "structure" sounds.**
Two distinct mechanisms exist, both text-only, no markup authoring: (a) `insert-text.ts:runInsert` adds plain prose ADJACENT to an existing anchor via a zero-width splice (`scripts/il-edit/ops/insert-text.ts:1-9`), carrier `plain-prose-v1`; (b) `list-item-shape.ts:deriveListItemShapeRuling` (`scripts/editability/list-item-shape.ts:32`) lets that same insert mint a new `<li>` matching an existing sibling's shape inside an EXISTING `<ul>/<ol>` (proven by `scripts/list-item-insert.fixture.ts:1-16`). Real markup authoring (`<a href>`, a new `<ul>`, a new section) is explicitly refused by name, `BLOCKED_INSERT_MARKUP` (`scripts/il-edit/ops/insert-text.ts:512-521`: "Adding markup is real design work and it is not built yet"). `remove-inserted-text.ts` is the exact inverse, fenced to zero-width operator-added anchors only (`scripts/il-edit/ops/remove-inserted-text.ts:15-20`). Separately, "STRUCTURE VERBS" (`scripts/structure-mint.fixture.ts:1`) is a different name for `mint-page`/`unmint-page` (whole-page creation, class 10) — `runGuardOnStructureOp` is called ONLY from those two ops (`scripts/guard/change-safety-guard.ts:5224`, callers at `scripts/il-edit/ops/mint-page.ts:1047` and `unmint-page.ts:209`), confirming insert-text is a separate, narrower lane.

**4. IMAGES/MEDIA — PARTIAL (photos only).**
`edit:image` (`scripts/il-edit/ops/image.ts`) is a like-for-like swap and hard-refuses any fact whose `type !== "image-ref"` (`:167-168`); 1155 `image-ref` facts exist in `facts/`. `edit:logo` (`scripts/il-edit/ops/logo.ts:173-176`) is narrower still — scoped to the `role === "business-logo-url"` claim only, via `claimsForBook`/`planClaimEdit`. Both route bytes through `ingestImage` (`scripts/il-edit/ops/ingest-image.ts`), raster-only (`.png/.gif/.webp`/jpeg sniff at `:130-146`, 25MB cap `:39`), which writes through `writeAttributedImageResource` (`scripts/guard/genome-fact-writer.ts:354`). `media:mint` = `scripts/generate-media-anchors.ts` — a CAPTURE-time miner for video/embed anchors, not a teammate edit verb. `video-ref` (13 facts) and `embed-ref` (2 facts) types exist and are captured/observed, but grep confirms **no edit verb writes them** — no `edit:video`/`edit:embed` exists anywhere in `edit-cli.ts`. New (never-before-anchored) images have no mint path either — `createAttributedFactWithAnchor` exists (`scripts/guard/genome-fact-writer.ts:493`) but is called from nowhere outside its own file and `fact-value-writer.ts`'s comment.

**5. HOURS special-case — EXISTS (display-costume layer only).**
`scripts/editability/hours-display.ts` (58 lines total) composes two display formats — `hours-hmm-meridiem`, `hours-bare-meridiem` — from a canonical 24h `HH:MM` value (`:5-8, 35-47`), and reverse-matches a rendered string to its format (`:49-58`). This is purely a byte-costume translator sitting on top of ordinary `opening-hours-opens`/`opening-hours-closes` facts (class 1); the actual value edit still goes through `edit:fact`.

**6. STYLING/DESIGN — EXISTS, but bounded (B6).**
`DESIGN_TOKEN_TYPES_REGISTRY` (`scripts/design-token-types.ts:250-330`) registers exactly 4 types — `design-color`, `design-font-family`, `design-font-size`, `design-spacing` — each with a value predicate, canonical fold, allowed CSS properties, and risk tier (color/font-family = advisory; font-size/spacing = gate, reflow-prone). Facts present: 3 `design-color-*`, 2 `design-font-family-*`, 2 `design-font-size-*`, 10 `design-spacing-*` (`facts/design-*.yaml`). Edited via plain `edit:fact` (no dedicated verb) — the registry is consumed by `scripts/guard/change-safety-guard.ts`. Bound explicitly by B6 (`docs/specs/bounds-ledger-registry.md:136`, `docs/specs/bounds-rulings/B6-styling-whitespace.md:3-4`): "styling hooks/class names/page plumbing change by rebuilding the page, never through the copy lane" — CSS class names/selectors are out of the edit surface's reach.

**7. NAVIGATION (menu items, links) — PARTIAL.**
No dedicated nav verb, no `nav-link`/`menu-item` fact type. Nav-menu TEXT is reachable via ordinary bind-then-edit: `"chrome-nav"` is a Step-1-miner pre-binding exclusion, not a permission boundary — `scripts/editability/absence-ledger.ts:127` + `:111-119` ("the edit lane binds this text on demand and then changes it"; `bind.ts` "refuses none of them"). But an `href` is NOT in `CONTENT_ATTR_ALLOWLIST` (only `alt`@img and `title`@a/img/abbr, `scripts/generate-generic-anchors.ts:169-172`) — it is `structural-attribute`, mapped to a `page-plumbing` refusal (`scripts/lib/edit-resolution.ts:679`). So: a teammate can reword an existing nav link's label; **retargeting the href or adding/removing a nav item is not demonstrated anywhere** (no fixture/test exercises inserting a new `<li>` into a `<nav><ul>`, though `list-item-shape.ts` is generic enough it isn't explicitly fenced against it either). `scripts/editability/region-map.ts` and `scripts/genie/classify-shared-region.ts` are unrelated to nav editing — the former is frozen/composed byte-region bookkeeping, the latter is the Class-A/Class-B shared-template classifier (feeds class 13) that happens to use `"nav"` as one of its 4 qualifying structural slots (`scripts/genie/classify-shared-region.ts:43-48`).

**8. FORMS — ABSENT (B3 wall confirmed).**
`il-forms/231554896289473/` is a captured static-resource mirror of one JotForm embed (JS/CSS/fonts/SVGs) — grep of `facts/*.yaml` and `anchors/*.json` for that widget ID returns nothing; it carries zero fact/anchor linkage. `THIRD_PARTY_TAGS = ["iframe","object","embed"]` (`scripts/find-facts.ts:664`) are explicitly walled ("the interior of an `<iframe>`... is served by somebody else... we do not own those bytes," `:658-661`), reified as `PortalPrincipalAbsenceClaim` (`scripts/find-facts.ts:150-156`). Ledger confirms this is a **wall, not a bound**: B3 (`docs/specs/bounds-ledger-registry.md:142`) — "the refusal cannot fire — all 188 third-party regions carry zero interior bytes, so a teammate asking about a form question they can *see* gets 'found nothing.'" No form-field edit machinery exists anywhere in `scripts/`.

**9. REDIRECTS/URLS — ABSENT (teammate-facing); EXISTS (factory-only, read-only to edit lane).**
`scripts/lib/redirect-record.ts:1-8,27-32`: `RedirectObservation.owner` is hardcoded `"compiler"` — redirects are factory-captured observations written to `serving/_redirects`, never teammate-authored. Callers are all producer/CI (`scripts/produce.ts`, `scripts/lib/produce-serving-ledgers.ts`, `scripts/video-redirects.fixture.ts`) — none in `edit-cli.ts`. `mint-page.ts` only *reads* `redirect_dispositions` defensively, refusing to mint a page at a route that already redirects elsewhere (`scripts/il-edit/ops/mint-page.ts:222-228`); it never writes one. `scripts/lib/url-map-scope.ts` (1752 lines) is entirely capture/produce-time URL-rewriting machinery, not an edit surface. Grep for "rename"/slug-rename across `edit-cli.ts` and `il-edit/ops/` returns nothing — **no verb creates a redirect or renames a page slug.**

**10. NEW CONTENT (new page) — EXISTS, confirmed inputs.**
`mint-page.ts` (`scripts/il-edit/ops/mint-page.ts:1-28`) is a pure verifier/writer: the "creating intelligence" (external to this file) must hand it `MintRequest` (`:105-118`) = `principalBytes`/`principalPath` (the full new-page HTML) + `compositionDocument`/`compositionPath` (a word-level span-attribution ledger — copied-span digests + per-span authorship) + `actorId`/`actorKind`/`ask` (provenance-only, never read for meaning, M15(a)) + optional `slug` (else derived from the principal's own `<title>`/`<h1>`, never from `ask`, `:168-174`). Verified by `checkPartition`/`checkCopiedSpans`/`checkAuthoredAttribution`/`checkBornCovered` (`scripts/il-edit/mint-record.ts`, exercised in `scripts/structure-mint.fixture.ts:5-16`). `unmint-page.ts` is the exact inverse, fenced to pages carrying a `mint/<slug>.json` only (`scripts/il-edit/ops/unmint-page.ts:8-13`). No `mint/` directory exists yet at this pin — 187 pages, all genesis-captured, zero minted.

**11. DELETIONS — PARTIAL/mostly ABSENT.**
Value-level blanking is a hard, explicit refusal: `assertNonDestructiveReplacement` (`scripts/lib/destructive-blank-rail.ts:154-163`) — "Clearing the rendered text WITHOUT emptying the business record is a separate operation this compiler does not have yet, so there is no supported way to blank this fact today." Structural deletion is narrowly fenced to two cases only: operator-added zero-width inserts (`remove-inserted-text.ts`, class 3) and self-minted pages (`unmint-page.ts`, class 10) — captured/genesis content can reach neither. `scripts/lib/link-removal.ts` defines a full carrier (`structural-link-v1`/`link-removal-v1`) for stripping a dead `<a>` wrapper while preserving inner text, consumed by the projector (`scripts/editability/render-anchor-bytes.ts:255`) and guard (`scripts/guard/change-safety-guard.ts:301`) — **but its own docstring's calling op, `scripts/il-edit/ops/remove-link.ts`, does not exist at this pin**, nor does `scripts/belt-a-manifest-readers.ts`; no `edit-cli.ts` verb calls it; no fact or anchor in this book uses the carrier. Verdict: designed and half-wired, but currently uncallable — dead machinery, not a live capability.

**12. METADATA/SEO — EXISTS.**
Confirmed fact types in `facts/*.yaml`: `page-title`, `meta-description`, `og-title`, `og-description`, `og-image-url`, `og-url`, `twitter-title`, `twitter-description`, `twitter-image-url`, `social-same-as` — all ordinary facts, edited via `edit:fact` (or bind-then-edit if unbound). `META_DESCRIPTION_NAMES`/`isOgTextProperty` gate which `<meta>` fields the miner admits as content (`scripts/generate-generic-anchors.ts:175-181`; `og:image`/`og:url` are deliberately excluded as structural, only text properties admitted). `scripts/lib/seo-social-meta-absolute.ts` is a separate PRODUCE-time transform (absolutizes `og:url`/`og:image`/canonical at deploy origin, `:1-37`), not a teammate edit op. Structured-data (JSON-LD) mirror copies are guarded, not silently left stale: a visible-text edit that would desync a JSON-LD mirror refuses as `"structured-data-mirror"` (`scripts/lib/edit-resolution.ts:1986-1993`, `82`) unless it resolves as a `claim-edit`, which moves both copies together in one diff (`:1976-1980`).

**13. MULTI-PAGE CASCADE — EXISTS via two distinct mechanisms; carrier-group is NOT one of them.**
(a) `edit:fact --sweep` (`scripts/lib/edit-sweep.ts`, class 1) is the book-wide rename cascade — resolves every fact holding the exact old value across the WHOLE book as one atomic diff. (b) `edit:join` (`scripts/il-edit/ops/join.ts:1`: "gather a value's occurrences, stage one human ruling, then apply that ruling in one batch") consolidates previously-distinct occurrences across the book. (c) `scripts/genie/classify-shared-region.ts:1-31` (Class-A/Class-B) explains WHY a single `edit:fact` on one fact often already cascades to all pages for free: a value in a qualifying slot (footer/header/nav/address) that's byte-identical and unanimous across every page carrying it is "Class-A" — one anchor set, already shared. `scripts/il-edit/carrier-group.ts` is a red herring for this class — it groups sibling facts composing ONE visual block on a SINGLE page (feeds `edit:headline`, class 2), not a cross-page mechanism. `scripts/il-edit/neighborhood-edit.ts` is the reader-decision seat for ambiguous multi-fact carrier groups (also single-block-scoped), routing only explicit `replace` decisions to `cmdFactEdit` (`:11-15`).