Ordered, not-yet-started work. Git history is the audit trail; this file is only what is still open. Last reviewed 2026-06-01.
Acto runs on Cloudflare Workers + D1. Persistence-heavy work is built once on that substrate; the platform-independent AI improvements below can land anytime.
These change how Gemini is called and how a beat is delivered; none depend on the hosting platform, so they carry over to Cloudflare unchanged.
- Structured model output. Call Gemini with
responseMimeType: 'application/json'and aresponseSchemaderived fromStorySceneSchema(lib/domain/schemas.ts). Removes the markdown-strip +JSON.parsestep in app/actions/generateStoryScene.ts and theMALFORMED_OUTPUTerror class it produces. - System instruction. Pass the storyteller preamble in
lib/promptUtils.ts as a
systemInstructionrather than concatenating it into the user turn. - Progressive media delivery. Return passage + choices as soon as the text
beat is ready; load image and audio lazily instead of blocking on
Promise.allin app/actions/generateStoryScene.ts. The store already tolerates a missingimageUrl/audioBase64. - Eval harness. Golden scenarios -> generate -> assert structural validity, with optional LLM-as-judge for coherence and variety, so prompt changes are measurable rather than vibes-only. This is the main missing technique for an AI-first product.
- (Stretch) Stream the prose with
generateContentStreamfor word-by-word display, once text generation is split from media.
Acto is deployed on Cloudflare Workers + D1 at https://acto.tre.systems (Worker
acto, database acto-db). What remains is mostly account-side configuration.
- Register OAuth callback URLs for the new domain. In each provider console add
https://acto.tre.systems/api/auth/callback/{github,google,discord}(GitHub Developer Settings, Google Cloud Console, Discord Developer Portal). Until then, sign-in fails with a redirect-URI mismatch. - Enable CI auto-deploy. Create a Cloudflare API token (Workers-deploy scope) and
add it as the
CLOUDFLARE_API_TOKENrepo secret; the deploy job in .github/workflows/cloudflare.yml skips until it is set. - Retire the Fly app. The Fly machine still runs the old build;
fly apps destroy actoonce Cloudflare is confirmed. The Fly-capable code is preserved on thefly-fallbackbranch. - Re-add the PWA via Serwist.
@ducanh2912/next-pwais not OpenNext-compatible and is disabled in next.config.js; adopt@serwist/next(the pattern Comprehendo uses). - Drop dead deps. Remove
@google-cloud/text-to-speechand@ducanh2912/next-pwafrom package.json once the Serwist PWA lands.
- Persist generated stories server-side: share/replay for users, a corpus for the eval harness, and creator visibility into what is being generated. Generated beats currently live only in one browser's localStorage.
- AI-call telemetry. Record tokens, latency, model, and outcome per call; surface in the existing admin panel. Three paid APIs run per beat with no structured record today.
- Error tracking. Add a service such as Sentry; production failures are currently invisible.
Spec: docs/LIVESTREAM_MVP.md. The MVP is streamer-mediated — chat-command voting and a local story-driving agent, with the streamer approving each beat — so the first version reads votes from platform chat and needs a streamer control surface, not a high-fan-out public web UI.
- Server-authoritative session + beat state (D1). A Durable Object per session is the right primitive if live in-app web voting is added later — they are built for one coordinator per room.
- Streamer control surface: approve / edit / reroll / veto a beat before it publishes.
- Keep hosted-model usage optional and capped; keep the local-agent path first-class.
- Re-enable admin-panel e2e tests. Regenerate the auth fixtures and remove the
describe.skip(see docs/TESTING.md). - Externalize rate limits. Move the per-API daily limits out of lib/rateLimitSqlite.ts into environment-driven config.
- Drop the dead
maxTokensfield.MODELS[].maxTokens(lib/modelConfig.ts) is unused; the real cap ismaxOutputTokensin lib/ai/googleAiService.ts. Wire it through or remove it. - NextAuth v4 -> Auth.js v5 whenever auth is next touched; v4 is on the legacy line.