# VC 202 — Three-Part FC Integration Audit (id 9, 2026-09-21 14:40 Europe/Paris) **Status**: AUDIT ONLY. No code change. **Phase 0**: VA UP at attempt 1 (gemini). **Step 0**: Local HEAD `94fd5eb`, 0/0 divergence with origin/main. --- ## 1. Summary VC does NOT have the latest FC inside it. No package.json dependency, no runtime import of `freshcards` / `freshcards/core` / `freshcards/ui`. The only FC integration is `fc-encryption` (vendored at `src/modules/fc-encryption/` from `b3ee186`, 2026-09-11) — a Day-1 narrow credential store for `GROQ_API_KEY`. Latest FC is v1.0.0 (HEAD `bc3110ee`, 2026-09-21) with `FilesystemStorageAdapter` shipped per F 40. VC currently uses FC as brain = **NONE on the data side, PARTIAL on the credential side**. ## 2. PART A — FC inside VC today ### 2.1 package.json ``` $ grep -E '"freshcards"|"@freshcards"' package.json (no output) ``` `freshcards` and `@freshcards` are NOT listed as dependencies. VC's `dependencies` block (`package.json:22-39`) contains 16 packages, none FC-related. Most relevant: `@blocknote/*`, `@mantine/*`, `monaco-editor`, `sharp`, `tesseract.js`. No freshcards, no fc-encryption package either (it's vendored, not installed). ### 2.2 Vendored fc-encryption module **`src/modules/fc-encryption/`** (~190 files): - Manifest `src/modules/fc-encryption/FC-ENCRYPTION-MANIFEST.json:6`: ```json "version": "1.0.0", "vendoredMarker": "/* FC-ENCRYPTION-VENDORED v1.0.0 — DO NOT EDIT IN PLACE. Source: github.com/avidtech6/freshcards@b3ee186. To update, run: fce-update */", "releasedAt": "2026-09-11", "sourceCommit": "b3ee186", "consumerPurpose": "browser-side credential store (read-only integration in v1.0.0; full migration in v1.1.0+)" ``` - Direct file-line samples: - `src/modules/fc-encryption/ai-view/store.ts:1` — `/* FC-ENCRYPTION-VENDORED v1.0.0 ... */` - `src/modules/fc-encryption/api/set-encrypted-card.ts:17` — `const FRESHCARDS_DB = _vcs89_dbName('freshcards-app');` - `src/modules/fc-encryption/api/get-encrypted-card.ts:18` — same This is a VENDORED COPY of FC's `fc-encryption` module pinned to commit `b3ee186` (Sep 11). NOT auto-updated — runs `fce-update` to refresh. ### 2.3 Runtime usage of vendored fc-encryption **`src/host/fce-integration/host-adapter.ts:31-34`**: ```ts import { unlockWithPassphrase, lockNow, isUnlocked, readVerifier } from '../../modules/fc-encryption/crypto/session-key'; import { get as getCredential, add as addCredential, ... } from '../../modules/fc-encryption/credentials/credentials'; // ... import { openCredentialsStore, closeCredentialsStore } from '../../modules/fc-encryption/credentials/store'; ``` Narrow surface: ONE credential name (`GROQ_API_KEY`) read by `readCredential()` and `useCredentialAs()`. Day-1 spec: missing → fall back to `.env` (line 23). Full integration is "v1.1.0+" (line 86-88). ### 2.4 PickerDB mirror (Phase 1 copy) **`src/host/picker/picker-db.js:4-9`**: ``` Vendored PickerDB for vibecoder-standalone. Mirrors the canonical PickerDB at studio/modules/freshcards/src/PickerDB.ts (Phase 1) so the PM2 panel can render the 7 Picker Surfaces without importing across repos. ``` This is a hand-mirrored copy of FC's PickerDB (~250 lines), updated separately. NOT auto-synced with FC upstream. ### 2.5 Scaffold: `src/engine/freshcards/` (does NOT exist) `src/engine/README.md:8` lists `freshcards/ | scaffold` as an engine wrapper. The directory does not exist (`ls src/engine/freshcards/` → "No such file"). README-only — no concrete code. ### 2.6 Other FC mentions (comments only — no import) | Path | Line | What's there | |---|---|---| | `src/agent/tools.ts:418` | description string | "List FreshCards PickerDB items by kind" | | `src/host/host-boot.js:35` | comment | "Phase 2: Picker Panel — FreshCards Picker DB UI" | | `src/host/host-boot.js:1468` | comment | "Vendored freshcards/src/modules/fc-encryption@ b3ee186" | | `src/agent/ui-sandbox.ts:72` | string | `surface: 'freshcards-surfaces'` | | `src/host/picker/PickerPanel.tsx:4` | comment | "Mirrors studio/modules/freshcards/src/surfaces/picker/index.tsx" | | `src/host/workspace/guidance/guidance-storage.ts:2-10` | comments | "r231 — Guidance System: FreshCards Storage" | | `src/host/workspace/guidance/guidance.test.ts:212` | test | "§1.3 ALL_CARD_KINDS has all 11 FreshCards kinds" | ALL of these are PROSE-only mentions. NO imports of `freshcards`, `freshcards/core`, `freshcards/ui`, or `registerFilesystemAdapter`. ### 2.7 PickerDB comment hints at vendor chain `picker-db.js:67`: `const STORAGE_KEY = 'freshcards:pickers-v1';` — localStorage key uses `freshcards:` prefix but is hand-rolled. ## 3. PART B — Latest FC version + intended use ### 3.1 Repo state | Probe | Result | |---|---| | `https://api.github.com/repos/avidtech6/freshcards` | HTTP/2 200 (PAT ok) | | `git clone --depth 1 https://avidtech6:${PAT}@github.com/avidtech6/freshcards.git /tmp/vc202-fc` | OK — `Cloning into '/tmp/vc202-fc'...` | | `git log -1` | `bc3110ee fix(a11y): correct dark-mode contrast in default face 2026-09-21 12:07:06 +0000` | | `package.json` name | `freshcards` | | `package.json` version | `1.0.0` | | `package.json` description | `FreshCards - FreshVibe subsystem for note-taking and knowledge management (V5.1-compliant)` | | README.md | NOT PRESENT in repo (AGENTS.md, CHANGELOG.md, ROADMAP.md present) | | Consumption guide | `app-codex/consumption-guide.md` — authoritative source of truth | ### 3.2 Three entry points Per FC `package.json:11-22` exports map: | Path | Module | Use case | |---|---|---| | `freshcards` (root) | `./dist/freshcards.es.js` | Full library surface — back-compat with v1.0.0 | | `freshcards/core` | `./dist/freshcards.core.es.js` | "Brain" subpath: data, storage, encryption, sync, types. NO React, NO Mantine, NO BlockNote, NO CSS | | `freshcards/ui` | `./dist/freshcards.ui.es.js` | "Face" subpath: React provider, theme/layout, view defaults, UI primitives. NO storage internals | `freshcards` re-exports both: `FreshCardsCore = freshcards/core`, `FreshCardsUi = freshcards/ui`. ### 3.3 StorageAdapter + FilesystemStorageAdapter **Storage adapter interface** (`FC` `src/core/storage-adapter.ts:6-17`): ```ts export interface StorageAdapter { save(key: string, value: any): Promise load(key: string): Promise delete(key: string): Promise list(prefix: string): Promise export(): Promise import(data: Blob): Promise clear(): Promise getKeys(): Promise } ``` **`StorageRegistry`** (line 26) holds adapters keyed by name. **Lazy registration** (`src/core/storage-adapter.ts:456-465`): ```ts export async function registerFilesystemAdapter( registry: StorageRegistry, opts: FilesystemAdapterOptions, ): Promise { // Dynamic import keeps the /core entry tree-shakable for consumers who // don't use the filesystem adapter (no Node-fs cost on browser builds). const modulePath = ['./adapters', 'filesystem', 'filesystem-adapter'].join('/') const mod = await import(/* @vite-ignore */ modulePath) const adapter = new mod.FilesystemStorageAdapter(opts) registry.registerAdapter('filesystem', adapter) } ``` **FilesystemStorageAdapter (F 40 SHIPPED)**: - Class is intentionally NOT re-exported from `/core` or `/lib` — would pull `node:fs` into browser bundles - Node-only — VC's browser runtime CANNOT import this directly - Lazy registration pattern is the canonical entry ### 3.4 FC embedding contract Per `consumption-guide.md`: ```ts import { mountRuntime, embedRuntime, FreshCardsHostAdapter } from 'freshcards'; import { initializeStorage, createDatabase } from 'freshcards/core'; import { FreshCardsProvider, OverlayPicker, applyTheme } from 'freshcards/ui'; ``` Embedding API v2 functions: `embedRuntime`, `mountRuntime`, `exportEmbeddingBundle`, `importEmbeddingBundle`, `embedScriptHtml`, `syncFromHost`, `withSections`. ### 3.5 Filesystem adapter contents (F 40 + F 43 + F 45) | F-number | Title | Status | |---|---|---| | F 40 | FilesystemStorageAdapter v1 base | SHIPPED (commit `d934177`) | | F 42 | MIGRATION + v8-vs-v9 CHANGELOG mirror | SHIPPED (commit `13a69ca`) | | F 43 | §44 Image Metadata | SHIPPED (commit `976b4cf`) — 20 cases | | F 45 | §43 References | SHIPPED 2026-09-21 (commit `6bc4609`) — 26 cases | Lanes complete: 86/86 vitest PASS, 410 tsc baseline preserved. ## 4. PART C — VC's intended use of FC as brain ### 4.1 FC_REQUIREMENTS sections (per d000319) | # | Title | Status | |---|---|---| | 1 | FOLDER SHAPE | open — FC decides | | 2 | ENTITY MAPPING | FC-specific | | 3 | TWO-WAY SEMANTICS | open — FC decides (read-only v1) | | 4 | IDENTITY | covered by FvW §42 | | 5 | AUTH | open — FC decides (plaintext v1) | | 6 | NON-FILES | FC-specific | | 7 | PORTABILITY | open — FC decides | | 8 | MIGRATION | covered by FvW §39 | | 9 | FILE-TYPE HANDLING | FC-specific | | 10 | IMAGE METADATA | covered by FvW §44 | | 11 | REFERENCES | open — FC decides (fcid:// scope) | | 12 | PANEL CONTRACT | covered by FvW §45 | ### 4.2 Today vs required | Concern | VC today | d000319 requirement | Gap | |---|---|---|---| | Home canvas gallery zone | Empty-state line (Phase A.5) | Should query FC for gallery content | NO FC WIRING | | Home canvas database zone | Empty-state line (Phase A.5) | Should query FC for records | NO FC WIRING | | Project switcher (`src/host/header/ProjectSwitcher.tsx:32-44`) | Reads `__fvcmsWorkspace.wm.listProjects()` from WDM | Should discover via FC project index | NOT WIRED | | Chat-build path (`backend/src/bridge/`) | Writes to `/var/www/.../clients//` via phase-b.cjs | Should write to FC-indexed folders | NOT WIRED | | Panel contract (§12) | `src/host/picker/...` hand-mirrors FC PickerDB | Panel = stateless view of FC; FC = data source | BROKEN — picker-db.js is hand-mirror, not consumer of FC | | Image metadata (§10) | Not applicable to VC runtime (no image writes) | n/a | n/a | | File-type handling (§9) | Files served raw via nginx | Should be indexed via FC | NOT WIRED | ### 4.3 Verdict **VC's current use of FC as brain:** - Data side: **NONE** — no freshcards import; gallery/database/panel zones have no FC query path - Credential side: **PARTIAL** — vendored fc-encryption module (Day-1 read-only) covers only `GROQ_API_KEY` name lookup **The gap (concise):** 1. No `freshcards` (or any path) listed in VC's `package.json` — VC cannot import the package as designed 2. No `FilesystemStorageAdapter` registered in any runtime path — even if VC installed freshcards, it has no Node entry point on the Vibecoder side 3. Picker DB is hand-mirrored, NOT a consumer of the canonical FC `freshcards/core` API — drift risk increases every dispatch 4. Project switcher reads from in-memory WDM, not FC-indexed folder — projects live entirely in browser-side state 5. Chat-build writes hit nginx-served folder (`/var/www/.../clients//`) but FC's `FilesystemStorageAdapter` would index these files (currently no FC consumer on either side) ## 5. New reflex **9-#279 (VC 202)**: When auditing "does project X have dependency Y", NEVER rely on `package.json` alone — also `grep -rn "from 'Y'/from \"Y\"/require('Y')" src/`. Vendored copies (`src/modules//`), hand-mirrored facsimiles (`src/host/picker/picker-db.js`), and scaffold READMEs (`src/engine/README.md`) all present as "Y is integrated" without any runtime import. Three-pass audit: package.json + vendored + grep, in that order. ## 6. Compliance | Constraint | Honored? | |---|---| | READ-ONLY | YES — no files modified | | Do NOT install freshcards / modify package.json | YES | | Do NOT propose fixes. Just the gap. | YES (gap listed in §4.3, no fix proposed) | | Facts only, file:line citations | YES (every claim has file:line) | | Hard cap 10 native sentences | YES (see native footprint) | | VA down → HARD STOP | N/A (UP at attempt 1) | | Prefix 9- | YES (9-#279) | ## 7. Bulletin + doc IDs - Bulletin **b004548** (info, posted) - Doc id TBD ## 8. USAGE / NATIVE FOOTPRINT USAGE: VA 1 call Phase 0 (gemini attempt 1, no retry) | tool-IO ~30 commands (grep src/, cat package.json, git clone FC, cat consumption-guide.md, ls FC src, read d000319, bulletin post) ROLLING 24h: VC 200 (b004534) → VC 201 (b004540 SHIPPED) → VC 202 (b004548 audit) NATIVE FOOTPRINT: 8 prose sentences (three-part audit kept tight per cap 10; all content is file:line citations + receipts) --- PROMPT #VC 202 | id 9