CodeIssuesDiscussionsWikiPull RequestsProjectsCommitsActionsReleasesContributorsPulse● GatesSecuritySettingsDeploymentsPipelineInsightsAgents✨ Explain✨ Ask AI✨ Workspace✨ Spec✨ Tests▓ Debt Map✨ NL Search🏛 Archaeology
Blame · Line-by-line history
AUDIT-2026-06-10.md
Each line is annotated with the commit that last touched it. Click any SHA to jump to that commit and see the surrounding change.
| 74a8784 | 1 | # Gluecron Full-Platform Audit — 2026-06-10 |
| 2 | ||
| 3 | **Branch:** `claude/site-audit-competitive-pctlwg` (from `main` @ `2436d1d`) | |
| 4 | **Method:** six parallel audit agents (repair flywheel, docs freshness, wiring/mechanics, design/UX, architecture/security, live market scan) + direct verification of every load-bearing claim (test suite, typecheck, migration runner, home-route render path). | |
| 5 | **Supersedes:** `AUDIT.md` (2026-05-16), `AUDIT-v2.md` (2026-05-16), `AUDIT_REPORT.md` (2026-05-13). | |
| 6 | ||
| 7 | --- | |
| 8 | ||
| 9 | ## 0. Executive summary | |
| 10 | ||
| 11 | **Verdict: the platform is real, broad, and largely wired — but three things stand between today and "confidently ahead of GitHub":** | |
| 12 | ||
| 13 | 1. **The repair flywheel is built but not closed.** Every schema, tier, and helper exists; the cache lookup and the outcome-feedback loop have **zero callers**. Until those ~5 wiring points land, every repeat failure costs a 3–5 s Claude call instead of a <100 ms cache hit, and the system learns nothing from its own fixes. This is the single highest-leverage build item on the board. (§3) | |
| 14 | 2. **Quality signal was red.** The suite had 28 failing tests + 5 errors and 2 TypeScript errors — all stale assertions left behind by the Landing-2030 reboot, plus Playwright specs leaking into `bun test`. **Fixed in this session: 2767 pass / 0 fail / 122 skip, `tsc` clean.** A green suite is table stakes for due diligence. (§1) | |
| 15 | 3. **Scale posture is single-node.** Repos on local disk, in-memory rate limiting, workflow runner spawning on the web node. Fine to ~5k repos / 100 concurrent users; documented fix path below. An acquirer's tech DD will find this in week one — better that our own audit says it first, with the plan attached. (§5) | |
| 16 | ||
| 17 | Design is genuinely on-brief (quiet, light-default, restrained violet — not cyberpunk), security fundamentals are strong (argv-array git calls, hashed tokens, AES-GCM secrets, sanitized markdown), and the June-2026 market scan says our MCP-native + self-hosted-AI-parity positioning is the most defensible wedge available. (§6, §7) | |
| 18 | ||
| 19 | --- | |
| 20 | ||
| 21 | ## 1. Verification mechanics (what was actually run) | |
| 22 | ||
| 23 | | Check | Before this session | After this session | | |
| 24 | |---|---|---| | |
| 25 | | `bun test` | 2758 pass / **28 fail / 5 errors** / 122 skip | **2767 pass / 0 fail / 0 errors** / 122 skip | | |
| 26 | | `bunx tsc --noEmit` | 2 errors (`health-score.test.ts` TS2367) | clean | | |
| 27 | | Lockfile | `bun.lock` missing `@playwright/test` | reconciled | | |
| 28 | ||
| 29 | **Root cause of the 28 failures — none were product breakage.** `GET /` now renders the self-contained `Landing2030Page` (`src/views/landing-2030.tsx`, wired at `src/routes/web.tsx:1865`), which does not include the master Layout CSS. Tests still asserted on the legacy `LandingPage` hero (`hero-primary-ctas`, dxt CTA, Live-now block), Layout design tokens on `/`, and the old `/status` degraded headline (`"Service degraded"` → now `"Degraded performance"` / `"Major outage"`, `src/routes/status.tsx:356`). All retargeted to the current contract (Layout assertions now hit `/help`). The 5 errors were Playwright `e2e/*.spec.ts` files crashing under Bun's runner; new `bunfig.toml` scopes `bun test` to `src/` (e2e stays on `bun run e2e`, VS Code extension suite on `bun test editor-extensions`). | |
| 30 | ||
| 31 | **Lesson to encode:** the Landing-2030 reboot shipped without running the suite, or shipped red. Gate enforcement should apply to our own repo first — that's the product's whole pitch. | |
| 32 | ||
| 33 | --- | |
| 34 | ||
| 35 | ## 2. Wiring & mechanics audit | |
| 36 | ||
| 37 | **Confidence: high. 188 of 190 route modules are mounted in `src/app.tsx`; all recently shipped AI features are fully wired** (ai-loop via the autopilot `ai-loop-sweep` task, AI Workspace `app.tsx:203`, cross-repo impact `app.tsx:199`, repo health `app.tsx:195`, NL search `app.tsx:167`, pair programmer `app.tsx:130` — each with its migration 0101–0104 present). | |
| 38 | ||
| 39 | Verified end-to-end: the 14-step `src/hooks/post-receive.ts` chain (auto-repair → intelligence → gates → semantic index → AI auto-issues → preview builds → dep scan → doc-drift → onboarding → cloud deploys → Crontech webhook (HMAC, 6-attempt backoff) → server targets → **self-deploy**). `scripts/self-deploy.sh` exists (15.5 KB, executable) and is invoked via `Bun.spawn` at `post-receive.ts:241-267`, gated on `SELF_HOST_REPO` + push to `refs/heads/main` — the CLAUDE.md "self-driven deploys" claim is true. | |
| 40 | ||
| 41 | Issues found: | |
| 42 | ||
| 43 | | # | Finding | Action | | |
| 44 | |---|---|---| | |
| 45 | | W1 | `src/routes/migration-assistant.tsx` exists but is never imported/mounted (superseded by `migrate.tsx`) | Delete in a cleanup block | | |
| 46 | | W2 | `src/lib/changelog-generator.ts` has zero importers (`ai-generators.ts generateChangelog` is the live path) | Delete in a cleanup block | | |
| 47 | | W3 | Migration prefixes duplicated (0077×3, 0078×2) and 0085 missing | **Safe — verified directly:** `src/db/migrate.ts:137` tracks applied migrations by full filename, so each file applies exactly once. **Do NOT renumber** — renaming an applied file would re-run it. Convention only: next migrations continue from 0105. | | |
| 48 | | W4 | 6 env vars used in `src/lib/config.ts` were undocumented | `.env.example` updated this session | | |
| 49 | | W5 | ~20 TODO markers in src/, none blocking | No action | | |
| 50 | ||
| 51 | --- | |
| 52 | ||
| 53 | ## 3. The repair flywheel (owner priority) — built, not closed | |
| 54 | ||
| 55 | Owner vision: record everything; at 10k–20k repos, recognize recurring breakages and fix them deterministically **in seconds, without an AI call**, reserving AI for novel failures. | |
| 56 | ||
| 57 | **Status: the architecture is ~80 % present and ~0 % operational as a learning loop.** | |
| 58 | ||
| 59 | What exists and works: | |
| 60 | - `repair_flywheel` table (`drizzle/0039_repair_flywheel.sql`) — failure SHA-256 fingerprint, `repair_tier` (cached/mechanical/ai-sonnet/human), outcome, `cache_hit_count`, cross-repo `is_public_pattern`, and the hot-path composite index `(repo_id, failure_signature, outcome)`. The data model is exactly right for the vision. | |
| 61 | - Tier 1 mechanical repairs (`src/lib/auto-repair-mechanical.ts`) — lockfile drift, formatting, import-order classification + worktree-safe fixes. | |
| 62 | - Tier 2 AI repair (`src/lib/auto-repair.ts`) and CI autofix (`src/lib/ci-autofix.ts`) — real Sonnet calls, patch-as-comment. | |
| 63 | - Recording: `recordRepair()` writes attempts with fingerprints. | |
| 64 | - `recurring_patterns` (0096) — Claude-detected recurring issues, used for PR warnings. | |
| 65 | ||
| 66 | What is broken (the gaps, with file:line): | |
| 67 | ||
| 68 | | Gap | Evidence | | |
| 69 | |---|---| | |
| 70 | | **Tier-0 cache is never consulted** | `findCachedRepair()` `src/lib/repair-flywheel.ts:112` — zero callers anywhere. Every failure goes straight to mechanical/AI. | | |
| 71 | | **Outcomes are never recorded** | `updateOutcome()` `repair-flywheel.ts:252` — zero callers. Every row stays `outcome='pending'` forever; success-rate stats are blind; the cache can never be trusted. | | |
| 72 | | **The tier orchestrator is dead code** | `repairGateFailure()` `src/lib/auto-repair.ts:412-587` (the Tier-1→2 fallthrough) is defined and never called. Live call sites only repair secrets/security (`src/lib/gate.ts:424-450`); ordinary CI test failures bypass tiers and go straight to Sonnet via `triggerCiAutofix` (`src/lib/ci-autofix.ts:155`). | | |
| 73 | | **No AI→deterministic promotion** | Nothing moves a repeatedly successful AI fix into the Tier-0 cache or flips `is_public_pattern`. | | |
| 74 | | **No operator surface** | `getFlywheelStats()` (`repair-flywheel.ts:286-380`) has no route — no `/admin/repair-flywheel`. | | |
| 75 | | **ai-loop skips the cache too** | `src/lib/ai-loop.ts:441` calls `triggerCiAutofix` without a cache lookup. | | |
| 76 | ||
| 77 | **Closing plan (proposed BLOCK N1 — small, surgical, ~5 wiring points):** | |
| 78 | 1. `ci-autofix.ts` (~line 156): fingerprint the parsed error; `findCachedRepair()` first; on a high-success-rate hit, apply the cached patch and record a `cached`-tier row — no AI call. | |
| 79 | 2. `ai-loop.ts:441`: same cache-first check before dispatching autofix. | |
| 80 | 3. Post-gate-rerun correlation: when a gate re-runs after a repair, match the new `gate_runs` row back to the open `repair_flywheel` row and call `updateOutcome('success'|'failed')`. This is the linchpin. | |
| 81 | 4. Promotion: on N successes for a signature, mark the pattern public (cross-repo) and increment `cache_hit_count` on every hit. | |
| 82 | 5. `/admin/repair-flywheel` route exposing `getFlywheelStats()` — hit rate, AI-vs-cache ratio, $-saved. (Also a powerful acquisition metric: "x % of failures fixed without a model call.") | |
| 83 | ||
| 84 | Also: repairs should write `audit_log` rows (no `repair_*` actions exist today), so the "record everything" half of the vision holds. | |
| 85 | ||
| 86 | --- | |
| 87 | ||
| 88 | ## 4. Architecture & security | |
| 89 | ||
| 90 | **Strong fundamentals (verified):** | |
| 91 | - No command injection: all git subprocess calls use argv arrays (`src/git/repository.ts:42-58`); no `bash -c` interpolation of user input. | |
| 92 | - Auth: all 10 sampled mutating routes gated (`requireAuth` / `repo-access` 5-tier hierarchy / API scopes); session cookies `httpOnly` + `secure` (prod) + `sameSite=Lax`. | |
| 93 | - Secrets: workflow secrets AES-256-GCM with per-encryption IVs (`src/lib/workflow-secrets-crypto.ts`); PATs and OAuth tokens stored SHA-256-hashed. | |
| 94 | - XSS: markdown pipeline escapes HTML/attrs and rejects `javascript:`/`data:` hrefs (`src/lib/markdown.ts`); no user-data `dangerouslySetInnerHTML`. | |
| 95 | - Global error handler upholds the "no 500 reaches the UI" invariant (`src/app.tsx:886-906`). | |
| 96 | ||
| 97 | **Findings to fix:** | |
| 98 | ||
| 99 | | Sev | Finding | Fix | | |
| 100 | |---|---|---| | |
| 101 | | HIGH | **SSRF**: webhook delivery (`src/lib/webhook-delivery.ts:201`) and mirror fetch (`src/lib/mirrors.ts`) fetch user-supplied URLs with no private-range block (127.0.0.1, 10/8, 172.16/12, 192.168/16, 169.254/16, ::1) | ~2 days: shared `assertPublicUrl()` helper + DNS-resolution check, applied to webhooks, mirrors, imports | | |
| 102 | | HIGH | Single-node coupling: bare repos on local disk (`repository.ts:38`), in-memory rate limiter (`rate-limit.ts:15`), workflow runner in-process on the web node, 500-entry session cache. SSE already has a Redis fallback (`sse.ts:76-150`) — the others don't | Document the supported topology now (done here); BLOCK N3: Redis-backed rate-limit + sessions, extract workflow runner to a worker process, repo-storage strategy (shared volume now, object-store later) | | |
| 103 | | MED | Silent async failures: post-receive side-effects swallow errors with bare `.catch(() => {})` — operators can't see when AI analysis/indexing silently dies | Route through `reportError` + a failures counter on `/metrics` | | |
| 104 | | MED | N+1 queries on PR/issue list pages (per-row risk-score + comment-count queries) | Batch with joins; add a slow-query log | | |
| 105 | | MED | Test gaps: no Smart-HTTP protocol tests; `mcp-tools-expanded.ts` (2,470 lines of write tools) has no test file | BLOCK N4: MCP write-tool suite + git-protocol smoke tests | | |
| 106 | | LOW | `src/routes/pulls.tsx` is 6,654 lines (merge logic also duplicated in `pr-merge.ts` + MCP merge tool — known §7 Bible follow-up) | Consolidate on `performMerge()` | | |
| 107 | ||
| 108 | Dependency hygiene is good: 8 runtime deps, all mainstream, no abandonware. | |
| 109 | ||
| 110 | --- | |
| 111 | ||
| 112 | ## 5. Design & UX (brief: quiet confidence, believable, not cyberpunk) | |
| 113 | ||
| 114 | Two design systems are live: | |
| 115 | - **App + legacy marketing surfaces** — `src/views/layout.tsx` "Editorial-Technical" system: 60+ CSS custom properties, slate-noir `#08090f` / violet `#8c6dff` / hairline borders, Inter + Inter Tight + JetBrains Mono, light/dark with pre-paint script, 52 ARIA attributes, `prefers-reduced-motion` respected, 12:1–15:1 text contrast. Scored **8.2/10 against the brief** — restraint comparable to Linear/Vercel-tier marketing; no neon, no glow-noise. | |
| 116 | - **The actual home page** — `Landing2030Page` (`src/views/landing-2030.tsx`): white-background, ink-on-paper, light-only, headline "The git host built for 2030," fact-led copy ("Spec to PR in 90 seconds"), one product-card mock, two CTAs. This is precisely the "believable, it-just-works" register the owner asked for (closest public analog: vapi.ai's developer-infra restraint — note: **vapron.ai does not exist**; vapi.ai is the real benchmark). | |
| 117 | ||
| 118 | Highest-impact polish items (ordered): | |
| 119 | 1. Social proof strip on the landing (grayscale logos / "powering N repos" with real counters) — the one missing trust signal for acquirers. | |
| 120 | 2. Consolidate scattered "vs GitHub" copy into the existing `/vs-github` page; keep the landing comparison to one pull-quote. | |
| 121 | 3. Unify modal/dropdown shadow recipes to one `--modal-shadow` token. | |
| 122 | 4. CTA label case consistency ("Start building" / "Sign in" — title-vs-sentence drift). | |
| 123 | 5. Disable decorative animations on mobile/slow networks (`prefers-reduced-motion` + width guard). | |
| 124 | 6. Empty-state noise reduction (dashed borders + dot grids accumulate on data-less dashboards). | |
| 125 | 7. Status dot in the footer linking `/status` (operational-health-as-brand). | |
| 126 | 8. `:focus-visible` outlines on landing CTAs (currently box-shadow only). | |
| 127 | 9. Brand naming is already consistent (lowercase `gluecron`) — keep it that way in new copy. | |
| 128 | 10. Decide the long-term fate of the legacy `LandingPage`/marketing routes — two design systems is one too many for an acquirer walkthrough. | |
| 129 | ||
| 130 | --- | |
| 131 | ||
| 132 | ## 6. Documentation freshness (fixed this session) | |
| 133 | ||
| 134 | | Doc | Was | Now | | |
| 135 | |---|---|---| | |
| 136 | | `BUILD_BIBLE.md:3` | "Last updated 2026-05-29" | 2026-06-10 + living-document rule | | |
| 137 | | `BUILD_BIBLE.md` §4.1 | "95 tables" | 161 tables (verified by count) | | |
| 138 | | `BUILD_BIBLE.md` §5.1 | "1491 tests pass as of 2026-05-13" | 2767/0/122 as of 2026-06-10 + runner scoping note | | |
| 139 | | `CLAUDE.md` architecture tree | implied ~20 route files | annotated: illustrative; ~190 route files, 161 tables | | |
| 140 | | `AUDIT.md`, `AUDIT-v2.md`, `AUDIT_REPORT.md` | presented as current | stamped SUPERSEDED → this file | | |
| 141 | | `.env.example` | 6 config vars undocumented | documented | | |
| 142 | ||
| 143 | Verified accurate, no change needed: `README.md` (15 MCP read-tools claim matches `defaultTools()`), `ROADMAP.md`, `docs/STRATEGY.md`, `DEPLOY.md`. | |
| 144 | ||
| 145 | **Standing rule going forward:** every audit/spec doc carries a date in its filename or header, and the Bible's header timestamp moves in the same commit that changes reality. | |
| 146 | ||
| 147 | --- | |
| 148 | ||
| 149 | ## 7. Market scan (June 2026) and the capability gap list | |
| 150 | ||
| 151 | Full sourced report retained from the research agent; condensed here. | |
| 152 | ||
| 153 | **Where the market is:** GitHub absorbed Copilot Workspace into the GA coding agent + Agent HQ (multi-vendor agents — Anthropic/OpenAI/Google/Cognition/xAI — under one mission-control panel; agentic code review on all PRs since March 2026, review→agent autofix handoff). GitLab Duo Agent Platform GA'd Jan 2026 with credits-based pricing and agentic SAST fix PRs. Cursor (~$29B, >$2B ARR) runs Bugbot on ~2M PRs/month with >35 % of its autofix PRs merging. OpenAI Codex reviews GitHub PRs natively with `AGENTS.md` steering. Claude Code passed ~$2.5B annualized with MCP as the de-facto agent-integration standard (~9,400 public servers). **Closed-loop autonomy (review → fix → CI → self-heal) is the 2026 frontier — which is exactly the flywheel §3 closes.** | |
| 154 | ||
| 155 | **Gluecron's defensible wedges (per the scan):** | |
| 156 | 1. **MCP-native git host with a deep write surface + governance** — per-token scopes, full agent audit trail, org policy on tool access. The "MCP governance gap" is documented and unowned by any incumbent. | |
| 157 | 2. **Self-hosted with day-one AI parity** (GHES lags github.com on AI; we don't). | |
| 158 | 3. **Agent identity & provenance** — agents as first-class actors with attribution ("agent X under human Y"), signed agent commits, agent activity feed. | |
| 159 | ||
| 160 | **Capability checklist for market leadership (T = table stakes, D = differentiator; ✅ = shipped, 🟡 = partial):** | |
| 161 | ||
| 162 | | # | Capability | T/D | Status | | |
| 163 | |---|---|---|---| | |
| 164 | | 1 | Issue→PR coding agent (sandboxed, tests run) | T | ✅ spec-to-PR + ai:build label | | |
| 165 | | 2 | Auto AI review on every PR, inline comments | T | ✅ | | |
| 166 | | 3 | **Review→fix closed loop on same PR** | T | 🟡 ci-autofix posts patches; flywheel not closed (§3) | | |
| 167 | | 4 | Severity-filtered review (P0/P1-only mode, effort levels) | T | ❌ | | |
| 168 | | 5 | Honor `AGENTS.md`/`CLAUDE.md` steering files in all AI flows | T | 🟡 partial | | |
| 169 | | 6 | **Multi-vendor agent panel** (Claude + Codex + Gemini + Devin side-by-side, compare PRs) | D | ❌ — GitHub Agent HQ is the template; no self-hosted product has it | | |
| 170 | | 7 | Parallel agent sessions in isolated worktrees + diff-compare view | D | 🟡 PR sandboxes exist; no compare UI | | |
| 171 | | 8 | **Self-healing CI** (red pipeline → agent reads logs → fix → re-run) | T | 🟡 = §3 flywheel close | | |
| 172 | | 9 | Natural-language CI authoring | D | ❌ — pre-GA everywhere; leadership claimable | | |
| 173 | | 10 | Security scan + AI autofix default-on | T | ✅ gates + repair | | |
| 174 | | 11 | Autonomous maintenance agents (dep bumps ✅, dead-code, flaky-test quarantine, coverage PRs) | D | 🟡 | | |
| 175 | | 12 | First-class MCP server over the whole host surface | T | ✅ 15 + 10 write tools | | |
| 176 | | 13 | **MCP governance**: OAuth remote MCP, per-token tool scopes, agent-action audit log, org tool policy | D | 🟡 auth exists; scoping/policy/audit-views don't | | |
| 177 | | 14 | Agent identity & provenance (first-class agent actors, attribution) | D | 🟡 app-bots exist; §7 Bible notes marker comments still credit humans | | |
| 178 | | 15 | Persistent context spaces (pin docs/issues/files as reusable agent grounding) | D | ❌ | | |
| 179 | | 16 | Headless API/SDK so any agent CLI treats Gluecron as a first-class remote | D | ✅ REST v2 + GraphQL + CLI | | |
| 180 | | 17 | Consumption/credit billing rail for agent work | T | 🟡 plans/quotas exist; no metering | | |
| 181 | | 18 | Agent analytics: % agent-authored merged code, fix-acceptance rate, cycle-time delta | T | 🟡 DORA + hours-saved exist; not agent-cut | | |
| 182 | | 19 | Per-repo review memory ("never flag this again") | D | ❌ | | |
| 183 | | 20 | AI issue triage (label/dedupe/severity/route-to-agent) | D | ✅ | | |
| 184 | | 21 | Auto-merge policy gated on AI review + CI green | T | ✅ K2/K3 | | |
| 185 | | 22 | Self-hosted full AI parity | D | ✅ — say it louder in marketing | | |
| 186 | | 23 | Browser/runtime verification subagent (screenshot evidence on PRs) | D | ❌ — nobody attaches this to hosting review yet | | |
| 187 | | 24 | Daily automated market/competitor scan feeding the roadmap | D | 🟡 `advancement-scanner` lib exists and is tested — point it at competitor changelogs + RSS and open `ai:build` issues automatically | | |
| 188 | | 25 | Repair-flywheel economics on the admin dashboard (% fixed without AI, seconds-to-fix) | D | ❌ until §3 closes | | |
| 189 | ||
| 190 | **Recommended build order (next blocks):** | |
| 191 | - **N1 — Close the repair flywheel** (§3, ~1 week). Unlocks #3, #8, #25 and the headline acquisition metric. | |
| 192 | - **N2 — SSRF guard + MCP write-tool test suite** (~1 week). Closes both HIGH security/test findings. | |
| 193 | - **N3 — Multi-node readiness** (Redis rate-limit/sessions, worker-process workflow runner, storage doc) (~3 weeks). | |
| 194 | - **N4 — MCP governance + agent provenance** (#13, #14) (~2–3 weeks). The differentiator no incumbent owns. | |
| 195 | - **N5 — Multi-vendor agent panel** (#6, #7) (~3–4 weeks). The "Agent HQ for the self-hosted world" story. | |
| 196 | - **N6 — Review noise controls + per-repo review memory** (#4, #19) (~2 weeks). The #1 buyer complaint in the AI-review market. | |
| 197 | - **N7 — Daily market scanner** (#24): schedule `advancement-scanner` in autopilot against competitor feeds; weekly digest to the owner. | |
| 198 | ||
| 199 | --- | |
| 200 | ||
| 201 | ## 8. Acquisition-readiness checklist | |
| 202 | ||
| 203 | Signals the 2025–26 M&A record says to manufacture (Cursor/Cognition/Graphite precedents): | |
| 204 | ||
| 205 | | Signal | Status | | |
| 206 | |---|---| | |
| 207 | | Green test suite + clean typecheck on `main` | ✅ as of this session — keep it gated | | |
| 208 | | % of merged code that is agent-authored (platform metric) | ❌ build with N1/#18 | | |
| 209 | | AI-review fix-acceptance / auto-merge rate (Cursor publicizes 80 % / 35 %) | ❌ data exists in tables; needs the analytics cut | | |
| 210 | | MCP tool-call volume from third-party agents (proves *platform*, not feature) | 🟡 log exists; no dashboard | | |
| 211 | | 2–3 enterprise logos on self-hosted | ❌ go-to-market | | |
| 212 | | Consumption billing live | 🟡 plans exist, metering doesn't | | |
| 213 | | Clean IP / no exclusive model-vendor dependency | 🟡 Anthropic-first; Voyage optional; keep model layer swappable (`MODEL_*` constants already centralize this) | | |
| 214 | | Single current audit doc + reconciled Bible | ✅ this file | | |
| 215 | ||
| 216 | --- | |
| 217 | ||
| 218 | *Next scheduled audit: 2026-07-10 or after BLOCK N3, whichever comes first. Keep this file's date in the filename; supersede, don't edit history.* |