Skip to main content
Colab at colab.tuturuuu.com is a standalone React application served by a Cloudflare Worker. A SQLite Durable Object owns each room. The reusable @tuturuuu/multiplayer package defines room policy and safe member-specific projections; the Worker owns authentication, inference, storage and WebSockets.

Vite+ toolchain

Colab uses the pinned local Vite+ CLI for development, tests and client builds. Its existing React/Tailwind plugins, framework-import bundle guard and Cloudflare Worker entrypoint remain intact. Tests import vite-plus/test; the shared Vitest and coverage version is aligned with Vite+‘s bundled runner. Colab retains a direct vite dependency aliased to the same @voidzero-dev/vite-plus-core release, so Bun resolves plugin peers and configuration types to one Vite implementation. See the Vite+ dependency rules. Use Node 24.11+ (CI pins Node 24), Node 22.18+, or Node 26+; Node 25 is outside the package’s declared support range. bun run lint uses Oxlint through Vite+ and bun run format:check provides a read-only Oxfmt comparison. Explicit .oxlintrc.json and .oxfmtrc.json files avoid native config-loader resolution through Bun’s shared package store; the CLI uses these files directly. The initial Oxlint gate covers core/TypeScript/Oxc correctness and native-dialog prohibition. React compiler diagnostics and additional accessibility rules need separate behavior-reviewed fixes before enabling those rule families; existing Biome accessibility/hooks checks remain authoritative. Biome remains the repository formatter until this scope’s formatting/rule parity and editor/generator changes are complete; do not enable competing format writers. Colab tests use the thread pool with per-file isolation retained. Repeated fork-pool runs on Vitest 5.0.0 and 5.0.3 failed collection while opening temporary transformed modules under /tmp/.../ssr or /tmp/.../client; the same focused suites passed with --pool=threads. One worker, result-cache disabling, and Node 24 did not resolve that collection failure. Treat it as a runner boundary to investigate, not evidence that product assertions failed; preserve every suite and assertion. This tooling change does not alter cookies, sponsorship, Durable Object class names, bindings, storage, routes or canonical deployment ownership.

Shared application shell

apps/colab/src/client/structure.tsx composes the same @tuturuuu/ui/custom/satellite-shell component used by satellite apps. It uses shared UI buttons, icons and design tokens, with persistent desktop collapse, a mobile navigation drawer, account controls and room-section links. The app imports the shared UI stylesheet through Tailwind’s Vite integration. Keep Colab content CSS in the components layer so shared component utilities remain authoritative. Colab supplies a History API navigation adapter so the sidebar and account menu stay mounted between pages.

Running a workshop

  1. Sign in with a confirmed Tuturuuu account. Only an exact @tuturuuu.com account can create a room. Choose its start/end time, participant limit and number of teams. Limits are 5 minutes–8 hours, 2–100 participants including admins, and 1–12 teams.
  2. In the facilitator desk, allow account emails and share the room URL. This adds an account invitation; it does not send email. Alternatively, generate a random temporary password and share it separately. The password appears once; only its SHA-256 digest is stored. Rotation removes password-only guests.
  3. Each team writes and saves a system prompt. Version checks reject concurrent overwrites. Drafts remain local until saved. A teammate can explicitly load the latest saved version after a conflict.
  4. Generate a single skill or let the model split the instructions into up to four focused skills. Each download contains YAML frontmatter and readable Markdown instructions. Place it in <skill-name>/SKILL.md in a compatible agent environment after reviewing it. If Workers AI returns incomplete or differently shaped JSON, Colab retries once and then produces a conservative prompt-based working guide so a learner is never blocked by model formatting.
  5. Test the generated skills against the room scenario. The journal records the prompt snapshot, scenario, actual sandbox tool inputs/results, final answer and AI coaching. Each run starts with a plain-language health summary: its completion reason, evidence actions, successful practice-data changes, action failures, and apps used. The timeline makes failed actions visually distinct and offers a recovery hint; raw JSON and prompt diagnostics stay collapsed for facilitators who need them. Coaching is advisory, not proof of agent correctness.
  6. New rooms share team work live by default. The dedicated Live showcase tab follows the team on stage and presents its challenge, system prompt, reusable skills, and latest test result in one audience-facing view. Authorized team members can run the live test there, while facilitators advance teams in order. Saved prompts, generated skills, sandbox records, and run journals update for viewers without reloading. Unsaved editor drafts stay local. Room admins can turn showcase off or on immediately; disabling it removes other teams from participant views and server payloads. Existing rooms retain their saved setting. Admins can always inspect all teams. Only staff admins can promote other signed-in accounts to room admin.
  7. Close to read-only, or set private mode to restrict access to admins. At the scheduled end the room becomes read-only. Every mutation checks the clock; the Durable Object alarm also updates connected clients. Private mode and revoked memberships close affected sockets.

Sandbox boundary

The eight adapters cover Google Drive, Notion, Zalo, Messenger, Microsoft Teams, Google Calendar, Jira and Trello. They simulate searchable records and create/update actions. They are educational mockups, not replicas of the full products. No third-party app credentials, network fetch tools or real messaging connectors are available to the agent. Each team’s writes affect only its own records. Admins can reset those records to the seeded RISE dataset. AI Studio sponsors skills, scenarios, agent decisions and feedback using the configured COLAB_AI_MODEL. Agent execution uses a bounded JSON tool protocol with an allowlist and runtime validation. New workshops allow 500 AI operations, 60 turns, and 50 app actions per run; new teams begin with 150 AI operations, 60 turns, and 50 app actions. Hosts can use Guided, Extended, or Deep dive presets or set exact room and team limits, up to 5,000 AI operations, 100 turns, and 80 app actions. An app-action limit must stay below the turn limit so the agent retains a final answer turn. Existing rooms are normalized to the new defaults only when a value was never stored. A room allows one concurrent AI job. If room state changes while inference is running, the stale result is discarded. The system prompt, scenario, practice records and traces are sent to the AI provider; participants should use workshop examples rather than confidential real data.

Authentication and deployment

The Worker redirects to central Tuturuuu login with a nonce-bound return URL. POST /api/v1/auth/colab/verify consumes a Colab-targeted one-time handoff and looks up the confirmed, non-banned user in Supabase Auth. It deliberately ignores cross_app_tokens.session_data.email, which is caller-controlled. Colab signs its own short-lived, HttpOnly, Secure, SameSite cookie using COLAB_SESSION_SECRET. The Worker never receives a Supabase service key. Ship the Colab domain registration in packages/utils/src/internal-domains.ts and the verifier on the live web app before accepting production account logins. The new verifier is tracked as Rust migration backlog; the Rust backend does not serve production traffic. No Supabase migration or production database push is required for Colab. The Cloudflare configuration is apps/colab/wrangler.jsonc. It creates tuturuuu-colab, binds the room Durable Object and Workers AI, serves static assets, and attaches the colab.tuturuuu.com custom domain. Use the authorized Tuturuuu Cloudflare account. Provision a cryptographically random COLAB_SESSION_SECRET through Wrangler’s secret input; never commit it. The exact-commit Cloudflare workflow owns client builds, Worker dry-run bundling, asset publication and authorized production deployment. Do not run release builds or build-triggering deploy scripts on the shared host. Provision secrets through an explicitly authorized secret-management flow, separately from tooling changes. Rotate the session secret only intentionally: it signs out all Colab sessions. Room state persists in Durable Object SQLite storage across Worker deployments. Keep the v1 migration and class name stable. Read-only rooms are retained; there is no automatic data deletion policy in this release.

Verification

Queue focused non-build checks through the shared resource broker:
Use a supported Node runtime for the CLI. Require exact-commit CI type/lint/test and real Vite+ client/Worker build validation. Runtime/browser verification may consume immutable CI artifacts or local dev bundling with isolated persistence; it does not authorize a local release build or deployment. Do not run bun check on this shared host because its dependency graph can build workspaces. The finite runtime script starts a local Worker on port 8795 with a test-only signing secret, uses isolated in-memory Durable Objects, verifies access and concurrent updates, and opens headless Chromium for desktop/mobile and Vietnamese checks. It never creates a production session. It writes screenshots to /private/tmp/colab-*.png and closes the browser/runtime when finished. Install the Playwright Chromium browser if it is not already available. After deployment verify /api/health, static asset responses, central sign-in, an invited account and temporary guest, live team updates, skill generation and an AI run. Correlate the Worker version with its source revision and inspect Wrangler logs without logging passwords, cookies or prompts. A successful Cloudflare upload alone does not establish that central sign-in is deployed.

Automatic deployment

.github/workflows/colab-cloudflare.yaml validates affected main and production revisions and deploys only production. The repository switchboard in tuturuuu.ci.ts controls it. Manual dispatch on production retries a release. The validation job pins supported Node, tests both workspaces, runs Oxlint, builds the client, bundles the Worker, and uploads revision-specific assets. Deployment downloads those same assets, records the Git SHA in the Worker version message, and checks canonical health and every asset hash. Verification retries up to 12 times, five seconds apart, so a successful upload is not mistaken for immediate edge propagation; persistent hash mismatches still fail the job. Deployments are serialized and never cancel an active release. Configure the repository Actions secret (or environment colab-production secret) COLAB_CLOUDFLARE_API_TOKEN: Workers Scripts edit, Workers AI read, account read, and Workers Routes edit plus zone read for tuturuuu.com, scoped to Tuturuuu. The session signing secret stays in Cloudflare and is not regenerated by CI. An expired or incomplete login returns to a bilingual recovery panel instead of a JSON error. /verify-token unwraps the central portal’s callback only for Colab’s own /auth/callback; the callback still requires its original nonce cookie.

Appearance and satellite parity

Colab opens into a compact workshop lobby and uses the shared Tuturuuu logo, Structure layout, buttons, dropdown menus, and semantic color tokens. The toolbar provides Light, Dark, and System appearance choices. Like the satellite apps, next-themes stores the preference under theme; System follows OS changes. The initial HTML applies that preference before painting to avoid a light flash. Account and language controls live in the sidebar account menu. Colab’s Vite runtime uses framework-independent UI primitives rather than Next-only providers. The runtime verification script covers explicit themes, persistence across reloads, live system-theme changes, account-menu keyboard dismissal, and mobile navigation.

Shared shell and framework adapters

Colab, Tasks, Calendar, and the other satellite apps share the shell in @tuturuuu/ui/custom/satellite-shell. The shared layer owns brand markup, sidebar layout, navigation sections, workspace-selector reveal, nested-navigation state, and collapse/hover behavior. It accepts React slots and callbacks without importing Next.js, authentication clients, or translation providers. @tuturuuu/satellite/sidebar-structure remains the Next.js adapter. Its public props are unchanged; it supplies Next links, pathname, translations, cookie persistence, workspace context, settings, billing, and the app launcher. Colab’s structure.tsx supplies native links, local preference persistence, and its Cloudflare room/account controls to the same implementation. Theme support continues through shared CSS tokens and next-themes. Make shell presentation changes in the shared UI components. Keep routing, authorization, and workspace services in the adapters. Colab’s Vite build rejects Next.js or next-intl runtime modules in its bundle, guarding this boundary. Colab and Next satellite apps use the same SatelliteUserMenuItems, account switcher, language and theme items, Settings layout, report form, and footer components from @tuturuuu/ui. Framework adapters supply session and navigation services; they must not replace the shared UI with reduced menu items or a different design. Colab self-hosts the same Noto Sans variable font used by Next apps. The menu preserves the Next satellite ordering: Dashboard; Sidebar (expanded, collapsed, expand on hover, hidden); Language (English, Vietnamese, system); Theme (light, dark, system); Report a problem; account switching/removal/management; Log out. Settings retain the shared search, keyboard navigation, desktop/mobile layout and guidance controls. The report dialog retains attachments, validation, compression and draft handling. There is no Reconnect account menu action. Central account changes automatically complete the Colab handoff while preserving the room URL. The verifier resolves display name and avatar from the verified user’s profile; confirmed auth email remains the permission authority. Central and Colab sessions expire independently, and signed-out users can continue through the central login portal. Guests can still join with a room password. The Worker forwards only explicitly allowlisted real account/support endpoints (reports, onboarding progress, and the sidebar preference) to AUTH_ORIGIN, with central Supabase auth cookies and same-origin mutation checks. This bridge is separate from the simulated workshop tools, which cannot call real services. Account switching uses the existing central account API with credentialed CORS. Regression checks cover the allowlist, cookie filtering, rejected origins/methods and body limits.

Workspace entry and notifications

Colab requires a Tuturuuu login when opening the app. The sidebar separates Workshops (/), Join a room (dialog), Host a workshop (dialog, staff only), and Practice guide (/guide). Direct /?room=... invitations retain temporary password entry for guests. Login preserves the selected app destination. The desktop shell has no page navbar. Appearance remains in the account menu, and the shared shell retains mobile navigation and the sidebar edge toggle. The home screen offers the most recent room on this device without implying that the room is still open or that its access has been verified. The sidebar notification bell uses the same inbox, archive, pagination, read actions, and invitation controls as Next.js satellites. Colab supplies native central-site links and polls the unread count and open notification list every 30 seconds while visible; Next.js satellites use the shared authenticated API refresh subscription every 120 seconds while visible and online; notification actions and return-to-app events refresh immediately. Only exact notification and workspace-invitation endpoints are proxied to the central app, with central authentication cookies, same-origin mutation checks, and preserved query filters. These account endpoints are never exposed to simulated AI tools. Validate with focused non-build tests, exact-commit CI builds, and the finite scripts/verify-runtime.mjs under supported Node using verified Worker artifacts. The runtime verifier covers default-login redirects, guest invitation documents, separate sidebar destinations, notification read/archive actions with mock data, and English/Vietnamese desktop/mobile layouts. No production notification is changed. Workspace navigation uses client-side history and keeps the shell, account controls, and notification queries mounted. Join a room opens a shared dialog above the current page; dismissing it preserves host drafts and guide interactions. Browser Back/Forward follows navigation and dialog history. Direct /join links still require login and open the dialog over the workspace home. Modified link clicks retain normal browser behavior. The finite runtime verifier checks document and sidebar identity, dialog dismissal, draft retention, and mobile overflow. Hosting also opens above the current page, and its draft survives closing and reopening the dialog. Direct /host links open it above the home workspace. Colab refreshes its account session before the one-hour expiry using the central /api/auth/me endpoint, which revalidates the Supabase user. Only central auth cookies are forwarded; rotated auth cookies are returned to the browser. Confirmed account email remains the permission source. Guest sessions are never extended by this mechanism. The visible client checks its session every minute and reopens its room WebSocket when renewed credentials change. Temporary identity-service failures retain the current workspace and can be retried; explicit sign-out, account revocation, and private-room access denial still apply.

RISE learning and sponsored workshops

New workshops start with the RISE Induction Day publishing mission. Teams build a reusable system prompt, generate skills, gather evidence across practice apps, and produce a bilingual Facebook draft plus artwork guidance and a publishing checklist. The catalog has 202 records across 24 apps, including ten connected Induction Day sources. Conflicting schedules and unconfirmed partner claims are deliberate research exercises. Dates, venue and registration links are rehearsal data: replace them with verified event details and obtain human approval before publishing. Colab does not publish to Facebook. Existing rooms receive the new scenario as an additional choice without changing their selected scenario, edited prompts or records. Learning is available from the workspace guide and as a dedicated workshop destination. It includes six lessons, an editable Markdown preview, a source map, and interactive RISE and CRAFT framework examples. Explored lessons are remembered on the device. The prompt editor provides an immediate, explicitly heuristic structure check. Ask AI to review performs a sponsored model call, maps exact prompt excerpts to framework sections, and explains suggested improvements. Reviews are shared with the team and marked outdated after prompt edits. Suggestions never replace a prompt automatically. A structure match is not a quality or safety guarantee. Only accounts with a centrally verified @tuturuuu.com email can create or manage workshops. Hosts may promote only other eligible Tuturuuu accounts. External members retain attendee, multi-team collaboration, learning and showcase access; legacy external admin flags are removed during room normalization. Production AI uses automatic first-party authorization with COLAB_REQUIRE_SPONSORSHIP=true; no AI API key needs to be created or copied. The authorized room job stores a random, one-use capability bound to the SHA-256 digest of the exact model request. AI Studio redeems it over HTTPS at the pinned canonical https://colab.tuturuuu.com/api/sponsorship/verify endpoint. Redemption is an atomic delete, expires after 60 seconds, and cannot be replayed concurrently. The capability never enters browser state, activity logs or billing metadata. AI Studio revalidates the host’s confirmed Tuturuuu account, fixes the billing workspace to root, and derives request/idempotency IDs from the approved job. Root workspace model, rate, budget and credit policies still apply. This is metered first-party usage, not an unmetered external-app credential. No new database migration is required: the existing reservation procedure supports a null API key. Deploy the AI Studio endpoint and Colab verifier together before testing live generation. COLAB_AI_MODEL selects an enabled, priced root-workspace model. Canonical HTTPS reachability is required in both directions; preview deployments cannot approve their own root-credit requests. No shared machine secret is needed. COLAB_AI_API_KEY remains an optional legacy transport for callers without room approval support; app-bound keys are rejected. Invalid approval, disabled hosts, unavailable verification or insufficient credits fails closed. The direct Cloudflare AI binding remains available only for local/legacy setups that do not require sponsorship; local verification uses deterministic responses. The dedicated endpoint checks root workspace ownership, reserves and settles credits through AI Studio, and records workshop, host, team, participant, scenario, operation, generation phase, job and request identifiers with a human-readable sponsorship description. Retries are separate metered calls. Unknown pricing must not be reported as free usage. Hosts can export the latest 100 confirmed receipts; attendees receive totals, not receipt identifiers. Workshop totals cover confirmed responses only; AI Studio remains authoritative for failed or interrupted calls. The finite browser verifier exercises learning interactions, shared prompt reviews, skill generation, multi-account showcase runs and reconnection with isolated Durable Objects. It does not establish real provider output quality or production credit settlement: verify those separately after deployment. node scripts/verify-sponsorship.mjs additionally exercises keyless generation, body tampering, concurrent replay rejection and receipts using isolated Durable Objects and mocked AI Studio responses. It does not spend production credits.

Reliable practice runs

New workshops and teams default to 60 agent turns and 50 tool calls. Existing custom limits are preserved; hosts can choose the Deep dive preset for both the workshop and its teams. The catalog contains 250 linked RISE practice records across 24 apps, including review workflows, study support, capacity planning, and the Induction Day evidence pack. The agent can use draft to save a reviewable record without sending or publishing anything. generate_image calls AI Studio using the same one-use first-party grant and root-workspace billing as text. It requires an enabled, priced image model in the root workspace; it does not bypass model policy. Each call generates one image, with at most 50 retained images per workshop. Unavailable image generation is reported in the action trace with setup guidance, and the agent can continue with an artwork brief. Gemini Flash artwork supports google/gemini-3.1-flash-image through Google’s multimodal language API using GOOGLE_GENERATIVE_AI_API_KEY, even though the catalog classifies it as language. Colab requests one 1K image without search or publishing tools. Enable the model in the catalog, global access policy, and sponsor plan before using it. The reservation is conservative; settlement uses Google’s actual modality token counts (0.50/Minput,0.50/M input, 3/M text/thinking, $60/M image output), then applies the sponsor plan’s markup. Root AI Studio runs retain provider response IDs, token counts, image counts, and workshop sponsorship descriptions. Missing modality data fails closed and mark measured usage for reconciliation instead of treating artwork as free. Do not select the retired -preview alias; Google lists its shutdown on June 25, 2026. Generated PNG/JPEG/WebP assets are stored separately from realtime room JSON in bounded SQLite chunks. Image requests re-check room membership and team visibility, including showcase access, and return private no-store responses. Workshop deletion removes its images. Captions, tables, checklists, code, and image outputs use safe Markdown rendering; structured bilingual answers have separate copy buttons. Practice actions accept search, read, create, draft, update, and generate_image, including exact namespaced forms such as drive.search. A namespace must match the selected app; unsupported actions such as publishing or deleting remain rejected. Record IDs are always checked within the selected app. Normalized actions appear in the trace. The agent reserves its last available turn for an answer and cannot execute another tool after exhausting its action budget. Coaching is a secondary step: if it fails, the answer and actual tool trace remain available with an explicit unavailable notice. Results containing a JSON object are displayed as readable, separately copyable sections, including bilingual captions, source notes and review checklists. Plain Markdown and incomplete responses remain readable without silently dropping text. The local showcase verifier exercises this output and namespaced actions through the real room, persistence and multi-browser broadcast path using deterministic AI.

Workshop directory and activity log

Workshops is the default signed-in screen and is also available at /workshops. Current/upcoming and past sessions have separate searchable tabs. Join and host remain dialogs. Within a room, Brief, Prompt, Skills, Sandbox, Results, Activity log and Host controls are sidebar destinations, without a duplicate tab bar. Host controls appear only for room admins and update with realtime role changes. Expandable host settings preserve form state while closed. Editor components stay mounted when sidebar destinations or selected teams change, preserving local unsaved work. Shared UI labels, checkboxes, cards and selectors use consistent spacing; sandbox apps are selected from a compact dropdown. The directory uses per-account Durable Object identifiers in the existing ROOMS binding. Creation, successful joining and authorized visits register a room. Reads recheck membership and private mode against each room before returning metadata; withdrawn access is excluded. The directory returns the 100 most recently visited rooms. Legacy rooms appear after an authorized visit to their existing link; no global historical enumeration or backfill is performed. The room persists its latest 200 successful actions with time, actor display name and action category. Password values, invitation addresses, prompts and tool payloads are not copied into audit entries. Host operations are admin-only; team work entries follow the current live-sharing policy, including immediate WebSocket removal when sharing is disabled. Old rooms begin with an empty log; this is a bounded workshop activity record, not a compliance archive.

Idempotent workshop expiry

The room expiry alarm emits one ended audit entry per scheduled end timestamp. Open rooms become read-only; already read-only or private rooms keep their mode and still receive that single end event. A durable completion marker is committed atomically with the room and private audit state. Duplicate alarm delivery and object restart do not increment the revision, rewrite state or reschedule an already completed expiry. A host’s later end timestamp can expire independently. Early delivery schedules the existing future deadline; open-ended rooms do no work. The first expiry performs three state writes (room, audit, completion marker). Each duplicate performs three bounded point reads and no writes or downstream calls. This prevents duplicate-write amplification, not all alarm-related billing. Storage failure rolls back the whole expiry transaction and remains visible to Cloudflare’s bounded platform retry mechanism; the handler adds no retry chain. apps/colab/src/server/room-alarm.test.ts covers 100 repeated wakes, restart, all room modes, atomic failure recovery, schedule extension and early/no-end cases using SQLite with a Worker context fixture. node --test apps/colab/scripts/verify-expiry-runtime.mjs also invokes the actual expiry handler in a loopback Worker and SQLite Durable Object through Wrangler’s test harness, including an aborting SQL trigger to verify rollback. The test-only configuration has a separate fixture identity and no production bindings, remote services or secrets; the harness closes its temporary runtime after the tests. Run it through ttr resources run -- locally; CI runs it before the real app build. Use a private writable TMPDIR if the host’s shared temporary directory rejects writes. This test invokes the handler through fixture RPC; hosted alarm scheduling, platform retries and production cost caps remain separate acceptance evidence.