# Canonical Home for FreshVibe Way v8 — Proposal > **Direction** (operator 2026-07-22): FVW v8 canonical home should be **`avidtech6/fv-module-gallery/gallery-pact/fvw/`**. The gallery is where modules live, where you learn to refactor apps into modules, where you post modules. The doctrine is the meta-of-the-gallery — the rules for how to do everything the gallery exists to do. So the doctrine should live there too. > **Sync model**: bidirectionally — every consumer of the doctrine (any AI, any app) can pull from the gallery. When they pull, they also pull the **freshness check**: the doctrine they have must be in sync with the gallery. If it's not, the AI is operating on stale doctrine and the freshness check fails. > **Status of this doc**: PROPOSAL. Needs operator approval, then 5 concrete steps to make it happen. --- ## 0. The current state, honestly There are **7 places** where the FVW v8 doctrine or its derivatives live today: | # | Repo | Path | What | Last commit | Status | |---|---|---|---|---|---| | 1 | `avidtech6/freshvibe-way-v8` (dedicated top-level repo) | `doctrine/` (41 .md files) | Frozen FVW v8 distribution with scaffolding/, CHANGELOG, VERSION, AGENTS.md | 2026-06-25 | **DEPRECATED, FROZEN** — own AGENTS.md says *"DO NOT USE AS SOURCE OF TRUTH. Canonical home is `avidtech6/freshvibestudio/pact/freshvibe-way-v8`."* The 2026-06-25 attempt at a Sync Action GitHub App was reverted because it caused more problems than it solved. | | 2 | `avidtech6/freshvibestudio` (the Studio) | `pact/freshvibe-way-v8/` (42 .md files) | The **de facto** canonical home today. Has v8.1 work-in-progress (§38-two-recipe-model.md added 2026-07-21). | 2026-07-21 | **ACTIVE, DRIFTING** — gallery copy is 1 file behind; no auto-sync | | 3 | `avidtech6/fv-module-gallery` | `gallery-pact/fvw/` (41 .md files) | Self-contained copy of FVW v8 from 2026-07-17, so the gallery-ui docs route can render the doctrine offline. | 2026-07-17 | **STALE, 1 file behind** — bundled fallback per `fv-gallery-ui/README.md` | | 4 | `avidtech6/oscar-platform` | `pact/` (15 subdirs incl. recipes/, codex/, dna/, trace-atlas/, decisions/) | Oscar's own constitutional home (OSCR- prefix per README) | 2026-07-20 | **ACTIVE** — Oscar is sovereign, has its own pact, but contains FVW-derived material (mirror state) | | 5 | `avidtech6/freshvibe-dochub` | `dev/doctrine/fvw-v8.md` (1 summary file) + `recipe-book/` (4 files) | docHub's Mavis-readable FVW summary + docHub's own recipe book | 2026-07-05 | **STALE-ISH** — summary, not the full doctrine | | 6 | `avidtech6/smartpantry-app` | `recipe-book/` (8 subdirs, per-module) | SmartPantry's own per-module recipe books | 2026-07-06 | **ACTIVE per-module** — built from the doctrine but its own consumer | | 7 | `avidtech6/freshvibe-reconstruction-engine` | `pact/01-fvre-doctrine.md` (1 file) | FVRE's own doctrine, mostly about its separation from Studio | 2026-07-18 | **ACTIVE** — FVW-derived but its own thing | Plus 3 less-FVW-tied but still doctrinal: - `avidtech6/ai-shell` — `pact/` exists, AI-related - `avidtech6/freshvibe-cms` — `app-pact/` (FVW v8 §1.1 compliant) - `avidtech6/fv-gallery-ui` — `app-pact/` (FVW v8 §1.1 compliant) - `avidtech6/disciple-connect` — `app-pact/` (FVW v8 §1.1 compliant) - `avidtech6/oscar-web` — `app-pact/` (FVW v8 §1.1 compliant) That's at least **7+ places** that either carry FVW-derived doctrine or implement the 8 mandatory artefacts. No sync between them. No canonicality declared. **Today's de facto answer** (operator Mavis-on-behalf-of-memory): "the canonical home is `avidtech6/freshvibestudio/pact/freshvibe-way-v8/`" — the deprecated top-level repo's own AGENTS.md says so, and the gallery's STATUS.md says so. But: - The gallery has a full copy anyway (because the docs route needs it) - The deprecated repo has a full copy anyway (because it was the canonical home before 2026-06-25) - fvs has v8.1 work that nobody is propagating - There's a `pact-coherence.yml` workflow in fvs that runs `drift-check.sh` on every PR but it's **advisory only** (does not block merge, per the YAML comment) and only checks fvs's own pact/, not cross-repo drift So today: doctrine is scattered, the canonical home is implicit (fvs), and **everything drifts silently**. --- ## 1. The operator's direction, restated > *"Aye aye goes. If you look for modules, it's where it goes. To post modules. Modules. It's where it goes to learn how to refactor modules. Refactor apps into modules. Etc. Etc. So when you... Need to turn this around. So an AI will pull a module down. Into its repo. It will also pull a Freshvibe way into its repo. Then have to check whether the modules are up to date with the canonical on the gallery. And also have to check whether the freshvibe way is up to date with the gallery."* Two distinct concepts, both pointing at the same place: ### 1.1 The gallery is where doctrine + modules co-locate - The gallery is the **post-modules, find-modules, learn-how-to-refactor-modules** surface. - FVW v8 is **the rules for how to do all of that** (the recipe book doctrine, the 9 things in `rules.md`, the §11 recipe-book format, §12 mirrors-and-forks, §17 modules-and-tiers, §18 revibe-pattern). - Therefore: the doctrine naturally lives **in the gallery**, because the doctrine IS the meta-of-the-gallery. ### 1.2 The sync model: bidirectional, with freshness check - The gallery is **canonical**. Period. - An AI session pulls a **module** from the gallery → places it in its working repo. Now the AI's repo has a `modules//` (probably a copy of `gallery/modules//`). - The AI also pulls **FWV v8** from the gallery → places it in its repo at `pact/freshvibe-way-v8/` (probably a copy of `gallery/gallery-pact/fvw/`). - The AI's repo now has **two freshness checks** to run: 1. **Module freshness**: "Is my `modules//` byte-identical (or within drift threshold) to `gallery/modules//`?" 2. **Doctrine freshness**: "Is my `pact/freshvibe-way-v8/` byte-identical to `gallery/gallery-pact/fvw/`?" - If either is stale, the AI is operating on **outdated instructions** and the freshness check fails (or warns, depending on policy). - The AI's repo can also **contribute back**: when the AI improves a module or extends the doctrine, it sends a PR back to the gallery. The gallery owner reviews and merges. The doctrine evolves from the gallery outward. This is the model. Let me put it in a diagram: ``` ┌─────────────────────────────────┐ │ avidtech6/fv-module-gallery │ │ ─── CANONICAL ─── │ │ │ │ gallery-pact/fvw/ ← doctrine │ │ modules/ai-toast/ ← modules │ │ bundles/ai-bundle/ │ │ registry.json │ └────────────┬────────────────────┘ │ ┌──────────────────┼──────────────────┐ │ sync (mirror) │ freshness-check │ contribute-back (PR) │ │ │ ▼ ▼ ▲ ┌────────────────────┐ ┌──────────────────┐ ┌───┴─────────────┐ │ any consumer repo │ │ any AI session │ │ any AI session │ │ (Oscar, Smart- │ │ pulls module + │ │ improves and │ │ Pantry, docHub, │ │ doctrine, then │ │ PRs back to │ │ fvs, freshcards- │ │ runs freshness │ │ the gallery │ │ standalone, etc.)│ │ check on both │ │ │ └────────────────────┘ └──────────────────┘ └─────────────────┘ ``` **Three things flow through this system**: 1. **Down mirror** (gallery → consumer): the canonical → every consumer's working copy 2. **Freshness check** (consumer self-checks): "am I in sync with canonical?" 3. **Up contribution** (consumer → gallery): "I'm proposing an improvement" The freshness check is the critical piece — it makes the sync **observable** rather than silent. Without it, the doctrine drifts unnoticed (which is exactly what's happening today: 1 file drift in 5 days, no alarm). --- ## 2. What this direction means concretely ### 2.1 What stays where | Path | What | New role | |---|---|---| | `avidtech6/fv-module-gallery/gallery-pact/fvw/` | FVW v8 doctrine | **CANONICAL** (was: self-contained copy) | | `avidtech6/freshvibestudio/pact/freshvibe-way-v8/` | FVW v8 doctrine | **MIRROR** (was: de facto canonical) | | `avidtech6/freshvibe-way-v8/doctrine/` | FVW v8 doctrine | **DEPRECATED, archive the repo** (was: deprecated, frozen) | | `avidtech6/oscar-platform/pact/` | Oscar's own constitution (OSCR- prefix) | **SOVEREIGN, keeps its own pact** | | `avidtech6/smartpantry-app/recipe-book//` | Per-module recipe books | **CONSUMER** (its own instances of the recipe-book format) | | `avidtech6/freshvibe-dochub/dev/doctrine/fvw-v8.md` | Mavis-readable summary | **CONSUMER** (the summary file, points at gallery as canonical) | | `avidtech6/fv-re` (FVRE) | Its own doctrine | **SOVEREIGN** | ### 2.2 The 4 doctrinal homes that **don't** merge - Oscar's `pact/` is its own constitutional home — Oscar is sovereign, per its README. It contains FVW-derived material but is a separate legal document. - SmartPantry's per-module recipe books are *instances* of the recipe-book format, not copies of the doctrine itself. - docHub's summary is a curator's view, not a copy of the source. - FVRE's pact/ is its own doctrine about the FvRE engine, not FVW v8. These don't get canonicalised into the gallery. They **reference** the gallery. The gallery is the **upstream**, these are **downstream**. ### 2.3 The 2 that **do** merge - `avidtech6/fv-module-gallery/gallery-pact/fvw/` ← **CANONICAL HOME** (today: self-contained copy) - `avidtech6/freshvibestudio/pact/freshvibe-way-v8/` ← **mirror** (today: de facto canonical) - `avidtech6/freshvibe-way-v8/doctrine/` ← **archive the repo** (today: deprecated top-level) After the change: the gallery is canonical, fvs is a mirror, the dedicated top-level repo is archived. One source of truth. --- ## 3. The sync model, in detail ### 3.1 The 3 sync flows **Flow 1: gallery → consumer (the canonical → mirror direction)** Triggers: every push to the gallery's `gallery-pact/fvw/` (or `modules/`). Mechanism: a GitHub Action in the gallery, on push to those paths, opens a PR (or pushes directly) to each known consumer repo's corresponding path. Consumers to update: - `avidtech6/freshvibestudio` → `pact/freshvibe-way-v8/` - `avidtech6/freshvibe-dochub` → `dev/doctrine/` (regenerate `fvw-v8.md` summary, OR keep it as a curated summary that links to gallery) - (Optionally) any other consumer that explicitly opts in For modules, the gallery-action's consumer list is `registry.json.consumer_index[module-id]` — same mechanism. **Flow 2: consumer → gallery freshness check (the check direction)** Triggers: every push to a consumer's `pact/freshvibe-way-v8/` (or `modules//`). Mechanism: a GitHub Action in the consumer, on push, fetches the canonical from the gallery and diffs. Result: a check that **passes** (canonical == mirror) or **fails** (drift detected). For the doctrine: the check is byte-equality, or byte-equality modulo a `MIRROR-ALLOWED-DELTA` of e.g. ±3 days. For modules: same. **Flow 3: consumer → gallery (the contribute-back direction)** Triggers: a PR from a consumer that wants to change the canonical. Mechanism: the consumer opens a PR against the gallery. The gallery owner reviews and merges. This is the "normal" PR flow, no special machinery needed. The freshness-check workflow (Flow 2) makes sure consumers don't *silently* drift — but they can still *intentionally* contribute back. ### 3.2 What "freshness check" means concretely For a consumer repo, the check is: ```bash # Pseudo-shell CANONICAL_URL="https://raw.githubusercontent.com/avidtech6/fv-module-gallery/main/gallery-pact/fvw/" LOCAL_PATH="pact/freshvibe-way-v8/" # For each file in canonical, check it exists in local and matches drift_count=0 for f in $(curl -s "$CANONICAL_URL" | jq -r '.[] | .name'); do if ! diff -q <(curl -s "$CANONICAL_URL$f") "$LOCAL_PATH$f" >/dev/null 2>&1; then echo "DRIFT: $f" drift_count=$((drift_count + 1)) fi done # For each file in local, check it exists in canonical for f in $(find "$LOCAL_PATH" -type f -name '*.md'); do rel=${f#$LOCAL_PATH/} if ! curl -sf "$CANONICAL_URL$rel" >/dev/null 2>&1; then echo "EXTRA: $f (in local but not canonical)" fi done if [ $drift_count -eq 0 ]; then echo "✅ Doctrine is in sync with canonical" exit 0 else echo "❌ Doctrine drift: $drift_count files differ" exit 1 fi ``` This is a 50-line GitHub Action. Could also be a CLI tool in the gallery: `fv-gallery freshness check --doctrine --modules --path /workspace/`. ### 3.3 The protocol for AI sessions When an AI session is set up to do work in a FreshVibe app, the protocol is: 1. **Pull**: `git clone fv-module-gallery` (or use the local copy) into the working dir. Now you have `gallery-pact/fvw/` (doctrine) and `modules//` (modules). 2. **Mirror to local paths**: copy `gallery-pact/fvw/` → `pact/freshvibe-way-v8/` in the working repo. Copy `modules//` → `modules//` in the working repo. 3. **Run freshness check**: are the mirrors in sync with the canonical? (Right after the clone, the answer is yes — by construction. But over time, as the gallery evolves, the answer can become no.) 4. **If stale, refresh**: re-pull from the gallery, re-mirror. The session's work is now on the latest doctrine. 5. **Operate**: use the doctrine to do the work (refactor, build, refactor-back-into-modules, etc.) 6. **Contribute back** (optional): if the AI made improvements, open a PR against the gallery. The gallery owner reviews. This is the protocol. The Mavis budget-rule document (the operator's constitutional doc for how Mavis sessions work) should reference it. ### 3.4 The 2 missing pieces (today) 1. **Flow 1 (gallery → consumer) is not implemented.** Today the gallery-pact/fvw/ copy is 1 file behind. No GitHub Action. No cron. Nothing. 2. **Flow 2 (freshness check) is not implemented.** Today the consumer (fvs) has its own `pact-coherence.yml` workflow, but it runs `drift-check.sh` against fvs's *own* pact/, not against the gallery. Cross-repo drift is invisible. Both are 50-200 lines of code each. The GitHub Actions or the cron job. Plus a small CLI tool for the AI session protocol. --- ## 4. The 5 concrete steps to make this happen If the operator approves the direction, the rollout is: ### Step 1: Record the decision - Write a decision-record (DR) at `avidtech6/freshvibestudio/pact/decisions/2026-07-22-fvw-canonical-home-is-gallery.md` (or wherever decisions live — confirm). Status: APPROVED by operator on 2026-07-22. - The DR declares: "FVW v8 canonical home is `avidtech6/fv-module-gallery/gallery-pact/fvw/`. All other copies are mirrors or consumers." - It supersedes D-2026-07-17-03 in the gallery's STATUS.md (which said the opposite). - Update `STATUS.md` D-2026-07-17-03 to mark it as superseded. - Update `registry-plan.md` Section H Q5 from "open question" to "decision". ### Step 2: Catch up the gallery - Copy `38-two-recipe-model.md` from fvs to gallery (the only drift). - Verify all 42 doctrine files are now in `gallery-pact/fvw/`. - Commit: "feat(fvw): sync from canonical — §38-two-recipe-model". ### Step 3: Set up the sync mechanism **Option A: GitHub Actions** (recommended for portability) - Add a workflow to `avidtech6/fv-module-gallery/.github/workflows/mirror-doctrine.yml`: - On push to `gallery-pact/fvw/`, open a PR against `avidtech6/freshvibestudio`'s `pact/freshvibe-way-v8/`. - Use `peter-evans/create-pull-request` action. - Add a workflow to `avidtech6/freshvibestudio/.github/workflows/freshness-check-doctrine.yml`: - On PR/push to `pact/freshvibe-way-v8/`, fetch the gallery's `gallery-pact/fvw/`, diff, comment on the PR with drift report. - Update the existing `pact-coherence.yml` to also do this cross-repo check. **Option B: cron in fva-control-panel** (recommended for operator's existing infra) - The VPS already runs cron jobs (per memory: conversation watcher every 30 min). - Add a cron: every 6 hours, `rsync fv-module-gallery's gallery-pact/fvw/ → fvs's pact/freshvibe-way-v8/`. If a diff exists, open a PR via the GitHub API. - Same for the freshness check: every 6 hours, fetch the gallery, diff against the local mirror, write a status file. If drift, alert. **Option C: a small CLI tool** (recommended for the AI session protocol) - Add to `avidtech6/mavis-templates/` (or a new repo `avidtech6/fv-gallery-cli`): - `fv-gallery pull --doctrine` — clones the doctrine into `pact/freshvibe-way-v8/` - `fv-gallery pull --module ai-toast` — clones one module into `modules/ai-toast/` - `fv-gallery freshness --doctrine --path ./pact/freshvibe-way-v8/` — diffs against canonical, exits 0 or 1 - `fv-gallery freshness --module ai-toast --path ./modules/ai-toast/` — same for modules - `fv-gallery contribute --pr "improved ai-ask facet"` — opens a PR back to the gallery This is the AI-session-facing tool. It can be called by `glm-once.py` or whatever Mavis uses to bootstrap a session. ### Step 4: Archive the deprecated top-level repo - `avidtech6/freshvibe-way-v8` is already marked deprecated in its own AGENTS.md. Archive it via the GitHub web UI (Settings → Archive). - Update the AGENTS.md to point to the **gallery**, not fvs: "The canonical FreshVibe Way v8 doctrine lives at https://github.com/avidtech6/fv-module-gallery/tree/main/gallery-pact/fvw/." ### Step 5: Update consumers - `avidtech6/freshvibe-dochub/dev/doctrine/fvw-v8.md` — update the `pact_refs` to point at gallery paths, not fvs paths. - `avidtech6/freshvibestudio/pact/freshvibe-way-v8/README.md` — add a "Source attribution" line that says "Mirror of canonical: `avidtech6/fv-module-gallery/gallery-pact/fvw/`. Run freshness check before relying on this copy." - `avidtech6/fv-gallery-ui` — already fetches from the gallery (per its README), no change needed. But verify the bundled fallback is regenerated. - `avidtech6/oscar-platform/pact/` — Oscar is sovereign, but its pact/ contains FVW-derived material. Add a note: "Mirrored from FVW v8 (canonical: `avidtech6/fv-module-gallery/gallery-pact/fvw/`). Last sync: ." - `avidtech6/freshvibe-reconstruction-engine/pact/01-fvre-doctrine.md` — same, add a "Mirrored from FVW v8" note. - All `app-pact/` consumers (freshvibe-cms, freshvibe-dochub, fv-gallery-ui, disciple-connect, oscar-web) — these are FVW v8 §1.1 compliant; add a "Source attribution" line to each `app-pact.md` saying which FVW v8 version they were built against. --- ## 5. The 4 things to verify before declaring done 1. **The doctrine in the gallery is the latest.** Verify: `diff -r fvs/pact/freshvibe-way-v8/ gallery/gallery-pact/fvw/` shows zero differences. (After Step 2, this should be true.) 2. **The freshness check runs and passes.** Add the GitHub Action or cron (Step 3). Verify it runs without errors on both fvs and gallery. 3. **The deprecated top-level repo is archived.** Verify: web UI shows "This repository has been archived. It is now read-only." 4. **A consumer (e.g. an AI session set up in `/workspace/smartpantry/`) successfully pulls module + doctrine, runs the freshness check, sees it pass.** Verify: end-to-end smoke test. --- ## 6. Why the gallery (and not fvs) The operator's reasoning, captured here for the decision record: > *"Aye aye goes. If you look for modules, it's where it goes. To post modules. Modules. It's where it goes to learn how to refactor modules. Refactor apps into modules. Etc."* The gallery is the **where-to-find-and-do-modules** surface. FVW v8 is **the rules for how to find, post, and refactor modules**. So the doctrine belongs with the gallery, because the doctrine is the meta-of-what-the-gallery-does. Today, the gallery's `registry-plan.md` Section H Q5 says: *"My proposal: gallery is the source of truth; studio consumes the gallery's registry."* — and Section A asks: *"if I have a module with proprietary bits I don't want to share, how do I split it?"* The gallery is being designed as a **doctrinal hub**, not just a module pool. The doctrine living there is consistent with that direction. The studio (fvs) is the **where-the-app-runs** surface. It has its own constitutional home (the FVS pact), its own Mavis workflow, its own drift-check. It uses FVW v8 as a *reference* — it doesn't *own* FVW v8. After this change, fvs becomes a **mirror of the doctrine**, with a freshness check that makes drift observable. --- ## 7. Summary | Question | Answer | |---|---| | Where should FVW v8 canonical home be? | **`avidtech6/fv-module-gallery/gallery-pact/fvw/`** | | What is the sync model? | **Bidirectional**: gallery → consumer (down mirror), consumer self-checks freshness, consumer → gallery (up contribution via PR) | | How does an AI session use this? | **Pull** module + doctrine from gallery, **mirror** to local paths, **check freshness**, operate, **contribute back** via PR | | What existing repos change role? | fvs/pact/freshvibe-way-v8/ becomes a mirror (was: de facto canonical). freshvibe-way-v8 (top-level repo) gets archived. The gallery's fvw/ copy becomes canonical (was: self-contained). | | What's the freshness check? | A small script that diffs the local mirror against the canonical. ~50 lines. Exit 0 if in sync, exit 1 if drift. Runs as a GitHub Action or a cron in fva-control-panel. | | What consumers change? | oscar-platform pact/, fvre pact/, freshvibe-dochub fvw-v8.md, plus all `app-pact/`-bearing apps add "source attribution" notes. | | What's the rollout? | 5 steps: decision-record, catch up the gallery, set up the sync mechanism, archive the deprecated repo, update consumers. Plus 4 verifications. | | What's the cost? | One decision record. One sync (1 file). One GitHub Action or cron (~50 lines). One CLI tool for AI sessions (~200 lines). One repo archive. Plus updating ~7 consumer docs with "source attribution" lines. Total: 1 day of work. | The next thing to do: get the operator's approval on the direction, then write the decision record. Want me to draft it? --- *Compiled 2026-07-22 by Mavis from: 7 places that carry FVW-derived material, 1 already-deprecated top-level repo with its own AGENTS.md, 1 self-declared mirror at the gallery, 1 freshness-check gap (the fvs pact-coherence.yml is advisory + intra-repo only), 1 already-rolled-back Sync Action GitHub App (2026-06-25, the lessons of which are in freshvibe-way-v8/AGENTS.md), and the operator's direction stated in this conversation.*