> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tuturuuu.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Hive on Start + Void

> Cutover packet for the native Hive Worker: names, bindings, build, smoke checks and rollback.

`apps/hive` has native TanStack Start + Vite+ + Void source beside its Next build,
generated by the [start-bridge codemod](https://docs.tuturuuu.com/build/devops/start-bridge-codemod.md). The Next
build and `vercel.json` are untouched. `hive.tuturuuu.com` serves the maintenance
Worker below until a release owner flips the route. That 503 is the approved
interim response, not a failed native deploy.

## Maintenance Worker and the native Worker

Flipping `hive.tuturuuu.com` between these Workers is a product decision for the
release owner. It is not a build defect, and this packet does not perform the flip.

| | Maintenance | Native Start Worker |
| - | - | - |
| Script | `tuturuuu-hive-maintenance` | `tuturuuu-hive` when `VITE_HIVE_NATIVE_PROFILE=production`; the staging Worker name otherwise |
| Module | `apps/hive/maintenance/worker.mjs` | `apps/hive/cloudflare/worker.ts`, emitted into `dist` |
| Config that deploys it | `apps/hive/maintenance/metadata.json` (Workers script upload metadata: `main_module` `worker.mjs`, compatibility date `2026-10-26`, empty `bindings`). There is no Wrangler file for this page. | Wrangler config emitted by `apps/hive/void.config.ts` (`dist/server/wrangler.json` through the deploy pointer). The config attaches no route. |
| Route | Zone route `hive.tuturuuu.com/*` bound to `tuturuuu-hive-maintenance`. DNS stays a proxied discard record, so the Worker answers the host and does not fall through to the old tunnel origin. | None until cutover. |

The maintenance module returns HTTP 503, `Retry-After: 300`, `Cache-Control: no-store`, and `noindex` for every path, including API and WebSocket upgrades. It has no bindings and no upstream calls.

A cutover to the native Worker replaces the script on the existing route `hive.tuturuuu.com/*`: the pattern stays, and the script becomes `tuturuuu-hive`. Leave `tuturuuu-hive-maintenance` uploaded. Rollback points that same route back at `tuturuuu-hive-maintenance`. No database write and no rebuild of the maintenance module is required to put the maintenance page back.

## Worker

* Profile selector: `VITE_HIVE_NATIVE_PROFILE=production` at build time. Staging stays the default (`workers_dev` and `preview_urls` off, `TUTURUUU_NOINDEX=1`). Production is `tuturuuu-hive` with the same route flags and `TUTURUUU_NOINDEX=0`. Nothing in config attaches a route.
* Entry: `apps/hive/cloudflare/worker.ts`.
* Host: `hive.tuturuuu.com`. Root-only: `mountHosts` is empty and `unknownHost` is `reject`, so `tuturuuu.com/hive` and any other host answer 404 before app code runs.
* Binding: `ASSETS` (static output, `run_worker_first`). No D1 binding. `apps/hive/db/migrations` is Postgres SQL for `HIVE_DATABASE_URL`. `void.config.ts` sets `database: 'pg'` so Void does not emit those files as a local D1 binding (`DB` / `database_id: local`). The Apps seal still requires `d1_databases` to be the empty normalizer default.
* Variables (names): `TUTURUUU_NOINDEX`, optional `INTERNAL_WEB_API_ORIGIN` (default `https://tuturuuu.com`).
* Secrets (names, set in the Worker, never in the repo): `NEXT_PUBLIC_SUPABASE_URL`, `NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY`, `SUPABASE_SECRET_KEY`, `TUTURUUU_APP_COORDINATION_SECRET`, `HIVE_DATABASE_URL`, `HIVE_REALTIME_TOKEN_SECRET`, `GOOGLE_GENERATIVE_AI_API_KEY`, `CRON_SECRET`. Compare with the Vercel project environment list before the flip.
* Optional variables read by the source: `HIVE_REALTIME_URL`, `HIVE_OLLAMA_BASE_URL`, `HIVE_APP_URL`. Realtime ownership is in the [Hive realtime runbook](https://docs.tuturuuu.com/build/devops/hive-realtime-runbook.md).
* Hive talks to its own database and realtime service; confirm both are reachable from Workers before the flip.

## Build and qualification

```bash theme={null}
bun install --frozen-lockfile --ignore-scripts
bun turbo:local run build --filter=@tuturuuu/hive^... --concurrency=2
bun scripts/ci/generate-build-metadata.ts
bun run --cwd apps/hive routes:check
bun run --cwd apps/hive type-check:cloudflare
export VITE_HIVE_NATIVE_PROFILE=production
export HIVE_SOURCE_SHA="$(git rev-parse HEAD)"
export GITHUB_OUTPUT="$(mktemp)" RUNNER_TEMP="$(mktemp -d)"
bun run --cwd apps/hive build:cloudflare
CI=true CI_SOURCE_SHA="$HIVE_SOURCE_SHA" bun run --cwd apps/hive test:runtime
python3 scripts/ci/hive-native-artifact.py config apps/hive
python3 scripts/ci/hive-native-artifact.py seal apps/hive --receipt "$RUNNER_TEMP/hive-native-artifact.json"
python3 scripts/ci/hive-native-artifact.py pack apps/hive --receipt "$RUNNER_TEMP/hive-native-artifact.json" --archive "$RUNNER_TEMP/hive-cutover.tar.gz"
```

`hive-cloudflare.yaml` runs the same production profile in its `hive-cutover-artifact` job and seals the emitted config with `scripts/ci/hive-native-artifact.py`. The seal reads the config Void wrote. It does not rewrite Worker name, vars, or normalized fields after the build. Run the build on a CI or remote runner, not a developer machine.

`test:runtime` starts the emitted Worker in workerd
with synthetic secrets and no network egress: build identity, root host, apex rejection,
unknown paths, and the signed-out redirect through the app-owned
`cloudflare/auth-redirect.runtime.mjs` fixture (8 checks).

The app proxy admits anonymous `GET`/`HEAD /api/build-info` without an app-session
refresh, so deployment verification gets `200` instead of `401`.

## Smoke checks after the route is attached

```bash theme={null}
curl -sI https://hive.tuturuuu.com/api/build-info   # 200, JSON, no-store
curl -sI https://hive.tuturuuu.com/                 # 307 to /login for a signed-out client
curl -sI https://hive.tuturuuu.com/login            # renders, no 5xx
curl -sI https://tuturuuu.com/hive        # 404 (root-only app)
```

Every page redirects signed-out users to login, so a signed-in check needs a test
session and belongs to the release owner. No smoke request may return `5xx`.

## Rollback

The live origin is the maintenance Worker. After a native cutover, put maintenance
back by binding the route `hive.tuturuuu.com/*` to `tuturuuu-hive-maintenance` again.
Keep the maintenance script in place so rollback is that route change.

1. Before the flip, record the route id, the script it points at (`tuturuuu-hive-maintenance`), and the DNS record for `hive.tuturuuu.com`.
2. To leave maintenance, point `hive.tuturuuu.com/*` at `tuturuuu-hive`. To restore maintenance, point the same pattern back at `tuturuuu-hive-maintenance`.
3. Rerun the maintenance checks (503, `Retry-After: 300`, noindex) or the native smoke checks, matching the script the route names.

Rolling back touches no database rows and no migrations. Route changes belong to the release owner.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.