# Gallery Repos — Deep Investigation > **Scope**: `avidtech6/fv-module-gallery` (the registry source) + `avidtech6/fv-gallery-ui` (the website front-end), plus their cross-references in the doctrine. > **Date**: 2026-07-22 > **Compiler**: Mavis, root session > **Verdict in one line**: The gallery is **planned but barely started** — 1 of 11 promised modules actually exists, the rest are still living in their source repos. The schemas, plans, and UI are all there; the actual module *extraction* has not happened. --- ## 0. TL;DR - **2 repos** are gallery-related: `avidtech6/fv-module-gallery` (the hub) and `avidtech6/fv-gallery-ui` (the website). - **Both are private**, both pushed ~4 days ago, both working. No leaks, no deadwood here. - **The hub (`fv-module-gallery`) is 95% planning, 5% execution.** The `bundles/ai-bundle/` exists with a full manifest of 11 modules. The `modules/` directory has **only 1 of 11 modules** — `ai-toast` — and that 1 is just a copy of code from `ai-shell`. The other 10 are **TODO** and still living in `avidtech6/ai-shell` (chrome) and `avidtech6/oscar-platform` (engine). - **The UI (`fv-gallery-ui`) is fully built and FVW v8 compliant** — it has all 8 mandatory artefacts, 6 user routes + 5 docs routes, 9 implemented validity tests. It even does live fetch of `registry.json` from the hub with a bundled fallback. It just shows a registry that lists 1 module and 1 bundle. - **There's a real architectural gap**: the doctrine says "modules are flat, reusable, versioned independently, forkable, swappable" (FVW v8 §10, §11, §17), and the gallery implements that pattern fully on the **planning** side. But the **actual extraction** of those 10 modules is the work that's been deferred. --- ## 1. The 2 repos at a glance | Repo | Type | Size | Last push | Created | Lang | What it is | |---|---|---:|---|---|---|---| | **avidtech6/fv-module-gallery** | Library / hub | 220 KB | 4d ago | 2026-07-17 | TypeScript | The shared module pool. Flat `modules/` + `bundles/` + `gallery-pact/` (schemas, doctrine copy) + `registry.json` (hand-written, not CI-generated). | | **avidtech6/fv-gallery-ui** | App / SPA | 133 KB | 4d ago | 2026-07-17 | TypeScript | The website front-end at `gallery.freshvibeapps.com`. React 18 + TS + Vite + zustand + marked. **Has all 8 FVW v8 mandatory artefacts.** | Both created 4 days ago (2026-07-17) — this is a **fresh initiative** that started from the monorepo deprecation (2026-07-18) and took shape in 1 day. --- ## 2. The hub — `avidtech6/fv-module-gallery` ### 2.1 What's actually in the repo ``` fv-module-gallery/ ├── README.md ← the entry point ├── STATUS.md ← the state-of-play (2026-07-17) ├── registry.json ← the gallery index (hand-written, 1 module, 1 bundle) │ ├── modules/ ← FLAT, top-level modules (the "code" layer) │ └── ai-toast/ ← THE ONLY MODULE that exists │ ├── module.json (identity, tags, tier, tier_meta) │ ├── module-meta.json (versioned metadata: deps, consumers, facets, changelog, lineage) │ ├── facets.json (visibility slices — only "default" facet exists) │ ├── package.json (@fv/ai-toast, peerDeps: react 18) │ ├── tsconfig.json │ ├── node_modules → (symlink) │ ├── recipe-book/ (FVW §11 3-file model: recipe.md + codex.md + rules.md) │ ├── src/ │ │ ├── default/ (PUBLIC facet exports) │ │ └── .private/ (private internals — currently empty) │ └── test-cases/ │ └── no-throw.test.ts │ ├── bundles/ ← JUST lists, no code │ └── ai-bundle/ │ ├── module.json (tags: ["bundle"], identity) │ ├── bundle-manifest.json (lists 11 submodules with versions, visibility, optional, feature) │ └── bundle-features.md (human description) │ └── gallery-pact/ ← schemas + doctrine copy ├── bundle-manifest.schema.json ├── bundle-features.template.md ├── facets.schema.json ├── fvw-versioning-rules.md ├── module-meta.schema.json ├── registry-plan.md ← THE BIG DESIGN DOC ├── registry.schema.json ├── repo-safety-charter.md ← 4-layer protection model └── fvw/ ← COPY of FVW v8 doctrine (41 .md files) ├── 00-philosophy.md → 35-path-a-deploy-rollback.md ├── INTEGRATION-WITH-OPERATOR-V8-RFC.md ├── MIGRATION-v7-to-v8.md ├── README.md ├── VERSIONING-RULES.md ├── v7-VS-v8-CHANGELOG.md ├── rules-md-doctrine.md ├── gotchas/ (subdir) ├── test-cases/ (subdir) └── verdicts/ (subdir) ``` ### 2.2 The "11 modules" reality check The `ai-bundle` manifest claims **11 submodules**. The `registry.json` says **1 module**. Here's the truth table from `STATUS.md`: | Module | Type | Promised source | Moved to gallery? | |---|---|---|:---:| | `ai-toast` | chrome | `ai-shell/src/components/ToastHost.tsx` v0.3.0 | ✅ **DONE** (1.0.0) | | `ai-mic` | chrome | `ai-shell/src/voice/MicButton.tsx` v0.3.0 | ❌ TODO | | `ai-stt` | chrome | `ai-shell/src/voice/{groq-stt,useSpeechToText}.ts` v0.3.0 | ❌ TODO | | `ai-workspaces-chip` | chrome | `ai-shell/src/components/WorkspacesChip.tsx` v0.3.0 | ❌ TODO | | `ai-ask` | engine | `oscar-platform/app/src/assistant/ask.ts` | ❌ TODO | | `ai-orchestrator` | engine | `oscar-platform/app/src/assistant/orchestrator.ts` | ❌ TODO | | `ai-adapters` | engine | `oscar-platform/app/src/intelligence/adapters/*.ts` | ❌ TODO | | `ai-settings` | engine | spread across Oscar's `assistant/` + `intelligence/` | ❌ TODO | | `ai-credentials` | engine | Oscar's `oscar-credential-surface/` | ❌ TODO | | `ai-fragments` | engine | Oscar's `fragment-store.ts` + `conversation-log.ts` + `memory.ts` | ❌ TODO | | `ai-ambient` | engine | Oscar's `ambient.ts` + `warm.ts` | ❌ TODO | **Status: 1/11 modules extracted (9%).** The 10 missing modules are **still source-coupled** to `ai-shell` and `oscar-platform` — they're physically there, they're working, but they're not yet a "gallery module". ### 2.3 The `ai-toast` extraction — what "done" looks like For the 1 module that IS done, here's the actual shape: **`modules/ai-toast/module.json`** — constitutional identity (FVW §17): ```json { "name": "ai-toast", "version": "1.0.0", "tags": ["module", "ui", "chrome", "toast"], "tier": "off-the-shelf", "tier_meta": { "license": "avidtech6-proprietary", "copyable": true, "copy_requires": "license-key", "user_can_ship": "with-license", "user_can_edit": true, "source_visible_in_fvs": true, "platform_shared": false }, "description": "Transient info/error toasts. Bottom-center stack, type-colored, fade-in animation, Esc dismisses all. The chrome half of the AI Bundle — usable on its own as a stand-alone toast system for any FreshVibe app.", "category": "ui", "subcategory": "feedback", "homepage": "https://github.com/avidtech6/fv-module-gallery/tree/main/modules/ai-toast", "repository": "avidtech6/fv-module-gallery", "default_facet": "default", "available_facets": ["default"], "facets_manifest": "facets.json" } ``` **`modules/ai-toast/module-meta.json`** — versioned metadata (NEW per `registry-plan.md`): - 5 constitutional fragments - `depends_on: {}` (no deps) - `depended_on_by: [ai-mic, ai-orchestrator, ai-ask]` (the 3 that don't exist yet) - `consumers: [oscar, freshcards-standalone, vibecoder-standalone, vibescope-standalone]` - 1 facet, 0 variants, not deprecated - 1 changelog entry: "Sourced from @freshvibe/ai-shell v0.3.0 (ToastHost.tsx, with 0 modifications)" **`modules/ai-toast/facets.json`** — the visibility-slicing pattern: - Only `default` facet exists today - `.private/` folder is empty - Once more code is moved in, the operator can add an `oscar-internal` facet that exposes proprietary internals while keeping them hidden from the public gallery **`modules/ai-toast/package.json`** — npm-ready: - `@fv/ai-toast` v1.0.0 - `main` and `types` → `./src/default/index.ts` - Peer: `react@^18.0.0`, `react-dom@^18.0.0` - License: `avidtech6-proprietary` ### 2.4 The `registry.json` (the public answer to "what's in the gallery?") ```json { "version": "1.0.0", "generated_at": "2026-07-17T12:00:00Z", "generated_by": "hand-written (gallery-ci not yet implemented)", "fvw_version": "8.0", "modules": [ { "id": "ai-toast", "version": "1.0.0", "tier": "off-the-shelf", ... } ], "bundles": [ { "id": "ai-bundle", "version": "1.0.0", "submodule_count": 11 } ], "tags_index": { "module": ["ai-toast"], "ui": ["ai-toast"], "chrome": ["ai-toast"], "toast": ["ai-toast"] }, "consumer_index": { "oscar": ["ai-toast"], "freshcards-standalone": ["ai-toast"], "vibecoder-standalone": ["ai-toast"], "vibescope-standalone": ["ai-toast"] }, "dependency_graph": { "ai-toast": [] }, "dependents_graph": { "ai-toast": ["ai-mic", "ai-orchestrator", "ai-ask"] }, "facet_index": { "ai-toast": { "default": { ... 4 consumers, no deps, license: avidtech6-proprietary } } }, "variant_index": { "ai-toast": [] }, "stats": { "total_modules": 1, "total_bundles": 1, "total_facets": 1, "total_chrome_modules": 1, "total_engine_modules": 0 } } ``` **Note**: `generated_by` admits "hand-written (gallery-ci not yet implemented)". The plan (`registry-plan.md` Section F "Robustness audit") explicitly says the gallery needs a CI script to walk the modules and regenerate this. **It doesn't exist yet.** So if someone adds a 2nd module, they have to hand-edit `registry.json` too. ### 2.5 The `gallery-pact/` — the design + doctrine | File | What it is | Status | |---|---|---| | `registry-plan.md` | The 30+ page design doc. 5-layer model, proprietary-splitting pattern (facets), fork/mirror/variant lifecycle, robustness audit, 9 next steps. | DONE | | `registry.schema.json` | The JSON schema for `registry.json` (auto-generated index). | DONE | | `module-meta.schema.json` | The JSON schema for `module-meta.json` (versioned metadata). | DONE | | `facets.schema.json` | The JSON schema for `facets.json` (visibility slices — the proprietary split). | DONE | | `bundle-manifest.schema.json` | The JSON schema for bundle manifests. | DONE | | `fvw-versioning-rules.md` | The "constitution for the constitution" — meta-rules for building future FVW versions. Mandatory file structure, audit checklist. | DONE | | `repo-safety-charter.md` | The 4-layer repo protection model (branch protection, code review, AI isolation, etc.). | DONE | | `fvw/` | **A complete copy of the FVW v8 doctrine (41 .md files)** — the canonical home. | DONE | The `fvw/` subdirectory is the **canonical home** of FVW v8 doctrine (it was moved here from `freshvibestudio/pact/freshvibe-way-v8/` per the 2026-07-17 doctrine-mirror decision). The `freshvibestudio` repo has its own copy under `pact/freshvibe-way-v8/`, but the registry is the source of truth. ### 2.6 The migration plan (from STATUS.md) **Phase 1**: Move chrome modules (4 modules: ai-toast ✅, ai-mic, ai-stt, ai-workspaces-chip). Each: create folder structure, copy from `ai-shell/src/`, write the 5 metadata files, commit. **Phase 2**: Move engine modules (7 modules). Each: same shape, but copy from `oscar-platform/app/src/...`. **Phase 3**: Update consumers. - **Oscar**: switch from `app/src/assistant/` to gallery imports - **FreshCards / VibeCoder / VibeScope**: switch from `@freshvibe/ai-shell` to gallery modules - **Scrap `avidtech6/ai-shell`** (mark DEPRECATED, archive) **Phase 4**: Build gallery UI (DONE — it's `fv-gallery-ui`, live at `gallery.freshvibeapps.com`). **Key decision made**: D-2026-07-17-04 — repo name is `fv-module-gallery`, NOT `freshvibe-monorepo`. (The monorepo was tried for 1 day on 2026-07-16 and abandoned.) --- ## 3. The website — `avidtech6/fv-gallery-ui` ### 3.1 What it does A React 18 + TS + Vite SPA at `gallery.freshvibeapps.com`. The user-facing experience: | Route | Page | What it shows | |---|---|---| | `/` | HomePage | Hero + stats + featured bundles + featured modules | | `/modules` | ModulesPage | All modules, with filter bar | | `/modules/:id` | ModuleDetailPage | Module detail (facet tabs, deps, dependents, consumers, variants) | | `/bundles` | BundlesPage | All bundles | | `/bundles/:id` | BundleDetailPage | Bundle manifest (sub-modules, license, compatibility) | | `/variants` | VariantsPage | Forks + mirrors across all modules | | `/docs` | DocsPage | Two tiles: FVW v8 doctrine + this app's pact | | `/docs/fvw` + `/docs/fvw/:section` | DocsPage | Renders FVW sections as Markdown | | `/docs/pact` + `/docs/pact/:doc` | DocsPage | Renders App-Pact docs as Markdown | 11 routes total. The docs section fetches FVW from the **live gallery** (`raw.githubusercontent.com/avidtech6/fv-module-gallery/main/gallery-pact/fvw/`) with a bundled fallback. ### 3.2 The data flow ``` fv-module-gallery/registry.json │ │ live fetch (5s timeout) ▼ ┌──────────────┐ │ fv-gallery- │ │ ui │ └──────┬───────┘ │ if live fails → bundled /registry.json ▼ displays modules + bundles + docs ``` The header shows a status pill: **live / bundled / error** — so you can tell which source is active. ### 3.3 FVW v8 compliance — the 8 mandatory artefacts Per FVW v8 §1.1, every FreshVibe-compatible app MUST have 8 artefact folders. The gallery UI has all 8: | # | Folder | What | Status | |---|---|---|---| | 1 | `app-pact/` | Rules, constraints, guarantees, 3 invariants, 7 anti-drift rules, 6 rule categories (registry, ui, state, deploy, security, rebuild) | ✅ | | 2 | `app-codex/` | 12 surfaces, 9 behaviours, per-surface/per-behaviour files | ✅ | | 3 | `app-fragments/` | 9 fragment folders + index | ✅ | | 4 | `app-dna/` | `app.dna.json` v0.1.0, FVW v4 schema | ✅ | | 5 | `app-trace-atlas/` | `atlas.json` with 18 entries, 12 surfaces mapped | ✅ | | 6 | `app-overlays/` | `overlays.md` placeholder (0 overlays yet) | ✅ (placeholder) | | 7 | `app-vp/` | 6 validity tests + 3 protection tests + API contracts (16 planned, 9 implemented) | ✅ partial | | 8 | `app-recipe/` | `recipe.md` + `metadata.json` + `snapshot/` | ✅ | Plus the 3 FVW v4 invariants: **Reconstructable, Deterministic, Isolated** (no localStorage / cookies / service worker). ### 3.4 The 6 rule categories in `app-pact/rules/` | Category | File | Rules | |---|---|---| | registry | `registry-rules.md` | 6 rules on registry fetch + fallback | | ui | `ui-rules.md` | 7 rules on UI surface structure | | state | `state-rules.md` | 6 rules on the zustand store | | deploy | `deploy-rules.md` | 6 rules on build/deploy/serve | | security | `security-rules.md` | 6 rules on what the app does NOT do | | rebuild | `rebuild-rules.md` | 6 rules on rebuildability | ### 3.5 The 7 anti-drift tests (per FVW §08) | # | Rule | Test | |---|---|---| | 1 | No component without a surface | `app-vp/validity/atlas-coverage.test.ts` | | 2 | No state without a behaviour | TBD (`store-coverage.test.ts`) | | 3 | No route without a surface | `app-vp/validity/route-coverage.test.ts` | | 4 | No install/fork without an API contract | `app-vp/validity/button-coverage.test.ts` | | 5 | No new dep without a Recipe bump | `app-vp/validity/dep-coverage.test.ts` | | 6 | No shipped build without a snapshot | TBD (`snapshot-coverage.test.ts`) | | 7 | No changes without a changelog entry | Manual at merge time | **Status: 4 of 7 implemented as automated tests.** 3 are TODO. ### 3.6 What the app does NOT do (yet) - **No install / fork actions** — buttons alert "API not yet available". Real impl when `fv-gallery-api` ships. - **No auth** — anyone can browse. Auth comes with the API. - **No per-user state** — the registry is shared. "My installed modules" page comes later. - **No module authoring** — the UI is a viewer, not a CMS. Modules are added via PRs to the gallery repo. ### 3.7 The deployment Deployed to the FreshVibe VPS (`185.249.73.178`) via paramiko SCP, served from `/var/www/freshvibeapps/clients/gallery/` by nginx. **A dedicated vhost is required** (`/etc/nginx/sites-enabled/gallery.freshvibeapps.com`) because the wildcard handler doesn't fall through to `index.html` for SPA routes. --- ## 4. The proprietary-splitting pattern (the killer feature) This is the most interesting design decision in the gallery. The operator's hardest question, per `registry-plan.md`: > *"if I have a module with proprietary bits I don't want to share, how do I split it? When an AI online asks 'I want that module', how do they see only the public features and NOT my hidden ones?"* **The solution: facets.** A single module can have multiple named **facets**. Each facet is a visibility slice of the same code: ``` modules/ai-ask/ ├── module.json ← constitutional — declares default + available facets ├── module-meta.json ← metadata — per-facet deps + consumers ├── facets.json ← the facet declarations │ ├── src/ │ ├── default/ ← DEFAULT facet (everyone gets this) │ │ ├── index.ts ← public barrel │ │ ├── ask.ts ← 9-layer dispatcher │ │ └── layers/ │ │ │ ├── oscar-internal/ ← NAMED facet (operator only) │ │ ├── index.ts │ │ ├── smart-adapter.ts ← proprietary Oscar smart adapter │ │ ├── arboriculture-standards.ts │ │ └── warm-cache.ts │ │ │ └── shared/ ← code shared between facets (not exported directly) │ └── types.ts │ └── recipe-book/ ``` **`facets.json`:** ```json { "default": { "exports": ["src/default/index.ts"], "visibility": "public", "license": "avidtech6-proprietary", "requires": null, "description": "Public API. Everyone gets this." }, "oscar-internal": { "exports": ["src/oscar-internal/index.ts"], "visibility": "private", "license": "avidtech6-proprietary-strict", "requires": "operator-agreement", "description": "Oscar-specific internals. Operator-only." } } ``` **The rules:** - `default` facet is **required**, always - Facets don't import from each other (shared code goes in `src/shared/`) - The `public` AI sees only the `default` facet; the `private` Oscar gets the `oscar-internal` facet - One module, one recipe-book, one set of codex contracts — just two visibility slices - The cluster rule (FVW §10) still applies: the WHOLE module is one cluster, the facets are just visibility **Why this matters**: this is the pattern for selling / licensing modules. A 3rd-party consumer gets the `default` facet; the operator's other apps get the `oscar-internal` facet. The AI can't see the proprietary bits because the barrel file doesn't re-export them. **Status today**: schema is done, plan is documented, but no module actually uses the multi-facet pattern yet. `ai-toast` only has `default`. The pattern is parked until a real module needs the split. --- ## 5. The fork / mirror / variant lifecycle The state machine per FVW §12 + `registry-plan.md` Section E: ``` [NEW] → (upload) → MIRROR → (first change) → FORK → (50% override) → HEAVY_FORK ↓ (re-merge) → MIRROR or DELETED ``` | State | Meaning | Auto-action | |---|---|---| | **MIRROR** | Byte-identical to canonical | Build verifies byte-equality; auto-updates or warns | | **FORK** | Customised; state transitioned on first change | Diffs recorded in `recipe-book/diffs/` | | **HEAVY_FORK** | 50%+ files overridden | Mirror files removed from bundle; canonical bundled alongside; warning to operator | | **MERGED** | Fork's changes promoted back to canonical | Fork deleted OR kept as long-lived variant | | **DELETED** | Fork removed | Consumers notified to migrate to canonical | **The 20%/50% rule (FVW §10.3)**: when override % crosses 20%, build warns. When it crosses 50%, mirrors are removed; canonical is bundled alongside. **Drift detection**: every build checks mirror byte-equality. If canonical moves, the mirror is stale. **Stale forks**: a fork with no commits in 6+ months is marked "stale" in the registry. Consumers see a warning. **Status today**: doctrine is fully written, but no fork exists yet. There are 0 variants in `registry.json.variant_index`. --- ## 6. The 4-layer protection model (from `repo-safety-charter.md`) Every FreshVibe gallery repo MUST have 4 protection layers: | Layer | What | Specifics | |---|---|---| | 1. Repo-level | GitHub branch protection on `main`, `canonical`, any per-app canonical branches | Require PR, require 1 approval, prevent force-push, prevent deletion | | 2. Code review | CODEOWNERS, AI write restrictions, pre-commit hooks | AI never pushes to canonical directly; only via PR | | 3. AI isolation | `pact/scripts/` validates structural changes; `.mavis/` captures AI state separately | The AI can write freely in its own scratch dirs, not in canonical | | 4. Build/CI | Auto-runs gallery-ci, validates `registry.json`, runs all module tests, detects drift | Hard fail on any break | **What this charter does NOT defend against**: operator error, compromised credentials, misconfigured protection, GitHub infra failure, insider threat, supply chain attack. The charter **assumes operator good faith**. **Status today**: charter written and constitutional. The actual protection rules need to be verified per repo (branch protection settings, CODEOWNERS presence, etc.). Not in scope of this audit but worth a follow-up. --- ## 7. Connections to other repos ``` fv-module-gallery (the hub) │ ┌─────────────────────┼─────────────────────┐ │ │ │ │ consumed by │ reads from │ cited by ▼ ▼ ▼ fv-gallery-ui freshvibestudio/pact/ freshvibestudio (the website) freshvibe-way-v8/ (the constitutional hub) (the canonical FVW v8) via .prompts/ artefacts ↓ ai-shell (substrate, soon to be deprecated per Phase 3) ↓ oscar-platform (engine source, will be the source for ai-ask/ai-orchestrator/ ai-adapters/ai-settings/ ai-credentials/ai-fragments/ ai-ambient modules) ↓ freshcards-standalone vibecoder-standalone vibescope-standalone (consumers of the bundle) ``` **`@freshvibe/ai-shell` is the immediate parent of the chrome modules** (`ai-toast`, `ai-mic`, `ai-stt`, `ai-workspaces-chip`). When the gallery extraction is done, `ai-shell` will be deprecated (Phase 3). **`oscar-platform` is the immediate parent of the engine modules** (`ai-ask`, `ai-orchestrator`, `ai-adapters`, `ai-settings`, `ai-credentials`, `ai-fragments`, `ai-ambient`). When extraction is done, Oscar will switch to importing from the gallery instead of local `app/src/assistant/`. **`freshvibestudio/pact/freshvibe-way-v8/` is the constitutional home of FVW v8 doctrine.** The gallery has a copy at `gallery-pact/fvw/` for self-containment. The plan in `registry-plan.md` is: gallery is the source of truth; studio consumes the gallery's registry. So the doctrine-mirror direction is studio ← gallery, not the other way. **Per the gallery's `consumer_index` (in `registry.json`):** the 4 consumers are `oscar`, `freshcards-standalone`, `vibecoder-standalone`, `vibescope-standalone`. **Studio itself is NOT listed as a consumer** — because the gallery is a fresh init that's a *carve-out* from Studio, not a dep of Studio. (Studio has its own in-tree copies of these modules, and the gallery exists to make them shareable with the standalones.) --- ## 8. The hard problems that remain These are explicit, not me hand-wringing. They're either TODO in the STATUS.md, flagged in registry-plan.md, or implied by the gaps. ### 8.1 10 of 11 modules not extracted - `ai-mic`, `ai-stt`, `ai-workspaces-chip` (chrome — from `ai-shell`) - `ai-ask`, `ai-orchestrator`, `ai-adapters`, `ai-settings`, `ai-credentials`, `ai-fragments`, `ai-ambient` (engine — from `oscar-platform`) - Each needs: copy src, write 5 metadata files (module.json + module-meta.json + facets.json + recipe-book/{recipe,codex,rules}.md + test-cases/) - Status table in `STATUS.md` says "TODO" for all 10 ### 8.2 No `gallery-ci` script - `registry.json` is **hand-written** (per its own `generated_by` field) - Adding a 2nd module means hand-editing `registry.json` too, or building the CI first - `registry-plan.md` Section F lists this as a fragility ### 8.3 No `fv-gallery-cli` - The CLI commands listed in `registry-plan.md` Section C.2 (`fv-gallery list`, `fv-gallery info`, `fv-gallery deps`, etc.) are planned but not built - Would live in a separate repo or sub-folder ### 8.4 No API server (`fv-gallery-api`) - The "install / fork" buttons in the UI alert "API not yet available" - API design is mentioned in `registry-plan.md` Section C.3 but not built ### 8.5 No swap compatibility matrix - `registry-plan.md` Section F: "No 'swappability' guarantee. Can you replace module X with module Y in a bundle without breaking things?" - The bundle manifest pins versions, but no compatibility matrix exists ### 8.6 No version constraint enforcement - Bundle manifest says `ai-ask: ^1.0.0` but no one checks actual version satisfies - The plan calls for a "version constraint solver" but it doesn't exist ### 8.7 `app-vp/` is only 56% tested - 16 tests planned, 9 implemented - The 3 anti-drift tests (store coverage, snapshot coverage, manual changelog) are TODO ### 8.8 No deprecation policy - A deprecated module stays in the registry forever - Plan calls for 6-month removal window; not implemented ### 8.9 No license audit - A module's `module.json` says "MIT" but the code might have GPL bits - No automated check; the plan proposes one but it's not built --- ## 9. What I'd recommend next (if you're taking suggestions) Ordered by impact/effort, low-hanging first: 1. **Extract the 4 chrome modules from `ai-shell`** (ai-mic, ai-stt, ai-workspaces-chip, and confirm ai-toast is correct). Each is ~1-2 hours of work: copy file, write the 5 metadata artefacts, run vitest. Once done, `ai-shell` becomes a thin re-export layer that can be deprecated. 2. **Build `gallery-ci.ts`** — the script that walks `modules/` and `bundles/`, regenerates `registry.json`. This unblocks the hand-edit burden. ~200 lines of TS. 3. **Extract the 7 engine modules from `oscar-platform`** (ai-ask, ai-orchestrator, ai-adapters, ai-settings, ai-credentials, ai-fragments, ai-ambient). Heavier than chrome because they have inter-dependencies. 1-2 days of focused work. 4. **Update the 4 consumers** (Oscar, FreshCards, VibeCoder, VibeScope) to import from the gallery instead of `ai-shell`/local paths. The standalones already do this via `file:` paths. 5. **Build `fv-gallery-cli`** — the 200-line CLI from `registry-plan.md` Section C.2. Reads `registry.json`, no network. Lives in the gallery or in `mavis-templates`. 6. **Finish the 3 TODO anti-drift tests** in `app-vp/` (store coverage, snapshot coverage, manual changelog). Each is ~30 min. 7. **Verify the 4-layer protection model** is actually in place on both repos (branch protection, CODEOWNERS, pre-commit hooks). The charter says it's mandatory; an audit would confirm. 8. **Consider archiving `avidtech6/ai-shell`** once the chrome modules are extracted. It's the explicit Phase 3 outcome. Saves maintenance of having two sources of truth. --- ## 10. Summary - **2 repos**, both private, both live, both well-designed. - **1 of 11 modules actually extracted** (ai-toast). The other 10 are TODO. - **`registry.json` is hand-written**, not auto-generated. Fragile. - **The UI is fully built and FVW v8 compliant** — it has all 8 mandatory artefacts, 6+5 routes, 9 tests. - **The proprietary-splitting pattern (facets)** is designed and the schema is done, but no module uses it yet. - **The doctrine is complete** — 41 .md files copied into the gallery, 5 JSON schemas, 1 design plan, 1 safety charter. - **The 4-layer protection model** is constitutional but not verified. - **Hard work remaining**: extract 10 modules, build gallery-ci, build CLI, finish 3 tests, then update 4 consumers and deprecate ai-shell. - **No deadwood**, **no privacy leaks**, **no naming conflicts**. The gallery is a clean, well-scoped initiative that's just early in execution. --- *End of investigation. ~190 KB of repo data consumed. All facts sourced from live files in `avidtech6/fv-module-gallery` and `avidtech6/fv-gallery-ui` via the GITHUB_PAT_FG_1 fine-grained PAT.*