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

# Development

> Use explicit test fixtures, local emulators, and verification suites without confusing them with provider evidence.

## Explicit test-fixture modes

Harmonia's model and social-effect legs have explicit development-only fixtures for contract testing. Identity still uses Google sign-in and durable workflow state uses the emulators. With either flag unset, fixture code is unreachable. A fixture run must never be used in a demo, benchmark, provider claim, or authenticated evidence bundle.

### `HARMONIA_MOCK_AI=1`

Replaces every Gemini call with deterministic local fixtures that satisfy the exact JSON shapes of the real stages:

* **Transcription** — segments derived from audio size, plausible startup-podcast text
* **Analysis / strategy** — Nimi summary and grounded moments/angles, followed by Ryan's typed strategy proposal and briefs
* **Drafting** — three ≤280-char X posts referencing moment/angle ids
* **Image generation** — renders a *real* PNG locally via ffmpeg lavfi
* **Chat intent parsing** — keyword rules instead of structured output
* **Proactive proposals** — deterministic proposals derived from fixture signals; later learning inputs re-enter Ryan through the same strict strategy contract

Every mock path logs loudly (`[MOCK-AI] ...`) and persisted `modelUsed` labels read `mock-local (HARMONIA_MOCK_AI)` so offline runs are never mistaken for real model calls.

### `HARMONIA_MOCK_X=1`

Independent flag covering the X API client only. Publishing returns a deterministic id derived from the post text hash (`mock-<sha256[:12]>`), and verification/metrics return small stable payloads. This is useful for development assertions only. Leave it off when testing honest integration failures or collecting real evidence.

### What fixture mode still executes locally

Firestore and Pub/Sub run as Google emulators locally; ffmpeg rendering and the local asset store execute real code. Receipts and verification records exercise the real schemas but refer to fixture effects when `HARMONIA_MOCK_X=1`. YouTube ingestion through yt-dlp still uses the network and requires source authorization.

## Emulator-based workflow

`scripts/dev.sh` pins both emulators to fixed ports and exports:

```bash theme={"system"}
FIRESTORE_EMULATOR_HOST=127.0.0.1:8081
PUBSUB_EMULATOR_HOST=127.0.0.1:8082
GOOGLE_CLOUD_PROJECT=harmonia-local   # any project id works against emulators
```

The worker consumes stage triggers through a pull loop against the Pub/Sub emulator — the same dispatch path as the Cloud Run push receiver in production.

## Test suites

```bash theme={"system"}
# Web: lint, types, unit tests (vitest)
npm run lint && npx tsc --noEmit && npm test

# Worker: pytest
cd agent && ./.venv/bin/python -m pytest tests -q
```

Worker tests set safe dummy credentials via `agent/tests/conftest.py`; mock-mode tests exercise the fixture generators and assert their output shapes match the real stages' contracts.

## Useful local endpoints

| Endpoint                                   | Purpose                                                                       |
| ------------------------------------------ | ----------------------------------------------------------------------------- |
| `GET /api/proposals`                       | Proactive proposal inbox feed                                                 |
| `GET /api/content-items`                   | Calendar items                                                                |
| `GET /api/notifications`                   | Bell notifications                                                            |
| `POST /api/chat`                           | Chat surface (`{message, surface}`)                                           |
| `POST /api/chat/stream`                    | Durable Console stream (`{message, surface, attachmentIds}`), NDJSON response |
| `POST /api/chat/attachments/session`       | Create a validated resumable upload session                                   |
| `POST /api/chat/attachments/{id}/complete` | Verify bytes, quarantine, scan, and mark ready only on a clean verdict        |
| `GET /api/chat/runs/{id}/events?after=N`   | Replay persisted stream events after sequence `N`                             |
| `GET /api/internal/insights`               | Verified engagement and eligible context fed into Nimi/Ryan                   |

Internal routes require service authentication plus workspace and brand headers. Dashboard routes require a verified Google session and derive the workspace from server-side membership.

Cloud Storage direct uploads require bucket CORS to permit the deployed web origin to `PUT` the allowed content types and expose resumable-upload response headers. The application never sends Cloud Storage credentials to the browser; it returns only the single-object resumable session URL. With `GCS_BUCKET` unset, the authenticated local upload route stores bytes in `.data/artifacts`.
