> ## 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

> Voxel research playground for CRDT worlds, farming simulation, NPC economies, and manual or autonomous society experiments.

Hive is the Tuturuuu research satellite app at `https://hive.tuturuuu.com`.
It uses the centralized Tuturuuu login handoff and keeps protected product APIs
inside `apps/web` under `/api/v1/hive/*`.

Hive consumes cross-app login tokens through `/verify-token`. That verifier
posts the handoff token to `/api/auth/verify-app-token`, trusts the returned
HttpOnly app-session cookies, and then redirects to the requested Hive path.
Protected routes require both the Hive-local app-session cookie and the
Web-issued app-session cookie used for forwarded central APIs. If only the
Hive-local cookie remains, Hive sends the browser through local `/login` to
recover the full cookie pair. Expired access tokens should rotate through
same-origin `/api/auth/refresh-app-session` while refresh cookies remain valid.
Hive must not create or refresh a Hive-domain Supabase Auth session. Hive local
logout is intentionally app-local: `/api/auth/logout` clears
`tuturuuu_app_session`, expires stale Supabase Auth cookies on the Hive host, and
redirects browser form submissions back to `/login`. Keep that route outside the
generic API proxy guard path so logout does not wait on product API rate-limit
checks.

## Dual-Host Parity

Hive is available through both the standalone satellite host and the main web
dashboard. The standalone route shape stays `/` and `/not-whitelisted`. Inside
`apps/web`, the route shape is `/{wsId}/hive` and
`/{wsId}/hive/not-whitelisted`; the `wsId` segment is only the surrounding web
dashboard context and must not filter Hive servers, snapshots, realtime
membership, or world data.

Both hosts must render the same shared Studio UI, engine, realtime client, data
hooks, and access-request card from `@tuturuuu/hive-ui`. Keep `apps/hive` and
the `apps/web` Hive routes as thin host wrappers for auth, access resolution,
build metadata, and forwarded API context only. Future Hive feature work belongs
in `packages/hive-ui`, `@tuturuuu/realtime/hive`, or the centralized Hive APIs
so the standalone app and web-hosted app stay 1:1.

## Access Model

* Production access is resolved from Supabase `public.hive_members` with
  `enabled = true` plus platform-admin roles. The dedicated Hive Postgres
  `hive_members` table is still synchronized for product data workflows, but
  app access gates must not require `HIVE_DATABASE_URL` just to decide whether a
  signed-in user can open Hive.
* Researchers who authenticate successfully but are not enabled land on
  `/not-whitelisted`, where they can create or refresh a
  `hive_access_requests` row. That page polls
  `/api/v1/hive/access-requests/me` every 5 seconds and opens Hive automatically
  after the request reaches the approved/access-enabled state.
* Platform admins are users whose `platform_user_roles.allow_role_management`
  value is `true`; they can create and manage Hive servers and Hive members.
* Root workspace admins can enable or disable Hive access from
  `/{rootWorkspaceId}/platform/roles` without opening the Hive satellite app.
* Pending Hive requests appear in the same platform roles panel. Approving a
  request writes both the dedicated Hive Postgres `hive_members` row and the
  Supabase `public.hive_members` row that the Hive satellite uses for its local
  server gate and that `apps/web` uses for embedded Hive routes. Do not update
  only one store, or users can authenticate through Tuturuuu and then loop back
  to the restricted page or fail an embedded Hive preload.
* V1 server policy is intentionally broad: every enabled Hive member can join
  every enabled Hive server.
* Hive servers are global research worlds. Workspace selection inside the Hive
  editor is only an AI context and billing control; it must not filter server
  lists, snapshots, realtime membership, or world data.
* `apps/web` remains the login authority and verifies platform roles through
  internal APIs. Hive itself uses the app-session JWT as the local identity
  cookie. Hive product data is split across two databases (see
  [Data Model](#data-model)): the authoritative world-event, CRDT, and research
  tables live in the main Supabase `public` schema, while a parallel Docker-managed
  Hive Postgres baseline accessed through `HIVE_DATABASE_URL` carries the
  dedicated-store mirror used by backfill and product-data workflows.

## Data Model

Hive product state spans **two physical databases**, and it matters which one is
authoritative for any given table when you operate or debug the app.

### Authoritative store: main Supabase `public` schema

The live world-event, CRDT, economy, NPC, and research tables that the running
`/api/v1/hive/*` routes read and write are in the **main Supabase project**
(`public.hive_*`). All apps share one Supabase project, so these tables are
managed by the standard Supabase migration flow in
`apps/database/supabase/migrations/`, not by the Hive Postgres migrator. This is
where the audited world-event path actually runs:

* `hive_servers`
* `hive_world_states` — authoritative full-world snapshots
* `hive_world_events` — event metadata and compact payloads
* `hive_npcs`, `hive_npc_runs`, `hive_npc_memories`
* `hive_workflows`, `hive_workflow_runs`
* `hive_research_sessions`, `hive_research_session_events`
* `hive_members`, `hive_access_requests`

The `apply_hive_world_event()` Postgres function is defined as
`public.apply_hive_world_event(...)` in the Supabase migrations
(`20260510143500_add_hive_research_engine.sql`, then hardened by
`20260511160200_fix_hive_world_event_ambiguity.sql`,
`20260512151000_make_hive_revision_conflicts_non_exceptional.sql`, and
`20260512204028_secure_hive_world_event_actor.sql`). It inserts/updates
`public.hive_world_states` and appends to `public.hive_world_events` in one
transaction. It is **not** a Hive-Postgres migration. If a world save returns
`hive_event_failed`, debug it against Supabase — see
[Hive world event troubleshooting](/platform/applications/hive-world-event-troubleshooting).

### Dedicated Hive Postgres mirror (`HIVE_DATABASE_URL`)

A separate Docker-managed Hive Postgres database holds a parallel
dedicated-store baseline (`apps/hive/db/001_schema.sql`) that the one-shot
backfill path populates from legacy Supabase Hive rows. Its `001_schema.sql`
baseline declares its own copies of `hive_members`, `hive_access_requests`,
`hive_servers`, `hive_world_states`, `hive_world_events`,
`hive_research_sessions`, `hive_research_session_events`, `hive_crdt_updates`,
`hive_npcs`, `hive_npc_needs`, `hive_npc_wallets`, `hive_npc_memories`,
`hive_npc_runs`, `hive_ledger_entries`, `hive_inventory_items`,
`hive_warehouses`, `hive_trade_offers`, `hive_crop_instances`, and
`hive_simulation_ticks`. The `apply_hive_world_event` function and the
world-event/actor-security logic are **not** present in this baseline; that path
lives only in Supabase.

Because the dedicated baseline mirrors many of the same table names, do not
assume a fix applied to one database is visible to the other. App access gates
read Supabase `public.hive_members` (and platform-admin roles), and approving a
request writes **both** stores (see [Access Model](#access-model)).

## Database Migrations

Hive Postgres is forward-migrated by the `hive-db-migrate` Docker Compose job
before web, Hive, Hive realtime, or Hive cron processes are allowed to start.
The deployment watcher also runs that job explicitly with
`docker compose run --rm --no-build hive-db-migrate` on every blue/green
deployment so an already-completed migration container cannot silently satisfy a
new deploy.
After the explicit run and after Hive services start, the watcher removes the
one-shot migrator by Docker Compose project and service labels, including
stopped containers named like `tuturuuu-hive-db-migrate-*`, so the migration
job does not stay around consuming host resources or making the cluster look
unhealthy.

The migration runner records successful work in `hive_schema_migrations` with a
timestamp version, filename, checksum, `applied_at`, and `applied_by`. The
current `apps/hive/db/001_schema.sql` file is the immutable baseline; future
changes belong in `apps/hive/db/migrations/YYYYMMDDHHMMSS_description.sql`.
Deployment fails when a pending migration checksum disagrees with history, when
its timestamp is not newer than the last recorded migration version, or when its
timestamp is not newer than the last recorded `applied_at` time at deployment
start.

The runner rejects reset-style SQL such as `DROP DATABASE`, `DROP SCHEMA`,
`DROP TABLE`, `TRUNCATE`, `ALTER TABLE ... DROP COLUMN`, and mutation of
`hive_schema_migrations`. A destructive Hive DB operation requires an explicit
DevOps-admin override by setting `HIVE_DB_OPERATOR_ROLE=devops-admin`,
`HIVE_DB_ALLOW_DESTRUCTIVE_RESET=1`, and
`HIVE_DB_DEVOPS_ADMIN_APPROVED=1`; do not set those values in normal deploy
environments.

When the migration runner finds an older Hive DB that already has runtime tables
but no `hive_schema_migrations` history, it performs a forward-only compatibility
pass before recording the baseline. That pass creates the research-session table
when needed and adds missing nullable `research_session_id` columns to legacy
event, NPC run, and simulation tick tables so the immutable baseline can replay
without failing on partial indexes.

Shared editor state is a Yjs CRDT document per Hive server. Terrain blocks,
objects, public NPC projections, farm tiles, and visual warehouse/crop
projections live in keyed CRDT maps. Money, item ownership, trade settlement,
warehouse transfers, LLM spend, and bankrupt elimination stay relational and
transactional in Postgres so currency and inventory cannot be duplicated by CRDT
merge behavior.

`revision` is now a compatibility display value backed by the monotonic `op_seq`
audit counter. It is not a write precondition for normal CRDT world edits.
Authoritative economy writes must use SQL transactions, idempotency keys where
available, and ledger rows.

The one-shot Hive backfill path copies legacy Hive rows into the dedicated Hive
Postgres baseline so the dedicated store mirrors prior product data. Note that
the authoritative live world-event, CRDT, economy, NPC, and research writes
performed by `/api/v1/hive/*` run against the main Supabase `public` schema (see
[Data Model](#data-model)); the dedicated Hive Postgres is the mirrored
dedicated store, not the runtime authority for the world-event path. In all
cases, `apps/web` internal APIs use the forwarded app-session cookie to resolve
the caller and platform-admin status.

In Docker production, Hive satellite API rewrites must target the web service
through `INTERNAL_WEB_API_ORIGIN=http://web-proxy:7803`. If that value is empty,
the Hive Next.js rewrite can fall back to the public web origin and turn every
editor save into a browser-to-Hive-to-public-Web round trip.

Hive Docker production builds run the Next.js build through
`scripts/run-hive-docker-next-build.js` under the real `node:24` builder stage.
The builder still copies Bun from the dependency stage for workspace package
builds, but the final Hive `next build --turbopack` step must be launched with
Node and `/tmp/web.env` instead of `bun --env-file` so production E2E image
bakes do not depend on Bun's Next.js process shim.

Hive graph workflows are server-scoped product data. Platform admins author
shared workflow definitions in `hive_workflows`; enabled Hive members can run
enabled, unarchived workflows manually, and every run writes a row in
`hive_workflow_runs` with the input, output, step trace, status, and error
message. Workflow definitions are JSON graphs with typed nodes and edges. V1
manual execution disallows cycles, caps graphs at 80 nodes / 120 edges, and
uses restricted `{{steps.nodeId.output.path}}` or `{{input.path}}` references
only. Do not add arbitrary JavaScript evaluation to workflow config. Workflow
`world_event` nodes can also include a `worldPatch` object with `blocks`,
`objects`, `removeBlockIds`, `removeObjectIds`, or `clear: true`; the engine
applies that patch to the latest server snapshot and persists the result through
the same audited world-event path as manual editor saves.

Workflow `agent_interaction` nodes run configured NPC pairs through the same
LLM-backed interaction path as Agent Studio pair queues, with deterministic
fallback behavior when provider access is unavailable. Mind imports use
`/api/v1/hive/servers/:serverId/mind-simulations` to create NPC agents from a
Mind board, create source graph interaction pairs, and save a Hive workflow that
stamps the Mind source context before running those pairs. That import route is
an admin operation because it creates shared Hive server state.

Research sessions are the shared audit spine for multi-agent experiments. A
running `hive_research_sessions` row can be attached to NPC runs, workflow
runs, world events, and simulation ticks through nullable `research_session_id`
columns. When a run payload omits `researchSessionId`, the backend attaches the
active running session for that server when one exists. Session events in
`hive_research_session_events` record operational actions such as session
creation/update and pair queue start/complete markers. Session exports are
available from
`/api/v1/hive/servers/:serverId/research-sessions/:sessionId/export` as JSON or
JSONL and should preserve enough identifiers to replay research timelines
outside the app.

Shared realtime payloads and Hive CRDT helpers live in
`@tuturuuu/realtime/hive`. Keep protocol schemas there when both `apps/hive`,
`apps/hive-realtime`, or `apps/web` need the same message or document contract.

## AI Credit Context

Hive uses the same AI credit and model contracts as the main dashboard. The
editor top bar owns the workspace picker, personal/workspace credit source
toggle, credit meter, and model picker. The selected workspace is the credit
context only; it does not scope Hive servers.

Manual NPC runs and manual NPC-to-NPC interactions send `creditSource`,
`creditWsId`, and `model` through the Hive internal API. The web route verifies
that the signed-in Hive user can access the selected workspace, resolves the
requested model against the workspace plan, preflights AI credits, runs the LLM,
and deducts credits only after successful model usage. A failed post-generation
credit deduction is a request failure: the provider output is not persisted or
returned to the caller. If model access is not configured, the route can still
persist a deterministic NPC decision for inspectable simulation history.

Autonomous NPC interactions use server settings instead of the current browser
selection. `defaultCreditSource`, `defaultCreditWsId`, and `defaultModel` define
the billing/model context for scheduled simulation work. If the billing
workspace is missing or unauthorized, scheduled LLM autonomy is skipped and the
normal simulation tick continues.

`hive_npc_runs` stores grouped interaction metadata for manual pair queues,
one-shot manual runs, autonomous runs, and workflow-triggered decisions:
`interaction_id`, source/target NPCs, trigger, status, model, provider, token
counts, credit source/workspace, deducted credits, errors, and optional
`research_session_id`. Timeline surfaces should group or filter from this
persisted run history plus world events, workflow runs, simulation ticks, and
session events rather than recomputing transcripts from transient client state.

## Editor Surface

`apps/hive` is a hidden-locale Next.js satellite app. The editor uses a
full-bleed React Three Fiber viewport, compact top status chips, a bottom tool
dock with build/settings controls, an Agent Studio rail, a research timeline
drawer, and selected-detail overlays. The 3D world remains mounted while users
open agent setup, workflow authoring, timeline observability, AI context, or
operations controls.

The editor is built on the shared `@tuturuuu/satellite` workspace shell. Hive
uses that shell for collapsible left/right rails, top research overlays, and the
bottom tool dock so satellite apps can share layout mechanics while keeping
Hive-specific tool density and viewport behavior.

Collapsed editor slots must remove hit targets as well as opacity. Hidden Hive
toolbars use the satellite shell's collapsed `visibility` and pointer-event
gating so invisible dock buttons cannot still receive hover, focus, or tooltip
events.

Hive keeps one editable CRDT world per server. Admins manage that world through
server controls: creating a server creates its world, deleting a server deletes
the world through database cascade, and clear/reseed actions persist typed audit
events plus CRDT updates against the current server document.

Manual editor changes persist through the web gateway world-event API, which
calls the Supabase `public.apply_hive_world_event()` function. That function
stores the authoritative `world_data` and the matching event metadata in the
same Supabase transaction, then the Hive client only broadcasts the already
applied event through `hive-realtime`. Do not add a second client-side
`sync.update` persistence write after the gateway event succeeds; duplicate
writes can churn `op_seq`, slow visible save completion, and let older world
snapshots overwrite newer local edits. Realtime and snapshot consumers must
also ignore equal or older revisions so delayed broadcasts cannot revert an
optimistic edit that already advanced locally.

Keep full-world snapshots in `hive_world_states` only. `hive_world_events`
should store event metadata and the compact event payload, not another copy of
`world_data`, because normal editor saves can otherwise rewrite and insert the
entire voxel world twice on every operation.

The 3D editor treats the voxel grid as the source of truth. Perspective comes
from the camera and controls, not from rotating the editable world group. World
edits should commit only after click/drag threshold handling so orbit, pan,
zoom, placement, erasing, moving, and rotating do not conflict with each other.
The bottom dock uses explicit persistent panel toggles instead of hover-only
expansion. Build catalog, editor settings, and live operations each have a
visible icon control. Minimal tile gaps are the default terrain presentation;
gapless rendering is an explicit settings toggle. The Settings dock tab owns the
continuous 24-hour time slider, auto-time speed, season, weather, camera
presets, and simulation/server toggles. Do not restore the older five fixed
visible time buttons as the primary time control.

Live operations in the dock must use existing Hive snapshot state rather than a
new route: world counts, crops, warehouses, server currency, events, online
users, realtime status, revision, and the last sync notice. Agent Studio owns
multi-agent setup and ordered pair queues: multi-select NPCs, batch role/memory
/autonomy edits, round-robin pairs, all-to-all pairs, custom target pairs, run
prompt, turn count, and current AI context. NPC Lab remains the selected-agent
detail editor only. When no NPC is selected, it should show a selection prompt
instead of silently mutating the first NPC in the server.

The editor uses a single Research Studio panel state instead of separate
full-screen World / Workflow graph / Timeline destinations. Workflow graph is a
focused overlay on top of the persistent world viewport. Timeline is a drawer
that reads `/api/v1/hive/servers/:serverId/timeline`, filters by research
session and run metadata, and expands rows into input/output context, status,
model/provider, credits, and export identifiers. Workflow mode is still a 2D
React Flow graph builder for manual Hive automations, but it must reuse the same
AI context, run trace, and research timeline contracts as NPC pair queues.
Embedded `apps/web` Hive routes should load `@xyflow/react/dist/style.css` from
the Hive route segment layout rather than the root web layout, so React Flow
styles are available for workflow mode without adding that CSS to unrelated
dashboard routes.
Admins can drag nodes from the palette, use starter templates, edit JSON config
in the inspector, save shared workflows, and run them against the selected
server. Members see the same graph read-only and can manually run saved
workflows. Workflow runs apply live effects through the same gateway-backed Hive
actions used elsewhere: world events, simulation ticks, NPC decision records,
farming, warehouses, and trades. Effects are audited through the workflow run
trace, research session timeline, and existing Hive event/economy tables; v1 has
no schedule, webhook trigger, retry queue, credential vault, or rollback
approval layer.

Starter workflow templates should demonstrate a real server-side use case, not
just create trace rows. The farm cycle template plants a relational crop, then
uses a `world_event.worldPatch` step to stamp a visible crop plot into the Hive
world. The cleanup template removes that starter plot by id and records the
maintenance event.

Keep manual and autonomous interaction rows grouped by `interaction_id` whenever
a deeper transcript view is added. Pair queue runs must execute pairs in request
order and return partial failures without dropping successful earlier pairs.

NPC Lab is a draft editor for the selected NPC only. Identity, brain/model,
behavior/autonomy, memory/prompt flags, system prompt, and interaction controls
belong in the lab tabs. Save/Reset should protect large text and settings edits
from accidental persistence, while manual run buttons can launch one-shot
decisions or targeted NPC-to-NPC interactions using the current AI credit
context.

The chat composer is opt-in from the editor chrome button, and the mini-map is
a collapsible viewport overlay. If all Hive servers are deleted, the editor must
clear local world, NPC, revision, selection, presence, and awareness state so it
does not keep rendering the last server snapshot.

Time of day still maps to authored scene backdrops and lerped lighting, fog,
background, and cloud tint. Weather and season controls layer visual atmosphere
over that time base without changing the durable CRDT world snapshot.
Realtime multiplayer awareness is ephemeral. Avatar badges, terrain cursors,
selection rings, active tool state, camera focus, and in-world user markers are
sent as TTL-based awareness updates and must not be persisted into durable
world snapshots.

Offline world edits are queued as CRDT updates and replayed on reconnect. The
client uses token refresh, exponential backoff, state-vector resync, throttled
cursor/position updates, and local actor echo suppression to keep the research
surface responsive during reconnects and slow-client conditions.

Client data access must go through `@tuturuuu/internal-api` helpers and
TanStack Query. Do not add raw client `fetch()` calls in the satellite app.

## Testing

Hive has app-local Playwright coverage in `apps/hive/e2e`. The suite assumes
the local web app on `https://tuturuuu.localhost` and Hive app on
`https://hive.tuturuuu.localhost` are already running through Portless; it does
not auto-start dev servers. Root `bun test:e2e` intentionally runs the
self-contained Dockerized web E2E suite instead; after starting the Portless
services for Hive, run Hive coverage with:

```bash theme={null}
bun --filter @tuturuuu/hive test:e2e
```

The authenticated setup uses the web app's development session endpoint for the
seeded `local@tuturuuu.com` account before opening Hive. Override
`WEB_BASE_URL` or `HIVE_BASE_URL` when bypassing Portless or using direct
fallback ports.

## Economy And Farming

Each Hive server has a total currency pool, NPC wallets, inventories,
warehouses, trade offers, crops, and ledger-backed transfers. NPCs have hunger,
energy, morale, upkeep, and optional LLM spend budgets. Crop rules cover
soil/water/fertilizer state, growth stages, harvest yields, and day-cycle
simulation.

Manual tools can plant, water, harvest, deposit, withdraw, and settle trades.
Autonomous ticks can advance crops, choose NPC jobs, apply upkeep, record LLM
run costs, credit earnings, and eliminate NPCs whose wallets cannot cover
required costs.

Cron-backed Hive simulation is intentionally disabled by default. Enable global
Hive cron and per-server autonomous simulation through Hive settings only after
budget limits, tick interval, and max LLM spend have been reviewed.

## LLM Providers

Ollama is optional and disabled by default. Docker can start the
`hive-ollama` profile, and Hive settings can enable the local model id exactly
as `gemma4`. The app loads the model through Ollama's generate API, generates
through `/api/generate`, and unloads by sending `keep_alive: 0`.

Every Mira-powered LLM path must be gated by an exact `@tuturuuu.com` email
check. Subdomains such as `@xwf.tuturuuu.com` are not Tuturuuu-internal for
Mira access.
