13 — Open Questions
Decisions deferred to when we're actually building. Each has the tradeoff named so future-Christopher (or contributors) can pick without re-deriving the context.
Re-read this doc before starting each new sprint — answers settle here as they get made.
1. GitHub OAuth app vs creator-supplied PAT
Question: how does BKA get write access to a creator's GitHub repos?
Options:
- (a) BKA-owned GitHub App + OAuth flow — better UX, requires us to register + maintain the App, App must be installed per-creator
- (b) Creator generates fine-grained PAT + pastes it — friction, but no GitHub App registration on our side
- (c) Both — App as default, PAT as fallback
Recommendation: (a). Single OAuth click is the right UX; the GitHub App registration is one-time work on our side.
Tradeoff: GitHub App tokens have shorter expiry; we need refresh logic. PAT path doesn't (it's perpetual until revoked).
Decide when: Sprint 1 (onboarding wizard).
DECIDED (Sprint 1, 2026-06-30): (b), pasted token. The recommendation flipped from (a) once the browser-only constraint was made load-bearing. OAuth's code→token exchange needs a client secret, which forces a server into the request path — directly contradicting the philosophy doc ("no servers in your request path") and 04's own promise ("never sends the creator's tokens to our servers"). A pasted token is fully browser-direct, needs no secret, and matches the Cloudflare-token step the wizard already specifies. UX friction is softened with a pre-scoped token-creation deep link (
github.com/settings/tokens/new?scopes=repo,workflow) — "one click, right permissions," the same shape (a) promised. Revisit for v1.1: if we ever stand up the discovery indexer worker (07), a stateless OAuth-broker route on it (holds the secret, stores nothing, returns the token to the browser) could offer option (a) as an opt-in upgrade without a content-bearing backend. Implemented insrc/lib/github.ts.
2. Cloudflare OAuth vs creator-supplied API token
Same shape as #1 for the CF side.
Recommendation: token-paste for v1 (OAuth path exists in CF but is less mature; pasted tokens are well-trodden).
Decide when: Sprint 2.
DECIDED (Sprint 2, 2026-06-30): NEITHER — guided manual connect. Verified empirically that
api.cloudflare.comdoes not send CORS headers (noAccess-Control-Allow-Origin; preflightOPTIONS→ 400), so a browser-only app cannot call the CF API at all — a pasted CF token would be useless from the browser, and an OAuth token equally so. Both options in the question presumed browser→CF API calls that the platform can't make. Resolution: the creator connects CF Pages to their public repo once, manually, via the CF dashboard's "Connect to Git" — which is an OAuth app installation that no API can automate anyway (not a BKA limitation; a GitHub/CF security boundary). After that one-time connect, every publish is agit pushto GitHub (CORS-friendly) and CF Pages auto-deploys; BKA never calls the CF API and the creator's CF token never enters BKA. The wizard's "Connect Cloudflare" step is a guided checklist (deep link + exact build settings + liveness probe), not an automated call. Implemented insrc/components/wizard/StepCloudflare.tsx. Knock-on: the Stats tab (Sprint 8) hits the same CORS wall for CF Analytics — it'll need the same treatment or a read-only proxy; revisit then.
3. One GitHub Release per asset vs per post-bundle
Question: when uploading media to GitHub Releases, do we create one release per file (simple, easy to grep) or one release per post (grouped, fewer total releases)?
Options:
- (a) Per asset —
asset-<sha8>tag scheme, easy dedupe of identical files across posts - (b) Per post —
post-<slug>tag, all media for that post bundled, simpler to inspect "what's the v2 of post X" via release history - (c) Hybrid — per asset for large/unique files, per post for groups
Recommendation: (a) for v1 (simplest); migrate to (b) if creators ask for "give me the v3 zip of all this post's media."
Decide when: Sprint 4 (media library).
4. Viewer template as 4G app vs static SSG
Question: how is the public site generated?
Options:
- (a) 4G app (React+Vite) — same patterns as everything else, slightly bigger bundle
- (b) Astro / Eleventy / custom static SSG — smaller bundle, separate stack to maintain
- (c) Hybrid — 4G shell with static-generated routes, hydrate interactive bits
Recommendation: start with (a) for stack consistency; revisit when bundle size becomes a real complaint.
Decide when: Sprint 6 (viewer template).
DECIDED (Sprint 2, 2026-06-30): (b)-ish — no-build static, rendered in the browser by BKA itself. Not a separate SSG stack and not a CF-Pages-runs-Vite build. BKA renders the finished static site (HTML + feed.json/xml + sitemap) in the creator's browser at publish time (
src/lib/site-render.ts, markdown viamarked) and commits ready-to-serve files; CF Pages serves the repo with no build command. Why: (1) CF can't run a build triggered from us anyway (CORS, see #2), (2) a build is a failure surface — "CF build failed" is the worst onboarding moment — and an empty build command has nothing to fail, (3) it's the QC-harness thesis made literal: generation at authoring time, pure static determinism at runtime (06_PUBLISH_PIPELINE.md says exactly this). Sprint 6 ("viewer template") therefore becomes theming the in-app renderer, not standing up a build pipeline. The single bundled "Notebook" theme lives inrenderStyleCss().
5. Pull vs push for indexer
Question: does the indexer crawl creator feeds on a schedule (pull), or do creators ping when they publish (push)?
Resolved (per memory bka_architecture_proven_by_community.md): pull, with optional priority-pull hint via /api/refresh. Pull stays truer to "you are the platform" — creators are findable without enrolling in a notification protocol. The refresh hint is a priority signal, not a content push.
No further decision needed; this is settled.
6. How does BabyAI discovery actually rank?
Question: what's the prompt / model setup for /api/discover?
Options:
- (a) Single LoRA: one specialist trained on (query, accepted-item) pairs that re-ranks candidates
- (b) Multi-LoRA MoE: content-matching + taste-matching + freshness specialists, MoE-routed
- (c) Embedding similarity + light re-rank: vector embeddings on titles+summaries+tags, cosine similarity for initial pass, light LoRA re-rank of top 50
Recommendation: (c) for v1. Embeddings are cheap, fast, well-understood. The LoRA re-rank on top 50 adds the BabyAI-specific intelligence without paying for it on every candidate.
Tradeoff: embeddings need a model + storage (we'd compute at index time, store in D1 or KV). Adds one piece of infra. But this is well-trodden — many small projects do exactly this.
Decide when: Sprint 7 (indexer worker).
7. Taste-matching: how do we know what a user likes without storing their history?
Question: per 07_DISCOVERY_LAYER.md, we don't store per-user discovery history server-side. How does taste-matching work?
Options:
- (a) Client-side history: BKA app holds user's discovery clicks in localStorage; sends a small "I've previously accepted these tag-patterns" hint with each
/discoverquery - (b) Opt-in server-side profile: user explicitly opts in to "remember my preferences" → indexer stores a hashed/keyed pref profile, deleted on request
- (c) No taste-matching for v1: ship discovery as content-matching + freshness; taste-matching deferred
Recommendation: (c) for v1, (a) for v1.5. Ship the simpler version first; iterate when there's signal that taste-matching matters.
Decide when: Sprint 7 ship is content+freshness; taste-matching opens this question.
8. Creator email for unreachable / abuse notification
Question: per 11_OPERATIONS.md, we sometimes want to email a creator (feed unreachable for 30d, abuse report received). How do we get their email?
Options:
- (a) Capture during registration: indexer registration includes optional email; only used for these notifications
- (b) Use Google sub to look up email: we have the JWT at registration time → we have email there. But storing it long-term is a different commitment.
- (c) Don't email; in-app banner only: BKA shows "you have a notification" banner when next opened
Recommendation: (c) for v1 (no email infra at all on our side), upgrade to (a) when there's a real case.
Tradeoff: creators who don't open BKA for 30d won't see the in-app banner — but those creators are also the ones whose feeds will go unreachable, so it's somewhat self-correcting.
Decide when: Sprint 9 (alpha launch) — by then we'll know if it matters.
9. Wizard state encryption
Question: the wizard stores GitHub OAuth + CF API tokens in OPFS-SQLite. They're effectively localStorage-scope (per-origin, per-browser). Encrypt at rest?
Options:
- (a) Don't encrypt: rely on per-origin sandboxing + user's OS account security
- (b) Encrypt with a derived key from Google JWT: each session re-derives the key from the JWT
- (c) Encrypt with a passphrase the user sets: extra step in onboarding, but defense in depth
Recommendation: (a) for v1. This matches what foundry / community already do. The threat model (someone on the user's machine has full browser access) isn't well-defended by encryption — they could also just take the running app's memory. If we later identify a real threat vector, revisit.
Decide when: Sprint 1, but probably stays (a) indefinitely.
10. Multi-device sync conflicts
Question: a creator opens BKA on two devices, edits the same draft on both. What happens?
Options:
- (a) Last-write-wins: simpler; assumes single-creator usage means conflicts are rare
- (b) Three-way merge: BKA detects conflict on push, presents diff UI
- (c) Lock-based: explicit "I'm editing this" lock that prevents the other device
Recommendation: (a) for v1. Single-creator BKA usage rarely has true concurrent edits. If it becomes a real issue, (b) is the right escalation.
Mitigation in (a): BKA shows "this was edited by another session" warning when the local stale-write detection fires (compare local-last-known commit to current remote commit before push).
Decide when: Sprint 3 (Compose ships with this concern live).
11. Custom themes — fork vs registry
Question: how do creators with strong opinions about design get custom themes?
Options:
- (a) Fork the viewer template — creator commits their own theme to their public repo; loses default-update path
- (b) Theme registry — creators can publish themes to a central npm-or-similar; BKA shows a theme gallery
- (c) BKA-bundled themes only — keep it tight; if you want something custom, fork (a)
Recommendation: (c) for v1. Three bundled themes cover the typical creator. (a) is the escape hatch for power users. (b) is post-v1 if there's demand.
Decide when: Sprint 6 (viewer template).
12. Onboarding for creators who already have a GitHub/CF setup
Question: a creator already has their own static site on CF Pages from another tool. How does BKA absorb / integrate?
Options:
- (a) "I already have a site" path: wizard adapts to use an existing repo as the public repo (with migration / merge UX)
- (b) Always create fresh: simpler; creator can manually migrate
- (c) Side-by-side: BKA creates its own repos; creator's existing site untouched
Recommendation: (b) for v1, (a) when migration tools land in v2.
Decide when: Sprint 1 (onboarding); deferred to v2 in practice.
13. What's the BKA brand?
Inherited from v0.1 BKA: "Bender's Killer App," tagline "YOU are the platform."
Open: does the new version keep the BKA acronym, get a fresh name, or rebrand entirely? Worth a marketing pass when sprint 9 approaches alpha launch.
Decide when: Sprint 9 (launch prep).
14. Pricing for premium features (post-v1)
Resolved (per 01_PHILOSOPHY.md constraint #9): never. No paid tier. Done.
Process: how to use this doc
- When you hit one of these questions during a sprint, decide it
- Update the doc with the decision + the reasoning + the sprint where it was made
- Move resolved items to a "Resolved" section at the bottom (kept for posterity; future contributors might wonder why)
- Add new questions as they emerge
The doc evolves with the build. It's not meant to be answered all at once — it's the parking lot for "we don't need to decide this today, but we'll need to soon."