Task A — Post-Pull Gallery Spec (id 10, 2026-08-26)

**Repo state:** `/workspace/fv-module-gallery/` on `main` @ `c8b2af3`, synced with `origin/main` (verified post-C-1 pull).

**Operator directive:** "Sync the gallery at c8b2af3 and extract the real post-pull specification. ... Do not modify gallery files. Do not apply doctrine changes. Do not push anything."

**Status:** This doc is read-only output. No files were modified.

---

1. Full module inventory

1a. `cms-widgets/` — content-bound renderers (FES / v0.5.x pack shape)

**Total: 26 entries** (24 modules + `index.js` registry barrel + `theme-presets` + `tools` which are NOT modules — see §7)

| # | Dir basename | FES shape | module.json | recipe-book | src/widget.js | visual/ | Doctrinal kind |

|---|---|---|---|---|---|---|---|

| 1 | accordion | full | Y | Y | Y | Y | `gallery-original` |

| 2 | blog-post-card | partial | Y | Y | N | Y | `gallery-original` |

| 3 | blog-post-list | partial | Y | Y | N | Y | `gallery-original` |

| 4 | breadcrumb | full | Y | Y | Y | Y | `gallery-original` |

| 5 | button | full | Y | Y | Y | Y | `gallery-original` |

| 6 | carousel | full | Y | Y | Y | Y | `gallery-original` |

| 7 | contact-form | full | Y | Y | Y | Y | `gallery-original` |

| 8 | cta | full | Y | Y | Y | Y | `gallery-original` |

| 9 | cta-box | full | Y | Y | Y | Y | `gallery-original` |

| 10 | fv-recipe-book-checklist | partial (no codex/rules) | Y | partial | N | Y | FVS-chrome app-fragment, not a FES pack |

| 11 | fv-source-link | partial (no codex/rules) | Y | partial | N | Y | FVS-chrome app-fragment, not a FES pack |

| 12 | fv-theme-toggle | partial (no codex/rules) | Y | partial | N | Y | FVS-chrome app-fragment, not a FES pack |

| 13 | heading | full | Y | Y | Y | Y | `gallery-original` (canonical exemplar) |

| 14 | icon-list | full | Y | Y | Y | Y | `gallery-original` |

| 15 | image | full | Y | Y | Y | Y | `gallery-original` |

| 16 | index.js | n/a (registry barrel) | — | — | — | — | barrel: `import { headingModule } from './heading.js'` etc. |

| 17 | info-box | full | Y | Y | Y | Y | `gallery-original` |

| 18 | listing-grid | partial (no widget.js) | Y | Y | N | Y | `gallery-original` |

| 19 | menu | full | Y | N (has module-meta.json but no recipe-book) | Y | Y | `gallery-original` (anomaly — see §7) |

| 20 | paragraph | full | Y | Y | Y | Y | `gallery-original` |

| 21 | recipe-detail | partial (no widget.js) | Y | Y | N | Y | `gallery-original` |

| 22 | social-icons | full | Y | Y | Y | Y | `gallery-original` |

| 23 | testimonial | full | Y | Y | Y | Y | `gallery-original` |

| 24 | theme-presets | n/a (not a FES pack) | N | N | N | N | drop-in CSS bundle, see §7 |

| 25 | tools | n/a (not a FES pack) | N | N | N | N | tool atoms, see §7 |

| 26 | video | full | Y | Y | Y | Y | `gallery-original` |

**"Full" = has module.json + recipe-book/{recipe,codex,rules}.md + src/widget.js + visual/. "Partial" = missing one or more of those.** The 3 `fv-*` partials are not FES modules — they're FVS chrome app-fragments. The 4 partials without widget.js (blog-post-card, blog-post-list, listing-grid, recipe-detail) are presumably CMS-widget renderers delegated to the FvCMS chrome's editor system.

1b. `modules/` — top-level reusable (FVW v8.2 §17.5.7)

**Total: 30 entries**

| Family | Modules | count |

|---|---|---|

| ai-* (AI bundle sub-modules) | ai-actions, ai-adapters, ai-ambient, ai-ask, ai-credentials, ai-fragments, ai-history, ai-input, ai-mic, ai-orchestrator, ai-settings, ai-stt, ai-toast, ai-workspaces-chip | 14 |

| fv-* (FVS chrome app-fragments) | fv-pact-viewer, fv-recipe-book-checklist, fv-source-link, fv-theme-toggle | 4 |

| Other chrome / dev | anchor-system, card-constellation, cms, freshcards, lock, menu, mobile-unified-panel, navigation, pact-viewer, refresh, settings, vibechat-signals | 12 |

All 30 modules have full FES shape: module.json + module-meta.json + recipe-book/{recipe,codex,rules}.md + visual/. **None of them have src/widget.js** — they are all configuration-only exports consumed by the runtime. This is consistent with the FvW v8 doctrine ("modules-as-clusters" — the actual rendering is delegated to editors + skins).

1c. `apps/` and `bundles/`

1d. `fv-cms-vendored/` (chrome + CMS)

`fv-cms-vendored/` is the vendored FvCMS runtime (1.2.0, manifest `fv-cms-manifest.001`). Contains:

This is the FvCMS chrome + editor stack. **It is where the GOLD components live** (cms-local-loader, edge-panel, panel-manager, dev-btn-v2, dev-panel-v2 — see §6).

---

2. Gallery-pact alignment check (post-C-2 doctrine)

2a. What's in `gallery-pact/`

```

gallery-pact/

├── AI-PUBLISHING-GUIDE.md (doctrine doc)

├── CLEANUP-WORKFLOW.md (doctrine doc)

├── MIRROR-WORKFLOW.md (doctrine doc)

├── bundle-features.template.md

├── bundle-manifest.schema.json (Bundle Manifest, $id https://freshvibe.gallery/pact/bundle-manifest.schema.json)

├── facets.schema.json (Module Facets)

├── fes-vendor-mandate.md

├── fvw/

│ ├── README.md

│ ├── freshvibe-way-v8/ (49 .md files — the doctrine)

│ └── (FVW versioning)

├── fvw-versioning-rules.md

├── fes-fvw-updates/ (id 8's spec, 6 files for FES v2 + FVW v8.4)

├── module-meta.schema.json (Module Metadata, FVW v8.2)

├── registry-plan.md

├── registry.schema.json (Gallery Registry)

└── repo-safety-charter.md

```

2b. Critical: `cms-widget.schema.json` does NOT exist

Id 8's audit (2026-08-26) confirmed: **`gallery-pact/cms-widget.schema.json` is not in the repo.** The module identity schema lives in `module-meta.schema.json` and `registry.schema.json`, not a dedicated `cms-widget.schema.json`. The id regex (`^[a-z][a-z0-9-]*$`) is enforced by `module-meta.schema.json.properties.name.pattern`. There is no per-module-id pattern constraint; the name pattern is the closest equivalent.

**Implication for any prior claim (including id 10's earlier reports) that cited a `cms-widget.schema.json` with an `id` regex: that file was either deleted by id 8 in a recent commit or never existed. Either way, citing it as the source of an id-regex rule is wrong.** The actual regex is in `module-meta.schema.json`.

2c. FVW v8 doctrine M-prefix references (corrected from id 8's audit)

Id 8 said "ZERO M-prefix references" in `gallery-pact/fvw/freshvibe-way-v8/`. My audit found 5 files that contain the literal "M-" string. **All 5 are in M-prefix-as-a-word contexts, not module-id references:**

**Drift from id 8's claim:** 17.8-module-work-pipeline.md does contain 9 M-prefix module names as historical references. Id 8's "ZERO" claim missed this. Per the C-2 doctrine (dual-layer, M-prefix is runtime-only and shouldn't appear in doctrine), this is a **doctrinal drift** that should be cleaned up when id 8 writes `m-prefix-convention.md`. **Until then, the doctrine file is inconsistent with the dual-layer rule.**

2d. Doctrinal source for the M-prefix convention

The C-2 doctrine (id 8's reply, 2026-08-26) states: schema IDs lowercase, runtime IDs M-prefixed, doc at `gallery-pact/m-prefix-convention.md` (id 8 to write). The convention does not yet exist in the gallery as of `c8b2af3`. **When id 8 writes it, the 9 M-prefix references in `17.8-module-work-pipeline.md` will need to be either updated or annotated as historical.**

---

3. M-prefix impact analysis (post-C-2 doctrine)

3a. Distribution by location

| Location | Total | M-prefixed | Lowercase | Note |

|---|---|---|---|---|

| `cms-widgets/*/module.json` (id field) | 23 | 0 | 23 | id 8 audit "0/59" — there are only 23 with module.json, the "59" must be a different denominator (likely including feed entries or apps) |

| `cms-widgets/*/src/widget.js` (id export) | 16 | **16** | 0 | **DRIFT FROM id 8's claim of 11/16 — see §3b** |

| `feed/registry.json` (modules[]) | 59 | 0 | 59 | confirmed |

| `cms-widgets/*/visual/` (dir basename) | 23 | 0 | 23 | id 8 said "0/68" — 68 likely includes modules/ too |

| `gallery-pact/fvw/.../*.md` (doctrine) | 49 | 5 files contain M- (mixed contexts, see §2c) | — | **drift: 1 doctrinal file references 9 historical M-prefix module names** |

| `scripts/f11-visual-capture.mjs` | — | 0 (no `M-` string) | — | confirmed |

3b. Drift: id 8 said 11/16 widget.js M-prefixed, audit shows 16/16

Id 8's 2026-08-26 C-2 doctrine reply stated:

> "widget.js 11/16 cms-widgets with M- (M-accordion, M-breadcrumb, M-button, M-carousel, M-cta, M-heading, M-image, M-menu, M-paragraph, M-testimonial, M-video)

> 5/16 without (contact-form, cta-box, icon-list, info-box, social-icons)"

My audit shows 16/16 cms-widgets with widget.js have M-prefix. The 5 id 8 listed as "without" (contact-form, cta-box, icon-list, info-box, social-icons) all have M-prefix per my regex check:

**Possible explanations for the drift:**

**Operator decision needed:** confirm with id 8 before writing the convention doc. If 16/16 is the real state, the convention covers the entire widget.js surface, not 11/16. If 11/16 was correct at a different commit, the convention scope is smaller.

---

4. Feed/registry state (lowercase enforcement)

```

feed/registry.json: 59 modules, 0/59 with M- (confirmed)

feed/widget/: 49 entries (module renderers)

feed/recipe/: 49 entries (recipe-book indexes)

feed/apps/: app-pointers

feed/bundle/: bundle manifest

feed/category_index, facet_index, dependency_graph, dependents_graph, forks, deprecated_modules, fvw_doctrine_refs, fvw_version, generated_at, generated_by, module_kind_index, tags_index, tier_index, variant_index, stats, version

```

---

5. Widget.js M-prefix state (cms-widgets)

Full list of widget.js id exports (post-C-2 doctrine says these are runtime-only, FvCMS reads them at runtime, F11 doesn't):

```

accordion → M-accordion

breadcrumb → M-breadcrumb

button → M-button

carousel → M-carousel

contact-form → M-contact-form

cta → M-cta

cta-box → M-cta-box

heading → M-heading

icon-list → M-icon-list

image → M-image

info-box → M-info-box

menu → M-menu

paragraph → M-paragraph

social-icons → M-social-icons

testimonial → M-testimonial

video → M-video

```

**16 modules total**, all 16 with M- prefix. Id 8 said 11/16 — **drift, see §3b**.

`widget.js` is a thin data export (2-3KB). Per the FvW §10 modules-as-clusters doctrine, it provides `schema` + `defaultConfig` + `ui` + `editor` reference + `variants`. **It is NOT a renderer.** The chrome (FvCMS) reads it at runtime to wire the inspector → editor → live DOM update.

---

6. Crosswalk between gallery modules and GOLD inventory

6a. What GOLD actually is

Per `/workspace/GOLD-BASELINE/README.md`:

6b. GOLD is an Oscar rebuild, not a module catalog

**GOLD does not map 1:1 to FES module packs.** GOLD is the result of running 6 pipeline stages on a specific WordPress+Elementor site (oscarstreeacademy.org.uk). The output is a 425-file dist with a chrome (panel-manager + edge-panel + dev-btn + dev-panel + cms-local), not a 68-module FES universe.

6c. Crosswalk table (GOLD components → gallery)

| GOLD component | Description | Gallery location |

|---|---|---|

| `dist/runtime/cms-local-loader.js` | chrome bootstrap | `fv-cms-vendored/` (vendored FvCMS, 1.2.0) |

| `dist/runtime/edge-panel/` | edge panel | `modules/mobile-unified-panel/` (closest match, not identical) |

| `dist/app-fragments/fvcms-panel-manager/` | panel manager | **not in gallery** — lives in fv-cms-vendored/app-fragments/admin-* |

| `dist/app-fragments/fvcms-dev-btn-v2/` | dev button | **not in gallery** — fv-cms-vendored/ |

| `dist/app-fragments/fvcms-dev-panel-v2/` | dev panel | **not in gallery** — fv-cms-vendored/ |

| `dist/_loader.template.html` | chrome loader | `B1-_loader.template.html` in GOLD-BASELINE/ + 281ecb4's `src/chrome_loader.template.html` |

| `dist/cms-local/` | sample CMS module | `modules/cms/` (closest match, not identical) |

**The GOLD chrome components are NOT FES module packs.** They are FvCMS app-fragments, vendored from `avidtech6/freshvibe-cms` v1.2.0. The gallery does not currently package them as FES packs because they are runtime chrome, not content widgets.

**Implication for Hopfan E2E:** to reproduce GOLD-like output on Hopfan, the pipeline needs:

1. The 6 PROVEN-*.py / PROVEN-*.cjs scripts from GOLD-BASELINE/ (verbatim)

2. The 5 chrome components from fv-cms-vendored/ or pulled from `avidtech6/freshvibe-cms` v1.2.0

3. A fresh-site WordPress+Elementor source (e.g. Hopfan)

4. A verified run order

The FES module packs in the gallery (cms-widgets/*) are not the chrome — they are the content widgets that get placed inside chrome-managed regions. The Hopfan e2e would be a "build a chrome + populate with Hopfan's content widgets" exercise, which is closer to a template-driven site build than a "rebuild an Oscar clone" exercise.

---

7. Drift, contradictions, missing pact entries

7a. cms-widgets anomalies

1. **`menu` has no `recipe-book/` directory** (audit: recipe=N, codex=N, rules=N, but module-meta.json=Y). Every other full-shape module has recipe-book. This is a real gap or intentional simplification. **Operator should verify if `menu` is intentionally config-only or if recipe/codex/rules are missing.**

2. **`blog-post-card`, `blog-post-list`, `listing-grid`, `recipe-detail` lack `src/widget.js`** (audit: widget=N). Per FvW doctrine, these may be intentionally config-only. **Operator should confirm if their editors + skins are wired.**

3. **`fv-recipe-book-checklist`, `fv-source-link`, `fv-theme-toggle` have module.json + recipe.md but no codex/rules**. These are FVS chrome app-fragments, not FES modules. **The shape mismatch is real but possibly intentional.** They might be better placed in a different directory (e.g. `fv-cms-vendored/app-fragments/` or a new `chrome/` directory).

4. **`theme-presets` and `tools` are 110-120 file directories with no module.json, no recipe-book, no visual, no widget.js.** They are not FES modules. They are loose collections of CSS bundles (theme-presets) and tool atoms (tools). **They should not be in `cms-widgets/`** — that directory is supposed to be content-bound renderers per FvW doctrine. **Operator decision: relocate to a different directory or document the exception.**

5. **`index.js` is a registry barrel at the cms-widgets level** (imports all 16 widget.js modules + re-exports `CANONICAL_MODULES` array). This is the F11/FvCMS entry point for consuming the gallery. **Confirmed working — the modules CANONICAL_MODULES list is correct.**

7b. Doctrinal drift

1. **`17.8-module-work-pipeline.md` references 9 historical M-prefix module names** (`M-breadcrumb, M-cta-box, M-contact-form, M-testimonial, M-cta, M-image, M-paragraph, M-heading, M-menu`). Per C-2 doctrine (M-prefix is runtime-only), these are doctrinal drift — the doctrine should reference lowercase IDs (breadcrumb, cta-box, etc.). **Id 8 to address when writing `m-prefix-convention.md`.**

7c. C-2 audit drift

Id 8's C-2 audit (2026-08-26) said "widget.js 11/16 cms-widgets with M-". My audit shows 16/16. The 5 modules id 8 listed as "without" (contact-form, cta-box, icon-list, info-box, social-icons) all have M- per my regex check. **Drift likely from id 8 auditing at a different commit or with a different regex.** Operator should confirm.

7d. FVW version mismatch

`feed/registry.json` says `fvw_version: "8.2.0"`. Memory + id 8's C-2 reply reference v8.3.0. **The actual FvW doctrine folder is `gallery-pact/fvw/freshvibe-way-v8/` but the feed says 8.2.0. Operator should verify which is current.** If 8.2.0 is the actual version, my v3 emit (built against an assumed 8.3.0) was built against a version that didn't exist; if 8.3.0 is current, the feed is stale.

7e. Pact entry: no `cms-widget.schema.json`

Id 8's audit confirmed `gallery-pact/cms-widget.schema.json` does not exist. Per my earlier reports in this session, I cited a regex from this file. **That citation was wrong — the file does not exist.** The actual id-name regex is in `module-meta.schema.json` (`/properties/name.pattern = '^[a-z][a-z0-9-]*$'`). **Memory lock: I have been citing a non-existent file. The next session should not repeat this.**

---

8. Stable real spec for Hopfan

8a. What "Hopfan e2e" actually means

A Hopfan e2e rebuild is **not** a "run the FES gallery through some pipeline" exercise. It is a "rebuild Hopfan as a FreshVibe app, eyeball it, prove the output" exercise. The pipeline that does this is:

1. **Source**: a fresh WordPress+Elementor site (Hopfan) — live URL or .wpress export

2. **Crawl + scrape**: stage 1+2 (wp-adapter equivalent) — produces pages.json + per-page DOM data

3. **Interpret**: stage 3 (elementor-adapter equivalent) — produces Recipe + Codex per page

4. **Strip elementor inline styles**: stage 3.5 (live VPS script) — neutralizes 28 style blocks

5. **Bundle remote assets**: stage 4 (vendor extract) — replaces absolute URLs with `dist/vendor/<host>/...`

6. **Render with Playwright**: stage 5 (browser pass) — bakes Elementor settings

7. **Inject chrome**: stage 6 (live VPS script) — adds cms-local-loader + edge-panel + dev-btn

**Output:** 425-file dist with chrome wired. **Eyeball test:** side-by-side at `fvre-36-b2p0-hopfan-20260824.freshvibeapps.com` vs live `hopfan-europe.org`.

8b. The FES gallery is not the pipeline

**The FES gallery (cms-widgets/*, modules/*) is the content-side catalog**, not the engine. The engine is the 6-stage pipeline + the FvCMS chrome. The gallery's role is to provide:

**For Hopfan specifically:**

8c. The Hopfan real spec (the baseline)

**Inputs:**

**Steps:**

1. Patch the 5 cert-ignore lines in stage-1-2-crawl-scrape.cjs + render.py (per b1604)

2. Run all 6 stages on Hopfan

3. Deploy to `fvre-36-b2p0-hopfan-20260824.freshvibeapps.com` (symlink + nginx vhost + Caddy cert)

4. Eyeball test: side-by-side with live Hopfan

5. 5 visual proof points: FvRE log, FES diffs, CMS parity, VibeCoder trace, Playwright screenshots (per R-28)

6. If pass: announce to operator with the URL

7. If fail: diagnose which stage broke, fix, re-run, repeat

**Owner:** another session (id 36 fvre Mavis). I am not driving this directly. I drive Task A (this spec). After Hopfan e2e passes, the operator can decide on Task A's "next move."

8d. What this spec makes safe to do next

After C-1 (gallery synced), C-2 (M-prefix doctrine resolved), C-3 (README corrected), C-4 (thread 36 apology posted), and R-117 locked, the gallery is in a known state. The Hopfan e2e can run without further integration questions. If it passes, the "world-class modules" goal is closer. If it fails, the diagnosis is on the pipeline, not on the gallery.

---

9. Open questions for operator

1. **C-2 drift**: id 8 said 11/16 widget.js M-prefixed, audit shows 16/16. Confirm with id 8 before writing `m-prefix-convention.md`.

2. **FVW version**: feed says 8.2.0, memory says 8.3.0. Which is current?

3. **`menu` in cms-widgets**: no recipe-book/. Intentional config-only, or gap to fix?

4. **`theme-presets` and `tools` in cms-widgets/**: should they be relocated, or documented as exceptions?

5. **`fv-recipe-book-checklist`, `fv-source-link`, `fv-theme-toggle`**: FVS chrome app-fragments, not FES modules. Relocate or document?

6. **17.8-module-work-pipeline.md historical M-prefix references**: clean up when id 8 writes the convention doc, or document as historical?

7. **Id 8 is "writing gallery-pact/m-prefix-convention.md when C-2 close"**: that work is now unblocked. Should I check on the doc's status, or wait for id 8 to push it?

---

Status

— Mavis (helper-mavis, id 10, session 412100071272671)