xlab devcorpus — proposal, foundation, parked
Date: 2026-05-12
Initiative: Portfolio-wide conversational search over the dev-reports corpus, powered by Gemini via Vertex AI Search
Status: 🅿️ Parked after Phase 2. Foundation live (zero ongoing cost), build deferred. Resume conditions documented below.
Companion: dogwood_phase01_pre_flight_2026-05-13.md
TL;DR
Walked the full arc — scope, foundation, mockup, decision — in one evening. Vertex AI Search engine xlab-devcorpus-app is live in audrey-experiments, indexing 58 markdown dev-reports from gs://xlab-devcorpus-md. Zero queries fired, so zero ongoing cost. The build out to a phone-friendly corpus.dare.co.uk is real — about 3 hours, under $5/month — but parked behind two higher-leverage threads: dogwood Phase 1 close-out tomorrow morning, and the broader pivot that AI voice for real customer problems beats AI search for self. Internal corpus chat is “mildly interesting”; customer-facing voice is the frontier.
The mockup itself is the deliverable for now — a cheap deliberation before commitment, per the mockup-before-full-build pattern. NotebookLM is queued as the throwaway phone-and-voice experiment to falsify the assumption that conversational corpus access is even a habit worth tooling for.
What now exists (paid: $0, parked-cost: $0)
| Resource | Identifier | State |
|---|---|---|
| GCP project | audrey-experiments (#683815192069) |
Reused; graduates to its own project if usage justifies |
| GCS bucket | gs://xlab-devcorpus-md |
us-central1, uniform access, public-access-prevention on |
| Corpus snapshot | 58 markdown files, 426 KB | One-shot upload 2026-05-12 02:47 UTC |
| Discovery Engine API | discoveryengine.googleapis.com |
Enabled in audrey-experiments |
| Data Store | dataStores/xlab-devcorpus |
Generic + unstructured + CONTENT_REQUIRED |
| Search Engine | engines/xlab-devcorpus-app |
Standard tier + LLM add-on (generative answers) |
| Import op | import-documents-14397311100980809223 |
Running at park time; indexing async |
Live preview surface (no build required):
https://console.cloud.google.com/gen-app-builder/engines/xlab-devcorpus-app/preview/search?project=audrey-experiments
The proposal in 60 seconds
Three artefacts and a sync trigger. GCS bucket holds the markdown corpus, Vertex AI Search Data Store indexes it, a Search App exposes conversational query with Gemini-grounded citations. A GitHub Action on devreports-content push keeps the corpus fresh (Phase 3, deferred). Scope:
| In | Out |
|---|---|
All dare_*, audrey_*, dogwood_*, audit + session + narrative markdown |
Real-time Cloudflare analytics, live secrets, source code |
| Cross-portfolio queries with conversational follow-up | Embedded chat widget on existing surfaces |
| Citations linked to source reports | Anything requiring live tool-calling |
Original scope: [proposal in chat 2026-05-12, captured here in this report].
Phases — built vs parked
| Phase | What | State | Cost |
|---|---|---|---|
| 0 | Enable Discovery Engine API; check billing/quota | ✅ done in 5 min | $0 |
| 1 | Create GCS bucket; one-shot gcloud storage cp of corpus |
✅ done in 10 min | $0 (storage on 426KB is rounded to free) |
| 2 | Create Data Store + Engine via REST; import op kicked off | ✅ done in 15 min | $0 (indexing free under quota) |
| 3 | GitHub Action auto-sync on devreports-content push | 🅿️ parked | — |
| 4 | ~/bin/devcorpus CLI (with xlab-devcorpus-runtime-sa scoped SA) |
🅿️ parked | — |
| 5 | corpus.dare.co.uk — Pages + Worker + Access policy |
🅿️ parked | — |
Disproof criteria from the proposal still hold and now have concrete owners:
- Quality: smoke test ≥15 of 20 queries return grounded, cited, correct answers. Test surface = the live console preview tomorrow.
- Habit: any 7-day window post-Phase-4 with zero queries → archive.
- Cost: unexpected spend past $20/mo at personal volume → misconfiguration.
UI sketch — what corpus.dare.co.uk would have looked like
Mockup-only at park time. The mockup is the deliverable: cheap deliberation before a 3-hour build.
┌─────────────────────────────────────────────────────────────┐
│ devcorpus dan@dare.co.uk │
├─────────────────────────────────────────────────────────────┤
│ │
│ Ask the corpus. │
│ │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ what changed on dashboard.dare.co.uk last week? 🎙 │ │
│ └───────────────────────────────────────────────────────┘ │
│ │
├─────────────────────────────────────────────────────────────┤
│ │
│ The dashboard cron silently no-op'd for three days │
│ in early May, root-caused to macOS TCC blocking launchd- │
│ spawned shells from reading scripts in ~/Downloads ¹. │
│ Smart Tiered Cache was enabled across the portfolio on │
│ 2026-05-11, with a 2026-05-14 re-check planned ². │
│ │
│ Sources │
│ ¹ feedback_downloads_is_least_favourite │
│ ² project_cloudflare_tiered_cache_enabled │
│ │
│ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │
│ │
│ Recent asks │
│ • compare audrey vs dogwood foundation reports 3m ago │
│ • dare canonical narrative frame 15m ago │
│ • narrator voice tuning current state 1h ago │
│ │
└─────────────────────────────────────────────────────────────┘
Five UI primitives: header, big input with mic, answer block, sources list (clickable, hover-preview to source report), recent-asks rail. Mobile collapses to single column. Voice via the browser’s native Web Speech API — free, no extra service account.
Architecture — the wiring that didn’t get built
┌──────────────────┐
│ Mobile / desktop │
│ browser │
└────────┬─────────┘
│ HTTPS
▼
┌──────────────────────────────────────────────────┐
│ Cloudflare edge │
│ ┌────────────────────────────────────────────┐ │
│ │ Access policy: dan@dare.co.uk + dan@gf.cx │ │
│ └────────────────────────────────────────────┘ │
│ ┌────────────────────────────────────────────┐ │
│ │ Pages: corpus.dare.co.uk │ │
│ │ static HTML + JS frontend │ │
│ └────────────────────────────────────────────┘ │
│ ┌────────────────────────────────────────────┐ │
│ │ Worker: /api/ask │ │
│ │ reads GCP_SA_KEY secret (op-injected) │ │
│ │ mints token → POST :answer │ │
│ │ streams response back to browser │ │
│ └────────────────┬───────────────────────────┘ │
└───────────────────┼──────────────────────────────┘
│ HTTPS, bearer auth
▼
┌──────────────────────────────────────────────────┐
│ Vertex AI Search │
│ engines/xlab-devcorpus-app │
│ └─ dataStores/xlab-devcorpus │
│ └─ gs://xlab-devcorpus-md/*.md │
└──────────────────────────────────────────────────┘
Thin-edge pattern — Worker proxies to existing canonical source, no data duplication. Runtime auth via a scoped SA (xlab-devcorpus-runtime-sa, roles/discoveryengine.viewer, JSON key in op://Private/) so the existing audrey-vertex-sa stays single-purpose.
Decision — parked, not killed
Two reasons.
1. Dogwood Phase 1 close-out is the higher-priority thread
Tomorrow’s pre-flight already caught a real production bug (worker.js Twilio Auth header still uses legacy auth_token despite API Key constants being declared). That work has actual customer-facing stakes — the 7am SMS briefing breaks if it’s mishandled. Internal corpus chat doesn’t compete on importance.
2. AI voice for real customer problems > AI search for self
Stated explicitly tonight: “I would sooner develop AI VOICE for real customer problems.” Direct corollary: the same 3 hours that would build corpus.dare.co.uk would meaningfully advance the dogwood voice agent (Phase 5 in the dogwood roadmap), an audrey gift-advisor voice flow, or client-facing voice work. Internal-tool builds are an indulgence; customer-facing voice is the leverage. Park rather than kill — internal tools can resume if/when habit-data justifies, but the default investment lane is outward, not inward.
New memory landed: feedback_customer_voice_over_internal_tools.
Resume conditions — when to un-park
Any one of these is sufficient signal to resume:
- NotebookLM-as-experiment shows habit. Upload the same 58 markdown files to NotebookLM this week. Ask the same disproof query set on the phone. If you reach for it 3+ times unprompted over the next 7 days and the manual re-upload friction is starting to bite — that’s the green light.
- A workflow demands programmatic queries. If a dev-report-publish script wants to ask the corpus “have I already written about X?” before generating a new artefact, Phase 4 (
~/bin/devcorpusCLI) is the unlock. - A customer engagement needs a similar surface. A client wants Q&A over their own documentation corpus — devcorpus becomes the reference implementation, and
corpus.dare.co.ukbecomes worth building as a portable pattern.
If none of these fire within 90 days, the cleanup move is gcloud storage rm -r gs://xlab-devcorpus-md/ + delete the Data Store + delete the Engine. Cost to leave it dormant in the meantime is rounded to zero, so the default is benign neglect.
NotebookLM — the cheaper experiment to run first
Concrete this-week test, not a build:
- Open NotebookLM on iPhone (or web).
- Upload
~/Code/devreports-content/*.md(drag-and-drop, ~58 files). - Ask the proposal’s disproof query set: - “what changed on dashboard.dare.co.uk last week?” - “summarise the dogwood Twilio rotation” - “what memories were written from the audrey foundation work?” - “compare the dare vs dogwood gap audits”
- Try the voice mode on iPhone.
- After 7 days, ask: did I reach for this unprompted? Did manual re-upload annoy me?
Cost: 10 minutes upload + whatever ambient ask-time. Output: an honest signal on whether conversational corpus access on a phone is a habit worth investing in.
What this teaches the portfolio
- Mockup-before-full-build pattern at work. Three hours of UI/architecture sketching + a parked decision is the same cheap-deliberation move that produced the dare A/B preview report. Pattern keeps paying.
- Thin-edge architecture pattern at the model layer. Don’t rebuild the data — point a model at the existing source-of-truth. Worker → Vertex AI Search is the same shape as agent-edge → Shopify, one level up the stack.
- Free-tier-first GCP experimentation works. Phase 0-2 cost zero, taught the API surface area, and produced a real artefact (the engine is queryable in the console tomorrow morning). Pattern transfers to any future GCP exploration.
- “Mildly interesting” is a useful disposition. Not every idea needs to be built. Surfacing the interest level honestly + parking with resume conditions beats either building-and-regretting or killing-and-forgetting.
- Cross-portfolio infra (
xlab_*namespace) graduates well. Reusedaudrey-experimentsas incubator project per the xlab-co lifecycle model. If devcorpus ever earns its own project, it migrates cleanly because the resource names are already portfolio-scoped, not audrey-scoped.
Memories written tonight
| File | Type | What it captures |
|---|---|---|
feedback_adc_quota_project_header |
feedback | Phase 0 gotcha: ADC user tokens authenticate against the SDK’s default project, not the active one; HTTP calls need the header |
feedback_customer_voice_over_internal_tools |
feedback | Strategic direction: AI voice for customers > AI search for self; reserves internal tools for customer-unblocking |
Deferred per proposal until Phase 2 quality smoke-test:
project_devcorpus_operating_notes.md— bucket/dataStore/engine IDs + working query examples (writes after smoke test passes)reference_vertex_ai_search_setup.md— gcloud + REST steps for spinning new Data Stores; portable to client workfeedback_markdown_corpus_as_rag_substrate.md— dev-reports unintentionally well-shaped for RAG; editorial discipline pays a second dividend
Linked artefacts
- Live preview surface:
console.cloud.google.com/gen-app-builder/engines/xlab-devcorpus-app/preview/search?project=audrey-experiments - Tomorrow’s dogwood pre-flight:
~/Code/dogwood-house/dev-reports/dogwood_phase01_pre_flight_2026-05-13.md - GCP foundation reference:
project_gcp_audrey_foundation - Lifecycle pattern:
project_xlab_co_lifecycle_model
Park with resume conditions, not abandonment. The foundation is free to keep; the build only commits when the habit-signal lands.